[med-svn] [scrm] 01/04: Imported Upstream version 1.6.1

Kevin Murray daube-guest at moszumanska.debian.org
Fri Jan 8 07:41:01 UTC 2016


This is an automated email from the git hooks/post-receive script.

daube-guest pushed a commit to branch master
in repository scrm.

commit 5b13f3f4ce402bc69a75d9ec815c12e2fc5cc5fd
Author: Kevin Murray <spam at kdmurray.id.au>
Date:   Fri Jan 8 12:02:33 2016 +1100

    Imported Upstream version 1.6.1
---
 .gitignore                                         |   88 +
 .gitmodules                                        |    0
 .travis.yml                                        |   35 +
 .travis/build_src_pkg.sh                           |   11 +
 .travis/build_static_binaries.sh                   |    7 +
 .travis/build_win_binaries.sh                      |   12 +
 AUTHORS                                            |   10 +
 COPYING                                            |  674 +++++
 Makefile.am                                        |   71 +
 NEWS                                               |    1 +
 NEWS.md                                            |  196 ++
 README                                             |    1 +
 README.md                                          |   69 +
 bootstrap                                          |    8 +
 configure.ac                                       |   46 +
 doc/README.md                                      |   17 +
 doc/create-manual.sh                               |   29 +
 doc/knitr.css                                      |  156 ++
 doc/scrm.1                                         |  161 ++
 m4/ax_append_flag.m4                               |   69 +
 m4/ax_cflags_warn_all.m4                           |  122 +
 m4/ax_check_compile_flag.m4                        |   74 +
 m4/ax_check_link_flag.m4                           |   73 +
 m4/ax_cxx_compile_stdcxx_11.m4                     |  158 ++
 m4/ax_require_defined.m4                           |   37 +
 src/contemporaries_container.h                     |  364 +++
 src/doxygen_notation.txt                           |   23 +
 src/event.h                                        |  106 +
 src/forest-debug.cc                                |  635 +++++
 src/forest.cc                                      | 1344 ++++++++++
 src/forest.h                                       |  328 +++
 src/macros.h                                       |   71 +
 src/model.cc                                       |  710 ++++++
 src/model.h                                        |  529 ++++
 src/node.cc                                        |  169 ++
 src/node.h                                         |  212 ++
 src/node_container.cc                              |  300 +++
 src/node_container.h                               |  299 +++
 src/param.cc                                       |  536 ++++
 src/param.h                                        |  146 ++
 src/random/constant_generator.cc                   |   30 +
 src/random/constant_generator.h                    |   44 +
 src/random/fastfunc.cc                             |   49 +
 src/random/fastfunc.h                              |  100 +
 src/random/mersenne_twister.cc                     |   68 +
 src/random/mersenne_twister.h                      |   53 +
 src/random/random_generator.cc                     |   78 +
 src/random/random_generator.h                      |  105 +
 src/random/speedtest.cc                            |  201 ++
 src/scrm.cc                                        |   98 +
 src/summary_statistics/frequency_spectrum.cc       |   43 +
 src/summary_statistics/frequency_spectrum.h        |   66 +
 src/summary_statistics/newick_tree.cc              |   80 +
 src/summary_statistics/newick_tree.h               |   81 +
 src/summary_statistics/oriented_forest.cc          |   75 +
 src/summary_statistics/oriented_forest.h           |   65 +
 src/summary_statistics/seg_sites.cc                |   81 +
 src/summary_statistics/seg_sites.h                 |   75 +
 src/summary_statistics/summary_statistic.h         |   46 +
 src/summary_statistics/tmrca.cc                    |   34 +
 src/summary_statistics/tmrca.h                     |   57 +
 src/time_interval.cc                               |  234 ++
 src/time_interval.h                                |  149 ++
 src/tree_point.cc                                  |   43 +
 src/tree_point.h                                   |   46 +
 tests/README.md                                    |   21 +
 tests/algorithmtest/test_algorithm.cc              |  256 ++
 tests/cppunit/test_runner.cc                       |   35 +
 tests/cppunit/test_template.cc                     |   36 +
 tests/manualtests/LD/Untitled0.ipynb               | 2654 ++++++++++++++++++++
 tests/manualtests/LD/alldata.txt                   |  204 ++
 tests/manualtests/LD/cluster/1Pop20sample.par      |   18 +
 tests/manualtests/LD/cluster/1Pop6sample.par       |   18 +
 .../Constantpopsizefastsimcoal_Processed           |    4 +
 .../Constantpopsizemacs_Processed                  |    4 +
 .../Constantpopsizemacsretain100000_Processed      |    4 +
 .../Constantpopsizemacsretain10000_Processed       |    4 +
 .../Constantpopsizemacsretain1000_Processed        |    4 +
 .../Constantpopsizemacsretain30000_Processed       |    4 +
 .../Constantpopsizemacsretain50000_Processed       |    4 +
 .../Constantpopsizemacsretain70000_Processed       |    4 +
 .../6sample_processed/Constantpopsizems_Processed  |    4 +
 .../Constantpopsizescrmwindow0_Processed           |    4 +
 .../Constantpopsizescrmwindow100000_Processed      |    4 +
 .../Constantpopsizescrmwindow10000_Processed       |    4 +
 .../Constantpopsizescrmwindow1000_Processed        |    4 +
 .../Constantpopsizescrmwindow30000_Processed       |    4 +
 .../Constantpopsizescrmwindow3000_Processed        |    4 +
 .../Constantpopsizescrmwindow50000_Processed       |    4 +
 .../Constantpopsizescrmwindow5000_Processed        |    4 +
 .../Constantpopsizescrmwindow500_Processed         |    4 +
 .../Constantpopsizescrmwindow70000_Processed       |    4 +
 .../Constantpopsizescrmwindow7000_Processed        |    4 +
 .../cluster/Constantpopsizefastsimcoal_Processed   |    4 +
 .../LD/cluster/Constantpopsizemacs_Processed       |    4 +
 .../cluster/Constantpopsizemacsretain0_Processed   |    4 +
 .../Constantpopsizemacsretain100000_Processed      |    4 +
 .../Constantpopsizemacsretain10000_Processed       |    4 +
 .../Constantpopsizemacsretain1000_Processed        |    4 +
 .../Constantpopsizemacsretain30000_Processed       |    4 +
 .../Constantpopsizemacsretain3000_Processed        |    4 +
 .../Constantpopsizemacsretain50000_Processed       |    4 +
 .../Constantpopsizemacsretain5000_Processed        |    4 +
 .../cluster/Constantpopsizemacsretain500_Processed |    4 +
 .../Constantpopsizemacsretain70000_Processed       |    4 +
 .../Constantpopsizemacsretain7000_Processed        |    4 +
 .../LD/cluster/Constantpopsizems_Processed         |    4 +
 tests/manualtests/LD/cluster/Constantpopsizeparam  |   22 +
 .../cluster/Constantpopsizescrmwindow0_Processed   |    4 +
 .../Constantpopsizescrmwindow100000_Processed      |    4 +
 .../Constantpopsizescrmwindow10000_Processed       |    4 +
 .../Constantpopsizescrmwindow1000_Processed        |    4 +
 .../Constantpopsizescrmwindow30000_Processed       |    4 +
 .../Constantpopsizescrmwindow3000_Processed        |    4 +
 .../Constantpopsizescrmwindow50000_Processed       |    4 +
 .../Constantpopsizescrmwindow5000_Processed        |    4 +
 .../cluster/Constantpopsizescrmwindow500_Processed |    4 +
 .../Constantpopsizescrmwindow70000_Processed       |    4 +
 .../Constantpopsizescrmwindow7000_Processed        |    4 +
 .../LD/cluster/Divergence_test/Dpopparam           |   12 +
 .../LD/cluster/Divergence_test/Dsubmit_ms.sh       |   40 +
 .../LD/cluster/Divergence_test/Dsubmit_scrm0.sh    |   40 +
 .../LD/cluster/Divergence_test/Dsubmit_scrm1000.sh |   40 +
 .../cluster/Divergence_test/Dsubmit_scrm10000.sh   |   40 +
 .../cluster/Divergence_test/Dsubmit_scrm100000.sh  |   40 +
 .../cluster/Divergence_test/Dsubmit_scrm50000.sh   |   40 +
 .../LD2E4/Constantpopsizefastsimcoal_Processed     |    4 +
 .../LD/cluster/LD2E4/Constantpopsizemacs_Processed |    4 +
 .../LD2E4/Constantpopsizemacsretain0_Processed     |    4 +
 .../Constantpopsizemacsretain100000_Processed      |    4 +
 .../LD2E4/Constantpopsizemacsretain10000_Processed |    4 +
 .../LD2E4/Constantpopsizemacsretain1000_Processed  |    4 +
 .../LD2E4/Constantpopsizemacsretain30000_Processed |    4 +
 .../LD2E4/Constantpopsizemacsretain3000_Processed  |    4 +
 .../LD2E4/Constantpopsizemacsretain50000_Processed |    4 +
 .../LD2E4/Constantpopsizemacsretain5000_Processed  |    4 +
 .../LD2E4/Constantpopsizemacsretain500_Processed   |    4 +
 .../LD2E4/Constantpopsizemacsretain70000_Processed |    4 +
 .../LD2E4/Constantpopsizemacsretain7000_Processed  |    4 +
 .../LD/cluster/LD2E4/Constantpopsizems_Processed   |    4 +
 .../LD2E4/Constantpopsizescrmwindow0_Processed     |    4 +
 .../Constantpopsizescrmwindow100000_Processed      |    4 +
 .../LD2E4/Constantpopsizescrmwindow10000_Processed |    4 +
 .../LD2E4/Constantpopsizescrmwindow1000_Processed  |    4 +
 .../LD2E4/Constantpopsizescrmwindow30000_Processed |    4 +
 .../LD2E4/Constantpopsizescrmwindow3000_Processed  |    4 +
 .../LD2E4/Constantpopsizescrmwindow50000_Processed |    4 +
 .../LD2E4/Constantpopsizescrmwindow5000_Processed  |    4 +
 .../LD2E4/Constantpopsizescrmwindow500_Processed   |    4 +
 .../LD2E4/Constantpopsizescrmwindow70000_Processed |    4 +
 .../LD2E4/Constantpopsizescrmwindow7000_Processed  |    4 +
 .../manualtests/LD/cluster/fastsimcoal_process.py  |   39 +
 tests/manualtests/LD/cluster/fastsimcoal_sim.sh    |   52 +
 tests/manualtests/LD/cluster/launchall.sh          |   29 +
 tests/manualtests/LD/cluster/ld_test.py            |  404 +++
 tests/manualtests/LD/cluster/macs_process.py       |   19 +
 tests/manualtests/LD/cluster/macs_process.src      |   24 +
 tests/manualtests/LD/cluster/macs_retain0.sh       |   14 +
 tests/manualtests/LD/cluster/macs_retain1000.sh    |   14 +
 tests/manualtests/LD/cluster/macs_retain10000.sh   |   14 +
 tests/manualtests/LD/cluster/macs_retain100000.sh  |   14 +
 tests/manualtests/LD/cluster/macs_retain1000000.sh |   14 +
 tests/manualtests/LD/cluster/macs_retain3000.sh    |   15 +
 tests/manualtests/LD/cluster/macs_retain30000.sh   |   14 +
 tests/manualtests/LD/cluster/macs_retain300000.sh  |   14 +
 tests/manualtests/LD/cluster/macs_retain500.sh     |   15 +
 tests/manualtests/LD/cluster/macs_retain5000.sh    |   14 +
 tests/manualtests/LD/cluster/macs_retain50000.sh   |   14 +
 tests/manualtests/LD/cluster/macs_retain500000.sh  |   14 +
 tests/manualtests/LD/cluster/macs_retain7000.sh    |   15 +
 tests/manualtests/LD/cluster/macs_retain70000.sh   |   16 +
 tests/manualtests/LD/cluster/macs_retain700000.sh  |   14 +
 tests/manualtests/LD/cluster/parameters_preset     |   10 +
 tests/manualtests/LD/cluster/plot_new.py           |  136 +
 tests/manualtests/LD/cluster/plotting.py           |   29 +
 tests/manualtests/LD/cluster/process_actions.src   |   17 +
 tests/manualtests/LD/cluster/process_data.py       |  338 +++
 tests/manualtests/LD/cluster/process_data.sh       |   47 +
 tests/manualtests/LD/cluster/submit_ms.sh          |   19 +
 tests/manualtests/LD/cluster/submit_scrm0.sh       |   21 +
 tests/manualtests/LD/cluster/submit_scrm1000.sh    |   19 +
 tests/manualtests/LD/cluster/submit_scrm10000.sh   |   19 +
 tests/manualtests/LD/cluster/submit_scrm100000.sh  |   21 +
 tests/manualtests/LD/cluster/submit_scrm1000000.sh |   21 +
 tests/manualtests/LD/cluster/submit_scrm3000.sh    |   19 +
 tests/manualtests/LD/cluster/submit_scrm30000.sh   |   19 +
 tests/manualtests/LD/cluster/submit_scrm300000.sh  |   21 +
 tests/manualtests/LD/cluster/submit_scrm500.sh     |   19 +
 tests/manualtests/LD/cluster/submit_scrm5000.sh    |   19 +
 tests/manualtests/LD/cluster/submit_scrm50000.sh   |   19 +
 tests/manualtests/LD/cluster/submit_scrm500000.sh  |   21 +
 tests/manualtests/LD/cluster/submit_scrm7000.sh    |   19 +
 tests/manualtests/LD/cluster/submit_scrm70000.sh   |   19 +
 tests/manualtests/LD/cluster/submit_scrm700000.sh  |   21 +
 tests/manualtests/LD/cluster/toyparam              |   13 +
 tests/manualtests/LD/cluster/toyparam.src          |    9 +
 tests/manualtests/LD/ld_test.py                    |  406 +++
 tests/manualtests/README                           |  222 ++
 tests/manualtests/bl_r.src                         |   17 +
 tests/manualtests/chisq_r.src                      |   36 +
 tests/manualtests/fun_src.r                        |   84 +
 tests/manualtests/ks_r.src                         |   20 +
 tests/manualtests/ms_first_vs_last.sh              |   69 +
 tests/manualtests/ms_vs_scrm-bl.sh                 |   52 +
 tests/manualtests/ms_vs_scrm-mig-popsize.sh        |  120 +
 tests/manualtests/ms_vs_scrm-mig.sh                |  120 +
 tests/manualtests/ms_vs_scrm-mig_more.sh           |  103 +
 tests/manualtests/ms_vs_scrm-mig_more_recomb.sh    |  265 ++
 tests/manualtests/ms_vs_scrm-mig_recomb.sh         |  167 ++
 tests/manualtests/ms_vs_scrm-prune-tmrca.sh        |  173 ++
 tests/manualtests/ms_vs_scrm-prune_mig_recomb.sh   |  265 ++
 tests/manualtests/ms_vs_scrm-recomb-Tifs.sh        |   85 +
 tests/manualtests/ms_vs_scrm-recomb.sh             |   85 +
 tests/manualtests/ms_vs_scrm-seg.sh                |   84 +
 tests/manualtests/ms_vs_scrm-seg_wit_recomb.sh     |   78 +
 .../manualtests/ms_vs_scrm-seg_with_recomb_Tifs.sh |   78 +
 tests/manualtests/ms_vs_scrm-tmrca-wit-recomb.sh   |  176 ++
 .../ms_vs_scrm-tmrca-wit-recomb_Tifs.sh            |  176 ++
 tests/manualtests/ms_vs_scrm-tmrca.sh              |   52 +
 tests/manualtests/ms_vs_scrm-topofreq.sh           |   31 +
 .../ms_vs_scrm_1st_last_tmrca_2sample.sh           |  109 +
 tests/manualtests/ms_vs_scrm_SEG_samplestats.sh    |   49 +
 tests/manualtests/ms_vs_scrm_growth-recomb.sh      |  137 +
 tests/manualtests/ms_vs_scrm_growth.sh             |  169 ++
 .../ms_vs_scrm_last_tmrca-wit-recomb.sh            |  140 ++
 tests/manualtests/ms_vs_scrm_pop_struct.sh         |  184 ++
 tests/manualtests/ms_vs_scrm_subpop_struct.sh      |   79 +
 tests/manualtests/mysample_stats.c                 |  200 ++
 tests/manualtests/pairwise_test.sh                 |   44 +
 tests/manualtests/process_sample_stats.src         |   54 +
 tests/manualtests/pruning_test/compute_moment.py   |   33 +
 tests/manualtests/pruning_test/grep_stats.sh       |   48 +
 tests/manualtests/pruning_test/ms_sim.sh           |   38 +
 tests/manualtests/pruning_test/parameters          |   21 +
 tests/manualtests/pruning_test/printing_table.r    |   41 +
 .../pruning_test/prune_test_top_script.sh          |  270 ++
 tests/manualtests/pruning_test/r_tests.r           |  118 +
 tests/manualtests/pruning_test/scrm_sim.sh         |   38 +
 .../manualtests/pruning_test/scrmfull_prune_sim.sh |   38 +
 .../manualtests/pruning_test/scrmprune10000_sim.sh |   38 +
 .../manualtests/pruning_test/scrmprune50000_sim.sh |   38 +
 tests/manualtests/pruning_test/test.sh             |    4 +
 tests/manualtests/scrm_first_vs_last.sh            |   70 +
 tests/manualtests/scrm_prune_vs_ms.sh              |  173 ++
 tests/manualtests/spectrum-wit-recomb.sh           |  104 +
 tests/manualtests/spectrum.sh                      |  123 +
 tests/manualtests/tajd.c                           |  120 +
 tests/manualtests/tmrca_r.src                      |   19 +
 tests/test_binaries.sh                             |   92 +
 tests/test_read_init/3tax_gt                       |    1 +
 tests/test_read_init/4tax_gt                       |    1 +
 tests/test_read_init/bl_r.src                      |   17 +
 tests/test_read_init/chisq_r.src                   |   36 +
 tests/test_read_init/ks_r.src                      |   20 +
 tests/test_read_init/process_sample_stats.src      |   56 +
 tests/test_read_init/scrm_vs_scrmInitialtree.sh    |   55 +
 tests/test_read_init/tmrca_r.src                   |   19 +
 tests/unittests/test_contemporaries_container.cc   |  404 +++
 tests/unittests/test_fastfunc.cc                   |   60 +
 tests/unittests/test_forest.cc                     |  859 +++++++
 tests/unittests/test_model.cc                      |  667 +++++
 tests/unittests/test_node.cc                       |  175 ++
 tests/unittests/test_node_container.cc             |  248 ++
 tests/unittests/test_param.cc                      |  516 ++++
 tests/unittests/test_random_generator.cc           |  141 ++
 tests/unittests/test_seg.cc                        |   56 +
 tests/unittests/test_summary_statistics.cc         |  322 +++
 tests/unittests/test_time_interval.cc              |  264 ++
 tools/build_win_binaries.sh                        |   39 +
 tools/compare_versions.sh                          |   71 +
 tools/runTillError.sh                              |   25 +
 tools/try_seeds.sh                                 |   14 +
 272 files changed, 25012 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a6a5ea2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,88 @@
+# Compiled source #
+###################
+*.com
+*.class
+*.dll
+*.exe
+*.o
+*.so
+*.to
+
+# Packages #
+############
+# it's better to unpack these files and commit the raw source
+# git has its own built in compression methods
+*.7z
+*.dmg
+*.gz
+*.iso
+*.jar
+*.rar
+*.tar
+*.zip
+
+# Logs and databases #
+######################
+*.log
+*.sql
+*.sqlite
+*.swp
+
+tests/tests
+tests/test-*
+tests/bad-tests/
+tests/good-tests/
+tests/*working*
+scrm
+scrm_dbg
+scrm_prof
+
+# automake
+Makefile
+Makefile.in
+autom4te.cache
+config.*
+depcomp
+install-sh
+missing
+configure
+aclocal.m4
+.deps
+INSTALL
+
+
+# ./docs
+doc/latex
+doc/html
+doc/manual.html
+*.bbl
+*.blg
+*.aux
+*.pdf
+*.out
+
+html/
+latex/
+reference/
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+
+compile
+test-driver
+tests/tests.trs
+algorithm_tests
+unit_tests
+stuff
+.dirstamp
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..e69de29
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..bec3864
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,35 @@
+language: cpp
+os:
+- linux
+- osx
+compiler:
+- gcc
+- clang
+sudo: required
+before_install:
+- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:dns/gnu; fi
+- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
+- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq && sudo apt-get install -qqy automake libcppunit-dev valgrind; fi
+- if [ "$TRAVIS_OS_NAME" == "linux" -a "$CC" = "gcc" ]; then sudo apt-get install -qqy g++-5 && sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 50; fi
+- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update && brew install cppunit valgrind; fi
+before_script:
+- ./bootstrap
+script:
+- make scrm scrm_dbg
+- make unittests
+- ./tests/test_binaries.sh
+- make algorithmtest
+before_deploy:
+  - ./.travis/build_src_pkg.sh
+  - ./.travis/build_static_binaries.sh
+deploy:
+  provider: releases
+  api_key:
+    secure: UrEhKzTdSr7NB4ptDYcWKN02XjfgJgN1fNFu8G2a52Jpk1Z3UeenbmKxIDLj11JUlU427br7t1oQyScYSYEGEM5VEI0aWf7D2i9cPfSRD9QYnHOPG2XZE/xgkwWAm0s4TjnTBmudGSxs9g2KRjDXLz1f191jVGIghnHlxw/C9Ok=
+  file:
+    - "scrm-src.tar.gz"
+    - "scrm-x64-static.tar.gz"
+  on:
+    tags: true
+    condition: "$CC = gcc"
+    condition: "$TRAVIS_OS_NAME == linux"
diff --git a/.travis/build_src_pkg.sh b/.travis/build_src_pkg.sh
new file mode 100755
index 0000000..5216659
--- /dev/null
+++ b/.travis/build_src_pkg.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+# Build the manual
+sudo add-apt-repository -y ppa:marutter/c2d4u || exit 1
+sudo apt-get update -qq && sudo apt-get install -qqy pandoc || exit 1
+./doc/create-manual.sh || exit 1
+
+# Build the release
+CXXFLAGS="-O3" ./bootstrap || exit 1
+make clean && make distcheck || exit 1
+mv scrm-*.tar.gz scrm-src.tar.gz || exit 1
diff --git a/.travis/build_static_binaries.sh b/.travis/build_static_binaries.sh
new file mode 100755
index 0000000..4731b38
--- /dev/null
+++ b/.travis/build_static_binaries.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+# Build statically linked binaries
+CXXFLAGS="-O3" LDFLAGS='-static' ./configure || exit 1 
+make clean && make && \
+  tar -zcvf "scrm-x64-static.tar.gz" scrm doc/manual.html
+
diff --git a/.travis/build_win_binaries.sh b/.travis/build_win_binaries.sh
new file mode 100755
index 0000000..0892066
--- /dev/null
+++ b/.travis/build_win_binaries.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# 64 bit
+CXX=i686-w64-mingw32-g++ CXXFLAGS='-O3' LDFLAGS='-static-libgcc -static -lpthread' \
+  ./configure --host=i686-w64-mingw32 || exit 1
+make clean && make && zip scrm-win64.zip scrm.exe doc/manual.html
+
+# 32bit 
+CXX=i686-w64-mingw32-g++ CXXFLAGS='-O3 -m32' \
+  LDFLAGS='-static-libgcc -static -lpthread' \
+  ./configure --host=i686-w64-mingw32 || exit 1
+make clean && make && zip scrm-win32.zip scrm.exe doc/manual.html
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..a5e0297
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,10 @@
+** Authors **
+
+
+Paul R. Staab
+Ludwig-Maximilians-Universität München
+staab at biologie.uni-muenchen.de
+
+Sha (Joe) Zhu
+The Wellcome Trust Centre for Human Genetics, University of Oxford
+e-mail : sha.joe.zhu at gmail.com
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..eb95f96
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,71 @@
+EXTRA_DIST = doc/create-manual.sh doc/knitr.css doc/scrm.1 
+bin_PROGRAMS = scrm 
+man_MANS = doc/scrm.1
+
+TESTS = unit_tests algorithm_tests 
+check_PROGRAMS = unit_tests algorithm_tests scrm_dbg scrm_prof
+PROG = SCRM
+
+dist-hook: 
+	chmod u+w $(distdir)/doc
+	cd $(distdir); ./doc/create-manual.sh $(VERSION)
+
+test: unittests
+
+unittests: unit_tests
+	./unit_tests 
+
+algorithmtest: algorithm_tests
+	./algorithm_tests 
+
+nrml_src = src/param.cc src/forest.cc src/node.cc src/node_container.cc src/time_interval.cc \
+		   src/model.cc src/tree_point.cc \
+		   src/param.h src/forest.h src/node.h src/node_container.h src/time_interval.h \
+		   src/model.h src/tree_point.h src/event.h src/contemporaries_container.h \
+		   src/macros.h
+
+random_src = src/random/random_generator.cc src/random/mersenne_twister.cc \
+			 src/random/fastfunc.cc \
+			 src/random/random_generator.h src/random/mersenne_twister.h \
+			 src/random/fastfunc.h 
+
+sumstat_src = src/summary_statistics/tmrca.cc \
+			  src/summary_statistics/seg_sites.cc \
+			  src/summary_statistics/frequency_spectrum.cc \
+			  src/summary_statistics/newick_tree.cc \
+			  src/summary_statistics/tmrca.h \
+			  src/summary_statistics/seg_sites.h \
+			  src/summary_statistics/frequency_spectrum.h \
+			  src/summary_statistics/newick_tree.h \
+			  src/summary_statistics/summary_statistic.h \
+			  src/summary_statistics/oriented_forest.cc \
+			  src/summary_statistics/oriented_forest.h
+ 
+scrm_src = $(nrml_src) $(random_src) $(sumstat_src)
+
+debug_src = src/random/constant_generator.cc src/random/constant_generator.h \
+			src/forest-debug.cc src/random/constant_generator.h
+
+unit_test_src = tests/unittests/test_forest.cc tests/unittests/test_model.cc\
+				tests/unittests/test_node.cc tests/unittests/test_node_container.cc\
+			   	tests/cppunit/test_runner.cc tests/unittests/test_time_interval.cc\
+			   	tests/unittests/test_fastfunc.cc tests/unittests/test_param.cc\
+				tests/unittests/test_random_generator.cc tests/unittests/test_summary_statistics.cc\
+			    tests/unittests/test_contemporaries_container.cc	
+
+alg_test_src = tests/cppunit/test_runner.cc tests/algorithmtest/test_algorithm.cc 
+
+
+scrm_SOURCES = $(scrm_src) src/scrm.cc
+scrm_dbg_SOURCES = $(scrm_src) $(debug_src) src/scrm.cc
+scrm_prof_SOURCES = $(scrm_src) src/scrm.cc
+unit_tests_SOURCES = $(scrm_src) $(debug_src) $(unit_test_src)
+algorithm_tests_SOURCES = $(scrm_src) $(alg_test_src)
+ 
+scrm_CXXFLAGS= -DNDEBUG @OPT_CXXFLAGS@
+scrm_dbg_CXXFLAGS=
+scrm_prof_CXXFLAGS= -pg -DNDEBUG
+unit_tests_CXXFLAGS = -DUNITTEST -DNDEBUG
+algorithm_tests_CXXFLAGS = -DNDEBUG
+unit_tests_LDADD= -L/opt/local/lib -lcppunit -ldl #link the cppunit unittest library in mac, cppunit was installed via macports
+algorithm_tests_LDADD= -L/opt/local/lib -lcppunit -ldl  #link the cppunit unittest library in mac, cppunit was installed via macports
diff --git a/NEWS b/NEWS
new file mode 120000
index 0000000..7b97b99
--- /dev/null
+++ b/NEWS
@@ -0,0 +1 @@
+NEWS.md
\ No newline at end of file
diff --git a/NEWS.md b/NEWS.md
new file mode 100644
index 0000000..5082373
--- /dev/null
+++ b/NEWS.md
@@ -0,0 +1,196 @@
+scrm Version History
+========================
+
+scrm 1.6.1
+------------------------
+Released: 2015-07-09
+
+### Bug Fixes
++ scrm had extensive memory consumption when simulating trees in 
+  large models (#79). This is now fixed, it is however no longer
+  possible to use "-O" and "-T" at the same time.
+
+
+scrm 1.6.0
+------------------------
+Released: 2015-06-04
+
+### New Features
++ It is now possible to specify the approximation exact window in number 
+  of recombination events (#73).
++ scrm now uses a conservative approximation by default (#75).
+
+### Bug Fixes
++ Critical:  Position based rates changes (`-sr` and `-st`) were only
+  applied to the first locus. All other loci are simulated with the rates from
+  the end of the first one (#74).
++ In large models, the Newick trees could get larger than the character limit
+  of a C++ string. In this cases, only incomplete trees were printed (#76).
+
+
+
+scrm 1.5.1
+------------------------
+Released: 2015-05-18
+
++ Bug fix: Fixed a cache invalidation error that could lead to runs being
+  aborted after 100k recombinations (#70). Thanks to Jerome Kelleher for 
+  report this.
++ Minor: Small updates to the documentation and citation information.
+
+
+
+scrm 1.5.0
+------------------------
+Released: 2015-04-07
+
++ New feature: Added flag "--print-model" which prints a textual representation
+  of the demographic model for verification and debugging (#60). 
++ Bug fix: When multiple population splits and/or merges occurred at the same
+  time, only one of them affected each line while the others were ignored (#61). 
++ New feature: Added support for partial population admixtures (`-eps`, #62).
++ In addition to using "-seed" scrm now also supports "-seeds", as ms also 
+  supports both.
+
+
+
+scrm 1.4.1
+------------------------
+Released: 2015-04-04
+
++ Bug fix: Wrong population size where calculated when migration rates
+  changes or population splits and merges occurred in an growth period (#56)
++ Bug fix: When -es was used at time 0, _scrm_ ran into an endless loop (#53)
++ Improvement: Added an error message when a population size is set to 0 (#52)
+
+
+
+scrm 1.4.0
+------------------------
+Released: 2015-03-29
+
++ Improved memory management (#36)
++ Added option '-p' to set number of significant digits in output (#47) 
++ Switched to std::mt19937_64 as default random generator (#49)
++ Support arguments in scientific notation (#50, #51)
+
+
+
+scrm 1.3.2
+------------------------
+Released: 2014-12-23
+
++ Bug fix: Fix reproducibility problem when the large sample optimization was active (#42).
+
+
+
+scrm 1.3.1
+------------------------
+Released: 2014-10-23
+
++ Bug fix: Implement missing '-m' and '-em' arguments (#32).
+
+
+
+
+scrm 1.3.0
+------------------------
+Released: 2014-10-21
+
+### Improvements
++ Improved the autotools configuration to support more compilers and operating
+  systems (#10, #27).
++ Changed the Oriented Forest summary statistic (#25).
++ Various minor cleanups in the code base to simplify creation of an R package
+  containing scrm (#29).
+
+
+
+
+scrm 1.2.0
+------------------------
+Released: 2014-09-10
+
+### New Features
++ New `oriented forest` summary statistic as suggested by 
+
+    J. Kelleher, A.M. Etheridge, N.H. Barton (2014) Coalescent simulation in 
+    continuous space: Algorithms for large neighbourhood size, 
+    Theoretical Population Biology, Volume 95, August2014, Pages 13-23, 
+    ISSN 0040-5809, http://dx.doi.org/10.1016/j.tpb.2014.05.001. 
+
+### Improvements
++ Optimized the generation of newick trees (#22) and use a buffer (#23)
+
+
+ 
+
+scrm 1.1.0
+------------------------
+Released: 2014-08-04
+
+### Improvements
++ Improved the handling & storage of contemporary nodes. This gives a huge
+  performance boost if scrm is used with large sample sizes (>1000) (#20). 
++ Optimized scrm for use with many populations (#20). 
++ Added more automatic tests of the produced distribution of trees (#20).
+
+
+
+
+scrm 1.0.0 
+------------------------
+Released: 2014-07-09
+
+### Bug fixes
++ Fixed an access to unmapped memory
+
+
+
+
+scrm 1.0-beta2
+------------------------
+Released: 2014-06-18
+
+### Improvements
++ Fix file permissions
++ Remove clang warning suppression
++ Added a man page
+
+
+
+
+scrm 1.0-beta1
+------------------------
+Released: 2014-06-02
+
+### Bug fixes:
++ Option '-es' is now ms-compatible (#16).
++ It is now possible to use 3 seeds (as in ms).
+
+### Improvements:
++ Added help and version information.
++ Small performance tweaks.
+
+### New Features
++ Added variable recombination & mutation rates
+
+
+
+
+scrm 0.9-1
+------------------------
+
+### Bug fixes
++ Very first node in the tree was assigned to wrong population
++ The input time of "-eI" option was not scaled
++ Fixed the scaling of growth rates
+
+
+
+
+scrm 0.9-0
+------------------------
+
+Algorithm passes all tests now, starting explicit versioning.
+
diff --git a/README b/README
new file mode 120000
index 0000000..42061c0
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+README.md
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8c3a885
--- /dev/null
+++ b/README.md
@@ -0,0 +1,69 @@
+scrm
+====
+
+_scrm_ is a coalescent simulator for biological sequences. Different to similar programs, 
+it can approximate the coalescent with recombination as closely as needed, but still has 
+only linear runtime cost for long sequences. It allows you to rapidly simulate chromosome 
+scale sequences with an essentially correct genetic linkage structure.
+
+
+## Installation
+### Stable Release (recommended) 
+You can download the latest stable release packaged for a variety of different
+platform from [_scrm_'s homepage][1]. 
+Instructions on building the binary from the source packages are available in the [wiki][3].
+
+### Stable/Development Version From GitHub
+
+Version             | Branch | Build Status
+------------------- | ------ | -----------------
+Stable Version      | stable | [![Build Status](https://travis-ci.org/scrm/scrm.png?branch=stable)](https://travis-ci.org/scrm/scrm)
+Development Version | master | [![Build Status](https://travis-ci.org/scrm/scrm.png?branch=master)](https://travis-ci.org/scrm/scrm)
+
+You can also install `scrm` directly from the git repository. Here, you need to install `autoconf` first:  
+
+On Debian/Ubuntu based systems:
+```bash
+apt-get install build-essential autoconf autoconf-archive libcppunit-dev
+```
+
+On Mac OS:
+```bash
+port install automake autoconf autoconf-archive cppunit 
+```
+
+Afterwards you can build the binary using 
+```bash
+./bootstrap
+make
+```
+
+
+## Usage
+We designed scrm to be compatible to the famous program `ms` from Richard R. Hudson. 
+You can use it as a drop in replacement for `ms` if you avoid the options `-c` and `-s`. 
+Details are available [in the wiki][2]. 
+
+
+## Troubleshooting
+If you encounter problems while using _scrm_, please 
+[file a bug report](https://github.com/scrm/scrm/wiki/Reporting-Bugs) or mail to
+`develop (at) paulstaab.de`.
+
+
+## Citation
+_scrm_ is described in the manuscript
+
+> Paul R. Staab, Sha Zhu, Dirk Metzler and Gerton Lunter.
+> **scrm: efficiently simulating long sequences using the approximated coalescent
+> with recombination**. 
+> Bioinformatics (2015) 31 (10): 1680-1682.
+> [doi:10.1093/bioinformatics/btu861](http://bioinformatics.oxfordjournals.org/content/31/10/1680).
+
+## Licence
+You can freely use all code in this project under the conditions of the GNU
+GPL Version 3 or later.
+
+[1]: https://scrm.github.io
+[2]: https://github.com/paulstaab/scrm/wiki/Command-Line-Options
+[3]: https://github.com/scrm/scrm/wiki/Installation
diff --git a/bootstrap b/bootstrap
new file mode 100755
index 0000000..e363b5c
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+
+aclocal
+autoconf
+automake -a
+./configure
+
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..98fdd15
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,46 @@
+AC_INIT([scrm], [1.6.1],[https://github.com/paulstaab/scrm/issues])
+AM_INIT_AUTOMAKE([subdir-objects -Wall -Werror foreign])
+
+# Use -O3 as default optimization level
+: ${CXXFLAGS="-O3"}
+
+# Suppress output at compilation
+m4_ifndef([AM_SILENT_RULES], [m4_define([AM_SILENT_RULES],[])])
+AM_SILENT_RULES([yes])
+
+# Load macros in 'm4'-dir
+AC_CONFIG_MACRO_DIR([m4])
+
+AC_PROG_INSTALL
+AC_PREREQ
+AC_CANONICAL_HOST
+
+# Checks for programs.
+AC_PROG_RANLIB
+
+# Check for C++11
+AX_CXX_COMPILE_STDCXX_11(,mandatory)
+
+# Checks for libraries
+AC_CHECK_LIB(cppunit,TestCase,[])
+
+# Checks for header files for scrm.
+AC_HEADER_STDC
+AC_LANG(C++) 
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_SIZE_T
+
+# Enable Link-time optimization if supported (gcc only)
+if test x$CXX = xg++; then
+  AX_CHECK_COMPILE_FLAG([-flto], [OPT_CXXFLAGS="-flto"], [], [-Werror])
+  AC_SUBST(OPT_CXXFLAGS)
+fi
+
+# Enable Warnings
+AX_CXXFLAGS_WARN_ALL
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/doc/README.md b/doc/README.md
new file mode 100644
index 0000000..bd5a456
--- /dev/null
+++ b/doc/README.md
@@ -0,0 +1,17 @@
+# Documentation
+
+The documentation for scrm is automatically build from [scrm's wiki][1]. If you are
+here to view or edit the documentation, best go there directly. 
+
+## Building the documentation
+In order to build the documentation, you need to install the document converter
+[pandoc][2]. On Debian/Ubuntu, a simple
+
+```bash
+sudo apt-get install pandoc
+```
+
+should do. Afterwards you can do a simple `make` here.
+
+[1]: https://github.com/paulstaab/scrm/wiki
+[2]: http://johnmacfarlane.net/pandoc
diff --git a/doc/create-manual.sh b/doc/create-manual.sh
new file mode 100755
index 0000000..a8c4202
--- /dev/null
+++ b/doc/create-manual.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+#-------------------------------------------------#
+# Builds scrm's manual from scrm's wiki on GitHub #
+#-------------------------------------------------#
+
+pages="scrm.wiki/Installation.md scrm.wiki/Command-Line-Options.md scrm.wiki/Output.md"
+
+scrm_dir=$PWD
+if [ ! -d "$scrm_dir/doc" ]; then
+  "Error: please execute this script from scrm's folder"
+  exit 1
+fi
+
+tmpdir=$(mktemp -d)
+cd "$tmpdir" || exit 1
+git clone https://github.com/scrm/scrm.wiki.git || exit 1
+cp "$scrm_dir/doc/knitr.css" ./ || exit 1
+
+pandoc -t html5 -s -S --toc --toc-depth=2 \
+  -M title='The scrm Quick Reference' \
+  -M author='Paul R. Staab, Joe (Sha) Zhu, Dirk Metzler and Gerton Lunter' \
+  -c knitr.css \
+  --self-contained \
+  -o manual.html ${pages}
+
+cp -v manual.html "$scrm_dir/doc/"
+cd "$scrm_dir"
+rm -rf "$tmpdir"
diff --git a/doc/knitr.css b/doc/knitr.css
new file mode 100644
index 0000000..73effe9
--- /dev/null
+++ b/doc/knitr.css
@@ -0,0 +1,156 @@
+/* CSS Style inspired by knitr reports */
+
+body, td {
+   font-family: sans-serif;
+   background-color: white;
+   font-size: 13px;
+}
+
+body {
+  max-width: 800px;
+  margin: auto;
+  padding: 1em;
+  line-height: 20px;
+}
+
+tt, code, pre {
+   font-family: 'DejaVu Sans Mono', 'Droid Sans Mono', 'Lucida Console', Consolas, Monaco, monospace;
+}
+
+h1 {
+   font-size:2.2em;
+   padding-top: 1.5em;
+   text-align: center;
+   padding-bottom: 0.25em;
+   border-bottom: 1px solid #57c4d0;
+}
+
+h1.title {
+   padding-top: 0em;
+   border: 0px;
+}
+
+h2 {
+   font-size:1.8em;
+   padding-top: 1em;
+   line-height: 1.3em;
+}
+
+h2.author, h3.date {
+   text-align: center;
+   padding-top: 0em;
+}
+
+h3 {
+   font-size:1.4em;
+   padding-top: 0.5em;
+}
+
+h4 {
+   font-size:1.0em;
+}
+
+h5 {
+   font-size:0.9em;
+}
+
+h6 {
+   font-size:0.8em;
+}
+
+a:visited {
+   color: rgb(50%, 0%, 50%);
+}
+
+h1>a, h2>a, h3>a, h4>a, h5>a, h6>a {
+  color: black;
+  text-decoration: none;
+}
+
+pre, img {
+  max-width: 100%;
+}
+
+pre code {
+   display: block; padding: 0.5em;
+}
+
+code {
+  font-size: 92%;
+  border: 1px solid #ccc;
+}
+
+code[class] {
+  background-color: #F8F8F8;
+}
+
+table, td, th {
+  border: none;
+}
+
+blockquote {
+   color:#666666;
+   margin:0;
+   padding-left: 1em;
+   border-left: 0.5em #EEE solid;
+}
+
+hr {
+   height: 0px;
+   border-bottom: none;
+   border-top-width: thin;
+   border-top-style: dotted;
+   border-top-color: #999999;
+}
+
+ at media print {
+   * {
+      background: transparent !important;
+      color: black !important;
+      filter:none !important;
+      -ms-filter: none !important;
+   }
+
+   body {
+      font-size:12pt;
+      max-width:100%;
+   }
+
+   a, a:visited {
+      text-decoration: underline;
+   }
+
+   hr {
+      visibility: hidden;
+      page-break-before: always;
+   }
+
+   pre, blockquote {
+      padding-right: 1em;
+      page-break-inside: avoid;
+   }
+
+   tr, img {
+      page-break-inside: avoid;
+   }
+
+   img {
+      max-width: 100% !important;
+   }
+
+   @page :left {
+      margin: 15mm 20mm 15mm 10mm;
+   }
+
+   @page :right {
+      margin: 15mm 10mm 15mm 20mm;
+   }
+
+   p, h2, h3 {
+      orphans: 3; widows: 3;
+   }
+
+   h2, h3 {
+      page-break-after: avoid;
+   }
+}
diff --git a/doc/scrm.1 b/doc/scrm.1
new file mode 100644
index 0000000..272c6d9
--- /dev/null
+++ b/doc/scrm.1
@@ -0,0 +1,161 @@
+.TH SCRM 1 "Mar 2015" "Version 1.4.0" 
+.SH NAME
+scrm \- An accurate coalescent simulator for genome-scale sequences
+
+.SH SYNOPSIS
+.B scrm
+.I nsamp nloci
+[\fB\-hvL\fR]
+[\fB\-r\fR \fIrec L\fR [\fB\-l\fR \fIl\fR] [\fB\-sr\fR \fIb rec\fR]... ]
+[\fB\-I\fR \fInpop s1 \fR... \fIsn \fR[\fIM\fR]
+[\fB\-eI\fR \fIt s1 \fR... \fIsn\fR \fR[\fIM\fR]]... 
+[\fB\-M\fR \fIM\fR]
+[\fB\-eM\fR \fIt M\fR]...
+[\fB\-m\fR \fIi j M\fR]
+[\fB\-em\fR \fIt i j M\fR]...
+[\fB\-ma\fR \fIM11 M21 ... Mnn\fR]
+[\fB\-ema\fR \fIt M11 M21 ... Mnn\fR]...
+[\fB\-es\fR \fIt i p\fR]...
+[\fB\-ej\fR \fIt i j\fR]...]
+[\fB\-n\fR \fIi n\fR]
+[\fB\-en\fR \fIt i n\fR]...
+[\fB\-eN\fR \fIt i n\fR]...
+[\fB\-g\fR \fIi a\fR]
+[\fB\-eg\fR \fIt i a\fR]...
+[\fB\-G\fR \fIt a\fR]
+[\fB\-eG\fR \fIt a\fR]...
+[\fB\-t\fR \fItheta\fR [\fB\-oSFS\fR] [\fB\-st\fR \fIb theta\fR]... ]
+[\fB\-seed\fR \fIseed \fR[\fIseed2 seed3\fR]]
+[\fB\-p\fR \fIdigits\fR]
+
+.SH DESCRIPTION
+.B scrm is a coalescent simulator for biological sequences. Different to similar
+programs, it can approximate the Ancestral Recombination Graph with arbitrary
+precision. This allows you to rapidly simulate long sequences with essentially
+correct genetic linkage between sites.
+
+.SH OPTIONS
+.SS "Recombination:"
+.TP
+\fB\-r\fR \fIR\fR \fIL\fR
+Set recombination rate to R and locus length to L.
+.TP
+\fB\-sr\fR \fIp\fR \fIR\fR
+Change the recombination rate R at sequence position p.
+.TP
+\fB\-l\fR \fIl\fR
+Set the approximation window length to l.
+.SS "Population Structure:"
+.TP
+\fB\-I\fR \fInpop\fR \fIs1\fR ... \fIsn\fR [\fIM\fR]
+Use an island model with npop populations,
+.IP
+where s1 to sn individuals are sampled each population.
+Optionally assume a symmetric migration rate of M.
+.TP
+\fB\-eI\fR \fIt\fR \fIs1\fR ... \fIsn\fR [\fIM\fR]
+Sample s1 to sn indiviuals from their
+.IP
+corresponding populations at time t.
+.TP
+\fB\-M\fR \fIM\fR
+Assume a symmetric migration rate of M/(npop\-1).
+.TP
+\fB\-eM\fR \fIt\fR \fIM\fR
+Change the symmetric migration rate to M/(npop\-1) at time t.
+.TP
+\fB\-m\fR \fIi\fR \fIj\fR \fIM\fR
+Set the migration rate from population j to population i to M
+.TP
+\fB\-em\fR \fIt\fR \fIi\fR \fIj\fR \fIM\fR
+Set the migration rate from population j to
+.IP
+population i to M at time t.
+.TP
+\fB\-ma\fR \fIM11\fR \fIM21\fR ...
+Sets the (backwards) migration matrix.
+.TP
+\fB\-ema\fR \fIt\fR \fIM11\fR \fIM21\fR ...
+Changes the migration matrix at time t
+.TP
+\fB\-es\fR \fIt\fR \fIi\fR \fIp\fR
+Population admixture. Replaces a fraction of 1\-p of
+population i with individuals a from population npop + 1
+which is ignored afterwards (forward in time).
+.TP
+\fB\-ej\fR \fIt\fR \fIi\fR \fIj\fR
+Speciation event at time t. Creates population j
+from individuals of population i.
+.SS "Population Size Changes:"
+.TP
+\fB\-n\fR \fIi\fR \fIn\fR
+Set the present day size of population i to n*N0.
+.TP
+\fB\-en\fR \fIt\fR \fIi\fR \fIn\fR
+Change the size of population i to n*N0 at time t.
+.TP
+\fB\-eN\fR \fIt\fR \fIn\fR
+Set the present day size of all populations to n*N0.
+.TP
+\fB\-g\fR \fIi\fR \fIa\fR
+Set the exponential growth rate of population i to a.
+.TP
+\fB\-eg\fR \fIt\fR \fIi\fR \fIa\fR
+Change the exponential growth rate of population i to a
+at time t.
+.TP
+\fB\-G\fR \fIa\fR
+Set the exponential growth rate of all populations to a.
+.TP
+\fB\-eG\fR \fIt\fR \fIa\fR
+Change the exponential growth rate of all populations to a
+at time t.
+.SS "Summary Statistics:"
+.TP
+\fB\-t\fR \fITHETA\fR  
+Set the mutation rate to THETA = 4N_0u, where u is the
+neutral mutation rate per locus.
+.TP
+\fB\-T\fR
+Print the local genealogies in newick format.
+.TP
+\fB\-O\fR
+Print the local genealogies in the Oriented Forest format.
+.TP
+\fB\-L\fR
+Print the TMRCA and the local tree length for each segment.
+.TP
+\fB\-oSFS\fR
+Print the site frequency spectrum. Requires to set the mutation rate.
+.TP
+\fB\-SC\fR \fI[ms|rel|abs]\fR 
+Scaling of sequence positions. Either relative to the locus
+length between 0 and 1 (rel), absolute in base pairs (abs) or ms-like (ms).
+.SS "Other:"
+.TP
+\fB\-seed\fR \fISEED\fR [\fISEED2\fR \fISEED3\fR]
+The random seed to use. Takes up three integer numbers.
+.TP
+\fB\-v\fR, \fB\-\-version\fR
+Prints the version of scrm.
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Prints this text.
+.PP
+.TP
+\fB\-p\fR \fIdigits\fR
+Number of significant digits used in output.
+
+.SH Examples
+.SS Five independent sites for 10 individuals using Kingman's Coalescent:
+.IP
+scrm 10 5 \fB\-t\fR 10
+.SS "A sequence of 10kb from 4 individuals under the exact ARG:"
+.IP
+scrm 4 1 \fB\-t\fR 10 \fB\-r\fR 4 10000
+.SS "A sequence of 100Mb using the SMC' approximation:"
+.IP
+scrm 4 1 \fB\-t\fR 10 \fB\-r\fR 4000 100000000 \fB\-l\fR 0
+.SS "Same as above, but with essentially correct linkage:"
+.IP
+scrm 4 1 \fB\-t\fR 10 \fB\-r\fR 4000 100000000 \fB\-l\fR 300000 
diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4
new file mode 100644
index 0000000..1d38b76
--- /dev/null
+++ b/m4/ax_append_flag.m4
@@ -0,0 +1,69 @@
+# ===========================================================================
+#      http://www.gnu.org/software/autoconf-archive/ax_append_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
+#
+# DESCRIPTION
+#
+#   FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
+#   added in between.
+#
+#   If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+#   CFLAGS) is used.  FLAGS-VARIABLE is not changed if it already contains
+#   FLAG.  If FLAGS-VARIABLE is unset in the shell, it is set to exactly
+#   FLAG.
+#
+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod at gmx.de>
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans at gmail.com>
+#
+#   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 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_APPEND_FLAG],
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])dnl
+AS_VAR_SET_IF(FLAGS,
+  [case " AS_VAR_GET(FLAGS) " in
+    *" $1 "*)
+      AC_RUN_LOG([: FLAGS already contains $1])
+      ;;
+    *)
+      AC_RUN_LOG([: FLAGS="$FLAGS $1"])
+      AS_VAR_SET(FLAGS, ["AS_VAR_GET(FLAGS) $1"])
+      ;;
+   esac],
+  [AS_VAR_SET(FLAGS,["$1"])])
+AS_VAR_POPDEF([FLAGS])dnl
+])dnl AX_APPEND_FLAG
diff --git a/m4/ax_cflags_warn_all.m4 b/m4/ax_cflags_warn_all.m4
new file mode 100644
index 0000000..1f07799
--- /dev/null
+++ b/m4/ax_cflags_warn_all.m4
@@ -0,0 +1,122 @@
+# ===========================================================================
+#    http://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CFLAGS_WARN_ALL   [(shellvar [,default, [A/NA]])]
+#   AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
+#   AX_FCFLAGS_WARN_ALL  [(shellvar [,default, [A/NA]])]
+#
+# DESCRIPTION
+#
+#   Try to find a compiler option that enables most reasonable warnings.
+#
+#   For the GNU compiler it will be -Wall (and -ansi -pedantic) The result
+#   is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default.
+#
+#   Currently this macro knows about the GCC, Solaris, Digital Unix, AIX,
+#   HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and
+#   Intel compilers.  For a given compiler, the Fortran flags are much more
+#   experimental than their C equivalents.
+#
+#    - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS
+#    - $2 add-value-if-not-found : nothing
+#    - $3 action-if-found : add value to shellvariable
+#    - $4 action-if-not-found : nothing
+#
+#   NOTE: These macros depend on AX_APPEND_FLAG.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod at gmx.de>
+#   Copyright (c) 2010 Rhys Ulerich <rhys.ulerich at gmail.com>
+#
+#   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 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 15
+
+AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl
+AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl
+AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl
+AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
+VAR,[VAR="no, unknown"
+ac_save_[]FLAGS="$[]FLAGS"
+for ac_arg dnl
+in "-warn all  % -warn all"   dnl Intel
+   "-pedantic  % -Wall"       dnl GCC
+   "-xstrconst % -v"          dnl Solaris C
+   "-std1      % -verbose -w0 -warnprotos" dnl Digital Unix
+   "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
+   "-ansi -ansiE % -fullwarn" dnl IRIX
+   "+ESlit     % +w1"         dnl HP-UX C
+   "-Xc        % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
+   "-h conform % -h msglevel 2" dnl Cray C (Unicos)
+   #
+do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+                     [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
+done
+FLAGS="$ac_save_[]FLAGS"
+])
+AS_VAR_POPDEF([FLAGS])dnl
+AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
+case ".$VAR" in
+     .ok|.ok,*) m4_ifvaln($3,$3) ;;
+   .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;;
+   *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;;
+esac
+AS_VAR_POPDEF([VAR])dnl
+])dnl AX_FLAGS_WARN_ALL
+dnl  implementation tactics:
+dnl   the for-argument contains a list of options. The first part of
+dnl   these does only exist to detect the compiler - usually it is
+dnl   a global option to enable -ansi or -extrawarnings. All other
+dnl   compilers will fail about it. That was needed since a lot of
+dnl   compilers will give false positives for some option-syntax
+dnl   like -Woption or -Xoption as they think of it is a pass-through
+dnl   to later compile stages or something. The "%" is used as a
+dnl   delimiter. A non-option comment can be given after "%%" marks
+dnl   which will be shown but not added to the respective C/CXXFLAGS.
+
+AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
+AC_LANG_PUSH([C])
+AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+AC_LANG_POP([C])
+])
+
+AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
+AC_LANG_PUSH([C++])
+AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+AC_LANG_POP([C++])
+])
+
+AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl
+AC_LANG_PUSH([Fortran])
+AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+AC_LANG_POP([Fortran])
+])
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
new file mode 100644
index 0000000..51df0c0
--- /dev/null
+++ b/m4/ax_check_compile_flag.m4
@@ -0,0 +1,74 @@
+# ===========================================================================
+#   http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
+#
+# DESCRIPTION
+#
+#   Check whether the given FLAG works with the current language's compiler
+#   or gives an error.  (Warnings, however, are ignored)
+#
+#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+#   success/failure.
+#
+#   If EXTRA-FLAGS is defined, it is added to the current language's default
+#   flags (e.g. CFLAGS) when the check is done.  The check is thus made with
+#   the flags: "CFLAGS EXTRA-FLAGS FLAG".  This can for example be used to
+#   force the compiler to issue an error when a bad flag is given.
+#
+#   INPUT gives an alternative input source to AC_COMPILE_IFELSE.
+#
+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+#   macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod at gmx.de>
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans at gmail.com>
+#
+#   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 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 3
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+  ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+  _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+  AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
+    [AS_VAR_SET(CACHEVAR,[yes])],
+    [AS_VAR_SET(CACHEVAR,[no])])
+  _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+  [m4_default([$2], :)],
+  [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS
diff --git a/m4/ax_check_link_flag.m4 b/m4/ax_check_link_flag.m4
new file mode 100644
index 0000000..db899dd
--- /dev/null
+++ b/m4/ax_check_link_flag.m4
@@ -0,0 +1,73 @@
+# ===========================================================================
+#    http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
+#
+# DESCRIPTION
+#
+#   Check whether the given FLAG works with the linker or gives an error.
+#   (Warnings, however, are ignored)
+#
+#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+#   success/failure.
+#
+#   If EXTRA-FLAGS is defined, it is added to the linker's default flags
+#   when the check is done.  The check is thus made with the flags: "LDFLAGS
+#   EXTRA-FLAGS FLAG".  This can for example be used to force the linker to
+#   issue an error when a bad flag is given.
+#
+#   INPUT gives an alternative input source to AC_LINK_IFELSE.
+#
+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+#   macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod at gmx.de>
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans at gmail.com>
+#
+#   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 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 3
+
+AC_DEFUN([AX_CHECK_LINK_FLAG],
+[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
+AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS $4 $1"
+  AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
+    [AS_VAR_SET(CACHEVAR,[yes])],
+    [AS_VAR_SET(CACHEVAR,[no])])
+  LDFLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+  [m4_default([$2], :)],
+  [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_LINK_FLAGS
diff --git a/m4/ax_cxx_compile_stdcxx_11.m4 b/m4/ax_cxx_compile_stdcxx_11.m4
new file mode 100644
index 0000000..c49a664
--- /dev/null
+++ b/m4/ax_cxx_compile_stdcxx_11.m4
@@ -0,0 +1,158 @@
+# ============================================================================
+#  http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
+# ============================================================================
+#
+# SYNOPSIS
+#
+#   AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
+#
+# DESCRIPTION
+#
+#   Check for baseline language coverage in the compiler for the C++11
+#   standard; if necessary, add switches to CXXFLAGS to enable support.
+#
+#   The first argument, if specified, indicates whether you insist on an
+#   extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
+#   -std=c++11).  If neither is specified, you get whatever works, with
+#   preference for an extended mode.
+#
+#   The second argument, if specified 'mandatory' or if left unspecified,
+#   indicates that baseline C++11 support is required and that the macro
+#   should error out if no mode with that support is found.  If specified
+#   'optional', then configuration proceeds regardless, after defining
+#   HAVE_CXX11 if and only if a supporting mode is found.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Benjamin Kosnik <bkoz at redhat.com>
+#   Copyright (c) 2012 Zack Weinberg <zackw at panix.com>
+#   Copyright (c) 2013 Roy Stogner <roystgnr at ices.utexas.edu>
+#   Copyright (c) 2014 Alexey Sokolov <sokolov at google.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 4
+
+m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[
+  template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+    struct Base {
+    virtual void f() {}
+    };
+    struct Child : public Base {
+    virtual void f() override {}
+    };
+
+    typedef check<check<bool>> right_angle_brackets;
+
+    int a;
+    decltype(a) b;
+
+    typedef check<int> check_type;
+    check_type c;
+    check_type&& cr = static_cast<check_type&&>(c);
+
+    auto d = a;
+    auto l = [](){};
+]])
+
+AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
+  m4_if([$1], [], [],
+        [$1], [ext], [],
+        [$1], [noext], [],
+        [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
+  m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
+        [$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
+        [$2], [optional], [ax_cxx_compile_cxx11_required=false],
+        [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])
+  AC_LANG_PUSH([C++])dnl
+  ac_success=no
+  AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
+  ax_cv_cxx_compile_cxx11,
+  [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+    [ax_cv_cxx_compile_cxx11=yes],
+    [ax_cv_cxx_compile_cxx11=no])])
+  if test x$ax_cv_cxx_compile_cxx11 = xyes; then
+    ac_success=yes
+  fi
+
+  m4_if([$1], [noext], [], [dnl
+  if test x$ac_success = xno; then
+    for switch in -std=gnu++11 -std=gnu++0x; do
+      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
+      AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
+                     $cachevar,
+        [ac_save_CXXFLAGS="$CXXFLAGS"
+         CXXFLAGS="$CXXFLAGS $switch"
+         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+          [eval $cachevar=yes],
+          [eval $cachevar=no])
+         CXXFLAGS="$ac_save_CXXFLAGS"])
+      if eval test x\$$cachevar = xyes; then
+        CXXFLAGS="$CXXFLAGS $switch"
+        ac_success=yes
+        break
+      fi
+    done
+  fi])
+
+  m4_if([$1], [ext], [], [dnl
+  if test x$ac_success = xno; then
+    for switch in -std=c++11 -std=c++0x; do
+      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
+      AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
+                     $cachevar,
+        [ac_save_CXXFLAGS="$CXXFLAGS"
+         CXXFLAGS="$CXXFLAGS $switch"
+         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+          [eval $cachevar=yes],
+          [eval $cachevar=no])
+         CXXFLAGS="$ac_save_CXXFLAGS"])
+      if eval test x\$$cachevar = xyes; then
+        CXXFLAGS="$CXXFLAGS $switch"
+        ac_success=yes
+        break
+      fi
+    done
+  fi])
+  AC_LANG_POP([C++])
+
+  if test x$ax_cxx_compile_cxx11_required = xtrue; then
+    if test x$ac_success = xno; then
+       if test x$CXX = xg++; then
+         GCC_VERSION_MAJOR=$(g++ -dumpversion | cut -d'.' -f1)
+         GCC_VERSION_MINOR=$(g++ -dumpversion | cut -d'.' -f2)
+
+         if test "$GCC_VERSION_MAJOR" -ge 4; then
+           if test "$GCC_VERSION_MINOR" -ge 6; then
+             ac_success=yes
+             CXXFLAGS="-std=c++0x"
+             HAVE_CXX11=1
+           fi
+         fi
+       fi
+    fi
+
+    if test x$ac_success = xno; then
+      AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
+    fi
+  else
+    if test x$ac_success = xno; then
+      HAVE_CXX11=0
+      AC_MSG_NOTICE([No compiler with C++11 support was found])
+    else
+      HAVE_CXX11=1
+      AC_DEFINE(HAVE_CXX11,1,
+                [define if the compiler supports basic C++11 syntax])
+    fi
+
+    AC_SUBST(HAVE_CXX11)
+  fi
+])
diff --git a/m4/ax_require_defined.m4 b/m4/ax_require_defined.m4
new file mode 100644
index 0000000..cae1111
--- /dev/null
+++ b/m4/ax_require_defined.m4
@@ -0,0 +1,37 @@
+# ===========================================================================
+#    http://www.gnu.org/software/autoconf-archive/ax_require_defined.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_REQUIRE_DEFINED(MACRO)
+#
+# DESCRIPTION
+#
+#   AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
+#   been defined and thus are available for use.  This avoids random issues
+#   where a macro isn't expanded.  Instead the configure script emits a
+#   non-fatal:
+#
+#     ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
+#
+#   It's like AC_REQUIRE except it doesn't expand the required macro.
+#
+#   Here's an example:
+#
+#     AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
+#
+# LICENSE
+#
+#   Copyright (c) 2014 Mike Frysinger <vapier at gentoo.org>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 1
+
+AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
+  m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
+])dnl AX_REQUIRE_DEFINED
diff --git a/src/contemporaries_container.h b/src/contemporaries_container.h
new file mode 100644
index 0000000..1281de1
--- /dev/null
+++ b/src/contemporaries_container.h
@@ -0,0 +1,364 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef scrm_src_contemporaries_container
+#define scrm_src_contemporaries_container
+
+#include "macros.h" // Needs to be before cassert
+
+#include <vector>
+#include <unordered_set>
+#include <cassert>
+#include <algorithm>
+
+#include "node.h"
+#include "random/random_generator.h"
+
+class ContemporariesIterator {
+ public:
+  ContemporariesIterator(std::unordered_set<Node*>::iterator it) {
+    it_set_ = it; 
+    use_set_ = true;
+  };
+
+  ContemporariesIterator(std::vector<Node*>::iterator it) {
+    it_vec_ = it; 
+    use_set_ = false;
+  };
+
+  Node* operator*() const {
+    if (use_set_) return *it_set_;
+    else return *it_vec_;
+  }
+
+  Node* operator++() { 
+    if (use_set_) {
+      ++it_set_; 
+      return *it_set_; 
+    } else {
+      ++it_vec_; 
+      return *it_vec_; 
+    }
+  }
+
+  Node* operator++(int) { 
+    Node* node = **this;
+    ++*this;
+    return node;
+  }
+  
+  bool operator==(const ContemporariesIterator &other) const {
+    if (use_set_) return (it_set_ == other.it_set_); 
+    else return (it_vec_ == other.it_vec_);
+  }
+
+  bool operator!=(const ContemporariesIterator &other) const {
+    return !(*this == other);
+  }
+
+ private:
+  std::unordered_set<Node*>::iterator it_set_;
+  std::vector<Node*>::iterator it_vec_;
+  bool use_set_;
+};
+
+
+class ContemporariesConstIterator {
+ public:
+  ContemporariesConstIterator(std::unordered_set<Node*>::const_iterator it) {
+    it_set_ = it; 
+    use_set_ = true;
+  };
+
+  ContemporariesConstIterator(std::vector<Node*>::const_iterator it) {
+    it_vec_ = it; 
+    use_set_ = false;
+  };
+
+  Node const* operator*() const {
+    if (use_set_) return *it_set_;
+    else return *it_vec_;
+  }
+
+  Node const* operator++() { 
+    if (use_set_) {
+      ++it_set_; 
+      return *it_set_; 
+    } else {
+      ++it_vec_; 
+      return *it_vec_; 
+    }
+  }
+
+  Node const* operator++(int) { 
+    Node const* node = **this;
+    ++*this;
+    return node;
+  }
+  
+  bool operator==(const ContemporariesConstIterator &other) const {
+    if (use_set_) return (it_set_ == other.it_set_); 
+    else return (it_vec_ == other.it_vec_);
+  }
+
+  bool operator!=(const ContemporariesConstIterator &other) const {
+    return !(*this == other);
+  }
+
+ private:
+  std::unordered_set<Node*>::const_iterator it_set_;
+  std::vector<Node*>::const_iterator it_vec_;
+  bool use_set_;
+};
+
+class ContemporariesContainer {
+ public:
+  ContemporariesContainer();
+  ContemporariesContainer(const size_t pop_number, 
+                          const size_t sample_number,
+                          RandomGenerator *rg);
+
+  void add(Node* node);
+  void remove(Node *node);
+  void replaceChildren(Node *add_node);
+  void replace(Node *add_node, Node *del_node_1, Node *del_node_2 = NULL);
+  void clear();
+  void buffer(const double current_time);
+
+  Node* sample(const size_t pop) const;
+  size_t size(const size_t pop) const;
+  double buffer_time() const { return buffer_time_; }
+  bool empty() const;
+  bool use_set() const { return use_set_; };
+
+  // Create Iterators
+  ContemporariesConstIterator begin(const size_t pop) const { 
+    if (use_set_) return ContemporariesConstIterator(contemporaries_set().at(pop).cbegin()); 
+    else return ContemporariesConstIterator(contemporaries_vector().at(pop).cbegin());
+  }
+  ContemporariesConstIterator end(const size_t pop) const { 
+    if (use_set_) return ContemporariesConstIterator(contemporaries_set().at(pop).cend()); 
+    else return ContemporariesConstIterator(contemporaries_vector().at(pop).cend());
+  }
+
+  // Create Iterators for the buffer
+  ContemporariesConstIterator buffer_begin(const size_t pop) const { 
+    if (use_set_) return ContemporariesConstIterator(buffer_set().at(pop).cbegin()); 
+    else return ContemporariesConstIterator(buffer_vector().at(pop).cbegin());
+  }
+  ContemporariesConstIterator buffer_end(const size_t pop) const { 
+    if (use_set_) return ContemporariesConstIterator(buffer_set().at(pop).cend()); 
+    else return ContemporariesConstIterator(buffer_vector().at(pop).cend());
+  }
+  ContemporariesIterator buffer_begin(const size_t pop) { 
+    if (use_set_) return ContemporariesIterator(buffer_set().at(pop).begin()); 
+    else return ContemporariesIterator(buffer_vector().at(pop).begin());
+  }
+  ContemporariesIterator buffer_end(const size_t pop) { 
+    if (use_set_) return ContemporariesIterator(buffer_set().at(pop).end()); 
+    else return ContemporariesIterator(buffer_vector().at(pop).end());
+  }
+
+ private:
+  std::vector<std::unordered_set<Node*> > &contemporaries_set() {
+    if (use_first_) return contemporaries_set1_;
+    else return contemporaries_set2_;
+  }
+  const std::vector<std::unordered_set<Node*> > &contemporaries_set() const {
+    if (use_first_) return contemporaries_set1_;
+    else return contemporaries_set2_;
+  }
+  std::vector<std::unordered_set<Node*> > &buffer_set() {
+    if (!use_first_) return contemporaries_set1_;
+    else return contemporaries_set2_;
+  }
+  const std::vector<std::unordered_set<Node*> > &buffer_set() const {
+    if (!use_first_) return contemporaries_set1_;
+    else return contemporaries_set2_;
+  }
+
+  std::vector<std::vector<Node*> > &contemporaries_vector() {
+    if (use_first_) return contemporaries_vec1_;
+    else return contemporaries_vec2_;
+  }
+  const std::vector<std::vector<Node*> > &contemporaries_vector() const {
+    if (use_first_) return contemporaries_vec1_;
+    else return contemporaries_vec2_;
+  }
+  std::vector<std::vector<Node*> > &buffer_vector() {
+    if (!use_first_) return contemporaries_vec1_;
+    else return contemporaries_vec2_;
+  }
+  const std::vector<std::vector<Node*> > &buffer_vector() const {
+    if (!use_first_) return contemporaries_vec1_;
+    else return contemporaries_vec2_;
+  }
+
+
+  std::vector<std::unordered_set<Node*> > contemporaries_set1_, contemporaries_set2_;
+  std::vector<std::vector<Node*> > contemporaries_vec1_, contemporaries_vec2_;
+
+  bool use_first_;
+  bool use_set_;
+  double buffer_time_;
+  RandomGenerator* rg_;
+};
+
+inline ContemporariesContainer::ContemporariesContainer() {
+  contemporaries_vec1_ = std::vector<std::vector<Node*> >(1, std::vector<Node*>(100));
+  contemporaries_vec2_ = std::vector<std::vector<Node*> >(1, std::vector<Node*>(100));
+
+  rg_ = NULL;
+  use_first_ = true;
+  buffer_time_ = -1;
+  use_set_ = false;
+}
+
+inline ContemporariesContainer::ContemporariesContainer(const size_t pop_number, 
+                                                        const size_t sample_number,
+                                                        RandomGenerator* rg) {
+
+  // Use vectors for the storage if the number of samples is below 750.
+  // This threshold is mostly arbitrary, with simulation supporting it in
+  // special situations. 
+  if (sample_number <= 750) {
+    contemporaries_vec1_ = std::vector<std::vector<Node*> >(pop_number);
+    for ( auto it : contemporaries_vec1_ ) it.reserve(sample_number + 200);
+    contemporaries_vec2_ = std::vector<std::vector<Node*> >(pop_number);
+    for ( auto it : contemporaries_vec2_ ) it.reserve(sample_number + 200);
+    use_set_ = false;
+  } else {
+    size_t bucket_nr = std::ceil((sample_number + 200) * 1.4);
+    contemporaries_set1_ = std::vector<std::unordered_set<Node*> >(pop_number, std::unordered_set<Node*>(bucket_nr));
+    contemporaries_set2_ = std::vector<std::unordered_set<Node*> >(pop_number, std::unordered_set<Node*>(bucket_nr));
+    use_set_ = true;
+  }
+  this->rg_ = rg;
+  use_first_ = true;
+  buffer_time_ = DBL_MAX;
+}
+
+inline void ContemporariesContainer::add(Node* node) {
+  assert(node != NULL);
+  assert(!node->is_root());
+  if (use_set_) contemporaries_set().at(node->population()).insert(node);
+  else contemporaries_vector().at(node->population()).push_back(node);
+}
+
+inline void ContemporariesContainer::remove(Node* node) {
+  assert(node != NULL);
+  if (use_set_) contemporaries_set().at(node->population()).erase(node);
+  else {
+    size_t pop = node->population();
+    auto it = std::find(contemporaries_vector().at(pop).begin(),
+                        contemporaries_vector().at(pop).end(),
+                        node);
+    if (it != contemporaries_vector().at(pop).end()) {
+      contemporaries_vector().at(pop).erase(it);
+    }
+  }
+}
+
+inline void ContemporariesContainer::replaceChildren(Node *add_node) {
+  replace(add_node, add_node->first_child(), add_node->second_child());  
+}
+
+inline void ContemporariesContainer::replace(Node *add_node, Node *del_node_1, Node *del_node_2) {
+  assert(add_node != NULL);
+  if (del_node_1 != NULL) remove(del_node_1);
+  if (del_node_2 != NULL) remove(del_node_2);
+  if (!add_node->is_root()) add(add_node);
+}
+
+inline void ContemporariesContainer::clear() {
+  if (use_set_) {
+    for (auto it = contemporaries_set().begin(); it != contemporaries_set().end(); ++it) {
+      if ((*it).size() > 0) (*it).clear();
+    }
+  } else {
+    for (auto it = contemporaries_vector().begin(); it != contemporaries_vector().end(); ++it) {
+      if ((*it).size() > 0) (*it).clear();
+    }
+  }
+}
+
+inline size_t ContemporariesContainer::size(const size_t pop) const {
+  if (use_set_) return contemporaries_set().at(pop).size();
+  else return contemporaries_vector().at(pop).size();
+}
+
+/**
+ * @brief Function that buffers the current state of contemporaries for later
+ * use. 
+ *
+ * Be careful not to change the tree at the time of buffer, as this
+ * will not be reflected in the buffered contemporaries.
+ *
+ * @param current_time The time for with the current state is valid.
+ *
+ * @return 
+ */
+inline void ContemporariesContainer::buffer(const double current_time) {
+  buffer_time_ = current_time;
+  use_first_ = 1 - use_first_; 
+  this->clear();
+}
+
+// Uniformly samples a random node from the current contemporaries.
+// Distribution checked.
+inline Node* ContemporariesContainer::sample(const size_t pop) const {
+  assert( (!use_set_) || pop < contemporaries_set().size() );
+  assert( (use_set_)  || pop < contemporaries_vector().size() );
+  assert( this->size(pop) > 0 );
+
+  size_t sample = rg_->sampleInt(this->size(pop));
+
+  if (use_set_) {
+    // Sample the position of the Node we return
+
+    for (auto it = contemporaries_set().at(pop).begin(); 
+         it != contemporaries_set().at(pop).end(); ++it) {
+      assert( *it != NULL );
+      if ( sample == 0 ) return (*it);
+      --sample;
+    }
+  } else {
+    return contemporaries_vector().at(pop).at(sample);
+  }
+
+  throw std::logic_error("Failed to find the contemporary I wanted to sample.");
+  return NULL;
+}
+
+inline bool ContemporariesContainer::empty() const {
+  if (use_set_) {
+    for (auto pop_container : contemporaries_set()) {
+      if ( !pop_container.empty() ) return false;
+    }
+  } else {
+    for (auto pop_container : contemporaries_vector()) {
+      if ( !pop_container.empty() ) return false;
+    }
+  }
+  return true;
+}
+#endif
diff --git a/src/doxygen_notation.txt b/src/doxygen_notation.txt
new file mode 100644
index 0000000..6676984
--- /dev/null
+++ b/src/doxygen_notation.txt
@@ -0,0 +1,23 @@
+/** @defgroup group_scrm Scrm
+*
+*/
+
+/** @defgroup group_scrm_init Build initial genealogy
+*@ingroup group_scrm
+*/
+
+/** @defgroup group_scrm_next New genealogy
+*@ingroup group_scrm
+*/
+
+/** @defgroup group_out Output
+*
+*/
+
+/** @defgroup group_seg Segregating data
+*@ingroup group_out
+*/
+
+/** @defgroup group_debug Debug utilities
+*
+*/
diff --git a/src/event.h b/src/event.h
new file mode 100644
index 0000000..917ce2d
--- /dev/null
+++ b/src/event.h
@@ -0,0 +1,106 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef scrm_src_event
+#define scrm_src_event
+
+#include <iostream>
+#include "node.h"
+
+class Event {
+ public:
+  Event() {
+    type_  = 0;
+    time_  = -1;
+    node_  = NULL;
+    active_node_nr_ = -1;
+    mig_pop_ = -1;
+  };
+
+  Event(double time) {
+    type_ = 0;
+    time_ = time;
+    node_ = NULL;
+    mig_pop_ = -1;
+    active_node_nr_ = -1;
+  }
+  
+  friend std::ostream& operator<< (std::ostream& stream, const Event& event);
+
+  double time() const { return time_; }
+  Node* node() const { return node_; }
+  size_t mig_pop() const { return mig_pop_; }
+  size_t type() const { return type_; }
+  size_t active_node_nr() const { return active_node_nr_; }
+
+  bool isNoEvent() const { return (type_ == 0); }
+  bool isCoalescence() const { return (type_ == 1); }
+  bool isPwCoalescence() const { return (type_ == 2); }
+  bool isMigration() const { return (type_ == 3); }
+  bool isRecombination() const { return (type_ == 4); }
+  
+  void set_time(const double time) { time_ = time; }
+
+  void setToCoalescence(Node *node, const size_t active_node_nr) {
+    type_  = 1;
+    node_  = node;
+    active_node_nr_ = active_node_nr;
+  }
+  void setToPwCoalescence() {
+    type_  = 2;
+  }
+  void setToMigration(Node *node, const size_t active_node_nr, const size_t mig_pop) {
+    type_  = 3;
+    node_  = node;
+    active_node_nr_ = active_node_nr;
+    mig_pop_ = mig_pop;
+  }
+  void setToRecombination(Node *node, const size_t active_node_nr) {
+    type_  = 4;
+    node_  = node;
+    active_node_nr_ = active_node_nr;
+  }
+
+ private:
+  size_t type_;
+  size_t active_node_nr_;
+  double time_;
+  size_t mig_pop_;
+  Node* node_;
+};
+
+inline std::ostream& operator<< (std::ostream& stream, const Event& event) {
+  if (event.isNoEvent()) {
+    stream << "No Event";
+    return stream;
+  }
+
+  stream << "Event at time " << event.time() << ": ";
+  if (event.isCoalescence()) stream << "Coalesence of a" << event.active_node_nr();
+  else if (event.isPwCoalescence()) stream << "Pair-wise coalescence";
+  else if (event.isMigration()) stream << "Migration of Node " << event.node() 
+                                        << " into pop " << event.mig_pop();
+  else if (event.isRecombination()) stream << "Recombination of Node " << event.node();
+  return stream;
+}
+
+#endif
diff --git a/src/forest-debug.cc b/src/forest-debug.cc
new file mode 100644
index 0000000..421f95f
--- /dev/null
+++ b/src/forest-debug.cc
@@ -0,0 +1,635 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "forest.h"
+
+/******************************************************************
+ * Debugging Utils
+ *****************************************************************/
+
+void Forest::createExampleTree() {
+  this->clear();
+  this->writable_model()->disable_approximation();
+  // Only set the number of samples to 4, but keep rest of the model
+  this->writable_model()->sample_times_.clear();
+  this->writable_model()->sample_populations_.clear();
+  this->writable_model()->addSampleSizes(0.0, std::vector<size_t>(1, 4));
+
+  this->rec_bases_.push_back(5.0);  
+  this->current_rec_ = 1;
+  //this->rec_bases_.push_back(105.0);  
+
+  Node* leaf1 = nodes()->createNode(0, 1);
+  Node* leaf2 = nodes()->createNode(0, 2);
+  Node* leaf3 = nodes()->createNode(0, 3);
+  Node* leaf4 = nodes()->createNode(0, 4);
+
+  leaf1->set_label(1);
+  leaf2->set_label(2);
+  leaf3->set_label(3);
+  leaf4->set_label(4);
+
+  this->nodes()->add(leaf4);
+  this->nodes()->add(leaf3);
+  this->nodes()->add(leaf2);
+  this->nodes()->add(leaf1);
+
+  Node* node12 = nodes()->createNode(1);
+  this->addNodeToTree(node12, NULL, leaf1, leaf2);
+
+  Node* node34 = nodes()->createNode(3);
+  this->addNodeToTree(node34, NULL, leaf3, leaf4);
+
+  Node* root = nodes()->createNode(10);
+  this->addNodeToTree(root, NULL, node12, node34);
+  this->set_local_root(root);
+  this->set_primary_root(root);
+
+  // Add a non-local tree
+  Node* nl_node = nodes()->createNode(4); 
+  nl_node->make_nonlocal(current_rec_);
+  Node* nl_root = nodes()->createNode(6);
+  nl_root->make_nonlocal(current_rec_);
+  
+  nl_node->set_parent(nl_root);
+  nl_root->set_first_child(nl_node);
+  this->nodes()->add(nl_node);
+  this->nodes()->add(nl_root);
+  updateAbove(nl_node);
+
+  updateAbove(leaf1);
+  updateAbove(leaf2);
+  updateAbove(leaf3);
+  updateAbove(leaf4);
+
+  this->set_sample_size(4);
+
+  this->contemporaries_ = ContemporariesContainer(model().population_number(), 
+                                                  model().sample_size(),
+                                                  random_generator());
+  this->tmp_event_time_ = -1; 
+  this->coalescence_finished_ = true;
+
+  assert( this->checkTreeLength() );
+  assert( this->checkTree() );
+}
+
+void Forest::createScaledExampleTree() {
+  this->createExampleTree();
+
+  this->nodes()->at(4)->set_height(1 * 4 * model().default_pop_size); 
+  this->nodes()->at(5)->set_height(3 * 4 * model().default_pop_size); 
+  this->nodes()->at(6)->set_height(4 * 4 * model().default_pop_size); 
+  this->nodes()->at(7)->set_height(6 * 4 * model().default_pop_size); 
+  this->nodes()->at(8)->set_height(10 * 4 * model().default_pop_size); 
+
+  updateAbove(nodes()->at(4));
+  updateAbove(nodes()->at(5));
+  updateAbove(nodes()->at(6));
+
+  assert( this->checkTreeLength() );
+  assert( this->checkTree() );
+}
+
+double Forest::calcTreeLength() const {
+  double local_length = 0;
+
+  for (ConstNodeIterator it = getNodes()->iterator(); it.good(); ++it) {
+    if ( *it == local_root() ) return local_length;
+    if ( (*it)->is_root() || !(*it)->local() ) continue;
+    local_length += (*it)->height_above();
+  }
+
+  return local_length;
+}
+
+
+void Forest::addNodeToTree(Node *node, Node *parent, Node *first_child, Node *second_child) {
+  this->nodes()->add(node);
+
+  if (parent != NULL) {
+    node->set_parent(parent);
+    if (parent->first_child() == NULL) parent->set_first_child(node);
+    else {
+      if (parent->first_child()->height() > node->height()) {
+        parent->set_second_child(parent->first_child());
+        parent->set_first_child(node);
+      } else {
+        parent->set_second_child(node);
+      }
+    }
+  }
+
+  if (first_child != NULL) {
+    node->set_first_child(first_child);
+    first_child->set_parent(node);
+  }
+
+  if (second_child != NULL) {
+    node->set_second_child(second_child);
+    second_child->set_parent(node);
+  }
+}
+
+
+bool Forest::checkTreeLength() const {
+  double local_length = calcTreeLength();
+
+  if ( !areSame(local_length, getLocalTreeLength(), 0.000001) ) {
+    dout << "Error: local tree length is " << this->getLocalTreeLength() << " ";
+    dout << "but should be " << local_length << std::endl;
+    return(0);
+  }
+
+  return(1);
+}
+
+
+bool Forest::checkInvariants(Node const* node) const {
+  if (node == NULL) {
+    bool okay = 1;
+
+    for (ConstNodeIterator it = getNodes()->iterator(); it.good(); ++it) {
+      if ( (*it)->height() >= local_root()->height()) {
+        if (!(*it)->local()) continue;
+        dout << "Node " << *it << " is above the local root and local!" << std::endl;
+        okay = 0;  
+      } else {
+        okay *= checkInvariants(*it);
+      }
+    }
+    return(okay);
+  }
+
+  size_t samples_below = node->in_sample();
+  double length_below = 0;
+
+  if (node->first_child() != NULL) {
+    samples_below += node->first_child()->samples_below();
+    length_below += node->first_child()->length_below();
+    if (node->first_child()->local()) 
+      length_below += node->first_child()->height_above();
+  }
+
+  if (node->second_child() != NULL) {
+    samples_below += node->second_child()->samples_below();
+    length_below += node->second_child()->length_below();
+    if (node->second_child()->local()) 
+      length_below += node->second_child()->height_above();
+  }
+
+  if ( samples_below != node->samples_below() ||
+      !areSame(length_below, node->length_below(), 0.00001) ) {
+    dout << "Node " << node << " not up to date" << std::endl;
+    dout << "samples_below: is " << node->samples_below() 
+         << " and should be " << samples_below << std::endl;
+    dout << "length_below: is " << node->length_below() 
+         << " and should be " << length_below 
+         << " ( Diff " << node->length_below() - length_below << " )" << std::endl;
+
+    printNodes();
+    printTree();
+    return false;
+  }
+
+  if ( (samples_below == 0 || samples_below == sample_size()) && node->local() ) {
+    dout << "Node " << node << " is local but should be non-local" << std::endl;
+    return false;
+  }
+
+  return true;
+}
+
+
+bool Forest::checkLeafsOnLocalTree(Node const* node) const {
+  if (node == NULL) {
+    size_t all_on_tree = 1;
+    bool on_tree = 0;
+    for (ConstNodeIterator it = getNodes()->iterator(); it.good(); ++it) {
+      if ( !(*it)->in_sample() ) continue;
+      on_tree = checkLeafsOnLocalTree(*it);
+      if (!on_tree) dout << "Leaf " << *it << " is not on local tree!" << std::endl;
+      all_on_tree *= on_tree;
+    }
+    return(all_on_tree);
+  }
+  if ( node->local() ) return( checkLeafsOnLocalTree(node->parent()) );
+  return( node == this->local_root() );
+}
+
+
+bool Forest::checkNodeProperties() const {
+  bool success = true;
+  for (ConstNodeIterator it = getNodes()->iterator(); it.good(); ++it) {
+    if ( !(*it)->local() ) {
+      if ( (*it)->last_update() == 0 && !(*it)->is_root() ) {
+        dout << "Error: Node " << *it << " non-local without update info" << std::endl;
+        success = false;
+      }
+    }
+  } 
+  return success; 
+} 
+
+
+bool Forest::checkTree(Node const* root) const {
+  if (root == NULL) {
+    bool good = true;
+    // Default when called without argument
+    for (ConstNodeIterator it = getNodes()->iterator(); it.good(); ++it) {
+      if ( (*it)->is_root() ) good *= checkTree(*it);
+    }
+
+    good *= this->checkInvariants();
+    good *= this->checkNodeProperties();
+    good *= this->checkTreeLength();
+    good *= this->checkRoots();
+    return good;
+  }
+  assert( root != NULL );
+
+  Node* h_child = root->second_child();
+  Node* l_child = root->first_child();
+
+  bool child1 = 1;
+  if (h_child != NULL) {
+    if (l_child == NULL) {
+      dout << root << ": only child is second child" << std::endl;
+      return 0;
+    }
+    if (h_child->parent() != root) {
+      dout << h_child << ": is child of non-parent" << std::endl;
+      return 0;
+    }
+    if (h_child->height() > root->height()) {
+      dout << root << ": has child with greater height" << std::endl;
+      return 0;
+    }
+    if (h_child->population() != root->population()) {
+      dout << root << ": has child of other population" << std::endl;
+      return 0;
+    }
+    if (l_child->population() != root->population()) {
+      dout << root << ": has child of other population" << std::endl;
+      return 0;
+    }
+    child1 = checkTree(h_child);
+  }
+
+  bool child2 = 1;
+  if (l_child != NULL) {
+    if (l_child->parent() != root) {
+      dout << l_child << ": is child of non-parent" << std::endl;
+      return 0;
+    }
+    child2 = checkTree(l_child);
+
+    if (l_child->height() > root->height()) {
+      dout << root << ": has child with greater height" << std::endl;
+      return 0;
+    }
+  }
+
+  // Check that parent if above node
+  if (!root->is_root()) {
+    Node* parent = root->parent();
+    Node const* current = root;
+    while (current != parent) {
+      if (current->is_last()) {
+        dout << root << ": node is above it's parent.";
+        return 0;
+      }
+      current = current->next();
+    } 
+  }
+
+  return child1*child2;
+}
+
+
+
+
+/******************************************************************
+ * Tree Printing
+ *****************************************************************/
+bool Forest::printTree() const {
+  //this->printNodes();
+  std::vector<Node const*> positions = this->determinePositions();
+  //this->printPositions(positions);
+  std::vector<Node const*>::iterator position;
+  int h_line;
+  double start_height = 0, 
+         end_height = getNodes()->get(0)->height();
+
+  for (ConstNodeIterator ni = getNodes()->iterator(); ni.good(); ) {
+    if ( !(*ni)->is_root() && (*ni)->height_above() == 0.0 ) {
+      std::cout << "A rare situation occurred were a parent and a child have exactly "
+           << "the same height. We can't print such trees here, the algorithm however"
+           << "should not be affected." << std::endl; 
+      return 1;
+    }
+    h_line = 0;
+    start_height = end_height;
+    while ( ni.height() <= end_height ) ++ni;
+    end_height = ni.height(); 
+    //std::cout << start_height << " - " << end_height << std::endl;
+
+    for (position = positions.begin(); position != positions.end(); ++position) {
+      assert( *position != NULL );
+      if ( (*position)->height() == start_height ) {
+        if ( (*position)->local() || *position == local_root() ) std::cout << "╦";
+        else std::cout << "┬";
+        if ( (*position)->countChildren() == 2 ) {
+          h_line = 1 + !((*position)->local());
+          if ( *position == local_root() ) h_line = 1;
+        }
+        if ( (*position)->countChildren() == 1 ) {
+          h_line = 0;
+        }
+      } 
+      else if ( (*position)->height() < start_height &&
+                (*position)->parent_height() >= end_height ) {
+        if ( (*position)->local() ) std::cout << "║";
+        else std::cout << "│";
+
+      } 
+      else if ( (*position)->parent_height() == start_height ) {
+        if ( *position == (*position)->parent()->first_child() ) {
+          if ( (*position)->local() ) { 
+            std::cout << "╚";
+            h_line = 1;
+          }
+          else {
+            std::cout << "└";
+            h_line = 2;
+          }
+        }
+        else {
+          if ( (*position)->local() ) std::cout << "╝";
+          else std::cout << "┘";
+          h_line = 0;
+        }
+      }
+      else {
+        if ( h_line == 0 ) std::cout << " ";
+        else if ( h_line == 1 ) std::cout << "═";
+        else std::cout << "─";
+      }
+    }
+    std::cout << " - " << std::setw(7) << std::setprecision(7) << std::right << start_height << " - "; 
+    for (position = positions.begin(); position != positions.end(); ++position) {
+      if (*position == NULL) continue;
+      if ( (*position)->height() == start_height ) {
+        if ((*position)->label() != 0) std::cout << (*position)->label() << ":";
+        if (!(*position)->is_migrating()) std::cout << *position << "(" << (*position)->population() << ") ";
+        else std::cout << *position << "(" << (*position)->first_child()->population()
+                  << "->" << (*position)->population() << ") ";
+        if (nodeIsOld(*position)) std::cout << "old ";
+      }
+    }
+    std::cout << std::endl;
+  }
+  return true;
+}
+
+/**
+ *  For printing the tree, each node gets assigned its own column in the printed area, 
+ *  referred to as its positions. This function determines the position for all
+ *  nodes and returns the nodes in a vector sorted by position.   
+ *
+ *  \return Vector of all nodes, sorted by position 
+ */
+std::vector<Node const*> Forest::determinePositions() const {
+  std::vector<Node const*> positions(this->getNodes()->size(), NULL); 
+
+  ReverseConstNodeIterator it;
+  std::vector<const Node*>::iterator cit;
+  size_t lines_left, lines_right, position, root_offset = 0;
+  Node const* current_node;
+
+  for (it = getNodes()->reverse_iterator(); it.good(); ++it) {
+    current_node = *it;
+
+    lines_left = countLinesLeft(current_node);
+    lines_right = countLinesRight(current_node);
+
+    if ( current_node->is_root() ) {
+      // Add root to the right of all current trees
+      position = countBelowLinesLeft(current_node->first_child()) + lines_left + root_offset;
+      //std::cout << current_node << " " << position << " " << lines_left << " "
+      //          << lines_right << " "  
+      //          << countBelowLinesLeft(current_node->first_child()) << std::endl;
+      
+      root_offset = position + 
+                    countBelowLinesRight(current_node->second_child()) + 
+                    lines_right + 1;
+
+      assert( positions[position] == NULL ); 
+      positions[position] = current_node;
+    } else {
+      // Get the position of the node (which was assigned when looking at its
+      // parent
+      position = 0;
+      for (cit = positions.begin(); cit < positions.end(); ++cit) {
+        if ( *cit == current_node ) break;
+        ++position;
+      }
+    }
+    
+    // Insert the child/children into branches
+    if (current_node->first_child() != NULL) {
+        assert( positions.at(position - lines_left) == NULL );         
+        positions[position - lines_left] =  current_node->first_child();
+    }
+    
+
+    if (current_node->second_child() != NULL) { 
+        assert( positions.at(position + lines_right) == NULL );         
+        positions[position + lines_right] = current_node->second_child();
+    }
+  
+  }
+  return positions;
+}
+
+  void Forest::printPositions(const std::vector<Node const*> &positions) const {
+      for (size_t col = 0; col < positions.size() ; ++col) {
+        std::cout << positions[col] << " ";
+      } 
+      std::cout << std::endl;
+  }
+
+  int Forest::countLinesLeft(Node const* node) const {
+    if ( node->first_child() == NULL ) return 0;
+    //if ( node->second_child() == NULL ) return 1;
+    return ( 1 + countBelowLinesRight(node->first_child()) );
+  }
+
+  int Forest::countLinesRight(Node const* node) const {
+    if ( node->first_child() == NULL ) return 0;
+    if ( node->second_child() == NULL ) return 0;
+    return ( 1 + countBelowLinesLeft(node->second_child()) );
+  }
+
+  int Forest::countBelowLinesLeft(Node const* node) const {
+    if ( node == NULL ) return 0;
+    if ( node->first_child() == NULL ) return 0;
+    else return ( countLinesLeft(node) + countBelowLinesLeft(node->first_child()) );
+  }
+
+  int Forest::countBelowLinesRight(Node const* node) const {
+    if ( node == NULL ) return 0;
+    if ( node->second_child() == NULL ) return 0;
+    else return ( countLinesRight(node) + countBelowLinesRight(node->second_child()) );
+  }
+
+  bool Forest::printNodes() const {
+    std::cout << std::setw(15) << std::right << "Node";
+    std::cout << std::setw(15) << std::right << "Height";
+    std::cout << std::setw(6) << std::right << "label";
+    std::cout << std::setw(15) << std::right << "Parent";
+    std::cout << std::setw(15) << std::right << "1th_child";
+    std::cout << std::setw(15) << std::right << "2nd_child";
+    std::cout << std::setw(6) << std::right << "local";
+    std::cout << std::setw(6) << std::right << "pop";
+    std::cout << std::setw(10) << std::right << "l_upd";
+    std::cout << std::setw(6) << std::right << "s_bel";
+    std::cout << std::setw(10) << std::right << "l_bel";
+    std::cout << std::endl;
+
+    for(size_t i = 0; i < this->getNodes()->size(); ++i) {
+      std::cout << std::setw(15) << std::right << this->getNodes()->get(i);
+      std::cout << std::setw(15) << std::right << this->getNodes()->get(i)->height();
+      std::cout << std::setw(6) << std::right << this->getNodes()->get(i)->label();
+      if (!getNodes()->get(i)->is_root()) 
+        std::cout << std::setw(15) << std::right << this->getNodes()->get(i)->parent();
+      else std::cout << std::setw(15) << std::right << 0;
+      std::cout << std::setw(15) << std::right << this->getNodes()->get(i)->first_child();
+      std::cout << std::setw(15) << std::right << this->getNodes()->get(i)->second_child();
+      std::cout << std::setw(6) << std::right << this->getNodes()->get(i)->local();
+      std::cout << std::setw(6) << std::right << this->getNodes()->get(i)->population();
+      std::cout << std::setw(10) << std::right << this->getNodes()->get(i)->last_update();
+      std::cout << std::setw(6) << std::right << this->getNodes()->get(i)->samples_below();
+      std::cout << std::setw(10) << std::right << this->getNodes()->get(i)->length_below();
+      std::cout << std::endl;
+    }
+    std::cout << "Local Root:    " << this->local_root() << std::endl;
+    std::cout << "Primary Root:  " << this->primary_root() << std::endl;
+    return true;
+  }
+
+
+bool Forest::checkForNodeAtHeight(const double height) const {
+  for (auto it = getNodes()->iterator(); it.good(); ++it) {
+    if ((*it)->height() == height) return true;
+    if ((*it)->height() > height) return false;
+  }
+  return false;
+}
+
+// Checks if all nodes in contemporaries are contemporaries.
+bool Forest::checkContemporaries(const double time) const {
+  // Check if all nodes in contemporaries() are contemporaries
+  for (size_t pop = 0; pop < model().population_number(); ++pop) {
+    for (auto it = contemporaries_.begin(pop); it != contemporaries_.end(pop); ++it) {
+      if ( *it == NULL ) {
+        dout << "NULL in contemporaries" << std::endl; 
+        return 0;
+      }
+
+      if ( (*it)->is_root() ) {
+        dout << "Root " << *it << " in contemporaries" << std::endl; 
+        return 0;
+      }
+
+      if ( (*it)->height() > time || (*it)->parent_height() <= time ) {
+        dout << "Non-contemporary node " << *it << " in contemporaries " 
+             << "at time " << time << " (node at " << (*it)->height() 
+             << "; parent at " << (*it)->parent_height() << ")." << std::endl; 
+        printNodes();
+        return 0;
+      }
+
+      if ( nodeIsOld(*it) ) { 
+        if ( *it == local_root() ) {
+          if ( !(*it)->is_root() ) {
+            dout << "Branch above local root should be pruned but is not" << std::endl;
+            return 0;
+          }
+        } else {
+          dout << "Contemporary node " << *it << " should be pruned by now!" << std::endl;
+          return 0;
+        }
+      }
+
+      for (size_t i = 0; i < 2; ++i) {
+        if ( *it == active_node(i) && states_[i] == 1 ) {
+          dout << "Coalescing node a" << i << " in contemporaries!" << std::endl;
+          return 0;
+        }
+      }
+    }
+  }
+
+  // Check if all contemporaries are in contemporaries() 
+  for (auto ni = getNodes()->iterator(); ni.good(); ++ni) {
+    if ( (*ni)->height() <= time && time < (*ni)->parent_height()) {
+      if ( *ni == active_node(0) && states_[0] == 1 ) continue; 
+      if ( *ni == active_node(1) && states_[1] == 1 ) continue; 
+      
+      bool found = false;
+      size_t pop = (*ni)->population();
+      for (auto it = contemporaries_.begin(pop); it != contemporaries_.end(pop); ++it) {
+        if ( *it == *ni ) {
+          found = true;
+          break;
+        }
+      } 
+      if (!found) { 
+        dout << "Node " << *ni << " (height " << (*ni)->height() 
+             << ") not in contemporaries at time " << time << std::endl;
+        return 0;
+      }
+    }
+  }
+
+  return 1;
+}
+
+bool Forest::checkRoots() const {
+  // Check that local_root() really is the local root:
+  if (local_root()->samples_below() != sample_size() ||
+      local_root()->first_child() == NULL ||
+      local_root()->second_child() == NULL ||
+      (!local_root()->first_child()->local()) ||
+      (!local_root()->second_child()->local()) ) {
+    dout << local_root() << " is registered as local root, but is not." << std::endl;
+    return false;
+  } 
+  
+  // Check that primary_root() really is the primary root:
+  Node* node = local_root();
+  while (!node->is_root()) node = node->parent(); 
+  if (node != primary_root()) {
+    dout << primary_root() << " is registered as primary root, but "
+         << node << " is." << std::endl;
+    return false;
+  }
+
+  return true;
+}
diff --git a/src/forest.cc b/src/forest.cc
new file mode 100644
index 0000000..436353f
--- /dev/null
+++ b/src/forest.cc
@@ -0,0 +1,1344 @@
+  /*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "forest.h"
+
+/******************************************************************
+ * Constructors & Initialization
+ *****************************************************************/
+
+Forest::Forest(Model* model, RandomGenerator* random_generator) {
+  this->initialize(model, random_generator);
+  dout << *model << std::endl;
+}
+
+// Sets member variable to default values
+void Forest::initialize(Model* model, 
+                        RandomGenerator* rg) {
+
+  model->resetTime();
+  model->resetSequencePosition();
+
+  this->set_model(model);
+  this->set_random_generator(rg);
+
+  current_rec_ = 0;
+  rec_bases_ = std::vector<double>(1, -1);
+  rec_bases_.reserve(1000);
+
+  this->set_sample_size(0);
+
+  this->coalescence_finished_ = true;
+
+  this->contemporaries_ = ContemporariesContainer(model->population_number(), 
+                                                  model->sample_size(),
+                                                  rg);
+  tmp_event_time_ = -1;
+}
+
+/**
+ * @brief Copy constructor for forest
+ *
+ * This creates a copy of an Forest. It only produces valid results
+ * when there is no ongoing coalescence event (e.g. when we are not 
+ * inside of sampleNextGenealogy()).
+ *
+ * Also, both copies of it share the model and the random generator,
+ * so make sure that only one of them is sampling a new genealogy at
+ * a time.
+ *
+ * @param current_forest Forest that needs to be duplicated
+ */
+Forest::Forest(const Forest &current_forest) { 
+  if (!current_forest.coalescence_finished_) {
+    throw std::logic_error("Can not copy forest during an ongoing coalescence");
+  }
+
+  // Share a model and a random generator
+  this->set_model(current_forest.model_);
+  this->set_random_generator(current_forest.random_generator());
+
+  // Copy state information
+  this->set_sample_size(current_forest.sample_size());
+  this->rec_bases_ = current_forest.rec_bases_;
+  this->current_rec_ = current_forest.current_rec_;
+
+  // Copy the nodes
+  this->nodes_ = NodeContainer(*current_forest.getNodes());
+
+  // Rebuild invariants of the nodes, and determine new roots
+  this->set_local_root(NULL);
+  this->set_primary_root(NULL);
+  for (auto it = nodes()->iterator(); it.good(); ++it) {
+    updateAbove(*it, false, false);
+  }
+
+  // Set initial values for temporary variables
+  this->contemporaries_ = ContemporariesContainer(model().population_number(), 
+                                                  model().sample_size(),
+                                                  random_generator());
+  this->tmp_event_time_ = -1; 
+  this->coalescence_finished_ = true;
+
+  dout<<"  #################### check copied forest ###############"<<std::endl;
+  assert(this->printTree());
+  assert(this->printNodes());
+  assert(this->checkTree());
+  assert(this->checkLeafsOnLocalTree() );
+  dout<<"  #################### check copied forest finished ###############"<<std::endl<<std::endl;
+}
+
+
+/** 
+ * function that cuts a subtree out of a tree of the forest and reinserts it as
+ * a separate tree.
+ *
+ * This is primarily used to cut the subtree below an recombination
+ * away. 
+ *
+ * \param cut_point   A TreePoint marking the top of the subtree to cut.
+ * \return            The root of the now separated subtree.
+ */
+Node* Forest::cut(const TreePoint &cut_point) {
+  //The node above the cut_point in the old tree
+  Node* parent = cut_point.base_node()->parent();
+  assert( parent != NULL );
+
+  //The new end of the old branch after the cut
+  Node* new_leaf = nodes()->createNode(cut_point.height());
+  
+  if ( !cut_point.base_node()->local() )
+    new_leaf->make_nonlocal(cut_point.base_node()->last_update());
+  else
+    new_leaf->make_nonlocal(current_rec());
+  assert( !new_leaf->local() );
+
+  new_leaf->set_population(cut_point.base_node()->population());
+  new_leaf->set_length_below(0);
+  new_leaf->set_samples_below(0);
+
+  new_leaf->set_parent(parent);
+  parent->change_child(cut_point.base_node(), new_leaf);
+  nodes()->add(new_leaf, cut_point.base_node());
+
+  // Update all local nodes above.
+  updateAbove(parent, false, true);
+  dout << "* * New leaf of local tree: " << new_leaf << std::endl;
+
+  // The node below the recombination point becomes local in all possible cases
+  // (if it already isn't...)
+  updateAbove(cut_point.base_node(), false, false);
+  cut_point.base_node()->make_local();
+
+  // The new "root" of the newly formed tree
+  Node* new_root = nodes()->createNode(cut_point.height());
+  new_root->set_population(cut_point.base_node()->population());
+  cut_point.base_node()->set_parent(new_root);
+  new_root->set_first_child(cut_point.base_node());
+
+  // Set invariants of new root
+  new_root->set_length_below(cut_point.base_node()->length_below() + 
+                             cut_point.relative_height() );
+  new_root->set_samples_below(cut_point.base_node()->samples_below() );
+
+  nodes()->add(new_root, new_leaf);
+
+  dout << "* * New root of subtree: " << new_root << std::endl;
+  dout << "* * Done" << std::endl;
+
+  assert( this->checkInvariants(cut_point.base_node()) );
+  assert( this->checkInvariants(parent) );
+  assert( this->checkInvariants(new_leaf) );
+  assert( this->checkInvariants(new_root) );
+  assert( new_leaf->height() == cut_point.height() );
+  assert( new_root->height() == cut_point.height() );
+
+  return(new_root);
+}
+
+
+/**
+ * Function to update the invariants (local, samples_below, length_below) 
+ * of a 'node' and all of its (grand-)parents. Also sets local_root_ if it
+ * encounters it. Never makes non-local nodes local, only the other way round.
+ *
+ *  \param node       The node at which the functions starts updating the
+ *                    invariants. Then updates it's parent and the parents
+ *                    parent.
+ *  \param above_local_root If true, it uses a faster algorithm that is only correct
+ *                    for nodes above the local root. Default false. Best don't touch
+ *                    this.
+ *  \param recursive  If false, only the given node is updated, but not its parent.
+ *                    Default true.
+ *  \param invariants_only If true, it only updates the nodes invariants, but
+ *                    does not make nodes non-local and change the local root.
+ */
+void Forest::updateAbove(Node* node, bool above_local_root, 
+                         const bool &recursive, const bool &invariants_only) {
+
+  //dout << "Updating: " << node << " above_local_root: " << above_local_root << std::endl;
+  
+  // Fast forward above local root because this part is fairly straight forward
+  if (above_local_root) {
+    // Assure that everything is non-local
+    if (node->local()) node->make_nonlocal(current_rec());
+
+    // Update the primary root if needed
+    if ( node->is_root() ) {
+      if (node != primary_root()) {
+        set_primary_root(node);
+      }
+      return;
+    } 
+    if ( recursive ) updateAbove(node->parent(), true, true);
+    return;
+  }
+
+  node->set_last_change(current_rec());
+
+  // Calculate new values for samples_below and length_below for the current
+  // node
+  Node *l_child = node->first_child();
+  Node *h_child = node->second_child();
+
+  size_t samples_below = node->in_sample();
+  if (l_child != NULL) samples_below = l_child->samples_below();
+  if (h_child != NULL) samples_below += h_child->samples_below();
+  assert( samples_below <= this->sample_size() );
+
+  double length_below = 0.0;
+  if (l_child != NULL) {
+    length_below += l_child->length_below();
+    if (l_child->local()) length_below += l_child->height_above();
+
+    if (h_child != NULL) {
+      length_below += h_child->length_below();
+      if (h_child->local()) length_below += h_child->height_above();
+    }
+  }
+  assert( length_below >= 0 );
+
+  // Update whether the node is local or not 
+  if (!invariants_only) {
+    if (samples_below == 0) {
+      if ( node->local() ) node->make_nonlocal(current_rec());
+    }
+    else if ( samples_below == sample_size() ) {
+      if ( node->local() ) node->make_nonlocal(current_rec());
+
+      // Are we the local root?
+      if (node->countChildren() == 2 && 
+          l_child->samples_below() > 0 && h_child->samples_below() > 0) {
+        set_local_root(node);
+      }
+      if ( node->is_root() && node != primary_root() ) {
+        set_primary_root(node);
+      }
+      above_local_root = true;
+    }
+  }
+
+  // If nothing changed, we also don't need to update the tree further above...
+  if (samples_below == node->samples_below() && 
+      areSame(length_below, node->length_below()) ) {
+    return;
+  }
+
+  // Update the node invariants
+  node->set_samples_below(samples_below);
+  node->set_length_below(length_below);
+
+  // Go further up if possible
+  if ( recursive && !node->is_root() ) {
+    updateAbove(node->parent(), above_local_root, recursive, invariants_only);
+  }
+}
+
+
+/**
+ * Function that builds the initial tree at the very left end of the sequence.
+ *
+ * Also creates the sample nodes.
+ */
+void Forest::buildInitialTree() {
+  dout << "===== BUILDING INITIAL TREE =====" << std::endl;
+  assert(this->nodes()->size() == 0);
+  assert(this->segment_count() == 0);
+  assert(this->rec_bases_.size() == 1);
+  assert(this->model().getCurrentSequencePosition() == 0.0);
+  this->set_next_base(0.0);
+  ++current_rec_;
+
+  dout << "* Adding first node... ";
+  Node* first_node = nodes()->createNode(model().sample_time(0), 1);
+  first_node->set_population(model().sample_population(0));
+  this->nodes()->add(first_node);
+  this->set_local_root(first_node);
+  this->set_primary_root(first_node);
+  dout << "done." << std::endl;
+
+  Node* last_added_node = NULL;
+  for (size_t i=1; i < this->model().sample_size(); i++) {
+    this->set_sample_size(i+1);
+
+    dout << "* adding node ";
+    //Create a new separate little tree of and at height zero
+    Node* new_leaf = nodes()->createNode(model().sample_time(i), i+1);
+    new_leaf->set_population(model().sample_population(i));
+    dout << new_leaf << "(" << new_leaf->population() << ") "
+         << "at height " << new_leaf->height() << std::endl;
+    nodes()->add(new_leaf, last_added_node);
+    if (new_leaf->height() == 0.0) last_added_node = new_leaf;
+    dout << "* starting coalescences" << std::endl;
+
+    //Coalesces the separate tree into the main tree
+    this->sampleCoalescences(new_leaf);
+    dout << "* * Tree:" << std::endl;
+
+    assert(this->checkTree());
+    assert(this->checkLeafsOnLocalTree());
+    assert(this->printTree());
+    assert(this->printNodes());
+  }
+  this->sampleNextBase();
+  dout << "Next Sequence position: " << this->next_base() << std::endl;
+  this->calcSegmentSumStats();
+}
+
+
+/**
+ * Uniformly samples a TreePoint on the local tree.
+ *
+ * Its arguments are meant to be used only when the function iteratively calls
+ * itself. Just call it without any arguments if you want to sample a TreePoint.
+ *
+ * The function first samples a part of the total height of the tree and then
+ * goes down from the root, deciding at each node if that point is to the left
+ * or right, which should give us an O(log(#nodes)) algorithm.
+ *
+ * I checked the distribution of this function in multiple cases. -Paul
+ *
+ * \param node The current position in the tree when the functions goes down
+ *             iteratively.
+ *
+ * \param length_left The length that is left until we encounter the sampled
+ *              length.
+ *
+ * \return The sampled point on the tree.
+ */
+TreePoint Forest::samplePoint(Node* node, double length_left) const {
+  if (node == NULL) {
+    // Called without arguments => initialization
+    assert( this->checkTreeLength() );
+
+    node = this->local_root();
+    length_left = random_generator()->sample() * getLocalTreeLength();
+    assert( 0 < length_left && length_left < getLocalTreeLength() );
+  }
+
+  assert( node->local() || node == this->local_root() );
+  assert( length_left >= 0 );
+  assert( length_left < (node->length_below() + node->height_above()) );
+
+  if ( node != this->local_root() ) {
+    if ( length_left < node->height_above() ) {
+      assert( node->local() );
+      return TreePoint(node, length_left, true);
+    }
+
+    length_left -= node->height_above();
+    assert( length_left >= 0 );
+  }
+
+  // At this point, we should have at least one local child
+  assert( node->first_child() != NULL );
+  assert( node->first_child()->local() || node->second_child()->local() );
+
+  // If we have only one local child, then give it the full length we have left.
+  if ( !node->first_child()->local() ) {
+    return samplePoint(node->second_child(), length_left);
+  }
+  if ( node->second_child() == NULL || !node->second_child()->local() ) {
+    return samplePoint(node->first_child(), length_left);
+  }
+
+  // If we have two local children, the look if we should go down left or right.
+  double tmp = node->first_child()->height_above() + node->first_child()->length_below();
+  if ( length_left <= tmp )
+    return samplePoint(node->first_child(), length_left);
+  else 
+    return samplePoint(node->second_child(), length_left - tmp);
+}
+/* Alternative inefficient implementation
+TreePoint Forest::samplePoint(Node* node, double length_left) {
+ length_left = random_generator()->sample() * local_tree_length();  
+ for (auto ni = nodes()->iterator(); ni.good(); ++ni) {
+   if (!(*ni)->local()) continue;
+   if (length_left < (*ni)->height_above()) return TreePoint(*ni, length_left, true);
+   else length_left -= (*ni)->height_above();
+ }
+ assert(0);
+}
+*/
+
+
+
+/** 
+ * Function to modify the tree after we encountered a recombination on the
+ * sequence. Also samples a place for this recombination on the tree, marks the
+ * branch above as non-local (and updates invariants) if needed, cuts the
+ * subtree below away and starts a coalescence from it's root.
+ * @ingroup group_scrm_next
+ * @ingroup group_pf_update
+ */
+void Forest::sampleNextGenealogy() {
+  ++current_rec_; // Move to next recombination;
+
+  if (current_base() == model().getCurrentSequencePosition()) {
+    // Don't implement a recombination if we are just here because rates changed
+    dout << std::endl << "Position: " << this->current_base() << ": Changing rates." << std::endl;
+    this->sampleNextBase();
+    this->calcSegmentSumStats();
+    dout << "Next Position: " << this->next_base() << std::endl;
+    return;
+  }
+
+  assert( current_base() > model().getCurrentSequencePosition() );
+  assert( current_base() < model().getNextSequencePosition() );
+
+  assert( tmp_event_time_ >= 0 );
+  this->contemporaries_.buffer(tmp_event_time_);
+
+  dout << std::endl << "===== BUILDING NEXT GENEALOGY =====" << std::endl;
+  dout << "Segment Nr: " << current_rec() << " | "
+       << "Sequence position: " << this->current_base() << std::endl;
+  assert( this->current_base() <= this->model().loci_length() );
+
+  // Sample the recombination point
+  TreePoint rec_point = this->samplePoint();
+  assert( rec_point.base_node()->local() );
+
+  dout << "* Recombination at height " << rec_point.height() << " ";
+  dout << "(above " << rec_point.base_node() << ")"<< std::endl;
+
+  dout << "* Cutting subtree below recombination " << std::endl;
+  this->cut(rec_point);
+  assert( rec_point.height() == rec_point.base_node()->parent_height() );
+  assert( this->printTree() );
+
+  dout << "* Starting coalescence" << std::endl;
+  this->sampleCoalescences(rec_point.base_node()->parent());
+
+  assert( this->checkLeafsOnLocalTree() );
+  assert( this->checkTree() );
+  assert( this->printTree() );
+  assert( this->printNodes() );
+
+  this->sampleNextBase();
+  dout << "Next Sequence position: " << this->next_base() << std::endl;
+  this->calcSegmentSumStats();
+}
+
+
+/** 
+ * Function for doing a coalescence.
+ *
+ * \param start_node The node at which the coalescence starts. Must be the root
+ *                   of a tree.
+ */
+void Forest::sampleCoalescences(Node *start_node) {
+  assert( start_node->is_root() );
+  // We can have one or active local nodes: If the coalescing node passes the
+  // local root, it also starts a coalescence.
+  set_active_node(0, start_node);
+  set_active_node(1, this->local_root());
+
+  // Initialize Temporary Variables
+  tmp_event_ = Event(start_node->height());
+  coalescence_finished_ = false;
+
+  // This assertion needs an exception for building the initial tree
+  assert ( current_rec() == 1 || 
+           active_node(1)->in_sample() || 
+           start_node->height() <= active_node(1)->height() );
+
+  // Only prune every second round
+  for (TimeIntervalIterator ti(this, start_node); ti.good(); ++ti) {
+
+    dout << "* * Time interval: " << (*ti).start_height() << " - "
+         << (*ti).end_height() << " (Last event at " << tmp_event_.time() << ")" << std::endl;
+
+    // Assert that we don't accidentally jump in time 
+    assert( tmp_event_.time() < 0 || tmp_event_.time() == (*ti).start_height() );
+
+    // Update States & Rates (see their declaration for explanation); 
+    states_[0] = getNodeState(active_node(0), (*ti).start_height());
+    states_[1] = getNodeState(active_node(1), (*ti).start_height());
+
+    // Fixed time events (e.g pop splits/merges & single migration events first
+    if (model().hasFixedTimeEvent((*ti).start_height())) implementFixedTimeEvent(ti);
+
+    // Calculate the rates of events in this time interval
+    assert( checkContemporaries((*ti).start_height()) );
+    calcRates(*ti);
+
+    // Some debug checks
+    dout << "* * * Active Nodes: a0:" << active_node(0) << ":s" << states_[0]
+        << "(p" << active_node(0)->population() << ")" 
+        << " a1:" << active_node(1) << ":s" << states_[1] 
+        << "(p" << active_node(1)->population() << ")" << std::endl
+        << "* * * Total Rates: " << rates_[0] << " " 
+        << rates_[1] << " " << rates_[2] << std::endl;
+
+    assert( active_node(0) != active_node(1) );
+    assert( states_[0] != 0 || states_[1] != 0 );
+    assert( states_[0] != 1 || active_node(0)->is_root() );
+    assert( states_[1] != 1 || active_node(1)->is_root() );
+    assert( states_[0] == 1 || active_node(0)->parent_height() >= tmp_event_.time() );
+    assert( states_[1] == 1 || active_node(1)->parent_height() >= tmp_event_.time() );
+    assert( states_[0] != 2 || !active_node(0)->local() );
+    assert( states_[1] != 2 || !active_node(1)->local() );
+    
+    assert( active_node(0)->first_child() == NULL  || active_node(0)->first_child()->local() ||
+            active_node(0)->second_child() == NULL || active_node(0)->second_child()->local() );
+    assert( active_node(1)->first_child() == NULL  || active_node(1)->first_child()->local() ||
+            active_node(1)->second_child() == NULL || active_node(1)->second_child()->local() );
+
+    // Sample the time at which the next event happens (if any)
+    sampleEvent(*ti, tmp_event_time_, tmp_event_);
+    dout << "* * * " << tmp_event_ << std::endl;
+    assert( tmp_event_.isNoEvent() || (*ti).start_height() <= tmp_event_.time() );
+    assert( tmp_event_.isNoEvent() || tmp_event_.time() <= (*ti).end_height() );
+
+
+    // Go on if nothing happens in this time interval
+    if ( tmp_event_.isNoEvent() ) {
+      this->implementNoEvent(*ti, coalescence_finished_);
+      if (coalescence_finished_) return;
+    }
+
+    // First take care of pairwise coalescence
+    else if ( tmp_event_.isPwCoalescence() ) {
+      this->implementPwCoalescence(active_node(0), active_node(1), tmp_event_.time());
+      return;
+    }
+
+    else if ( tmp_event_.isRecombination() ) {
+      this->implementRecombination(tmp_event_, ti);
+    }
+
+    else if ( tmp_event_.isMigration() ) {
+      this->implementMigration(tmp_event_, true, ti);
+      assert( this->printTree() );
+    }
+
+    else if ( tmp_event_.isCoalescence() ) {
+      this->implementCoalescence(tmp_event_, ti);
+      assert( checkInvariants(tmp_event_.node()) );
+      if (coalescence_finished_) return;
+      assert( this->printTree() );
+    }
+  }
+}  
+
+
+void Forest::calcRates(const TimeInterval &ti) {
+  rates_[0] = 0.0;
+  rates_[1] = 0.0;
+  rates_[2] = 0.0;
+  active_nodes_timelines_[0] = 0;
+  active_nodes_timelines_[1] = 0;
+
+  // Set rate of first node
+  if (states_[0] == 1) {
+    // coalescing or migrating
+    rates_[0] += model().total_migration_rate(active_node(0)->population());
+    if (model().growth_rate(active_node(0)->population()) == 0.0) 
+      rates_[0] += calcCoalescenceRate(active_node(0)->population(), ti); 
+    else {
+      // exponential growth -- assign this node to timeline 1
+      rates_[1] += calcCoalescenceRate(active_node(0)->population(), ti);
+      active_nodes_timelines_[0] = 1;
+    }
+  }
+  else if (states_[0] == 2) {
+    // recombining
+    rates_[0] += calcRecombinationRate(active_node(0));    
+  }
+
+  // The second node is a bit more complicated 
+  if (states_[1] == 1) {
+    // coalescing or migrating
+    rates_[0] += model().total_migration_rate(active_node(1)->population());
+    if (model().growth_rate(active_node(1)->population()) == 0.0) {
+      // No Growth => Normal time
+      rates_[0] += calcCoalescenceRate(active_node(1)->population(), ti);
+
+      if (states_[0] == 1 && active_node(0)->population() == active_node(1)->population()) { 
+        // Also add rates for pw coalescence
+        rates_[0] += calcPwCoalescenceRate(active_node(1)->population(), ti); 
+      }
+    }
+    else {
+      // Growth => we need a exponential time
+      if (states_[0] == 1 && active_node(0)->population() == active_node(1)->population()) {
+        // Coalescing or migrating; and we can use the timeline of the first node
+        rates_[1] += calcCoalescenceRate(active_node(1)->population(), ti);
+        // And must add pw coalescence again
+        rates_[1] += calcPwCoalescenceRate(active_node(1)->population(), ti); 
+        active_nodes_timelines_[1] = 1;
+      } 
+      else {
+	      // No chance of a pairwise coalescence, but there is growth.
+        // We might need our own timeline (This could be made more efficient if both populations have
+	      // equal growth rates, but we ignore that for the moment).
+        rates_[2] += calcCoalescenceRate(active_node(1)->population(), ti);
+        active_nodes_timelines_[1] = 2;
+      }
+    }
+  }
+  else if (states_[1] == 2) {
+    // recombining
+    rates_[0] += calcRecombinationRate(active_node(1));
+  }
+
+  assert(rates_[0] >= 0);
+  assert(rates_[1] >= 0);
+  assert(rates_[2] >= 0);
+}  
+
+
+/**
+ * Samples if an event (coalescence, recombination or migration of active nodes)
+ * happens in the current TimeInterval or not. 
+ *
+ * In particular requires that the 'temporary' forest members samples_, rates_
+ * and active_nodes_ are set correctly beforehand.  
+ *
+ * \param ti The current time interval
+ * \returns the event that has happened (can also be a "NoEvent" event)
+ */
+void Forest::sampleEvent(const TimeInterval &ti, double &event_time, Event &return_event) const {
+  event_time = -1;
+  size_t event_line = -1;
+
+  // Sample on which time and time line the event happens (if any)
+  for (size_t i = 0; i < 3; ++i) {
+    if (rates_[i] == 0.0) continue;
+    selectFirstTime(random_generator()->sampleExpoExpoLimit(rates_[i], getTimeLineGrowth(i), ti.length()), 
+                    i, event_time, event_line);
+  }
+
+  // Correct the time from relative to the time interval to absolute 
+  if (event_time != -1) event_time += ti.start_height();
+  assert( (event_time == -1) || 
+         (ti.start_height() <= event_time && event_time <= ti.end_height()) );
+
+  assert( (event_line == -1 && event_time == -1) || (event_line != -1 && event_time != -1));
+  // Sample the event type
+  sampleEventType(event_time, event_line, ti, return_event);
+}
+
+
+/**
+ * Given that an event has happened, this function samples the events type. 
+ * 
+ * In particular requires that the 'temporary' forest members samples_, rates_, 
+ * active_nodes_, and nodes_timelines_ are set correctly beforehand.  
+ */
+void Forest::sampleEventType(const double time, const size_t time_line, 
+                             const TimeInterval &ti, Event &event) const {
+  event = Event(time);
+
+  if ( time_line != -1 && rates_[time_line] == 0.0 ) {
+    throw std::logic_error("An event with rate 0 has happened!");
+  }
+
+  // Situation where it is clear what happened:
+  if (time == -1) return;
+  if (time_line == 2) return event.setToCoalescence(active_node(1), 1);
+
+  double sample = random_generator()->sample() * rates_[time_line];
+
+  for (size_t i = 0; i < 2; ++i) {
+    // Only Nodes in state 1 or 2 can do something
+    if ( states_[i] == 0 ) continue;
+
+    // Coalescence can occur on all time lines  
+    if (states_[i] == 1 && active_nodes_timelines_[i] == time_line) {
+      sample -= calcCoalescenceRate(active_node(i)->population(), ti);
+      if (sample <= 0.0) return event.setToCoalescence(active_node(i), i); 
+    }
+
+    // Migration and Recombination only on time line 0    
+    if (time_line != 0) continue;
+
+    // Recombination
+    if (states_[i] == 2) {
+      sample -= calcRecombinationRate(active_nodes_[i]);
+      if (sample <= 0.0) return event.setToRecombination(active_node(i), i);
+      continue;
+    }
+
+    // Migration
+    assert( states_[i] == 1 );
+    if ( sample < model().total_migration_rate(active_node(i)->population()) ) {
+      for ( size_t j = 0; j < model().population_number(); ++j) {
+        sample -= model().migration_rate(active_node(i)->population(), j);
+        if ( sample <= 0.0 ) return event.setToMigration(active_node(i), i, j);
+      } 
+      throw std::logic_error("Error Sampling Type of Event");
+    }
+    sample -= model().total_migration_rate(active_node(i)->population());
+  }
+
+  // If we are here, than we should have sampled a pw coalescence...
+  assert( states_[0] == 1 && states_[1] == 1 );
+  assert( active_nodes_[0]->population() == active_nodes_[1]->population() );
+  assert( sample <= calcPwCoalescenceRate(active_nodes_[0]->population(), ti) );  
+  return event.setToPwCoalescence();
+}
+
+
+/**
+ * Looks if there was an event on a sampled time (e.g. this new_time != -1)
+ * and if so sets current_time to the event with the smallest time and increases
+ * the time_line counter.
+ *
+ * \param new_time An ExpoLimit Sample
+ * \param time_line The timeline that the sample was from 
+ * \param current_time The variable that save the time of the nearest event 
+ * \param time_line The variable that saves the timeline of the nearest event 
+ * \return Nothing, but updates current_time and current_time_line   
+ */
+void Forest::selectFirstTime(const double new_time, const size_t time_line, 
+                             double &current_time, size_t &current_time_line) const {
+  if (new_time == -1) return;
+  if (current_time == -1 || new_time < current_time) {
+    current_time = new_time;
+    current_time_line = time_line;
+  }
+}
+
+
+/**
+ *  Function to determine the state of (the branch above) a node for an ongoing
+ *  coalescence.
+ *
+ *  The States are: 0 = off, 1 = potentially coalescing, 2 = potentially recombining
+ *
+ *  \param node the node for which to tell the start
+ *  \param current_time the time at which the coalescence is
+ *  \return The state of the node
+ */
+size_t Forest::getNodeState(Node const *node, const double current_time) const {
+  if (node->height() > current_time) return(0);
+  if (node->is_root()) return(1);
+  if (!node->local()) return(2);
+  dout << "Error getting node state." << std::endl;
+  dout << "Height: " << node->height() 
+      << " current time: " << current_time 
+      << " diff: " << node->height() - current_time << std::endl;
+  dout << "Node local: " << node->local() << std::endl;
+  dout << "Node root: " << node->is_root() << std::endl;
+  assert( false );
+  return(-1);
+}
+
+
+double Forest::calcCoalescenceRate(const size_t pop, const TimeInterval &ti) const {
+  // Rate for each pair is 1/(2N), as N is the diploid population size
+  return contemporaries_.size(pop) * model().inv_double_pop_size(pop, ti.start_height());
+}
+
+
+double Forest::calcPwCoalescenceRate(const size_t pop, const TimeInterval &ti) const {
+  // Rate a pair is 1/(2N), as N is the diploid population size
+  return model().inv_double_pop_size(pop, ti.start_height());
+}
+
+
+double Forest::calcRecombinationRate(Node const* node) const {
+  assert(!node->local());
+  assert(this->current_base() >= model().getCurrentSequencePosition());
+  double last_update_pos = get_rec_base(node->last_update());
+
+  if (last_update_pos >= model().getCurrentSequencePosition()) {
+    // Rec rate is constant for the relevant sequence part
+    return (this->current_base() - last_update_pos) * model().recombination_rate();
+  } else {
+    // Rec rate may change. Accumulate the total rate.
+
+    double rate = model().recombination_rate() * 
+        (this->current_base() - model().getCurrentSequencePosition()); 
+    size_t idx = model().get_position_index() - 1;
+
+    while (model().change_position(idx) > last_update_pos) {
+      assert(idx > 0);
+      rate += model().recombination_rate(idx) * (model().change_position(idx+1)-model().change_position(idx));
+      --idx;
+    }
+
+    rate += model().recombination_rate(idx) * (model().change_position(idx+1)-last_update_pos);
+    return rate;
+  }
+}
+
+
+/** 
+ * Even if no event occurred in a time interval, there is some stuff that we
+ * might have to do. Mainly moving the "active" flag upwards if a active node
+ * was looking for recombinations, but none occurred. In that case, we also
+ * might finish the coalescences.
+ *
+ * \param ti The current time interval
+ * \param coalescences_finished temp variable to pass the information that the
+ *    coalescence has finished. 
+ */
+void Forest::implementNoEvent(const TimeInterval &ti, bool &coalescence_finished) {
+  if (ti.end_height() == DBL_MAX) 
+    throw std::logic_error("Lines did not coalescence. If you use an negative growth parameter (population rapidly declining forward in time), you need to set it to a non-negative value at some time.");
+  if (states_[0] == 2) {
+    set_active_node(0, possiblyMoveUpwards(active_node(0), ti));
+    if (active_node(0)->local()) {
+      assert( states_[1] == 0 );
+      dout << "* * * Active Node 0 hit a local node. Done" << std::endl;
+      updateAbove(active_node(0));
+      coalescence_finished = true;
+      tmp_event_time_ = active_node(0)->height();
+      contemporaries_.replace(active_node(0), 
+                              active_node(0)->first_child(), 
+                              active_node(0)->second_child());
+      return;
+    }
+  }
+
+  // There are no local node above the local root, which is the lowest node
+  // that active_node(1) can be.
+  if (states_[1] == 2) set_active_node(1, possiblyMoveUpwards(active_node(1), ti));
+
+  if (active_node(0) == active_node(1)) {
+    dout << "* * * Active Nodes hit each other in " << active_node(0) 
+        << ". Done." << std::endl;
+    updateAbove(active_node(0));
+    coalescence_finished = true;
+    // Update contemporaries for reuse
+    contemporaries_.replaceChildren(active_node(0));
+    tmp_event_time_ = active_node(0)->height();
+  }
+}
+
+/**
+ * Modifies the forest to reflect the coalescences of a coalescing node into
+ * a point on a existing tree.
+ *
+ * Attention: The returned node does still require an update!
+ *
+ * \param coal_node The coalescing node
+ * \param coal_point The point on the tree into which coal_node coalesces.
+ *
+ */
+void Forest::implementCoalescence(const Event &event, TimeIntervalIterator &tii) {
+  // Coalescence: sample target point and implement the coalescence
+  assert( event.node() == active_node(event.active_node_nr()) );
+
+  Node* coal_node = event.node();
+  Node* target = contemporaries_.sample(coal_node->population());
+
+  dout << "* * * Above node " << target << std::endl;
+  assert( target->height() < event.time() ); 
+  assert( coal_node->population() == target->population() );
+  assert( getEventNode() != NULL );
+  assert( getOtherNode() != NULL );
+
+  Node* new_node;
+
+  // ---------------------------------------------
+  // Actually implement the coalescence
+  // ---------------------------------------------
+
+  // Look if we can reuse the root that coalesced for marking the point of 
+  // coalescence
+  if ( coal_node->countChildren() == 1 && !coal_node->is_migrating() ){
+    assert( coal_node->local() );
+    new_node = coal_node;
+    coal_node = coal_node->first_child();
+    nodes()->move(new_node, event.time());
+    updateAbove(new_node, false, false);
+  } else {
+    // If not, create a new node
+    new_node = nodes()->createNode(event.time());
+    new_node->change_child(NULL, coal_node);
+    coal_node->set_parent(new_node);
+    nodes()->add(new_node);
+  }
+
+  // Now we have:
+  // target:    Node in the target tree under the coalescence
+  // coal_node: Root of the coalescing tree 
+  // new_node:  New parent of 'target' and 'coal_node'
+
+  // Update new_node
+  new_node->set_population(coal_node->population());
+  new_node->change_child(NULL, target);
+  new_node->set_parent(target->parent());
+  if (!target->local()) {
+    new_node->make_nonlocal(target->last_update());
+    contemporaries_.add(new_node);
+  } else {
+    new_node->make_local();
+  }
+
+  // Integrate it into the tree
+  target->set_parent(new_node);
+  new_node->parent()->change_child(target, new_node);
+
+  // And update
+  coal_node->make_local();
+  updateAbove(coal_node, false, false); 
+
+  set_active_node(event.active_node_nr(), new_node);
+
+
+  // ---------------------------------------------
+  // Check if are can stop.
+  // ---------------------------------------------
+
+  if ( getOtherNodesState() == 2 ) {
+    // If the coalescing node coalesced into the branch directly above 
+    // a recombining node, we are done.
+    if ( getOtherNode()->parent() == getEventNode() ) {
+      dout << "* * * Recombining Node moved into coalesced node. Done." << std::endl;
+      getOtherNode()->make_local();
+      updateAbove(getOtherNode(), false, false);
+      updateAbove(getEventNode());
+      coalescence_finished_ = true;
+      return;
+    }
+
+    // The branch below the event will be made local later anyway, so we don't
+    // have to care about marking it as updated.
+  }
+
+  if ( target->local() ) {
+    // Only active_node(0) can coalescence into local nodes. active_node(1) is 
+    // at least the local root and hence above all local nodes. 
+    // If active_node(0) coalescences into the local tree, there are no more
+    // active nodes and we are done. 
+    assert( event.active_node_nr() == 0 );
+    assert( states_[1] == 0 );
+
+    dout << "* * * We hit the local tree. Done." << std::endl;
+    updateAbove(getEventNode()); 
+    coalescence_finished_ = true;
+    contemporaries_.replace(new_node, coal_node, target);
+    return;
+  }
+
+  // If we hit an non-local branch:
+  // Begin next interval at the coalescence height and remove the branch
+  // below from contemporaries.
+  tii.splitCurrentInterval(getEventNode(), target);
+}
+
+
+
+/** 
+ * @brief Modifies the forest to reflect that two coalescing nodes coalesced together.
+ * 
+ * @param root_1 The first coalescing node
+ * @param root_2 The second coalescing node
+ * @param time   The time at which the coalescence happens
+ */
+void Forest::implementPwCoalescence(Node* root_1, Node* root_2, const double time) {
+  dout << "* * Both nodes coalesced together" << std::endl;
+  dout << "* * Implementing..." << std::flush;
+
+  Node* new_root = NULL;
+  assert( root_1 != NULL );
+  assert( root_2 != NULL );
+  assert( root_1->population() == root_2->population() );
+
+  // Both roots are now local
+  root_1->make_local();
+  root_2->make_local();
+
+  // both nodes may or may not mark the end of a single branch at the top of their tree,
+  // which we don't need anymore.
+  if (root_1->countChildren() == 1 && !root_1->is_migrating()) {
+    if (root_2->countChildren() == 1 && !root_2->is_migrating()) {
+      // both trees have a single branch => delete one
+      root_2 = root_2->first_child();
+      this->nodes()->remove(root_2->parent());
+      root_2->set_parent(NULL);
+      assert( root_2 != NULL );
+      assert( root_2->is_root() );
+    }
+    // (now) only root_1 has a single branch => use as new root
+    this->nodes()->move(root_1, time);
+    new_root = root_1;
+    root_1 = root_1->first_child();
+    assert( root_1 != NULL );
+  } 
+  else if (root_2->countChildren() == 1 && !root_2->is_migrating()) {
+    // only root_2 has a single branch => use as new root
+    this->nodes()->move(root_2, time);
+    new_root = root_2;
+    root_2 = root_2->first_child();
+  }
+  else {
+    // No tree a has single branch on top => create a new root
+    new_root = nodes()->createNode(time);
+    this->nodes()->add(new_root);
+  }
+
+  root_1->set_parent(new_root);
+  root_2->set_parent(new_root);
+  new_root->set_second_child(root_1);
+  new_root->set_first_child(root_2);
+  new_root->set_population(root_1->population());
+
+  updateAbove(root_1, false, false);
+  updateAbove(root_2, false, false);
+  updateAbove(new_root, false, false);
+  dout << " done" << std::endl;
+
+  assert( this->local_root()->height() == time );
+  assert( root_1->local() );
+  assert( root_2->local() );
+  assert( !new_root->local() );
+}
+
+
+void Forest::implementRecombination(const Event &event, TimeIntervalIterator &ti) {
+  TreePoint event_point = TreePoint(event.node(), event.time(), false);
+  set_active_node(event.active_node_nr(), cut(event_point));
+
+  ti.recalculateInterval();
+
+  assert( this->printTree() );
+  assert( event.node()->local() );
+}
+
+
+void Forest::implementMigration(const Event &event, const bool &recalculate, TimeIntervalIterator &ti) {
+  dout << "* * Implementing migration event... " << std::flush;
+  assert( event.node()->is_root() );
+
+  // There is only little to do if we can reuse the event.node() 
+  if ( event.node()->is_unimportant() || 
+       ( event.node()->height() == event.time() && event.node()->is_migrating() ) ) {
+    dout << "Reusing: " << event.node() << "... " << std::flush;
+    nodes()->move(event.node(), event.time());
+    event.node()->set_population(event.mig_pop());
+    updateAbove(event.node());
+  } else {
+    // Otherwise create a new node that marks the migration event,
+    Node* mig_node = nodes()->createNode(event.time());
+    dout << "Marker: " << mig_node << "... " << std::flush; 
+    nodes()->add(mig_node, event.node());
+    mig_node->set_population(event.mig_pop());
+
+    // integrate it into the tree
+    event.node()->set_parent(mig_node);
+    mig_node->set_first_child(event.node());
+    updateAbove(event.node(), false, false);
+    updateAbove(mig_node);
+
+    // and set it active.
+    this->set_active_node(event.active_node_nr(), mig_node);
+    assert(mig_node->is_migrating());
+
+    // Now make the event node local
+    event.node()->make_local();
+  }
+  // Recalculate the interval
+  if (recalculate) ti.recalculateInterval();
+  dout << "done." << std::endl;
+
+  assert( event.node()->local() );
+}
+
+
+void Forest::implementFixedTimeEvent(TimeIntervalIterator &ti) {
+  dout << "* * Fixed time event" << std::endl;
+  double sample;
+  bool migrated;
+  size_t chain_cnt, pop_number = model().population_number();
+
+  for (size_t i = 0; i < 2; ++i) {
+    if (states_[i] != 1) continue;
+    chain_cnt = 0;
+    while (true) {
+      migrated = false;
+      sample = random_generator()->sample();
+
+      for (size_t j = 0; j < pop_number; ++j) {
+        sample -= model().single_mig_pop(active_node(i)->population(), j);
+        if (sample < 0) {
+          tmp_event_ = Event((*ti).start_height());
+          tmp_event_.setToMigration(active_node(i), i, j);
+          implementMigration(tmp_event_, false, ti);
+          migrated = true;
+          break;
+        }
+      }
+
+      // Stop if no migration occurred
+      if (!migrated) break;
+
+      // Resolve a maximum of 10k chained events for each node
+      if (chain_cnt == 10000) 
+        throw std::logic_error("Circle detected when moving individuals between populations");
+      ++chain_cnt;
+    }
+  }
+  assert( printTree() );
+}
+
+/** 
+ * Helper function for doing a coalescence.
+ * Moves the 'active' flag (i.e. the node stored in root_1 or root_2 in sampleCoalescence)
+ * from a node to it's parent if the branch above the node
+ * ends this the current time interval.
+ *
+ * This function is used the pass the active flag upwards in the tree if the
+ * node is active, but neither coalescing nor a recombination happens on the
+ * branch above, e.g. after a local-branch became active because it was hit by a
+ * coalescence or a non-local branch was active and no recombination occurred.
+ *
+ * Also updates the active node if it moves up.
+ *
+ * \param node An active node
+ * \param time_interval The time interval the coalescence is currently in.
+ * 
+ * \return  Either the parent of 'node' if we need to move upwards or 'node'
+ *          itself
+ */
+Node* Forest::possiblyMoveUpwards(Node* node, const TimeInterval &time_interval) {
+  if ( node->parent_height() == time_interval.end_height() ) {
+    node->make_local();
+    updateAbove(node, false, false);
+    return node->parent();
+  }
+  return node;
+}
+
+
+bool Forest::pruneNodeIfNeeded(Node* node, const bool prune_orphans) {
+  assert(node != NULL);
+  if (!model().has_approximation()) return false;
+  if (node->in_sample()) return false;
+
+  if (node->is_root()) {
+    // Orphaned nodes must go
+    if (node->countChildren() == 0 && prune_orphans) {
+      dout << "* * * PRUNING: Removing node " << node << " from tree (orphaned)" << std::endl;
+      assert(node != local_root());
+      // If we are removing the primary root, it is difficult to find the new
+      // primary root. It should however be automatically set during the updates
+      // of the current coalescence.
+      if (node == primary_root()) set_primary_root(NULL);
+      nodes()->remove(node);
+      return true; 
+    }
+    // Other roots stay
+    return false;
+  } else {
+    // No root:
+    if (nodeIsOld(node)) {
+      // Old nodes have to go, no matter what
+      dout << "* * * PRUNING: Removing branch above " << node << " from tree (old)" << std::endl;
+      assert(!node->is_root());
+
+      node->parent()->change_child(node, NULL);
+      if (node->countChildren() == 0) nodes()->remove(node); 
+      else { 
+        // Remove link between `node` and its parent,
+        // which effectively removes the branch, 
+        // and separates the subtree below from the main tree
+        Node* parent = node->parent();
+        node->set_parent(NULL);
+        updateAbove(parent, false, true, true);
+      }
+      return true;
+    } 
+
+    else if (node->countChildren() == 1 && !node->is_migrating()) {
+      // Unneeded nodes 
+      dout << "* * * PRUNING: Removing node " << node << " from tree (unneeded)" << std::endl;
+      assert(!node->is_migrating());
+      assert(node->first_child()->last_update() == node->last_update());
+      assert(node->first_child()->local() == node->local());
+
+      Node* child = node->first_child();
+      child->set_parent(node->parent());
+      node->parent()->change_child(node, child); 
+      nodes()->remove(node);
+      return true;
+    }
+  }
+
+  return false;
+}
+
+
+void Forest::calcSegmentSumStats() {
+  for (size_t i = 0; i < model().countSummaryStatistics(); ++i) {
+    model().getSummaryStatistic(i)->calculate(*this);
+  }
+}
+
+
+void Forest::clearSumStats() {
+  for (size_t i = 0; i < model().countSummaryStatistics(); ++i) {
+    model().getSummaryStatistic(i)->clear();
+  }
+}
+
+
+void Forest::printLocusSumStats(std::ostream &output) const {
+  for (size_t i = 0; i < model().countSummaryStatistics(); ++i) {
+    model().getSummaryStatistic(i)->printLocusOutput(output);
+  }
+}
+
+
+void Forest::printSegmentSumStats(std::ostream &output) const {
+  for (size_t i = 0; i < model().countSummaryStatistics(); ++i) {
+    model().getSummaryStatistic(i)->printSegmentOutput(output);
+  }
+}
+
+
+void Forest::clear() {
+  // Clear roots tracking
+  set_local_root(NULL);
+  set_primary_root(NULL);
+
+  // Clear nodes
+  nodes()->clear();
+
+  // Reset Position & Segment Counts
+  this->rec_bases_.clear();
+  this->set_next_base(-1.0);
+  this->current_rec_ = 0;
+
+  // Clear Summary Statistics
+  this->clearSumStats();
+  
+  // Reset Model
+  writable_model()->resetTime();
+  writable_model()->resetSequencePosition();
+}
+
+
+
+Node* Forest::readNewickNode( std::string &in_str, std::string::iterator &it, size_t parenthesis_balance, Node* const parent ){
+  Node * node = nodes()->createNode( (double)0.0, (size_t)0 );
+  node->set_parent ( parent );
+  node->make_local();
+  //this->nodes()->push_front( node );
+  dout << "Node " << node
+       << " starts from [ " << std::endl;
+  for (  ; it != in_str.end(); ++it) {
+    dout << "\""<<(*it) <<"\"" ;
+    if        ( (*it) == '(' )  { // Start of a internal node, extract a new node
+      parenthesis_balance++;
+      Node* child_1 = this->readNewickNode ( in_str, it = (it+1),parenthesis_balance, node );
+      node->set_first_child ( child_1 );
+      this->nodes()->add( child_1 );
+      if ( node->first_child() != NULL)
+        node->set_height ( node->first_child()->height() + 40000*node->first_child()->bl()  ) ;
+    } else if ( (*(it+1)) == ',' ){ //
+      node->extract_bl_and_label(it);
+      dout << " " << parent
+           << " has first child node " << node
+           << " with branch length "   << node->bl()
+           << ", and with the label "  << node->label()
+           << ", height "              << node->height()
+           << " ]  Node " << node << " closed " << std::endl;
+      //if ( !node->in_sample() ) this->contemporaries_.add(node);
+      return node;
+    } else if ( (*(it)) == ',' ){ //
+      Node* child_2 = this->readNewickNode ( in_str, it=(it + 1), parenthesis_balance, node );
+      node->set_second_child ( child_2 );
+      this->nodes()->add( child_2 );
+    } else if ( (*(it+1)) == ')'  ){
+      // Before return, extract the branch length for the second node
+      node->extract_bl_and_label(it);
+      dout << " " << parent
+           << " has second child node " << node
+           << " with branch length "   << node->bl()
+           << ", and with the label "  << node->label()
+           << ", height "              << node->height()
+           << " ]  Node " << node << " closed " << std::endl;
+      //if ( !node->in_sample() ) this->contemporaries_.add(node);
+      return node;
+    } else if ( (*(it)) == ';' ) {
+      dout <<" Node " << node << " closed " << std::endl;
+      this->nodes()->add( node );
+      node->make_nonlocal(current_rec());
+      return node;
+    } else {
+      continue;
+    }
+  }
+  assert(false);
+  return NULL;
+}
+
+
+void Forest::readNewick( std::string &in_str ){
+  this->current_rec_ = 1;
+  std::string::iterator it = in_str.begin();
+  (void)this->readNewickNode( in_str, it );
+  this->set_local_root( this->nodes()->last() );
+  this->set_primary_root(this->nodes()->last() );
+  dout << std::endl<<"there are "<< this->nodes()->size() << " nodes " << std::endl;
+  (void)this->nodes()->sorted();
+  for (auto it = nodes()->iterator(); it.good(); ++it) {
+    updateAbove(*it, false, false);
+  }
+  assert(this->printNodes());
+  assert(this->printTree());
+  dout << "contemporaries_.size()"<<contemporaries_.size(0) <<std::endl;
+  this->sampleNextBase();
+  this->calcSegmentSumStats();
+  this->tmp_event_time_ = this->local_root()->height();
+}
+
+
+// Must be called AFTER the tree was modified.
+void Forest::sampleNextBase() {
+  double length = random_generator()->sampleExpoLimit(getLocalTreeLength() * model().recombination_rate(),
+                                                      model().getNextSequencePosition() - current_base());
+  if (length == -1) {
+    // No recombination until the model changes
+    set_next_base(model().getNextSequencePosition());
+    if (next_base() < model().loci_length()) writable_model()->increaseSequencePosition();
+  } else {
+    // Recombination in the sequence segment
+    set_next_base(current_base() + length);
+  }
+} 
+
diff --git a/src/forest.h b/src/forest.h
new file mode 100644
index 0000000..7dec984
--- /dev/null
+++ b/src/forest.h
@@ -0,0 +1,328 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+/*!
+ * \file forest.h
+ * \brief Contains the class Forest, which is the central class in scrm
+ *
+ * The central data structure of scrm is a forest, which is a collection of
+ * trees. This class on the one hand contains a NodeContainer object with all
+ * nodes building the trees, and on the other hand functions to manipulate to
+ * forest.
+ *
+ * Most functions are defined in forest.cc with exception of pure debugging
+ * functions, with are in forest-debug.cc.
+ */
+
+#ifndef scrm_src_forest
+#define scrm_src_forest
+
+#include <string>
+
+#include "macros.h" // Needs to be before cassert
+
+#include <vector>
+#include <unordered_set>
+#include <stdexcept>
+#include <cassert>
+#include <iostream> // ostreams
+#include <iomanip>  // Used for debug output
+#include <sstream>  // Used for debug output
+
+#include "contemporaries_container.h"
+#include "event.h"
+#include "model.h"
+#include "macros.h"
+#include "node.h"
+#include "node_container.h"
+#include "time_interval.h"
+#include "tree_point.h"
+#include "random/random_generator.h"
+#include "summary_statistics/summary_statistic.h"
+
+class TimeInterval;
+class TimeIntervalIterator;
+enum eventCode { NOEVENT, EVENT, INIT_NULL};
+
+class Forest
+{
+ public:
+  Node* readNewickNode( std::string &in_str, std::string::iterator &current_it, size_t parenthesis_balance = 0, Node* parent = NULL );
+  void readNewick(std::string &in_str);
+  ContemporariesContainer* contemporaries()  {return &this->contemporaries_;};
+
+#ifdef UNITTEST
+  friend class TestForest;
+  friend class TestNode;
+  friend class TestTimeInterval;
+  friend class TestModel;
+  friend class TestNodeContainer;
+#endif
+  friend class TimeInterval;
+  friend class TimeIntervalIterator;
+
+  Forest(Model *model, RandomGenerator *random_generator);
+  Forest(const Forest &current_forest);
+  virtual ~Forest() {};
+
+  //Getters & Setters
+  const Model &model() const { return *model_; }
+  void set_model(Model* model) { this->model_ = model; }
+  Model* writable_model() { return this->model_; };
+
+  Node* local_root() const { return local_root_; }
+  void set_local_root(Node* local_root) { local_root_ = local_root; };
+
+  Node* primary_root() const { return primary_root_; }
+  void set_primary_root(Node* primary_root) { primary_root_ = primary_root; };
+
+  size_t sample_size() const { 
+    if (sample_size_ == 0) return model().sample_size(); 
+    return this->sample_size_; 
+  }
+  void set_sample_size(const size_t size ) { sample_size_ = size; }
+
+  size_t segment_count() const { return current_rec_; }
+
+  void sampleNextBase();
+
+  /**
+   * @brief Returns the length of the sequence for with the current tree is
+   * valid
+   *
+   * @param finite_sites If 'true', the length is measured in number of bases
+   * (e.g. integer sequence positions) for which the tree is valid. Otherwise,
+   * the length is measured real valued number on a continuous chromosome.  
+   *
+   * @return The length of the current segment (see above for its unit)
+   */
+  double calcSegmentLength() const {
+    if (model().getSequenceScaling() == relative) {
+      return (next_base() - current_base()) / model().loci_length();
+    } else {
+      return ceil(next_base()) - ceil(current_base());
+    }
+  }
+
+  void set_random_generator(RandomGenerator *rg) {
+    this->random_generator_ = rg; 
+  }
+  RandomGenerator* random_generator() const { return this->random_generator_; }
+
+  NodeContainer const *getNodes() const { return &nodes_; };
+
+  // Central functions
+  void buildInitialTree();
+  void sampleNextGenealogy();
+  TreePoint samplePoint(Node* node = NULL, double length_left = -1) const;
+
+  void clear();
+
+  //Debugging Tools
+  void addNodeToTree(Node *node, Node *parent, Node *first_child, Node *second_child);
+  void createExampleTree();
+  void createScaledExampleTree();
+  bool checkLeafsOnLocalTree(Node const* node=NULL) const;
+  bool checkTree(Node const* root = NULL) const;
+  double calcTreeLength() const;
+  bool checkTreeLength() const;
+  bool checkInvariants(Node const* node = NULL) const;
+  bool checkNodeProperties() const;
+  bool checkContemporaries(const double time) const;
+  bool printNodes() const;
+  bool checkForNodeAtHeight(const double height) const;
+  bool checkRootIsRegistered(Node const* node) const;
+  bool checkRoots() const;
+
+  //Debug Tree Printing
+  int countLinesLeft(Node const* node) const;
+  int countLinesRight(Node const* node) const;
+  int countBelowLinesLeft(Node const* node) const;
+  int countBelowLinesRight(Node const* node) const;
+  bool printTree() const;
+  std::vector<Node const*> determinePositions() const;
+  void printPositions(const std::vector<Node const*> &positions) const;
+
+  NodeContainer *nodes() { return &(this->nodes_); }
+
+  double getTMRCA(const bool &scaled = false) const {
+    if (scaled) return local_root()->height() / (4 * this->model_->default_pop_size);
+    else return local_root()->height();
+  }
+
+  double getLocalTreeLength(const bool &scaled = false) const {
+    if (scaled) return local_root()->length_below() / (4 * this->model_->default_pop_size);
+    else return local_root()->length_below();
+  }
+
+  //derived class from Forest
+  virtual void record_Recombevent(size_t pop_i, 
+    double opportunity, 
+    eventCode event_code){
+    (void)pop_i;
+    (void)opportunity;
+    (void)event_code;  
+  }
+  virtual void record_all_event( TimeInterval const &ti){
+    (void) ti;   
+  }
+
+  // Calc & Print Summary Statistics
+  void calcSegmentSumStats();
+  void clearSumStats();
+  void printLocusSumStats(std::ostream &output) const;
+  void printSegmentSumStats(std::ostream &output) const;
+
+  double get_rec_base(const size_t idx) const {
+    assert(idx < rec_bases_.size());
+    return rec_bases_[idx];
+  }
+
+  double current_base() const { return get_rec_base(current_rec_); }
+  double next_base() const { return get_rec_base(current_rec_ + 1); }
+  void set_current_base(double const base) { rec_bases_[current_rec_] = base; }; 
+  void set_next_base(double const base) { rec_bases_.push_back(base); }; 
+
+  size_t current_rec() const { return current_rec_; };
+
+ private:
+  Forest() { this->initialize(); }
+
+  //Operations on the Tree
+  Node* cut(const TreePoint &cut_point);
+
+  void updateAbove(Node* node, 
+                   bool above_local_root = false,
+                   const bool &recursive = true,
+                   const bool &invariants_only = false);
+
+  // Tools for doing coalescence & recombination
+  void sampleCoalescences(Node *start_node);
+  size_t getNodeState(Node const *node, const double current_time) const;
+  Node* updateBranchBelowEvent(Node* node, const TreePoint &event_point); 
+  Node* possiblyMoveUpwards(Node* node, const TimeInterval &event);
+
+  // Implementation of the different events
+  void implementNoEvent(const TimeInterval &ti, bool &coalescence_finished);
+  void implementCoalescence(const Event &event, TimeIntervalIterator &tii);
+  void implementPwCoalescence(Node* root_1, Node* root_2, const double time);
+  void implementRecombination(const Event &event, TimeIntervalIterator &tii);
+  void implementMigration(const Event &event, const bool &recalculate, TimeIntervalIterator &tii);
+  void implementFixedTimeEvent(TimeIntervalIterator &ti);
+
+  // Pruning
+  bool nodeIsOld(Node const* node) const {
+    if ( node->local() ) return false;
+    if ( node->is_root() ) return false;
+    if ( model().has_window_rec() && 
+         segment_count() - node->last_update() > model().window_length_rec()) {
+      return true;
+    }
+    if ( model().has_window_seq() && 
+         current_base() - get_rec_base(node->last_update()) > model().window_length_seq()) {
+      return true;
+    }
+    return false;
+  }
+
+  bool nodeIsActive(Node const* node) const {
+    return (node == active_node(0) || node == active_node(1));
+  }
+
+  bool pruneNodeIfNeeded(Node* node, const bool prune_orphans = true);
+
+  // Calculation of Rates
+  double calcCoalescenceRate(const size_t pop, const TimeInterval &ti) const;
+  double calcPwCoalescenceRate(const size_t pop, const TimeInterval &ti) const;
+  double calcRecombinationRate(Node const* node) const;
+  void calcRates(const TimeInterval &ti);
+
+  void sampleEvent(const TimeInterval &ti, double &event_time, Event &return_event) const;
+
+  void sampleEventType(const double time, const size_t time_line, 
+                       const TimeInterval &ti, Event &return_event) const;
+
+  void selectFirstTime(const double new_time, const size_t time_line, 
+                       double &current_time, size_t &current_time_line) const;
+
+  double getTimeLineGrowth(const size_t time_line) const {
+    if (time_line == 0) return 0.0;
+    else if (time_line == 1) return model().growth_rate(active_node(0)->population());
+    else if (time_line == 2) return model().growth_rate(active_node(1)->population());
+    else throw std::out_of_range("Trying to get growthrate of unknown time line.");
+  }
+
+  // Private Members
+  NodeContainer nodes_;    // The nodes of the Tree/Forest
+
+  // We have 3 different kind of roots that are important:
+  // local root: root of the smallest subtree containing all local sequences
+  Node* local_root_;
+
+  // primary root: root of the tree that contains all local sequences
+  Node* primary_root_;
+
+  // secondary roots: roots of trees that contain only non-local nodes
+  // std::unordered_set<Node*> secondary_roots_;
+
+  size_t sample_size_;      // The number of sampled nodes (changes while building the initial tree)
+  size_t current_rec_;      // A counter for recombinations
+
+  std::vector<double> rec_bases_; // Genetic positions of the recombinations 
+
+  Model* model_;
+  RandomGenerator* random_generator_;
+
+  void initialize(Model *model = new Model(),
+                  RandomGenerator *rg = NULL);
+
+  void createSampleNodes();
+
+  // Temporarily used when doing the coalescence
+
+  // Rates: 
+  double rates_[3];
+
+  // States: Each (branch above an) active node can either be in state
+  // - 0 = off (the other coalescence has not reached it yet) or
+  // - 1 = potentially coalescing in a time interval or
+  // - 2 = potentially recombining in a time interval
+  size_t states_[2];
+  Node* active_nodes_[2];
+  Event  tmp_event_;
+  double tmp_event_time_;
+  ContemporariesContainer contemporaries_;
+
+  // These are pointers to the up to two active nodes during a coalescence
+  size_t active_nodes_timelines_[2];
+  Node* active_node(size_t nr) const { return active_nodes_[nr]; };
+  void set_active_node(size_t nr, Node* node) { active_nodes_[nr] = node; };
+
+  Node* getEventNode() const { return active_node(tmp_event_.active_node_nr()); }
+  size_t getEventNodesState() const { return states_[tmp_event_.active_node_nr()]; };
+  Node* getOtherNode() const { return active_node(1-tmp_event_.active_node_nr()); };
+  size_t getOtherNodesState() const { return states_[1-tmp_event_.active_node_nr()]; };
+
+  bool coalescence_finished_;
+};
+
+#endif
diff --git a/src/macros.h b/src/macros.h
new file mode 100644
index 0000000..ef5b807
--- /dev/null
+++ b/src/macros.h
@@ -0,0 +1,71 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef scrm_src_macros
+#define scrm_src_macros
+
+/* Used when building an R package (RBUILD) */
+#ifdef RBUILD
+
+// Include Rcpp Headers for Rcout.
+#include "Rcpp.h"
+
+// Suppress debug output.
+#pragma GCC diagnostic ignored "-Wunused-value"
+#define dout 0 && Rcpp::Rcout
+
+// Assure that assertions are deactivated.
+#ifndef NDEBUG
+#define NDEBUG
+#endif
+
+#else
+/* Used for normal compilation for scrm */
+
+// Unless compiled with options NDEBUG, we will produce a debug output using 
+// 'dout' instead of cout and execute (expensive) assert statements.
+#ifndef NDEBUG
+
+// Debug mode
+#ifdef UNITTEST // No debug output in unittests
+#pragma GCC diagnostic ignored "-Wunused-value"
+#define dout 0 && std::cout
+#else           // Produce debug output
+#define dout std::cout
+#endif
+
+#else
+// Normal Mode
+#pragma GCC diagnostic ignored "-Wunused-value"
+#define dout 0 && std::cout
+#endif
+
+#endif
+
+#include <limits>
+#include <cmath>
+// from Knuths "The art of computer programming"
+inline bool areSame(const double a, const double b, 
+                    const double epsilon = std::numeric_limits<double>::epsilon()) {
+  return fabs(a - b) <= ( (fabs(a) > fabs(b) ? fabs(b) : fabs(a)) * epsilon);
+}
+
+#endif
diff --git a/src/model.cc b/src/model.cc
new file mode 100644
index 0000000..815e3bb
--- /dev/null
+++ b/src/model.cc
@@ -0,0 +1,710 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "model.h"
+
+
+Model::Model() { 
+  default_pop_size = 10000;
+  default_loci_length = 100000;
+  default_growth_rate = 0.0;
+  default_mig_rate = 0.0;
+  scaling_factor_ = 1.0 / (4 * default_pop_size);
+
+  has_migration_ = false;
+  has_recombination_ = false;
+
+  this->addChangeTime(0.0);
+  this->addChangePosition(0.0);
+
+  this->set_population_number(1);
+
+  this->set_loci_number(1);
+  this->loci_length_ = this->default_loci_length;
+
+  this->setLocusLength(default_loci_length);
+  this->setMutationRate(0.0);
+  this->setRecombinationRate(0.0);
+
+  this->window_length_seq_ = 0;
+  this->set_window_length_rec(500);
+
+  this->setSequenceScaling(ms);
+
+  this->resetTime();
+  this->resetSequencePosition();
+}
+
+
+Model::Model(size_t sample_size) : Model() {
+  this->addSampleSizes(0.0, std::vector<size_t>(1, sample_size));
+  this->resetTime();
+}
+
+
+/*
+void Model::reset() {
+  pop_sizes_list_.clear();
+  growth_rates_list_.clear();
+  mig_rates_list_.clear();
+  total_mig_rates_list_.clear();
+  single_mig_probs_list_.clear();
+  summary_statistics_.clear();
+}
+*/
+
+/** 
+ * Function to add a new change time to the model.
+ *
+ * It preserves the relation between the times and the *param*_list_ containers.
+ * If the same time is added multiple times, it is just added once to the model,
+ * but this should not make a difference when using this function.
+ *
+ * @param time The time that is added
+ * @param scaled set to TRUE if the time is in units of 4N0 generations, and
+ * FALSE if it is in units of generations. 
+ *
+ * @returns The position the time has now in the vector
+ */
+size_t Model::addChangeTime(double time, const bool &scaled) {
+  if (scaled) time *= 4 * default_pop_size;
+
+  size_t position = 0;
+  if ( change_times_.size() == 0 ) {
+    change_times_ = std::vector<double>(1, time);
+    pop_sizes_list_.push_back(std::vector<double>());
+    growth_rates_list_.push_back(std::vector<double>());
+    mig_rates_list_.push_back(std::vector<double>());
+    total_mig_rates_list_.push_back(std::vector<double>());
+    single_mig_probs_list_.push_back(std::vector<double>());
+    return position;
+  }
+
+  std::vector<double>::iterator ti; 
+  for (ti = change_times_.begin(); ti != change_times_.end(); ++ti) {
+    if ( *ti == time ) return position;
+    if ( *ti > time ) break; 
+    ++position;
+  }
+
+  change_times_.insert(ti, time);
+  
+  // Add Null at the right position in all parameter vectors 
+  pop_sizes_list_.insert(pop_sizes_list_.begin() + position, std::vector<double>());
+  growth_rates_list_.insert(growth_rates_list_.begin() + position, std::vector<double>());
+  mig_rates_list_.insert(mig_rates_list_.begin() + position, std::vector<double>());
+  total_mig_rates_list_.insert(total_mig_rates_list_.begin() + position, std::vector<double>());
+  single_mig_probs_list_.insert(single_mig_probs_list_.begin() + position, std::vector<double>());
+  return position;
+}
+
+
+/** 
+ * Function to add a new change time to the model.
+ *
+ * It preserves the relation between the times and the *param*_list_ containers.
+ * If the same time is added multiple times, it is just added once to the model,
+ * but this should not make a difference when using this function.
+ *
+ * @param time The time that is added
+ * @param scaled set to TRUE if the time is in units of 4N0 generations, and
+ * FALSE if it is in units of generations. 
+ *
+ * @returns The position the time has now in the vector
+ */
+size_t Model::addChangePosition(const double position) {
+  size_t idx = 0;
+
+  if ( change_position_.size() == 0 ) {
+    change_position_ = std::vector<double>(1, position);
+    recombination_rates_.push_back(-1);
+    mutation_rates_.push_back(-1);
+    return 0;
+  }
+
+  std::vector<double>::iterator ti; 
+  for (ti = change_position_.begin(); ti != change_position_.end(); ++ti) {
+    if ( *ti == position ) return idx;
+    if ( *ti > position ) break;
+    ++idx; 
+  }
+
+  change_position_.insert(ti, position);
+  
+  // Add Null at the right position in all parameter vectors 
+  recombination_rates_.insert(recombination_rates_.begin() + idx, -1);
+  mutation_rates_.insert(mutation_rates_.begin() + idx, -1);
+
+  return idx;
+}
+
+
+void Model::addSampleSizes(double time, const std::vector<size_t> &samples_sizes, const bool &scaled) {
+  if (scaled) time *= 4 * default_pop_size;
+
+  for (size_t pop = 0; pop < samples_sizes.size(); ++pop) {
+    for (size_t i = 0; i < samples_sizes.at(pop); ++i) {
+      sample_populations_.push_back(pop);
+      sample_times_.push_back(time);
+    }
+  }
+}
+
+
+/**
+ * @brief This changes the size of all populations to the given values at a
+ * specific point in time. 
+ *
+ * The sizes apply for with point on backwards in time.    
+ *
+ * @param time The time at which the population changes their sizes.
+ * @param pop_sizes A vector of new population sizes. Can either be given as
+ *    fraction of N0 or as an absolute value. See relative.
+ * @param time_scaled Set to true if the time is given in units of 4*N0
+ *    generations, or to false if the time is given in units of generations.
+ * @param relative set to TRUE, if the population sizes are given relative to
+ *    N0, or to FALSE if they are absolute values.
+ */
+void Model::addPopulationSizes(double time, const std::vector<double> &pop_sizes, 
+                               const bool &time_scaled, const bool &relative) {
+
+  if ( pop_sizes.size() != population_number() ) 
+    throw std::logic_error("Population size values do not meet the number of populations");
+
+  size_t position = addChangeTime(time, time_scaled);
+
+  pop_sizes_list_[position].clear();
+  for (double pop_size : pop_sizes) {
+    if (!std::isnan(pop_size)) {
+      // Scale to absolute values if necessary
+      if (relative) { pop_size *= this->default_pop_size; }
+
+      // Save inverse double value
+      if (pop_size <= 0.0) throw std::invalid_argument("population size <= 0");
+      pop_size = 1.0 / (2 * pop_size); 
+    } 
+    pop_sizes_list_[position].push_back(pop_size);
+  }
+}
+
+
+/**
+ * @brief This changes the size of all populations to a given value at a
+ * specific point in time. 
+ *
+ * The sizes apply for with point on backwards in time.    
+ *
+ * @param time The time at which the population changes their sizes.
+ * @param pop_sizes The size to which we set all populations. Can either be given as
+ *    fraction of N0 or as an absolute value. See relative.
+ * @param time_scaled Set to true if the time is given in units of 4*N0
+ *    generations, or to false if the time is given in units of generations.
+ * @param relative set to TRUE, if the population sizes are given relative to
+ *    N0, or to FALSE if they are absolute values.
+ */
+void Model::addPopulationSizes(const double time, const double pop_size, 
+                               const bool &time_scaled, const bool &relative) {
+  addPopulationSizes(time, std::vector<double>(population_number(), pop_size), time_scaled, relative);
+}
+  
+
+/**
+ * @brief This changes the size of a single populations to a given value at a
+ * specific point in time. 
+ *
+ * The sizes apply for with point on backwards in time.    
+ * Requires Model.finalization() to be called after the model is set up.
+ *
+ * @param time The time at which the population change its size.
+ * @param pop The population which will change its size.
+ * @param population_size The size to which we set the population. Can either be given as
+ *    fraction of N0 or as an absolute value. See relative.
+ * @param time_scaled Set to true if the time is given in units of 4*N0
+ *    generations, or to false if the time is given in units of generations.
+ * @param relative set to TRUE, if the population sizes are given relative to
+ *    N0, or to FALSE if they are absolute values.
+ */
+void Model::addPopulationSize(const double time, const size_t pop, double population_size,
+                              const bool &time_scaled, const bool &relative) {
+  checkPopulation(pop);
+  size_t position = addChangeTime(time, time_scaled);
+  if (relative) population_size *= default_pop_size;
+
+  if (population_size <= 0.0) throw std::invalid_argument("population size <= 0");
+  if (pop_sizes_list_.at(position).empty()) addPopulationSizes(time, nan("value to replace"), time_scaled);
+  pop_sizes_list_.at(position).at(pop) = 1.0/(2*population_size);
+}
+
+
+/**
+ * @brief Set the population size growth rates at a certain time point.
+ *
+ * The population growth or shrinks exponentially from that time point on
+ * backwards in time. 
+ * Requires Model.finalization() to be called after the model is set up.
+ *
+ * @param time The time at which to set the growth rates
+ * @param growth_rates A vector of growth rates for all populations
+ * @param time_scaled Set to true if the time is given in units of 4*N0
+ *    generations, or to false if the time is given in units of generations.
+ */
+void Model::addGrowthRates(const double time, const std::vector<double> &growth_rates,
+                           const bool &time_scaled, const bool &rate_scaled) {
+  if ( growth_rates.size() != population_number() ) 
+    throw std::logic_error("Growth rates values do not meet the number of populations");
+  size_t position = addChangeTime(time, time_scaled);
+
+  growth_rates_list_[position].clear();
+  for (double rate : growth_rates) {
+    if (rate_scaled) rate *= scaling_factor();
+    growth_rates_list_[position].push_back(rate);
+  }
+}
+
+
+/**
+ * @brief Set the population size growth rates at a certain time point.
+ *
+ * The population growth or shrinks exponentially from that time point on
+ * backwards in time. 
+ * Requires Model.finalization() to be called after the model is set up.
+ *
+ * @param time The time at which to set the growth rates
+ * @param growth_rates The growth rate for all populations
+ * @param time_scaled Set to true if the time is given in units of 4*N0
+ *    generations, or to false if the time is given in units of generations.
+ */
+void Model::addGrowthRates(const double time, const double growth_rate,
+                           const bool &time_scaled, const bool &rate_scaled) {
+  addGrowthRates(time, std::vector<double>(population_number(), growth_rate), time_scaled, rate_scaled);
+}
+
+
+/**
+ * @brief Set the population size growth rates of a population at a certain time point.
+ *
+ * The population growth or shrinks exponentially from that time point on
+ * backwards in time. 
+ * Requires Model.finalization() to be called after the model is set up.
+ *
+ * @param time The time at which to set the growth rates
+ * @param population The population to which the growth rate applies.
+ * @param growth_rates The growth rate for the populations
+ * @param time_scaled Set to true if the time is given in units of 4*N0
+ *    generations, or to false if the time is given in units of generations.
+ */
+void Model::addGrowthRate(const double time, const size_t population, 
+                          double growth_rate, const bool &time_scaled, const bool &rate_scaled) {
+  checkPopulation(population);
+  size_t position = addChangeTime(time, time_scaled);
+  if (rate_scaled) growth_rate *= scaling_factor();
+  if (growth_rates_list_.at(position).empty()) addGrowthRates(time, nan("number to replace"), time_scaled); 
+  growth_rates_list_.at(position).at(population) = growth_rate;
+}
+
+
+/**
+ * @brief Sets a migration rate form a specific population to another starting from a
+ * certain time point (going backwards in time); 
+ *
+ * This requires model finalization, e.g. call model.finalize() after you set up
+ * the model completely.
+ *
+ * @param time The time at which the migration is set to the given value.
+ *        It applies backwards in time until it is changed again.
+ * @param source The population from which the individuals migrate from when
+ *        looking backwards in time. Is the sink population when looking forward.
+ * @param sink The population to which the individuals migrate to (also
+ *        when looking backwards in time)
+ * @param mig_rate The backwards scaled migration rate M_ij = 4N0 * m_ij, 
+ *        where m_ij is the fraction for population i = source that migrates 
+ *        to population j = sink (again, when looking backwards in time).
+ * @param scaled_time Set to true if the time is given in units of 4*N0
+ *    generations, or to false if the time is given in units of generations.
+ * @param scaled_rate Set to true if the rate is given as M = 4*N0*m and to
+ *  false if it is given as m.
+ *
+ */
+void Model::addMigrationRate(double time, size_t source, size_t sink, double mig_rate,
+                             const bool &scaled_time, const bool &scaled_rates) {
+  checkPopulation(source);
+  checkPopulation(sink);
+  size_t position = addChangeTime(time, scaled_time);
+  if (scaled_rates) mig_rate *= scaling_factor();
+  if (mig_rates_list_.at(position).empty()) { 
+    addSymmetricMigration(time, nan("value to replace"), scaled_time); 
+  }
+  mig_rates_list_.at(position).at(getMigMatrixIndex(source, sink)) = mig_rate;  
+}
+
+
+/** 
+ * @brief Sets the migration matrix to the given values for the time following at
+ * certain time point (backwards in time). 
+ *
+ * This requires model finalization, e.g. call model.finalize() after you set up
+ * the model completely.
+ *
+ * @param time The time at which the migration is set to the given values.
+ *        The values apply backwards in time until they are changed again.
+ * @param mig_rates The (backwards) scaled migration matrix, given as concatenation of
+ *        row vectors (M_00, M_01, ..., M_0n, M_10, ..., M_n1, ..., M_nn), where
+ *        M_ij = 4N0 * m_ij and m_ij is the faction of population i that
+ *        migrates to population j (viewed backwards in time; forwards the
+ *        migration is from population j to i). The diagonal elements of the
+ *        matrix are ignored and can be set to "x" for better readability. 
+ * @param scaled_time Set to true if the time is given in units of 4*N0
+ *    generations, or to false if the time is given in units of generations.
+ * @param scaled_rate Set to true if the rate is given as M = 4*N0*m and to
+ *  false if it is given as m.
+ */
+void Model::addMigrationRates(double time, const std::vector<double> &mig_rates,
+                              const bool &scaled_time, const bool &scaled_rates) {
+  double popnr = population_number();
+  double scaling = 1;
+  if (scaled_rates) scaling = scaling_factor();
+  if ( mig_rates.size() != population_number()*population_number() ) 
+    throw std::logic_error("Migration rates values do not meet the number of populations");
+
+  size_t position = addChangeTime(time, scaled_time);
+  mig_rates_list_[position].clear();
+  mig_rates_list_[position].reserve(popnr*popnr-popnr);
+  for (size_t i = 0; i < popnr; ++i) {
+    for (size_t j = 0; j < popnr; ++j) {
+      if (i == j) continue;
+      mig_rates_list_[position].push_back(mig_rates.at(i*popnr+j) * scaling); 
+    }
+  }
+}
+
+
+
+/**
+ * @brief Adds symmetric migration to a model.
+ *
+ * Sets migration between all population to the given value starting at a
+ * certain time point going backwards in time. Unlike 'ms', this uses the actual
+ * value provided and does not divide it by #population-1.
+ *
+ * This requires model finalization, e.g. call model.finalize() after you set up
+ * the model completely.
+ *
+ * @param time The time at which the migration is set to the given value.
+ *        It applies backwards in time until it is changed again.
+ * @param mig_rate The scaled migration rate M_ij = 4N0 * m_ij that is used
+ *        between all populations i and j. m_ij is the fraction of population i 
+ *        that migrates to population j.
+ * @param time_scaled Set to true if the time is given in units of 4*N0
+ *    generations, or to false if the time is given in units of generations.
+ * @param rate_scaled Set to true if the rate is given as M = 4*N0*m and to
+ *  false if it is given as m.
+ */
+void Model::addSymmetricMigration(const double time, const double mig_rate, 
+                                  const bool &time_scaled, const bool &rate_scaled) {
+    std::vector<double> mig_rates = std::vector<double>(population_number()*population_number(), mig_rate);
+    this->addMigrationRates(time, mig_rates, time_scaled, rate_scaled);
+  }
+
+
+void Model::addSingleMigrationEvent(const double time, const size_t source_pop, 
+                                    const size_t sink_pop, const double fraction,
+                                    const bool &time_scaled) {
+
+  size_t position = addChangeTime(time, time_scaled);
+  size_t popnr = population_number();
+
+  if ( time < 0.0 ) throw std::invalid_argument("Single migration event: Negative time");
+  if ( source_pop >= population_number() ) throw std::invalid_argument("Single migration event: Unknown population");
+  if ( sink_pop >= population_number() ) throw std::invalid_argument("Single migration event: Unknown population");
+  if ( fraction < 0.0 || fraction > 1.0 ) throw std::invalid_argument("Single migration event: Fraction out of range");
+
+  if ( single_mig_probs_list_.at(position).empty() ) {
+    single_mig_probs_list_.at(position) = std::vector<double>(popnr*popnr-popnr, 0.0);
+  }
+
+  single_mig_probs_list_.at(position).at(getMigMatrixIndex(source_pop, sink_pop)) = fraction; 
+  this->has_migration_ = true;
+} 
+
+
+std::ostream& operator<<(std::ostream& os, Model& model) {
+  size_t n_pops = model.population_number();
+  os << "---- Model: ------------------------" << std::endl;
+  os << "Total Sample Size: " << model.sample_size() << std::endl;  
+  os << "N0 is assumed to be " << model.default_pop_size << std::endl; 
+
+  model.resetSequencePosition();
+  for (size_t idx = 0; idx < model.countChangePositions(); ++idx) {
+    os << std::endl << "At Position " << model.getCurrentSequencePosition() << ":" << std::endl;  
+    os << " Mutation Rate: " << model.mutation_rate() << std::endl;  
+    os << " Recombination Rate: " << model.recombination_rate() << std::endl;  
+    model.increaseSequencePosition();
+  }
+  model.resetSequencePosition();
+  
+  model.resetTime();
+  for (size_t idx = 0; idx < model.countChangeTimes(); ++idx) { 
+    os << std::endl << "At Time " << model.getCurrentTime() << ":" << std::endl;  
+    
+    os << " Population Sizes: ";
+    for (size_t pop = 0; pop < n_pops; ++pop) 
+      os << std::setw(10) << std::right << model.population_size(pop, model.getCurrentTime());
+    os << std::endl;
+
+    os << " Growth Rates:     ";
+    for (size_t pop = 0; pop < n_pops; ++pop) 
+      os << std::setw(10) << std::right << model.growth_rate(pop);
+    os << std::endl;
+
+    os << " Migration Matrix: " << std::endl;
+    for (size_t i = 0; i < n_pops; ++i) {
+      for (size_t j = 0; j < n_pops; ++j) {
+        os << std::setw(10) << std::right << model.migration_rate(i, j);
+      }
+      os << std::endl;
+    }
+    
+    for (size_t i = 0; i < n_pops; ++i) {
+      for (size_t j = 0; j < n_pops; ++j) {
+        if (model.single_mig_pop(i, j) != 0) {
+          os << " " << model.single_mig_pop(i, j) * 100 << "\% of pop " 
+             << i + 1 << " move to pop " << j + 1 << std::endl;
+        }
+      }
+    }
+
+    if (idx < model.countChangeTimes() - 1) model.increaseTime();
+  }
+  model.resetTime();
+  os << "------------------------------------" << std::endl;
+  return(os);
+}
+
+
+void Model::updateTotalMigRates(const size_t position) {
+  if ( total_mig_rates_list_.at(position).empty() ) {
+    total_mig_rates_list_.at(position) = std::vector<double>(population_number(), 0.0);
+  }
+
+  std::vector<double>* mig_rates = &(total_mig_rates_list_.at(position)); 
+
+  for (size_t i = 0; i < population_number(); ++i) {
+    for (size_t j = 0; j < population_number(); ++j) {
+      if (i == j) continue;
+      mig_rates->at(i) += mig_rates_list_.at(position).at( getMigMatrixIndex(i,j) );
+    }
+    if (mig_rates->at(i) > 0) has_migration_ = true;
+  }
+}
+
+
+void Model::finalize() {
+  fillVectorList(mig_rates_list_, default_mig_rate);
+  fillVectorList(growth_rates_list_, default_growth_rate);
+  calcPopSizes();
+
+  for (size_t j = 0; j < mig_rates_list_.size(); ++j) {
+    if (mig_rates_list_.at(j).empty()) continue;
+    updateTotalMigRates(j);
+  } 
+
+  // Fill in missing recombination rates
+  assert( mutation_rates_.at(0) != -1 );
+  assert( recombination_rates_.at(0) != -1 );
+  for (size_t j = 1; j < change_position_.size(); ++j) {
+    if (mutation_rates_.at(j) == -1) {
+      mutation_rates_.at(j) = mutation_rates_.at(j-1);
+    }
+
+    if (recombination_rates_.at(j) == -1) {
+      recombination_rates_.at(j) = recombination_rates_.at(j-1);
+    }
+  }
+
+  resetTime();
+  resetSequencePosition();
+  check();
+}
+
+
+void Model::calcPopSizes() {
+  // Set initial population sizes
+  if (pop_sizes_list_.at(0).empty()) addPopulationSizes(0, default_pop_size); 
+  else {
+    // Replace values not set by the user with the default size
+    for (size_t pop = 0; pop < population_number(); ++pop) {
+      if (std::isnan(pop_sizes_list_.at(0).at(pop)))
+        addPopulationSize(0, pop, default_pop_size);
+    }
+  }
+
+  size_t last_growth = -1;
+  double duration = -1;
+  for (size_t i = 1; i < change_times_.size(); ++i) {
+    if (! growth_rates_list_.at(i - 1).empty()) last_growth = i - 1;
+
+    // Make sure we always have a pop sizes vector
+    if (pop_sizes_list_.at(i).empty()) {
+      addPopulationSizes(change_times_.at(i), nan("value to replace"));
+      assert( ! pop_sizes_list_.at(i).empty() ); 
+    }
+
+    // Calculate the effective duration of a growth period if it ends here 
+    duration = change_times_.at(i) - change_times_.at(i - 1);
+
+    // Calculate the population sizes: 
+    for (size_t pop = 0; pop < population_number(); ++pop) {
+      // If the user explicitly gave a value => always use this value
+      if ( !std::isnan(pop_sizes_list_.at(i).at(pop)) ) continue; 
+      
+      assert(!std::isnan(pop_sizes_list_.at(i - 1).at(pop)));          
+      // Otherwise use last value
+      pop_sizes_list_.at(i).at(pop) = pop_sizes_list_.at(i - 1).at(pop);  
+
+      // ... and scale it if there was growth 
+      if (last_growth != -1) {
+        pop_sizes_list_.at(i).at(pop) *=  
+          std::exp((growth_rates_list_.at(last_growth).at(pop)) * duration);
+      }
+    }
+  } 
+}
+
+
+void Model::check() {
+  // Sufficient sample size?
+  if (sample_size() < 2) throw std::invalid_argument("Sample size needs be to at least 2");
+
+  // Structure without migration?
+  if (population_number() > 1 && !has_migration())
+    throw std::invalid_argument("Model has multiple populations but no migration. Coalescence impossible"); 
+}
+
+
+void Model::fillVectorList(std::vector<std::vector<double> > &vector_list, const double default_value) {
+  std::vector<double>* last = NULL; 
+  std::vector<double>* current = NULL; 
+  for (size_t j = 0; j < vector_list.size(); ++j) {
+    current = &(vector_list.at(j));
+    if (current->empty()) continue;
+
+    for (size_t i = 0; i < current->size(); ++i) {
+      if ( !std::isnan(current->at(i)) ) continue;
+
+      if (last == NULL) current->at(i) = default_value;
+      else current->at(i) = last->at(i); 
+    }
+    last = current;
+  }
+}
+
+
+void Model::addPopulation() {
+  // Create the new population
+  size_t new_pop = population_number();
+  this->set_population_number(new_pop+1);
+
+  // Change Vectors
+  addPopToVectorList(growth_rates_list_);
+  addPopToVectorList(pop_sizes_list_);
+
+  // Change Matrices
+  addPopToMatrixList(mig_rates_list_, new_pop);
+  addPopToMatrixList(single_mig_probs_list_, new_pop, 0);
+}
+
+
+void Model::addPopToMatrixList(std::vector<std::vector<double> > &vector_list, size_t new_pop, double default_value) {
+  for (auto it = vector_list.begin(); it!= vector_list.end(); ++it) {
+    if (it->empty()) continue;
+    for (size_t i = 0; i < new_pop; ++i) {
+      it->insert(it->begin() + getMigMatrixIndex(i, new_pop), default_value);
+    }
+    for (size_t i = 0; i < new_pop; ++i) {
+      it->insert(it->begin() + getMigMatrixIndex(new_pop, i), default_value);
+    }
+  }
+}
+
+
+void Model::addPopToVectorList(std::vector<std::vector<double> > &vector_list) {
+  for (auto it = vector_list.begin(); it!= vector_list.end(); ++it) {
+    if (it->empty()) continue;
+    it->push_back(nan("value to replace"));
+  }
+}
+
+
+/**
+ * @brief Sets the recombination rate
+ *
+ * @param rate The recombination rate per sequence length per time unit. 
+ * The sequence length can be either per locus or per base pair and the time
+ * can be given in units of 4N0 generations ("scaled") or per generation. 
+ *
+ * @param loci_length The length of every loci.
+ * @param per_locus Set to TRUE, if the rate is given per_locus, and to FALSE
+ * if the rate is per base pair.
+ * @param scaled Set to TRUE is the rate is scaled with 4N0, or to FALSE if
+ * it isn't
+ */
+void Model::setRecombinationRate(double rate,  
+                                 const bool &per_locus, 
+                                 const bool &scaled,
+                                 const double seq_position) { 
+
+  if (rate < 0.0) { 
+    throw std::invalid_argument("Recombination rate must be non-negative");
+  }
+
+  if (scaled) rate /= 4.0 * default_pop_size; 
+  if (per_locus) {
+    if (loci_length() <= 1) {
+      throw std::invalid_argument("Locus length must be at least two");
+    }
+    rate /= loci_length()-1;
+  }
+
+  if (rate > 0.0) has_recombination_ = true;
+  recombination_rates_[addChangePosition(seq_position)] = rate; 
+}
+
+
+/**
+ * @brief Sets the mutation rate
+ *
+ * @param rate The mutation rate per locus, either scaled as theta=4N0*u or
+ * unscaled as u.
+ * @param per_locus TRUE if the rate is per locus, FALSE if per base.
+ * @param scaled Set this to TRUE if you give the mutation rate in scaled
+ * units (e.g. as theta rather than as u).
+ */
+void Model::setMutationRate(double rate, const bool &per_locus, const bool &scaled, 
+                            const double seq_position) { 
+  if (scaled) rate /= 4.0 * default_pop_size; 
+
+  size_t idx = addChangePosition(seq_position);
+  if (per_locus) {
+    mutation_rates_.at(idx) = rate / loci_length();
+  } else {
+    mutation_rates_.at(idx) = rate;
+  }
+}
diff --git a/src/model.h b/src/model.h
new file mode 100644
index 0000000..f2f9e15
--- /dev/null
+++ b/src/model.h
@@ -0,0 +1,529 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+/*!
+ * \file model.h
+ *
+ * \brief This file contains the class Model, which is a simple container object for
+ * model parameters.
+ *
+ */
+
+#ifndef scrm_src_model
+#define scrm_src_model
+#pragma GCC diagnostic ignored "-Wsign-compare"
+
+#include "macros.h" // Needs to be before cassert
+
+#include <cstddef>
+#include <vector>
+#include <cfloat>
+#include <algorithm>
+#include <iostream>
+#include <stdexcept>
+#include <cassert>
+#include <cmath>
+#include <iomanip>
+#include <memory>
+
+#include "summary_statistics/summary_statistic.h"
+
+class Param;
+
+enum SeqScale { relative, absolute, ms };
+
+class Model
+{
+  public:
+#ifdef UNITTEST
+   friend class TestModel;
+   friend class TestTimeInterval;
+   friend class TestParam;
+   friend class TestForest;
+#endif
+   friend class Forest;
+   friend class Param;
+
+   Model();
+   Model(size_t sample_size);
+
+   
+   // Default values;
+   double default_pop_size;
+   size_t default_loci_length;
+   double default_growth_rate;
+   double default_mig_rate;
+
+   // Getters & Setters
+
+   /**
+    * @brief Returns the scaling factor for times and many parameters
+    *
+    * @return 1 / ( 4 * default_pop_size);
+    */
+   double scaling_factor() const { return scaling_factor_; };
+
+   /**
+    * @brief Returns the mutation rate per base pair per generation for the
+    * currently active sequence position.
+    *
+    * @return The mutation rate per base per generation
+    */
+   double mutation_rate() const { return mutation_rates_.at(current_seq_idx_); }
+  
+   /**
+    * @brief Returns the recombination rate per base pair per generation for the
+    * currently active sequence positions.
+    *
+    * @return The recombination rate per base pair per generation
+    */
+   double recombination_rate(const size_t idx = -1) const { 
+     if (idx == -1) return recombination_rates_.at(current_seq_idx_); 
+     else return recombination_rates_.at(idx);
+   }
+
+   /**
+    * @brief Returns if the model has recombination.
+    *
+    * @return true if the model has recombination, false otherwise 
+    */
+   bool has_recombination() const { 
+     return has_recombination_; 
+   };
+
+
+   /**
+    * @brief Returns the length of all loci, in base pairs
+    *
+    * @return length of all loci, in base pairs
+    */
+   size_t loci_length() const { return loci_length_; }
+
+   /**
+    * @brief Getter for the current growth rate of a subpopulation
+    *
+    * This returns the growth rate for a population for the current time of the
+    * model. Use resetTime() and increaseTime() to set the model to the time you
+    * want.
+    *
+    * @param pop The population for which the growth rate is returned.
+    *
+    * @return The growth rate. 
+    */
+   double growth_rate(size_t pop = 0) const {
+     if (current_growth_rates_ == NULL) return default_growth_rate;
+     return current_growth_rates_->at(pop);
+   }
+   
+
+   /**
+    * @brief Getter for the current diploid size of a (sub-)population.
+    *
+    * This returns the size of a population for the current time of the
+    * model. Use resetTime() and increaseTime() to set the model to the time you
+    * want. In case of a growing population, you can use the time parameter to
+    * specify for which time of the current model stop you want to get the
+    * population size.
+    * 
+    * @param pop The population for which the size is returned.
+    * @param time The time inside the current model step for which to return the
+    * size. This will only make a difference if the model is growing.
+    *
+    * @return The size of the sub population
+    */
+   double population_size(const size_t pop = 0, const double time = -1) const { 
+     return 0.5 / inv_double_pop_size(pop, time);
+   }
+
+   double inv_double_pop_size(const size_t pop = 0, const double time = -1) const { 
+     double pop_size;
+     if (current_pop_sizes_ == NULL) 
+       pop_size = 1/(2*default_pop_size);
+     else 
+       pop_size = current_pop_sizes_->at(pop);   // population size basal to this segment
+
+     if (time >= 0 && growth_rate(pop) != 0.0) {
+       assert( time >= getCurrentTime() && time <= getNextTime() );
+       pop_size *= std::exp(growth_rate(pop) * (time - getCurrentTime())); 
+     }
+
+     return pop_size;
+   }
+
+   /**
+    * @brief Returns the current migration rate for a given pair of populations.
+    *
+    * The migration rate is returned unscaled, e.g. in migrants per generation.
+    * The rate is for the current time of the
+    * model. Use resetTime() and increaseTime() to set the model to the time you
+    * want.
+    *
+    * @param source The population from which the migrants come (when looking
+    *               backwards in time!)
+    * @param sink The population that the migration goes to.
+    *
+    * @return The current unscaled, backwards migration rate.
+    */
+   double migration_rate(const size_t source, const size_t sink) const {
+     if (sink == source) return 0.0;
+     if (current_mig_rates_ == NULL) return default_mig_rate;
+     return current_mig_rates_->at( getMigMatrixIndex(source, sink) );  
+   };
+
+   /**
+    * @brief Getter for the current total rate of migrating out of one
+    * population (viewed backwards in time).
+    *
+    *
+    * The migration rate is returned unscaled, e.g. in migrants per generation.
+    * The rate is for the current time of the
+    * model. Use resetTime() and increaseTime() to set the model to the time you
+    * want.
+    *
+    * @param source The population for which the rate is given. 
+    *
+    * @return The total current, unscaled rate of migration out if the population.
+    */
+   double total_migration_rate(const size_t source) const {
+     if (current_total_mig_rates_ == NULL) return default_mig_rate;
+     return current_total_mig_rates_->at(source); 
+   }; 
+
+   /**
+    * @brief Getter for the probability of spontaneous migration at the
+    * beginning of the current time interval. 
+    * 
+    * Use resetTime() and increaseTime() to set the model to the time interval you
+    * want. You can use hasFixedTimeEvent() to check if there is any single migration event.
+    *
+    * @param source The source population of the migration.
+    * @param sink The sink population of the migration.
+    *
+    * @return The probability/fraction of migration.
+    */
+   double single_mig_pop(const size_t source, const size_t sink) const {
+    if (single_mig_probs_list_.at(current_time_idx_).empty()) return 0.0;
+    if (sink == source) return 0.0;
+    return single_mig_probs_list_.at(current_time_idx_).at( getMigMatrixIndex(source, sink) ); 
+   }
+
+   void setMutationRate(double rate,
+                        const bool &per_locus = false, 
+                        const bool &scaled = false,
+                        const double seq_position = 0);
+
+   void setRecombinationRate(double rate,
+                             const bool &per_locus = false, 
+                             const bool &scaled = false,
+                             const double seq_position = 0);
+
+   bool hasFixedTimeEvent(const double at_time) const {
+     if (single_mig_probs_list_.at(current_time_idx_).empty()) return false; 
+     if (getCurrentTime() != at_time) return false;
+     return true;
+   }
+
+   size_t sample_size() const { return sample_times_.size(); };
+   size_t sample_population(size_t sample_id) const { return sample_populations_.at(sample_id); };
+   double sample_time(size_t sample_id) const { return sample_times_.at(sample_id); };
+
+   size_t population_number() const { return pop_number_; }
+  
+   
+   double getCurrentTime() const { return change_times_.at(current_time_idx_); }
+   double getNextTime() const { 
+    if ( current_time_idx_ + 1 >= change_times_.size() ) return DBL_MAX;
+    else return change_times_.at(current_time_idx_ + 1);
+   }
+
+   double getCurrentSequencePosition() const { 
+    if ( current_seq_idx_ >= change_position_.size() ) return loci_length();
+    return change_position_.at(current_seq_idx_); 
+   }
+
+   double getNextSequencePosition() const { 
+    if ( current_seq_idx_ + 1 >= change_position_.size() ) return loci_length();
+    else return change_position_.at(current_seq_idx_ + 1);
+   }
+
+   double window_length_seq() const { return window_length_seq_; }
+   size_t window_length_rec() const { return window_length_rec_; }
+   bool has_window_rec() const { return has_window_rec_; }
+   bool has_window_seq() const { return has_window_seq_; }
+   bool has_approximation() const { return has_appr_; }
+   void set_window_length_seq(const double ewl) { 
+     if (ewl < 0) throw std::invalid_argument("Exact window length can not be negative");
+     window_length_seq_ = ewl; 
+     has_window_seq_ = true;
+     has_window_rec_ = false;
+     has_appr_ = true;
+   }
+   void set_window_length_rec(const size_t ewl) { 
+     window_length_rec_ = ewl; 
+     has_window_seq_ = false;
+     has_window_rec_ = true;
+     has_appr_ = true;
+   }
+   void disable_approximation() {
+     has_appr_ = false;
+     has_window_rec_ = false;
+     has_window_seq_ = false;
+   }
+
+   void set_population_number(const size_t pop_number) { 
+    pop_number_ = pop_number; 
+    if (pop_number_<1) throw std::out_of_range("Population number out of range"); 
+   }
+
+   void resetTime() { 
+     if (pop_sizes_list_[0].empty()) current_pop_sizes_ = NULL;
+     else current_pop_sizes_ = &(pop_sizes_list_[0]);
+
+     if (growth_rates_list_[0].empty()) current_growth_rates_ = NULL;
+     else current_growth_rates_ = &(growth_rates_list_[0]);
+
+     if (mig_rates_list_[0].empty()) current_mig_rates_ = NULL;
+     else current_mig_rates_ = &(mig_rates_list_[0]);
+
+     if (total_mig_rates_list_[0].empty()) current_total_mig_rates_ = NULL;
+     else current_total_mig_rates_ = &(total_mig_rates_list_[0]);
+
+     current_time_idx_ = 0;
+   };
+
+   void resetSequencePosition() {
+     current_seq_idx_ = 0; 
+   }
+
+   void increaseTime() { 
+     if ( current_time_idx_ == change_times_.size() ) throw std::out_of_range("Model change times out of range");
+     ++current_time_idx_;
+
+     if ( ! pop_sizes_list_.at(current_time_idx_).empty() ) 
+       current_pop_sizes_ = &(pop_sizes_list_.at(current_time_idx_));
+     if ( ! growth_rates_list_.at(current_time_idx_).empty() ) 
+       current_growth_rates_ = &(growth_rates_list_.at(current_time_idx_)); 
+     if ( ! mig_rates_list_.at(current_time_idx_).empty() ) 
+       current_mig_rates_ = &(mig_rates_list_.at(current_time_idx_)); 
+     if ( ! total_mig_rates_list_.at(current_time_idx_).empty() ) 
+       current_total_mig_rates_ = &(total_mig_rates_list_.at(current_time_idx_)); 
+   };
+
+   void increaseSequencePosition() {
+    ++current_seq_idx_;
+   }
+
+   size_t countChangeTimes() const { return change_times_.size(); }
+   size_t countChangePositions() const { return change_position_.size(); } 
+  
+   void print(std::ostream &os) const;
+
+
+   size_t loci_number() const { return loci_number_; };
+   void set_loci_number(size_t loci_number) { loci_number_ = loci_number; }; 
+  
+   // Add populations size changes
+   void addPopulationSizes(double time, const std::vector<double> &pop_sizes, 
+                           const bool &time_scaled = false, const bool &relative = false);
+
+   void addPopulationSizes(const double time, const double pop_size, 
+                           const bool &time_scaled = false, const bool &relative = false); 
+
+   void addPopulationSize(const double time, const size_t pop, double population_sizes,
+                          const bool &time_scaled = false, const bool &relative = false);
+
+   // Add exponential growth
+   void addGrowthRates(const double time, const std::vector<double> &growth_rates,
+                       const bool &time_scaled = false, 
+                       const bool &rate_scaled = false);
+
+   void addGrowthRates(const double time, const double growth_rates,
+                       const bool &time_scaled = false,
+                       const bool &rate_scaled = false);
+
+   void addGrowthRate(const double time, const size_t population, 
+                      double growth_rates, const bool &time_scaled = false,
+                      const bool &rate_scaled = false);
+
+   void addSampleSizes(double time, const std::vector<size_t> &samples_sizes,
+                         const bool &scaled = false);
+
+   // functions to add Migration
+   void addMigrationRates(double time, const std::vector<double> &mig_rates,
+                          const bool &time_scaled = false, const bool &rate_scaled = false);
+
+   void addMigrationRate(double time, size_t source, size_t sink, double mig_rate,
+                         const bool &time_scaled = false, const bool &rate_scaled = false);
+
+   void addSymmetricMigration(const double time, const double mig_rate,
+                              const bool &time_scaled = false, const bool &rate_scaled = false);
+
+   void addSingleMigrationEvent(const double time, const size_t source_pop, 
+                                const size_t sink_pop, const double fraction,
+                                const bool &time_scaled = false);
+
+   void finalize(); 
+  
+   void check();
+   //void reset();
+
+   size_t countSummaryStatistics() const {
+     return summary_statistics_.size(); 
+   }
+
+   SummaryStatistic* getSummaryStatistic(const size_t i) const {
+     return summary_statistics_.at(i).get();
+   }
+
+   void addSummaryStatistic(std::shared_ptr<SummaryStatistic> sum_stat) {
+     summary_statistics_.push_back(sum_stat);
+   }
+
+  void addPopulation();
+
+  SeqScale getSequenceScaling() const { return seq_scale_; }
+  void setSequenceScaling(SeqScale seq_scale) { seq_scale_ = seq_scale; };
+
+  private:
+   std::vector<double> change_times_;
+   void setLocusLength(const size_t length) { 
+    // Rescale the rates that are per base pair
+    for (size_t i = 0; i < change_position_.size(); ++i) {
+      mutation_rates_.at(i) *= (double)loci_length() / length;
+      recombination_rates_.at(i) *= (double)(loci_length()-1) / (length-1);
+    }
+    loci_length_ = length; 
+   }
+
+   double change_position(size_t idx) const {
+    return this->change_position_.at(idx);
+   }
+
+   size_t get_position_index() const {
+    return this->current_seq_idx_;
+   }
+
+   size_t addChangeTime(double time, const bool &scaled = false);
+   size_t addChangePosition(const double position);
+
+   template <typename T>
+   void deleteParList(std::vector<T*> &parList) {
+    typename std::vector<T*>::iterator it;
+    for (it = parList.begin(); it != parList.end(); ++it) {
+      if (*it != NULL) delete *it;
+    }
+    parList.clear();
+   }
+
+   void updateTotalMigRates(const size_t position);
+   bool has_migration() { return has_migration_; };
+
+  void fillVectorList(std::vector<std::vector<double> > &vector_list, const double default_value);
+  void calcPopSizes();
+  void checkPopulation(const size_t pop) {
+    if (pop >= this->population_number()) 
+      throw std::invalid_argument("Invalid population"); 
+  }
+
+  friend void swap(Model& first, Model& second);
+
+  size_t getMigMatrixIndex(const size_t i, const size_t j) const {
+    assert(i != j);
+    return i * (population_number()-1) + j - ( i < j );
+  }
+
+  void addPopToMatrixList(std::vector<std::vector<double> > &vector_list, 
+                          size_t new_pop,
+                          double default_value = nan("value to replace"));
+  void addPopToVectorList(std::vector<std::vector<double> > &vector_list);
+
+   double scaling_factor_; // 1 / (4N0);
+
+   // Stores information about samples. Each index represents a sample.
+   std::vector<size_t> sample_populations_;
+   std::vector<double> sample_times_;
+
+   // Stores the time and sequences positions where the model changes.
+   std::vector<double> change_position_;
+
+   // These pointer vectors hold the actual model parameters that can change in
+   // time. Each index represents one period in time within which the model
+   // parameters are constant. NULL means that the parameters do not change.
+   std::vector<std::vector<double> > growth_rates_list_;
+   std::vector<std::vector<double> > mig_rates_list_;
+   std::vector<std::vector<double> > total_mig_rates_list_;
+   std::vector<std::vector<double> > single_mig_probs_list_;
+
+   // Population sizes are saved as 1/(2N), where N is the actual population
+   // size (do to fast multiplication rather than slow division in the
+   // algorithm)
+   std::vector<std::vector<double> > pop_sizes_list_;
+   
+   // These vectors contain the model parameters that may change along the sequence.
+   // Again, each index represents an sequence segment within with the model
+   // does not change.
+   std::vector<double> recombination_rates_;       /*!< Unit: Recombinations per base per generation */
+   std::vector<double> mutation_rates_;           /*!< Unit: Mutations per base per generation */
+
+   // The index of the time and sequence segment currently active.
+   size_t current_time_idx_;
+   size_t current_seq_idx_;
+
+   // Direct pointers to the currently active model parameters.
+   std::vector<double>* current_pop_sizes_;
+   std::vector<double>* current_growth_rates_;
+   std::vector<double>* current_mig_rates_;
+   std::vector<double>* current_total_mig_rates_;
+
+   size_t pop_number_;
+
+   size_t loci_number_;
+   size_t loci_length_;
+
+   double window_length_seq_;
+   size_t window_length_rec_;
+   bool has_window_seq_;
+   bool has_window_rec_;
+   bool has_appr_;
+
+   bool has_migration_;
+   bool has_recombination_;
+
+   SeqScale seq_scale_;
+
+   std::vector<std::shared_ptr<SummaryStatistic> > summary_statistics_;
+};
+
+
+
+std::ostream& operator<<(std::ostream& os, Model& model); 
+
+template <typename T>
+std::ostream& operator<<(std::ostream& os, const std::vector<T> &vec) {
+  typename std::vector<T>::const_iterator it;
+  for (it = vec.begin(); it != vec.end(); ++it) os << *it << " ";
+  return os;
+}
+
+
+
+#endif
diff --git a/src/node.cc b/src/node.cc
new file mode 100644
index 0000000..0a22a9c
--- /dev/null
+++ b/src/node.cc
@@ -0,0 +1,169 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "node.h"
+#include<sstream>
+#include<fstream>
+#include<iomanip>
+#include<iostream>
+
+
+Node::Node() { init(); }
+Node::Node(double height) { init(height); }
+Node::Node(double height, size_t label) { init(height, label); }
+Node::~Node() {}
+
+void Node::init(double height, size_t label) {
+  this->set_last_update(0);
+  this->set_population(0);
+
+  this->set_height(height);
+  this->set_label(label);
+  if (label == 0) this->set_samples_below(1);
+  else this->set_samples_below(0); 
+  this->set_length_below(0);
+  this->set_last_change(0);
+
+  this->set_parent(NULL);
+  this->set_second_child(NULL);
+  this->set_first_child(NULL);
+  this->set_previous(NULL);
+  this->set_next(NULL);
+}
+  
+
+void Node::change_child(Node* from, Node* to) {
+  if ( this->first_child() == from ) {
+    if (to != NULL) this->set_first_child(to);
+    else {
+      set_first_child(second_child());
+      set_second_child(NULL);
+    }
+  }
+  else if ( this->second_child() == from )
+    this->set_second_child(to);
+  else {
+    dout << "Error when changing child of " << this << " form "
+         << from << " to " << to << std::endl;
+    dout << "Children are " << this->first_child() << " and "
+         << this->second_child() << std::endl;
+    throw std::invalid_argument("Can't find child node to replace");
+  }
+}
+
+void Node::remove_child(Node* child) {
+  if ( this->first_child() == child ) {
+    this->set_first_child(this->second_child());
+    this->set_second_child(NULL);
+    return;
+  } 
+
+  if ( this->second_child() == child ) {
+    this->set_second_child(NULL);
+    return;
+  }
+
+  throw std::invalid_argument("Can't find child to delete");
+}
+
+/**
+ * @brief Returns is the parent of this node on the local tree.
+ *
+ * This should only be executed on local nodes!
+ *
+ * @return The node that is this node's parent on the local tree. 
+ */
+Node* Node::getLocalParent() const {
+  assert( this->local() );
+  assert( !this->is_root());
+  assert( this->parent()->countChildren() > 0 );
+  if (parent()->countChildren(true) == 2) return parent(); 
+  return parent()->getLocalParent();
+}
+
+/**
+ * @brief Returns one child of this node when looking 
+ * only at the local tree.
+ * 
+ * The up to two children of a node are in basically 
+ * arbitrary order. The only difference between child_1 and
+ * child_2 is that if a node has only one child, than
+ * it is always child_1.
+ *
+ * This should only be executed on local nodes!
+ *
+ * @return NULL if this node has no children on the local tree,
+ * or a pointer to the child otherwise. 
+ */
+Node* Node::getLocalChild1() const {
+  if (first_child() == NULL || !first_child()->local()) return NULL;
+  if (first_child()->countChildren(true) == 1) {
+    if (first_child()->first_child()->local()) return first_child()->getLocalChild1();
+    else return first_child()->getLocalChild2();
+  }
+  // Child has 0 or 2 local children => it is part of local tree 
+  return first_child();
+}
+
+/**
+ * @brief Returns one child of this node when looking 
+ * only at the local tree.
+ * 
+ * The up to two children of a node are in basically 
+ * arbitrary order. The only difference between child_1 and
+ * child_2 is that if a node has only one child, than
+ * it is always child_1.
+ *
+ * This should only be executed on local nodes!
+ *
+ * @return NULL if this node has less than two children on the local tree,
+ * or a pointer to the child otherwise. 
+ */
+Node* Node::getLocalChild2() const {
+  if (second_child() == NULL || !second_child()->local()) return NULL;
+  if (second_child()->countChildren(true) == 1) {
+    if (second_child()->first_child()->local()) return second_child()->getLocalChild1();
+    else return second_child()->getLocalChild2();
+  }
+  // Child has 0 or 2 local children => it is part of local tree 
+  return second_child();
+}
+
+
+void Node::extract_bl_and_label ( std::string::iterator in_it ){
+  // Going backwards, extract branch length first, then the node label
+  std::string::iterator bl_start = in_it;
+  //for (; (*(bl_start-1)) != ':'; --bl_start ){ }
+  while ((*(bl_start-1)) != ':')
+    --bl_start;
+  double bl = strtod( &(*bl_start), NULL );
+  this->set_bl ( bl );
+
+  std::string::iterator label_start = (bl_start-2);
+
+  while ( (*(label_start)) != ',' &&  ( *(label_start)) != '(' &&  (*(label_start)) != ')' )
+    --label_start;
+
+  this->set_label ( ( (*(label_start)) == ')' ? 0 /*! Label internal nodes */
+                                                : strtol ( &(*(label_start+1)), NULL , 10)) ); /*! Label tip nodes */
+}
+
diff --git a/src/node.h b/src/node.h
new file mode 100644
index 0000000..c5d710a
--- /dev/null
+++ b/src/node.h
@@ -0,0 +1,212 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * node.h
+ *
+ * A Node is the most elemental unit of a tree/forest. It represents the
+ * point of coalescence of two branches, as well as the single branch above. 
+ *
+ */
+
+#ifndef scrm_node
+#define scrm_node
+
+#include "macros.h" // Needs to be before cassert
+
+#include <cstddef>
+#include <cfloat>
+#include <stdexcept>
+#include <iostream>
+#include <cassert>
+#include <string>
+
+
+class Node
+{
+ public:
+#ifdef UNITTEST
+  friend class TestForest;
+  friend class TestNode;
+  friend class TestNodeContainer;
+#endif
+  friend class NodeContainer;
+  
+  ~Node();
+
+  //Getters & Setters
+  void extract_bl_and_label ( std::string::iterator in_it );
+  double bl_;
+  double bl() const { return this->bl_; }
+  void set_bl ( double bl ) { this->bl_ = bl; }
+
+  double height() const { return this->height_; }
+  void set_height(const double height) { this->height_ = height; }
+
+  double parent_height() const {
+    if ( this->is_root() ) return this->height();
+    return this->parent()->height();
+  }
+
+  double height_above() const { return this->parent_height() - this->height(); }
+
+  size_t population() const { return population_; }
+  void set_population(const size_t pop) { population_ = pop; }
+
+  bool local() const { return (last_update_ == 0); }
+
+  void make_local() { 
+    last_update_ = 0; 
+  }
+  void make_nonlocal(const size_t current_recombination) { 
+    assert( this->local() ); 
+    set_last_update(current_recombination);
+  }
+
+	Node *parent() const {
+    assert( this->parent_ != NULL ); 
+    return this->parent_; 
+  }
+  void set_parent(Node *parent) { this->parent_ = parent; }
+
+  Node *second_child() const { return this->second_child_; }
+  void set_second_child(Node *second_child) { this->second_child_ = second_child; }
+
+  Node *first_child() const { return this->first_child_; }
+  void set_first_child(Node *first_child) { this->first_child_ = first_child; }
+
+  size_t last_update() const { return last_update_; }
+
+  size_t last_change() const { return last_change_; }
+  void set_last_change(const size_t pos) { last_change_ = pos; }
+
+  size_t samples_below() const { return samples_below_; }
+  void set_samples_below(size_t samples) { samples_below_ = samples; }
+
+  double length_below() const { return length_below_; }
+  void set_length_below(const double length) { length_below_ = length; }
+
+  void change_child(Node* from, Node* to);
+  size_t countChildren(const bool only_local = false) const;
+  
+  void set_label(size_t label) { label_ = label; }
+  size_t label() const { return label_; }
+
+  bool is_root() const { return ( this->parent_ == NULL ); }
+  bool in_sample() const {
+    return ( this->label() != 0 ); 
+  }
+
+  bool is_migrating() const; 
+
+  bool is_first() const { return( previous_ == NULL ); }
+  bool is_last() const { return( next_ == NULL ); }
+
+  // Uminportant Nodes are nodes that sit at the top of the single 
+  // top branch of a tree after it got cut away from the primary tree. 
+  // These Nodes can be reused or removed if they are involved in an event.
+  bool is_unimportant() const {
+    return (this->countChildren() == 1 && !this->is_migrating()); 
+  }
+
+  bool is_contemporary(const double time) {
+    return ( time <= height() && height() <= parent_height() ); 
+  }
+
+  void remove_child(Node* child);
+
+  Node* next() const { 
+    if ( next_ == NULL ) throw std::out_of_range("Node has no next node");
+    return next_; 
+  }
+  Node* previous() const { 
+    if ( previous_ == NULL ) throw std::out_of_range("Node has no previous node");
+    return previous_; 
+  }
+
+  void set_next(Node* next) { next_ = next; }
+  void set_previous(Node* previous) { previous_ = previous; }
+
+  // Navigate on local tree
+  Node *getLocalParent() const;
+  Node *getLocalChild1() const;
+  Node *getLocalChild2() const;
+
+ private:
+  Node();
+  Node(double height);
+  Node(double height, size_t label);
+
+  void init(double heigh=-1, size_t label=0);
+  void set_last_update(const size_t recombination) { last_update_ = recombination; }; 
+
+  size_t label_;
+  double height_;        // The total height of the node
+  size_t last_update_;   // The recombination on which the branch above the node
+                         // was last checked for recombination events or 0 if
+                         // the node is local 
+  size_t last_change_;   // The recombination at which the subtree below the node
+                         // changed most recently.
+
+  size_t population_;    // The number of the population the node belong to. 
+  
+  size_t samples_below_; // the number of sampled nodes in the subtree below this node
+  double length_below_;  // the total length of local branches in the subtree below this node
+
+  Node* next_;
+  Node* previous_;
+
+  //The tree structure
+  Node *parent_;
+  Node *first_child_;
+  Node *second_child_;
+};
+
+inline bool Node::is_migrating() const { 
+  if ( this->countChildren() != 1 ) return false;
+  return ( this->population() != this->first_child()->population() );
+} 
+
+inline size_t Node::countChildren(const bool only_local) const { 
+  if (first_child() == NULL) return 0;
+  if (!only_local) {
+    if (second_child() == NULL) return 1;
+    else return 2;
+  } else {
+    if (second_child() == NULL) {
+      if (first_child()->local()) return 1; 
+      else return 0;
+    } else {
+      return first_child()->local() + second_child()->local();
+    }
+  }
+}
+
+/** Hash nodes based on their height */
+namespace std {
+  template <>
+  struct hash<Node*> {
+    std::size_t operator()(Node const* node) const {
+      return std::hash<double>()(node->height() - node->label());
+    }
+  };
+}
+#endif
diff --git a/src/node_container.cc b/src/node_container.cc
new file mode 100644
index 0000000..7d996df
--- /dev/null
+++ b/src/node_container.cc
@@ -0,0 +1,300 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "node_container.h"
+
+/*******************************************************
+ * Con- & Destructor
+ *******************************************************/
+
+NodeContainer::NodeContainer() {
+  set_first(NULL);
+  set_last(NULL);
+  unsorted_node_ = NULL;
+  size_ = 0;
+
+  node_counter_ = 0;
+  lane_counter_ = 0; 
+  std::vector<Node>* new_lane = new std::vector<Node>();
+  new_lane->reserve(10000);
+  node_lanes_.push_back(new_lane);
+}
+
+NodeContainer::NodeContainer(const NodeContainer &nc) {
+  size_ = 0;
+  set_first(NULL);
+  set_last(NULL);
+  this->unsorted_node_ = NULL;
+  this->last_node_ = NULL;
+  this->first_node_ = NULL;
+
+  std::map<Node const*, Node*> node_mapping;  
+  node_mapping[NULL] = NULL;
+
+  for (auto it = nc.iterator(); it.good(); ++it) {
+    Node *node = new Node(**it);
+    node_mapping[*it] = node;
+    add(node);
+  }
+  assert( this->sorted() );
+
+  for (auto it = iterator(); it.good(); ++it) {
+    if (!(*it)->is_root()) (*it)->set_parent(node_mapping[(*it)->parent()]);
+    (*it)->set_first_child(node_mapping[(*it)->first_child()]);
+    (*it)->set_second_child(node_mapping[(*it)->second_child()]);
+  }
+
+  unsorted_node_ = node_mapping[nc.unsorted_node_];
+}
+
+/*******************************************************
+ * Management of Nodes
+ *******************************************************/
+
+Node* NodeContainer::at(size_t nr) const {
+  Node* current = first();
+
+  for (size_t i=0; i < nr; ++i) {
+    assert(current != NULL);
+    current = current->next();
+  }
+
+  if ( current == NULL ) throw std::out_of_range("NodeContainer out of range"); 
+  return current;
+}
+
+// Adds 'node' to the container
+void NodeContainer::push_back( Node* node ) {
+    ++size_;
+    if ( this->first() == NULL ) {
+        this->set_first( node );
+        this->set_last( node );
+        return;
+    }
+    assert( this->first() != NULL );
+
+    //Adding to the End, similar to vector::push_back
+    node->set_previous(this->last());
+    node->set_next(NULL);
+    this->last()->set_next(node);
+    this->set_last(node);
+    return;
+}
+
+// Adds 'node' to the container
+void NodeContainer::push_front( Node* node ) {
+    ++size_;
+    if ( this->first() == NULL ) {
+        this->set_first( node );
+        this->set_last( node );
+        return;
+    }
+    assert( this->first() != NULL );
+
+    //Adding to the End, similar to vector::push_back
+    node->set_next(first());
+    node->set_previous(NULL);
+    first()->set_previous(node);
+    this->set_first(node);
+    return;
+}
+
+
+
+// Adds 'node' to the container
+// If you know that the node is higher in the tree than a other node,
+// than you can specify the latter as 'after_node' to speedup the process.
+void NodeContainer::add(Node* node, Node* after_node) {
+  ++size_;
+
+  if (first() == NULL) {
+    this->set_first(node);
+    this->set_last(node);
+    return;
+  }
+  assert(first() != NULL);
+
+  // Before first node?
+  if (node->height() < first()->height()) {
+    node->set_next(first());
+    node->set_previous(NULL);
+    first()->set_previous(node);
+    this->set_first(node);
+    assert( this->sorted() );
+    return;
+  }
+
+  // After last node?
+  if ( node->height() >= last()->height() ) {
+    node->set_previous(last());
+    node->set_next(NULL);
+    last()->set_next(node);
+    this->set_last(node);
+    assert( this->sorted() );
+    return;
+  }
+
+  assert( after_node == NULL || node->height() >= after_node->height() );
+
+
+  if (after_node == NULL) after_node = first();
+  Node* current = after_node;
+  // Find position in between
+  while ( current->height() <= node->height() ) {
+    assert( !current->is_last() );
+    if ( !current->is_root() ) {
+      if ( current->parent_height() < node->height() ) { 
+        current = current->parent();
+        continue;
+      }
+    }
+    current = current->next();
+  }
+ 
+  // And add the node;
+  this->add_before(node, current);
+  assert( this->sorted() );
+}
+
+
+void NodeContainer::remove(Node *node, const bool &del) {
+  --size_; 
+  if ( node->is_first() && node->is_last() ) {
+    this->set_first(NULL);
+    this->set_last(NULL);
+  }
+  else if ( node->is_first() ) {
+    this->set_first(node->next());
+    node->next()->set_previous(NULL);
+  }
+  else if ( node->is_last() ) {
+    this->set_last(node->previous());
+    node->previous()->set_next(NULL);
+  }
+  else {
+    node->previous()->set_next(node->next());
+    node->next()->set_previous(node->previous());
+  }
+  
+  if (del) free_slots_.push(node);
+  assert( this->sorted() );
+}
+
+
+void NodeContainer::move(Node *node, const double new_height) {
+  assert( node != NULL );
+
+  // Stupid edge case first: We may have only one node.
+  if ( node->is_first() && node->is_last() ) {
+    node->set_height(new_height);
+    return;
+  }
+
+  // Remove from old place
+  remove(node, false);
+
+  // Add at new place
+  Node* current = NULL;
+  if ( node->height() < new_height ) {
+    if ( node->is_first() ) current = NULL;
+    else current = node->previous();
+  } else {
+    current = first();
+  }
+
+  node->set_height(new_height);
+  this->add(node, current);
+  assert( this->sorted() );
+}
+
+
+void NodeContainer::clear() {
+  set_first(NULL);
+  set_last(NULL);
+  this->size_ = 0;
+  this->node_counter_ = 0;
+  this->lane_counter_ = 0;
+
+  // Clear free_slots_
+  std::stack<Node*>().swap(free_slots_);
+}
+
+void NodeContainer::add_before(Node* add, Node* next_node){
+  add->set_next(next_node);
+  add->set_previous(next_node->previous());
+
+  if ( add->previous() != NULL ) add->previous()->set_next(add);
+  next_node->set_previous(add);
+  if ( add->is_last() ) this->set_last(add);
+}
+
+
+
+/*******************************************************
+ * Consistency checking
+ *******************************************************/
+
+bool NodeContainer::sorted() const {
+  Node* current = first();
+  if ( !current->is_first() ) {
+    dout << "NodeContainer: First Node is not first" << std::endl;
+    return 0;
+  }
+
+  while ( !current->is_last() ) {
+    current = current->next();
+    if ( current->height() < current->previous()->height() ) {
+      dout << "NodeContainer: Nodes not sorted" << std::endl;
+      return 0;
+    }
+    if ( current == current->previous() ) {
+      dout << "NodeContainer: Fatal loop detected" << std::endl;
+      return 0;
+    }
+  }
+  
+  if ( !current->is_last() ) {
+    dout << "NodeContainer: Last Node not last" << std::endl;
+    return 0;
+  }
+
+  return 1;
+}
+
+
+void swap(NodeContainer& first, NodeContainer& second) {
+  using std::swap;
+  swap(first.first_node_, second.first_node_);
+  swap(first.last_node_, second.last_node_);
+  swap(first.size_, second.size_);
+  swap(first.unsorted_node_, second.unsorted_node_);
+}
+
+
+std::ostream& operator<< (std::ostream& stream, const NodeContainer& nc) {
+  for ( ConstNodeIterator it = nc.iterator(); it.good(); ++it ) {
+    stream << *it << "(" << (*it)->height() << ")";
+    if (*it != nc.last()) stream << " <--> "; 
+  }
+  return stream;
+}
+
diff --git a/src/node_container.h b/src/node_container.h
new file mode 100644
index 0000000..5a5d2d1
--- /dev/null
+++ b/src/node_container.h
@@ -0,0 +1,299 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef scrm_src_node_container
+#define scrm_src_node_container
+
+#include "macros.h" // Needs to be before cassert
+
+#include <vector>
+#include <stack>
+#include <stdexcept>
+#include <cfloat>
+#include <cassert>
+#include <iostream>
+#include <map>
+#include <algorithm>
+#include <list>
+
+#include "node.h"
+
+class NodeIterator;
+class ConstNodeIterator;
+class ReverseConstNodeIterator;
+
+class NodeContainer {
+ public:
+  NodeContainer();
+  ~NodeContainer() { 
+    clear(); 
+    for (std::vector<Node>* lane : node_lanes_) delete lane;
+  };
+
+  NodeContainer& operator=(NodeContainer nc) {
+    swap(*this, nc);  
+    return(*this);
+  };
+
+  NodeContainer(const NodeContainer &nc);
+    
+  NodeIterator iterator(); 
+  NodeIterator iterator(Node* node);
+  ConstNodeIterator iterator() const;
+  ConstNodeIterator iterator(Node* node) const;
+  ReverseConstNodeIterator reverse_iterator() const;
+  ReverseConstNodeIterator reverse_iterator(Node* node) const;
+
+  // Create Nodes
+  Node* createNode(double height, size_t label = 0) { 
+    // Use the slot of a previously deleted node if possible
+    if (free_slots_.size() > 0) {
+      Node* node = free_slots_.top();
+      free_slots_.pop();
+      *node = Node(height, label);
+      return node;
+    }
+
+    // Otherwise, use a new slot
+    if (node_counter_ >= 10000) {
+      ++lane_counter_;
+      node_counter_ = 0;
+      if (lane_counter_ == node_lanes_.size()) {
+        std::vector<Node>* new_lane = new std::vector<Node>();
+        new_lane->reserve(10000);
+        node_lanes_.push_back(new_lane);
+      }
+    } 
+    (*node_lanes_.at(lane_counter_))[node_counter_] = Node(height, label);
+    return &*(node_lanes_[lane_counter_]->begin() + node_counter_++); 
+  }
+
+  void push_back(Node* node);
+  void push_front(Node* node);
+  void add(Node* node, Node* after_node=NULL);
+  void remove(Node *node, const bool &del=true);
+  void move(Node *node, const double new_height);
+  void clear();
+
+  Node* at(size_t nr) const; 
+  Node const* get(size_t nr) const { return at(nr); }; 
+
+  Node* first() const { return first_node_; };
+  Node* last() const { return last_node_; };
+  
+  size_t size() const { return size_; };  
+  bool sorted() const; 
+
+#ifdef UNITTEST
+  friend class TestNodeContainer;
+#endif
+  friend class NodeIterator;
+  friend class ConstNodeIterator;
+  friend class ReverseConstNodeIterator;
+  friend std::ostream& operator<< (std::ostream& stream, const NodeContainer& nc);
+
+ private:
+  friend void swap(NodeContainer& first, NodeContainer& second);
+  //const std::vector<Node*> nodes() const { return nodes_; }
+
+  void add_before(Node* add, Node* next_node);
+
+  Node* first_node_;
+  Node* last_node_;
+  
+  void set_first(Node* node) { first_node_ = node; }
+  void set_last(Node* node) { last_node_ = node; }
+
+  Node* unsorted_node_;
+  size_t size_;
+
+  // Storing the nodes in lanes a 10k nodes
+  std::vector<std::vector<Node>*> node_lanes_;
+  std::stack<Node*> free_slots_;
+  size_t node_counter_;
+  size_t lane_counter_;
+};
+
+
+class NodeIterator {
+ public:
+  NodeIterator() { current_node_ = NULL; };
+  NodeIterator(NodeContainer& nc) { current_node_ = nc.first(); };
+  NodeIterator(Node* node) { current_node_ = node; };
+  ~NodeIterator() {};
+
+  Node* operator*() { 
+    if (current_node_ == NULL) 
+      throw std::out_of_range("Node iterator out of range");
+    return current_node_; 
+  }
+  
+  Node* operator++() {
+    if (current_node_ == NULL) 
+      throw std::out_of_range("Node iterator out of range");
+
+    if ( current_node_->is_last() ) current_node_ = NULL;
+    else current_node_ = current_node_->next();
+    return current_node_;
+  }
+
+  Node* operator--() {
+    if (current_node_ == NULL) 
+      throw std::out_of_range("Node iterator out of range");
+
+    if ( current_node_->is_first() ) current_node_ = NULL;
+    else current_node_ = current_node_->previous();
+    return current_node_;
+  }
+  
+  Node* operator++(int) {
+    if (current_node_ == NULL) 
+      throw std::out_of_range("Node iterator out of range");
+    
+    Node* ret = current_node_;
+    if ( current_node_->is_last() ) current_node_ = NULL;
+    else current_node_ = current_node_->next();
+    return ret;
+  }
+
+  bool good() const { 
+    return current_node_ != NULL;
+  }
+
+  double height() const {
+    if ( good() ) return current_node_->height();
+    else return DBL_MAX;
+  }
+  
+#ifdef UNITTEST
+  friend class TestNodeContainer;
+#endif
+
+ private:
+  Node* current_node_;
+};
+
+
+class ConstNodeIterator {
+ public:
+  ConstNodeIterator() { current_node_ = NULL; };
+  ConstNodeIterator(const NodeContainer& nc) { current_node_ = nc.first(); };
+  ConstNodeIterator(Node const* node) { current_node_ = node; };
+  ~ConstNodeIterator() {};
+
+  Node const* operator*() { 
+    if (current_node_ == NULL) 
+      throw std::out_of_range("Node iterator out of range");
+    return current_node_; 
+  }
+  
+  Node const* operator++() { 
+    if (current_node_ == NULL) 
+      throw std::out_of_range("Node iterator out of range");
+
+    if ( current_node_->is_last() ) current_node_ = NULL;
+    else current_node_ = current_node_->next();
+
+    return current_node_;
+  }
+  
+  Node const* operator--() {
+    if (current_node_ == NULL) 
+      throw std::out_of_range("Node iterator out of range");
+
+    if ( current_node_->is_first() ) current_node_ = NULL;
+    else current_node_ = current_node_->previous();
+    return current_node_;
+  }
+  
+  Node const* operator++(int) { 
+    if (current_node_ == NULL) 
+      throw std::out_of_range("Node iterator out of range");
+    
+    Node const* ret = current_node_;
+    if ( current_node_->is_last() ) current_node_ = NULL;
+    else current_node_ = current_node_->next();
+    return ret;
+  }
+ 
+  bool good() const { 
+    return current_node_ != NULL;
+  }
+
+  double height() const {
+    if ( good() ) return current_node_->height();
+    else return DBL_MAX;
+  }
+
+ private:
+  Node const* current_node_;
+};
+
+
+class ReverseConstNodeIterator {
+ public:
+  ReverseConstNodeIterator() { current_node_ = NULL; };
+  ReverseConstNodeIterator(const NodeContainer &nc) {  current_node_ = nc.last(); };
+  ReverseConstNodeIterator(Node const* node) { current_node_ = node; };
+  ~ReverseConstNodeIterator() {};
+
+  Node const* operator*() { 
+    if (current_node_ == NULL) 
+      throw std::out_of_range("Node iterator out of range");
+    return current_node_; 
+  }
+
+  Node const* operator++() { 
+    if (current_node_ == NULL) 
+      throw std::out_of_range("Node iterator out of range");
+
+    if ( current_node_->is_first() ) current_node_ = NULL;
+    else current_node_ = current_node_->previous();
+    return current_node_;
+  }
+
+  Node const* operator++(int) { 
+    if (current_node_ == NULL) 
+      throw std::out_of_range("Node iterator out of range");
+    
+    Node const* ret = current_node_;
+    if ( current_node_->is_first() ) current_node_ = NULL;
+    else current_node_ = current_node_->previous();
+    return ret;
+  }
+
+  bool good() const { 
+    return current_node_ != NULL;
+  }
+
+ private:
+  Node const* current_node_;
+}; 
+
+
+inline NodeIterator NodeContainer::iterator() { return NodeIterator(*this); }
+inline NodeIterator NodeContainer::iterator(Node* node) { return NodeIterator(node); }
+inline ConstNodeIterator NodeContainer::iterator() const { return ConstNodeIterator(*this); }
+inline ConstNodeIterator NodeContainer::iterator(Node* node) const { return ConstNodeIterator(node); }
+inline ReverseConstNodeIterator NodeContainer::reverse_iterator() const { return ReverseConstNodeIterator(*this); }
+inline ReverseConstNodeIterator NodeContainer::reverse_iterator(Node* node) const {return ReverseConstNodeIterator(node); }
+#endif
diff --git a/src/param.cc b/src/param.cc
new file mode 100644
index 0000000..0004518
--- /dev/null
+++ b/src/param.cc
@@ -0,0 +1,536 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "param.h"
+
+std::ostream& operator<< (std::ostream& stream, const Param& param) {
+  stream << "scrm";
+  for (std::string arg : param.argv_) stream << " " << arg;
+  return stream;
+}
+
+/*! 
+ * \brief Read in ms parameters and convert to scrm parameters
+ * The first parameters followed by -eG, -eg, -eN, -en, -em, -ema, -es 
+ * and -ej options in ms are time t in unit of 4N_0 generations. 
+ * In scrm, we define time t in number of generations. 
+ */
+Model Param::parse() {
+  this->read_init_genealogy_ = false;
+  Model model;
+
+  size_t sample_size = 0;
+  double par_dbl = 0.0;
+  double time = 0.0;
+  size_t source_pop, sink_pop;
+
+  // Placeholders for summary statistics.
+  // Statistics are added only after all parameters are parse, so that they will
+  // be added in the correct order.
+  std::shared_ptr<SegSites> seg_sites;
+  bool tmrca = false,
+       newick_trees = false,
+       orientedForest = false,
+       sfs = false; 
+
+
+  // The minimal time at which -eM, -eN, -eG, -eI, -ema and -es are allowed to happen. Is
+  // increased by using -es.
+  double min_time = 0.0;
+
+  if (!directly_called_) {
+    dout << "Indirectly called" << std::endl;
+  } else {
+    // Check that have have at least one argument
+    if (argv_.size() == 0) throw std::invalid_argument("Too few command line arguments.");
+
+    // Check if we need to print the help & version (only valid one argument commands)
+    if (*argv_i == "-h" || *argv_i == "--help") {
+      this->set_help(true);
+      return model;
+    }
+    if (*argv_i == "-v" || *argv_i == "--version") {
+      this->set_version(true);
+      return model;
+    }
+
+    // Check that have have at least two arguments
+    if (argv_.size() == 1) throw std::invalid_argument("Too few command line arguments.");
+  }
+
+  sample_size = convert<double>(*argv_i);
+  model.set_loci_number(readNextInt());
+
+  while (++argv_i != argv_.end()) {
+    // ------------------------------------------------------------------
+    // Mutation 
+    // ------------------------------------------------------------------
+    if (*argv_i == "-t" || *argv_i == "-st") {
+      // Position
+      if (*argv_i == "-st") time = readNextInput<double>(); 
+      else time = 0.0;
+
+      model.setMutationRate(readNextInput<double>(), true, true, time);
+      if (directly_called_ && !seg_sites){
+        seg_sites = std::make_shared<SegSites>();
+      }
+    }
+
+    // ------------------------------------------------------------------
+    // Recombination 
+    // ------------------------------------------------------------------
+    else if (*argv_i == "-r") {
+      par_dbl = readNextInput<double>();
+      model.setLocusLength(readNextInt());
+      model.setRecombinationRate(par_dbl, true, true, 0.0);
+    }
+
+    else if (*argv_i == "-sr") {
+      time = readNextInput<double>(); // Position
+      model.setRecombinationRate(readNextInput<double>(), true, true, time);
+    }
+
+    // ------------------------------------------------------------------
+    // Subpopulations 
+    // ------------------------------------------------------------------
+    // Set number of subpopulations and samples at time 0
+    else if (*argv_i == "-I") {
+      model.set_population_number(readNextInt());
+      std::vector<size_t> sample_size;
+      for (size_t i = 0; i < model.population_number(); ++i) {
+        sample_size.push_back(readNextInt());
+      }
+      model.addSampleSizes(0.0, sample_size);
+      // there might or might not follow a symmetric migration rate
+      try {
+        model.addSymmetricMigration(0.0, readNextInput<double>()/(model.population_number()-1), true, true);
+      } catch (std::invalid_argument e) {
+        --argv_i;
+      }
+    }
+
+    // Add samples at arbitrary times
+    else if (*argv_i == "-eI") {
+      time = readNextInput<double>();
+      if (time < min_time) {
+        throw std::invalid_argument(std::string("If you use '-eI' in a model with population merges ('-es'),") +
+                                    std::string("then you need to sort both arguments by the time."));
+      }
+      std::vector<size_t> sample_size;
+      for (size_t i = 0; i < model.population_number(); ++i) {
+        sample_size.push_back(readNextInt());
+      }
+      model.addSampleSizes(time, sample_size, true);
+    }
+
+    // ------------------------------------------------------------------
+    // Populations sizes 
+    // ------------------------------------------------------------------
+    else if (*argv_i == "-eN" || *argv_i == "-N") {
+      if (*argv_i == "-eN") time = readNextInput<double>();
+      else time = 0.0;
+      if (time < min_time) {
+        throw std::invalid_argument(std::string("If you use '-N' or '-eN' in a model with population merges ('-es'),") +
+                                    std::string("then you need to sort both arguments by time."));
+      }
+      model.addPopulationSizes(time, readNextInput<double>(), true, true); 
+      if (time != 0.0) model.addGrowthRates(time, 0.0, true);
+    }
+
+    else if (*argv_i == "-en" || *argv_i == "-n") {
+      if (*argv_i == "-en") time = readNextInput<double>();
+      else time = 0.0;
+      size_t pop = readNextInt() - 1;
+      model.addPopulationSize(time, pop, readNextInput<double>(), true, true);
+      if (time != 0.0) model.addGrowthRate(time, pop, 0.0, true);
+    }
+
+    // ------------------------------------------------------------------
+    // Exponential Growth 
+    // ------------------------------------------------------------------
+    else if (*argv_i == "-G" || *argv_i == "-eG") {
+      if (*argv_i == "-eG") time = readNextInput<double>();
+      else time = 0.0;
+      if (time < min_time) {
+        throw std::invalid_argument(std::string("If you use '-G' or '-eG' in a model with population merges ('-es'),") +
+                                    std::string("then you need to sort both arguments by time."));
+      }
+      model.addGrowthRates(time, readNextInput<double>(), true, true); 
+    }
+
+    else if (*argv_i == "-g" || *argv_i == "-eg") {
+      if (*argv_i == "-eg") time = readNextInput<double>();
+      else time = 0.0;
+      size_t pop = readNextInt() - 1;
+      model.addGrowthRate(time, pop, readNextInput<double>(), true, true); 
+    }
+
+    // ------------------------------------------------------------------
+    // Migration
+    // ------------------------------------------------------------------
+    else if (*argv_i == "-ma" || *argv_i == "-ema") {
+      if (*argv_i == "-ema") {
+        time = readNextInput<double>();
+      }
+      else time = 0.0;
+      if (time < min_time) {
+        throw std::invalid_argument(std::string("If you use '-ma' or '-ema' in a model with population merges ('-es'),") +
+                                    std::string("then you need to sort both arguments by time."));
+      }
+      std::vector<double> migration_rates;
+      for (size_t i = 0; i < model.population_number(); ++i) {
+        for (size_t j = 0; j < model.population_number(); ++j) {
+          if (i==j) {
+            migration_rates.push_back(0.0);
+            ++argv_i;
+          }
+          else migration_rates.push_back(readNextInput<double>());
+        }
+      }
+      model.addMigrationRates(time, migration_rates, true, true);
+    }
+
+    else if (*argv_i == "-m" || *argv_i == "-em") {
+      if (*argv_i == "-em") {
+        time = readNextInput<double>();
+      }
+      else time = 0.0;
+      if (time < min_time) {
+        throw std::invalid_argument(std::string("If you use '-m' or '-em' in a model with population merges ('-es'),") +
+                                    std::string("then you need to sort both arguments by time."));
+      }
+      source_pop = readNextInt() - 1;
+      sink_pop = readNextInt() - 1;
+
+      model.addMigrationRate(time, source_pop, sink_pop, readNextInput<double>(), true, true);
+    }
+
+    else if (*argv_i == "-M" || *argv_i == "-eM") {
+      if (*argv_i == "-eM") {
+        time = readNextInput<double>();
+      }
+      else time = 0.0;
+      if (time < min_time) {
+        throw std::invalid_argument(std::string("If you use '-M' or '-eM' in a model with population merges ('-es'),") +
+                                    std::string("then you need to sort both arguments by time."));
+      }
+      model.addSymmetricMigration(time, readNextInput<double>()/(model.population_number()-1), true, true);
+    }
+
+    // ------------------------------------------------------------------
+    // Population merges
+    // ------------------------------------------------------------------
+    else if (*argv_i == "-es") {
+      time = readNextInput<double>();
+      if (time < min_time) {
+        throw std::invalid_argument(std::string("You must sort multiple population merges ('-es'),") +
+                                    std::string("by the time they occur."));
+      }
+      min_time = time;
+      source_pop = readNextInt() - 1;
+      sink_pop = model.population_number();
+      double fraction = readNextInput<double>();
+      if (fraction < 0.0) 
+        throw std::invalid_argument("Probability in `-es` argument is negative."); 
+      if (fraction > 1.0)
+        throw std::invalid_argument("Probability in `-es` argument greater than one."); 
+
+      model.addPopulation();
+      model.addSingleMigrationEvent(time, source_pop, sink_pop, 1-fraction, true); 
+    }
+
+
+    else if (*argv_i == "-eps") {
+      time = readNextInput<double>();
+      source_pop = readNextInt() - 1;
+      sink_pop = readNextInt() - 1;
+      double fraction = readNextInput<double>();
+      if (fraction < 0.0) 
+        throw std::invalid_argument("Probability in `-eps` argument is negative."); 
+      if (fraction > 1.0)
+        throw std::invalid_argument("Probability in `-eps` argument greater than one."); 
+
+      model.addSingleMigrationEvent(time, source_pop, sink_pop, 1-fraction, true); 
+    }
+
+
+    // ------------------------------------------------------------------
+    // Population splits
+    // ------------------------------------------------------------------
+    else if (*argv_i == "-ej") {
+      time = readNextInput<double>();
+      source_pop = readNextInt() - 1;
+      sink_pop = readNextInt() - 1;
+      model.addSingleMigrationEvent(time, source_pop, sink_pop, 1.0, true); 
+      for (size_t i = 0; i < model.population_number(); ++i) {
+        if (i == source_pop) continue;
+        model.addMigrationRate(time, i, source_pop, 0.0, true);
+      }
+    }
+
+    // ------------------------------------------------------------------
+    // Pruning 
+    // ------------------------------------------------------------------
+    else if (*argv_i == "-l"){
+      if (++argv_i == argv_.end()) throw std::invalid_argument("Missing sequence scaling argument.");
+      if (*argv_i == "-1") {
+        model.disable_approximation(); 
+      } else if (argv_i->back() == 'r') {
+        model.set_window_length_rec(convert<double>(argv_i->substr(0, argv_i->size()-1)));
+      } else {
+        model.set_window_length_seq(convert<double>(*argv_i));
+      }
+    }
+
+    // ------------------------------------------------------------------
+    // Read initial trees from file
+    // ------------------------------------------------------------------
+    else if ( *argv_i == "-init" ){
+      this->read_init_genealogy_ = true;
+      std::string tmp_string = readNextInput<std::string>();
+      std::ifstream in_file( tmp_string.c_str() );
+      std::string gt_str;
+      if ( in_file.good() ){
+        getline ( in_file, gt_str );
+        while ( gt_str.size() > 0 ){
+          init_genealogy.push_back( gt_str );
+          getline ( in_file, gt_str );
+        }
+      } else {
+        throw std::invalid_argument("Invalid input file. " + tmp_string );
+      }
+      in_file.close();
+    }
+
+    // ------------------------------------------------------------------
+    // Summary Statistics
+    // ------------------------------------------------------------------
+    else if (*argv_i == "-T") {
+      newick_trees = true;
+    }
+
+    else if (*argv_i == "-O"){
+      orientedForest = true;
+    }
+
+    else if (*argv_i == "-SC" || *argv_i == "--SC") {
+      if (++argv_i == argv_.end()) throw std::invalid_argument("Missing sequence scaling argument.");
+
+      if (*argv_i == "rel") model.setSequenceScaling(relative);
+      else if (*argv_i == "abs") model.setSequenceScaling(absolute);
+      else if (*argv_i == "ms") model.setSequenceScaling(ms);
+      else throw 
+        std::invalid_argument(std::string("Unknown sequence scaling argument: ") +
+                              *argv_i +
+                              std::string(". Valid are 'rel', 'abs' or 'ms'."));
+    }
+
+    else if (*argv_i == "-L") {
+      tmrca = true;
+    }
+
+    else if (*argv_i == "-oSFS") {
+      sfs = true;
+    }
+
+    else if (*argv_i == "-p") {
+      this->precision_ = readNextInt() ;
+    }
+
+    // ------------------------------------------------------------------
+    // Seeds
+    // ------------------------------------------------------------------
+    else if (*argv_i == "-seed" || *argv_i == "--seed" ||
+             *argv_i == "-seeds" || *argv_i == "--seeds") {
+      std::vector<size_t> seeds(3, 0);
+      // Always require one seed
+      seeds.at(0) = readNextInt();
+      try {
+        // Maybe read in up to 3 seeds (ms compatibility)
+        for (size_t i = 1; i < 3; ++i) seeds.at(i) = readNextInt();
+      } catch (std::invalid_argument e) {
+        --argv_i;
+      }
+
+      if (seeds.at(1) != 0 || seeds.at(2) != 0) {
+        // Mangles the seed together into a single int stored in the vectors
+        // first entry.
+        std::seed_seq{seeds.at(0), seeds.at(1), seeds.at(2)}.
+             generate(seeds.begin(), seeds.begin()+1);
+      }
+      set_random_seed(seeds.at(0));
+    }
+    
+
+    // ------------------------------------------------------------------
+    // Help & Version
+    // ------------------------------------------------------------------
+    else if (*argv_i == "-h" || *argv_i == "--help") {
+      this->set_help(true);
+    }
+
+    else if (*argv_i == "-v" || *argv_i == "--version") {
+      this->set_version(true);
+    }
+
+    else if (*argv_i == "-print-model" || *argv_i == "--print-model") {
+      this->set_print_model(true);
+    } 
+
+
+    // ------------------------------------------------------------------
+    // Unsupported ms arguments
+    // ------------------------------------------------------------------
+    else if (*argv_i == "-c") {
+      throw std::invalid_argument("scrm does not support gene conversion.");
+    }
+
+    else if (*argv_i == "-s") {
+      throw std::invalid_argument("scrm does not support simulating a fixed number of mutations.");
+    }
+
+    else {  
+      throw std::invalid_argument(std::string("unknown/unexpected argument: ") + *argv_i);
+    }
+  }
+
+  if (model.sample_size() == 0) {
+    model.addSampleSizes(0.0, std::vector<size_t>(1, sample_size));
+  } 
+  //else if (model.sample_size() != sample_size && directly_called_) {
+    //throw std::invalid_argument("Sum of samples not equal to the total sample size");
+  //}
+  else if (model.sample_size() != sample_size ) {
+    throw std::invalid_argument("Sum of samples not equal to the total sample size");
+  }
+
+  // Add summary statistics in order of their output
+  if (newick_trees) model.addSummaryStatistic(std::make_shared<NewickTree>(this->precision(), 
+                                                                           model.has_recombination()));
+  if (orientedForest) {
+    if (newick_trees) throw std::invalid_argument("scrm does not support '-T' and '-O' at the same time"); 
+    model.addSummaryStatistic(std::make_shared<OrientedForest>(model.sample_size()));
+  }
+  if (tmrca) model.addSummaryStatistic(std::make_shared<TMRCA>());
+  if (seg_sites.get() != NULL) model.addSummaryStatistic(seg_sites);
+  if (sfs) {
+    if (seg_sites == NULL) 
+      throw std::invalid_argument("You need to give a mutation rate ('-t') to simulate a SFS"); 
+    model.addSummaryStatistic(std::make_shared<FrequencySpectrum>(seg_sites, model));
+  }
+
+  model.finalize();
+  return model;
+}
+
+void Param::printHelp(std::ostream& out) {
+  out << "scrm - Fast & accurate coalescent simulations" << std::endl; 
+  out << "Version " << VERSION << std::endl << std::endl; 
+
+  out << "Usage" << std::endl; 
+  out << "--------------------------------------------------------" << std::endl; 
+  out << "Call scrm follow by two integers and an arbitrary number" << std::endl; 
+  out << "of options described below:" << std::endl; 
+  out << std::endl << "  scrm <n_samp> <n_loci> [...]" << std::endl << std::endl; 
+  out << "Here, n_samp is the total number of samples and n_loci" << std::endl; 
+  out << "is the number of independent loci to simulate." << std::endl; 
+  out << std::endl << "Options" << std::endl; 
+  out << "--------------------------------------------------------" << std::endl; 
+  out << "A detailed description of these options and their parameters" << std::endl; 
+  out << "is provided is the manual." << std::endl << std::endl;
+
+  out << "Recombination:" << std::endl;
+  out << "  -r <R> <L>       Set recombination rate to R and locus length to L." << std::endl;
+  out << "  -sr <p> <R>      Change the recombination rate R at sequence position p." << std::endl;
+  out << "  -l <l>           Set the approximation window length to l." << std::endl;
+
+  out << std::endl << "Population Structure:" << std::endl;
+  out << "  -I <npop> <s1> ... <sn> [<M>]   Use an island model with npop populations," <<std::endl
+      << "                   where s1 to sn individuals are sampled each population." << std::endl
+      << "                   Optionally assume a symmetric migration rate of M." << std::endl;
+  out << "  -eI <t> <s1> ... <sn> [<M>]     Sample s1 to sn indiviuals from their" << std::endl
+      << "                   corresponding populations at time t." << std::endl;
+  out << "  -M <M>           Assume a symmetric migration rate of M/(npop-1)." << std::endl;
+  out << "  -eM <t> <M>      Change the symmetric migration rate to M/(npop-1) at time t." 
+      << std::endl;
+  out << "  -m <i> <j> <M>   Set the migration rate from population j to population i to M" 
+      << std::endl;
+  out << "  -em <t> <i> <j> <M>   Set the migration rate from population j to" << std::endl
+      << "                   population i to M at time t." << std::endl;
+  out << "  -ma <M11> <M21> ...   Sets the (backwards) migration matrix." << std::endl;
+  out << "  -ema <t> <M11> <M21> ...    Changes the migration matrix at time t" << std::endl;
+  out << "  -es <t> <i> <p>  Population admixture. Replaces a fraction of 1-p of" << std::endl
+      << "                   population i with individuals a from population npop + 1" << std::endl
+      << "                   which is ignored afterwards (forward in time). " << std::endl;
+  out << "  -eps <t> <i> <j> <p>  Partial Population admixture. Replaces a fraction of 1-p of" << std::endl
+      << "                   population i with individuals a from population j." << std::endl;
+  out << "  -ej <t> <i> <j>  Speciation event at time t. Creates population j" << std::endl
+      << "                   from individuals of population i." << std::endl;
+
+  out << std::endl << "Population Size Changes:" << std::endl;
+  out << "  -n <i> <n>       Set the present day size of population i to n*N0." << std::endl;
+  out << "  -en <t> <i> <n>  Change the size of population i to n*N0 at time t." << std::endl;
+  out << "  -eN <t> <n>      Set the present day size of all populations to n*N0." << std::endl;
+  out << "  -g <i> <a>       Set the exponential growth rate of population i to a." << std::endl;
+  out << "  -eg <t> <i> <a>  Change the exponential growth rate of population i to a" << std::endl
+      << "                   at time t." << std::endl;
+  out << "  -G <a>           Set the exponential growth rate of all populations to a." << std::endl;
+  out << "  -eG <t> <a>      Change the exponential growth rate of all populations to a" << std::endl
+      << "                   at time t." << std::endl;
+
+  out << std::endl << "Summary Statistics:" << std::endl;
+  out << "  -t <theta>       Set the mutation rate to theta = 4N0*mu, where mu is the " << std::endl
+      << "                   neutral mutation rate per locus." << std::endl;
+  out << "  -T               Print the simulated local genealogies in Newick format." << std::endl;
+  out << "  -O               Print the simulated local genealogies in Oriented Forest format." << std::endl;
+  out << "  -L               Print the TMRCA and the local tree length for each segment." << std::endl;
+  out << "  -oSFS            Print the Site Frequency Spectrum for each locus." << std::endl;
+  out << "  -SC [ms|rel|abs] Scaling of sequence positions. Either" << std::endl 
+      << "                   relative (rel) to the locus length between 0 and 1," << std::endl 
+      << "                   absolute (abs) in base pairs or as in ms (default)." << std::endl;
+
+  out << "  -init <FILE>     Read genealogies at the beginning of the sequence." << std::endl;
+
+  out << std::endl << "Other:" << std::endl;
+  out << "  -seed <SEED> [<SEED2> <SEED3>]   The random seed to use. Takes up to three" << std::endl 
+      << "                   integer numbers." << std::endl;
+  out << "  -p <digits>      Specify the number of significant digits used in the output." << std::endl
+      << "                   Defaults to 6." << std::endl;
+  out << "  -v, --version    Prints the version of scrm." << std::endl;
+  out << "  -h, --help       Prints this text." << std::endl;
+  out << "  -print-model,    " << std::endl
+      << "  --print-model    Prints information about the demographic model." << std::endl;
+
+  out << std::endl << "Examples" << std::endl;
+  out << "--------------------------------------------------------" << std::endl;
+  out << "Five independent sites for 10 individuals using Kingman's Coalescent:" <<std::endl;
+  out << "  scrm 10 5 -t 10" << std::endl << std::endl;
+
+  out << "A sequence of 10kb from 4 individuals under the exact ARG:" <<std::endl; 
+  out << "  scrm 4 1 -t 10 -r 4 10000" << std::endl << std::endl;
+
+  out << "A sequence of 100Mb using the SMC' approximation:" << std::endl;
+  out << "  scrm 4 1 -t 10 -r 4000 100000000 -l 0" << std::endl << std::endl;
+
+  out << "Same as above, but with essentially correct linkage:" << std::endl;
+  out << "  scrm 4 1 -t 10 -r 4000 100000000 -l 100000" << std::endl << std::endl;
+}
diff --git a/src/param.h b/src/param.h
new file mode 100644
index 0000000..7bfa377
--- /dev/null
+++ b/src/param.h
@@ -0,0 +1,146 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef scrm_param
+#define scrm_param
+
+#include <vector>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <stdexcept>
+#include <random>
+#include <iterator>
+#include <sstream>
+
+
+#include "model.h"
+#include "summary_statistics/summary_statistic.h"
+#include "summary_statistics/tmrca.h"
+#include "summary_statistics/seg_sites.h"
+#include "summary_statistics/frequency_spectrum.h"
+#include "summary_statistics/newick_tree.h"
+#include "summary_statistics/oriented_forest.h"
+
+class Param {
+ public:
+ #ifdef UNITTEST
+  friend class TestParam;
+ #endif
+
+  // Constructors
+  Param() { init(); }
+
+  Param(const std::string &arg) { 
+    std::istringstream iss(arg);
+    copy(std::istream_iterator<std::string>(iss),
+         std::istream_iterator<std::string>(),
+         std::back_inserter(argv_));
+    directly_called_ = true;
+    init();
+  }
+
+  Param(int argc, char *argv[], bool directly_called=true) : 
+    directly_called_(directly_called) {
+    argv_ = std::vector<std::string>(argv + 1, argv + argc);
+    init();
+  }
+
+  void init() {
+    this->seed_set_ = false;
+    this->random_seed_ = 0;
+    this->set_help(false);
+    this->set_version(false);
+    this->set_precision(6);
+    this->set_print_model(false);
+    this->argv_i = argv_.begin();
+  }
+
+  // Getters and setters
+  bool help() const { return help_; }
+  bool version() const { return version_; }
+  bool read_init_genealogy() const { return this->read_init_genealogy_; }
+  size_t random_seed() const { return random_seed_; }
+  size_t precision() const { return precision_; }
+  bool seed_is_set() const { return this->seed_set_; }
+  bool print_model() const { return this->print_model_; }
+
+  void set_precision ( const size_t p ) { this->precision_ = p; }
+  void set_random_seed(const size_t seed) { 
+    this->random_seed_ = seed;
+    this->seed_set_ = true; 
+  }
+  void set_print_model(const bool print_model) { print_model_ = print_model; }
+
+  // Other methods
+  void printHelp(std::ostream& stream);
+
+  friend std::ostream& operator<< (std::ostream& stream, const Param& param);
+
+  Model parse();
+
+  template<class T>
+  T readNextInput() {
+    ++argv_i;
+
+    if (argv_i == argv_.end()) {
+      throw std::invalid_argument(std::string("Unexpected end of arguments"));
+    }
+
+    return convert<T>(*argv_i);
+  }
+
+  template<class T>
+  T convert(const std::string &arg) {
+    T value;
+    std::stringstream ss(arg);
+    ss >> value;
+    if (ss.fail()) {
+      throw std::invalid_argument(std::string("Failed to parse option: ") + arg);
+    }
+    return value;
+  }
+
+  // Read to double first and then cast to int to support scientific notation
+  size_t readNextInt() {
+    return readNextInput<double>();
+  }
+
+
+  std::vector < std::string > init_genealogy;
+
+ private:
+  void set_help(const bool help) { this->help_ = help; } 
+  void set_version(const bool version) { this->version_ = version; } 
+
+  std::vector<std::string> argv_;
+  std::vector<std::string>::iterator argv_i;
+  size_t seed_set_;
+  size_t random_seed_;
+  size_t precision_;
+  bool directly_called_;
+  bool help_;
+  bool version_;
+  bool read_init_genealogy_;
+  bool print_model_;
+};
+#endif
diff --git a/src/random/constant_generator.cc b/src/random/constant_generator.cc
new file mode 100644
index 0000000..1bfa586
--- /dev/null
+++ b/src/random/constant_generator.cc
@@ -0,0 +1,30 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "constant_generator.h"
+
+ConstantGenerator::ConstantGenerator() {}
+ConstantGenerator::ConstantGenerator(int seed) { (void)seed; }
+ConstantGenerator::~ConstantGenerator(){}
+
+double ConstantGenerator::sample() { return(0.5); }
+void ConstantGenerator::initialize() {}
diff --git a/src/random/constant_generator.h b/src/random/constant_generator.h
new file mode 100644
index 0000000..93089f8
--- /dev/null
+++ b/src/random/constant_generator.h
@@ -0,0 +1,44 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef scrm_src_random_constant_generator
+#define scrm_src_random_constant_generator
+
+#include <iostream>
+#include <fstream>
+
+#include "random_generator.h"
+
+using namespace std;
+
+class ConstantGenerator : public RandomGenerator
+{
+  public:
+   ConstantGenerator();
+   ConstantGenerator(int seed);
+   virtual ~ConstantGenerator();
+
+   virtual double sample();
+   void initialize();
+};
+
+#endif
diff --git a/src/random/fastfunc.cc b/src/random/fastfunc.cc
new file mode 100644
index 0000000..5f108a7
--- /dev/null
+++ b/src/random/fastfunc.cc
@@ -0,0 +1,49 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "fastfunc.h"
+
+void FastFunc::build_fastlog_double_table(int size) {
+  fastlog_double_table_ = std::vector<double>(size+1);
+  double prevx = 1.0;
+  double prevy = 0.0;
+  for (int index=0; index<size+1; index++) {
+
+    // calculate x coordinate at which linear approximation is exactly equal
+    // to the true logarithm
+    double curx = 1.0 + (index+5.0/6.0) / size;
+    if (index == size-1)
+      curx = 1.0 + (index+1.0) / size;
+
+    // calculate true logarithm at the point
+    double cury = log( curx );
+
+    // calculate the linear approximation at the next join point
+    double targetx = 1.0 + (index+1.0)/size;
+    double targety = prevy + (targetx-prevx)*(cury-prevy)/(curx-prevx);
+
+    // store previous linear approximation in table, and update prevx/y
+    fastlog_double_table_.at(index) = (double)(prevy);
+    prevx = targetx;
+    prevy = targety;
+  }
+}
diff --git a/src/random/fastfunc.h b/src/random/fastfunc.h
new file mode 100644
index 0000000..dbb024e
--- /dev/null
+++ b/src/random/fastfunc.h
@@ -0,0 +1,100 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef scrm_src_random_fastfunc
+#define scrm_src_random_fastfunc
+
+#include <iostream>
+#include <cmath>
+#include <vector>
+
+#if !defined(__APPLE__)
+#include <malloc.h>
+#endif
+
+
+// Number of interpolation points.  If this is changed, several constants in fastlog must also be changed.
+#define SIZE_DOUBLE 1024
+
+class FastFunc {
+ public:
+  FastFunc() {
+    this->build_fastlog_double_table(SIZE_DOUBLE);
+  }
+
+  // Methods
+  double fastlog(double);       /* about as fast as division; about as accurate as logf */
+  double fastexp_up(double y);  /* upper bound to exp; at most 6.148% too high.  10x as fast as exp */
+  double fastexp_lo(double y);  /* lower bound to exp; at most 5.792% too low.  10x as fast as exp */
+
+ private:
+  void build_fastlog_double_table(int);
+  
+  static constexpr double LN2 = 0.693147180559945309417; //ln(2)
+  static constexpr double EXP_A = 1048576/LN2;
+  static constexpr long long EXP_C_LO = 90254;
+  static constexpr long long EXP_C_UP = -1;
+
+  std::vector<double> fastlog_double_table_;
+};
+
+// Fast and fairly tight upper and lower bounds for exp(x)
+// A quick test showed a ~10x speed improvement
+// See: Nicol N. Schraudolf, A Fast, Compact Approximation of the Exponential Function, Neural Computation 11, 853-862 (1999)
+// http://nic.schraudolph.org/pubs/Schraudolph99.pdf
+
+inline double FastFunc::fastexp_up(double y) {
+  if (y<-700) return 0.0;
+  if (y>700) return INFINITY;
+  union {
+    double d;
+    int64_t i;
+  } n;
+  n.i = (((long long)(EXP_A*y)) + (1072693248 - EXP_C_UP)) << 32;
+  return n.d;
+}
+
+inline double FastFunc::fastexp_lo(double y) {
+  if (y<-700) return 0.0;
+  if (y>700) return INFINITY;
+  union {
+    double d;
+    int64_t i;
+  } n;
+  n.i = (((long long)(EXP_A*y)) + (1072693248 - EXP_C_LO)) << 32;
+  return n.d;
+}
+
+inline double FastFunc::fastlog(double x) {
+  const float offset = 2047;                // as int64_t: 0x409ffc00000....
+  double y = x;
+  int64_t* yint = (int64_t*)(&y);
+  int expon = ((*yint) >> 52) - 1023;       // base-2 exponent of float
+  int index = ((*yint) >> (52-10)) & 1023;  // upper 10 bits of mantissa
+  *yint |= 0x7ffffc0000000000;              // convert float into remainder of mantissa; and
+  *yint &= 0x409fffffffffffff;              // modify exponent to get into proper range
+  return (expon * LN2 +                     // contribution of base-2 log
+	  fastlog_double_table_[index] +          // table lookup, and linear interpolation
+	  (fastlog_double_table_[index+1] - fastlog_double_table_[index]) * (*(double*)(yint) - offset) );
+}
+
+#endif
diff --git a/src/random/mersenne_twister.cc b/src/random/mersenne_twister.cc
new file mode 100644
index 0000000..e934e2f
--- /dev/null
+++ b/src/random/mersenne_twister.cc
@@ -0,0 +1,68 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "mersenne_twister.h"
+
+void MersenneTwister::construct_common(const size_t seed){
+  unif_ = std::uniform_real_distribution<>(0, 1);
+  this->set_seed(seed);
+}
+
+MersenneTwister::MersenneTwister() {
+  this->construct_common(generateRandomSeed());
+}
+
+MersenneTwister::MersenneTwister(const size_t seed){
+  this->construct_common(seed);
+}
+
+MersenneTwister::MersenneTwister(const bool use_seed, size_t seed){
+  if (!use_seed) seed = generateRandomSeed();
+  this->construct_common(seed);
+}
+
+MersenneTwister::MersenneTwister(FastFunc* ff):RandomGenerator(ff) {
+  this->construct_common(generateRandomSeed());
+}
+
+MersenneTwister::MersenneTwister(const size_t seed, FastFunc* ff):RandomGenerator(ff) {
+  this->construct_common(seed);
+}
+
+/**
+ * @brief Generates a random seed using entropy provided by the operating
+ * system. 
+ *
+ * @return A random int between 0 and 2^32
+ */
+size_t MersenneTwister::generateRandomSeed() const {
+  std::random_device rd;
+  std::uniform_int_distribution<size_t> dist(0, 4294967295); // 0 - 2^32-1
+  return(dist(rd));
+}
+
+void MersenneTwister::set_seed(const size_t seed) {
+  RandomGenerator::set_seed(seed);
+  mt_ = std::mt19937_64(seed);
+  this->initializeUnitExponential();
+}
+
diff --git a/src/random/mersenne_twister.h b/src/random/mersenne_twister.h
new file mode 100644
index 0000000..64de12d
--- /dev/null
+++ b/src/random/mersenne_twister.h
@@ -0,0 +1,53 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef scrm_src_random_mersenne_twister
+#define scrm_src_random_mersenne_twister
+
+#include <random>
+#include "random_generator.h"
+
+class MersenneTwister : public RandomGenerator
+{
+ public:
+  MersenneTwister();
+  MersenneTwister(FastFunc* ff);
+  MersenneTwister(const size_t seed);
+  MersenneTwister(const bool use_seed, size_t seed);
+  MersenneTwister(const size_t seed, FastFunc* ff);
+  virtual ~MersenneTwister() {};
+
+  void initialize() {};
+  void set_seed(const size_t seed);
+  void construct_common(const size_t seed);
+
+  double sample() { return unif_(mt_); }
+
+ protected:
+  std::mt19937_64 mt_; 
+  std::uniform_real_distribution<> unif_;
+
+ private:
+  size_t generateRandomSeed() const;
+};
+
+#endif
diff --git a/src/random/random_generator.cc b/src/random/random_generator.cc
new file mode 100644
index 0000000..3ed3dc9
--- /dev/null
+++ b/src/random/random_generator.cc
@@ -0,0 +1,78 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "random_generator.h"
+#include <iostream>
+#include <cmath>
+
+// Samples waiting time, with limit, for a process with an exponentially changing rate:
+//  rate(t) = b exp( c t )
+// This code allows c=0, and falls back to a standard exponential if so
+// For a p ~ unif(0,1), a waiting time sample is (1/c) log[ 1 - (c/b) log p ]
+// It returns -1 if no event occurred; this can happen even if limit == +infinity (if c<0)
+double RandomGenerator::sampleExpoExpoLimit(double b, double c, double limit){
+  if (b == 0.0) return -1;
+  assert (b>0);
+  assert (limit>=0);
+  // for any c, the no-event condition (t=maximum waiting time) is
+  //  (b/c) (exp(c t)-1) < -log p
+  // For c<0 and c>0 respectively this becomes
+  //  -c log p < b (exp(c t)-1)
+  //  -c log p > b (exp(c t)-1)  resp.
+  // These are implied by the conditions
+  //  -c log p < b (exp_up(c t)-1)    [c<0]
+  //  -c log p > b (exp_lo(c t)-1)    [c>0]
+  // where exp_up and exp_lo are upper and lower bounds for the exp(x) function resp.
+  if (c < 0) {
+    double c_logp_limit = b*(this->ff()->fastexp_lo(c*limit)-1);  // negative
+    if (c*unit_exponential_ < c_logp_limit) {
+      unit_exponential_ -= c_logp_limit / c;
+      return -1;
+    }
+    double y = 1.0 + c*unit_exponential_ / b;
+    unit_exponential_ = sampleUnitExponential();
+    if (y <= 0.0) return -1; // no event at all
+    y = this->ff()->fastlog( y )/c;
+    if (y > limit) return -1;  // the event time; can still be beyond limit
+    return y;
+  } else if (c > 0) {
+    double c_logp_limit = b*(this->ff()->fastexp_up( c*limit )-1);  // positive
+    if (c*unit_exponential_ > c_logp_limit) {
+      unit_exponential_ -= c_logp_limit / c;
+      return -1;
+    }
+    double y = this->ff()->fastlog( 1.0 + c*unit_exponential_ / b ) / c;
+    unit_exponential_ = sampleUnitExponential();
+    if (y > limit) return -1;
+    return y;
+  } else {
+    if (unit_exponential_ >= limit * b) {
+      unit_exponential_ -= limit * b;
+      return -1;
+    } else {
+      double result = unit_exponential_ / b;
+      unit_exponential_ = sampleUnitExponential();
+      assert( result > 0 );
+      return result;
+    }
+    }
+}
diff --git a/src/random/random_generator.h b/src/random/random_generator.h
new file mode 100644
index 0000000..30fdb2c
--- /dev/null
+++ b/src/random/random_generator.h
@@ -0,0 +1,105 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef scrm_src_random_random_generator
+#define scrm_src_random_random_generator
+
+#include "../macros.h" // Needs to be before cassert
+
+#include <cassert>
+#include <cmath>
+
+#include "fastfunc.h"
+
+
+class RandomGenerator
+{
+ friend class MersenneTwister;
+ public:
+  RandomGenerator() { this->ff_ = new FastFunc(); };
+  RandomGenerator( FastFunc* ff ) { this->ff_ = ff; };
+  virtual ~RandomGenerator() {}
+  void clearFastFunc() { delete this->ff_; }
+
+  //Getters & Setters
+  size_t seed() const { return seed_; }
+
+  virtual void set_seed(const size_t seed) {
+    this->seed_ = seed;
+  }
+
+  virtual void initialize() =0;
+  virtual double sample() =0;
+
+  // Base class methods
+  // Initialize unit_exponential; must be called when the random generator is up and running
+  void initializeUnitExponential() {
+    this->unit_exponential_ = sampleUnitExponential();
+  }
+
+  // Uniformly samples a number out of 0, ..., range-1
+  // Unit tested 
+  int sampleInt(const int max_value) {
+    return(static_cast<int>(this->sample()*max_value));
+  }
+
+  // Samples from an exponential distribution 
+  // Unit tested 
+  double sampleExpo(const double lambda) {
+    return sampleUnitExponential() / lambda;
+  }
+
+  // Samples from an exponential distribution; return -1 if beyond limit
+  // If a limit is known, this version is faster than the standard one
+  // Unit tested
+  double sampleExpoLimit(const double lambda, const double limit) {
+    return sampleExpoExpoLimit(lambda, 0, limit);
+  }
+
+  double sampleExpoExpoLimit(const double b, const double c, const double limit);
+
+#ifdef UNITTEST
+  friend class TestRandomGenerator;
+#endif
+
+  // fast functions
+  FastFunc *ff() { return this->ff_; }
+
+ protected:
+  // Sample from a unit exponential distribution
+  // Unit tested
+  // fastlog can return 0, which causes a bug in scrm.
+  // log or fastlog does seems to have an influence on the runtime.
+  virtual double sampleUnitExponential() {
+    return -(this->ff()->fastlog(sample()));
+    //return -std::log(sample());
+  }
+
+ protected:
+  // seed
+  size_t seed_;
+  // cache for a unit-exponentially distributed variable
+  double unit_exponential_;
+  FastFunc *ff_;
+};
+
+#endif
diff --git a/src/random/speedtest.cc b/src/random/speedtest.cc
new file mode 100644
index 0000000..0e244ca
--- /dev/null
+++ b/src/random/speedtest.cc
@@ -0,0 +1,201 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "fastfunc.h"
+#include "mersenne_twister.h"
+
+
+double speedtest(int oper, double rate, double growth, double limit) {
+
+  int i;
+  double x = 1.0;
+  float xf = 1.0;
+  double y = 0.999;
+  float yf = 0.0;
+  double z = 0.0;
+  float zf = 0.0;
+
+  class MersenneTwister rg;
+  class FastFunc ff;
+
+  for (i=0; i<100000000; i++) {
+    x += 1e-8;
+    xf = float(x);
+    y = x;
+    switch(oper) {
+    case 0: break;
+    case 1: y = x+y; break;
+    case 2: y = x/x; break;
+    case 3: y = x*x; break;
+    case 4: y = log(x); break;
+    case 5: yf = logf(xf); break;
+    case 6: y = ff.fastlog(x); break;
+    case 7: y = exp(x); break;
+    case 8: y = ff.fastexp_lo(x); break;
+    case 9: y = rg.sample(); break;
+    case 10: y = rg.sampleExpo( 1.0 ); break;
+    case 11: y = rg.sampleExpoLimit( 1.0, 0.1 ); break;
+    default: y = rg.sampleExpoExpoLimit( rate, growth, limit ); break;
+    }
+    z += y;
+    zf += yf;
+  }
+  return z + zf;  // to avoid optimizing everything away
+}
+
+//
+// set of unit tests
+//
+
+double ut_calclog( double x, char func, class FastFunc& ff ) {
+
+  switch (func) {
+  case 'l':
+    return log(x);
+  case 'f':
+    return (double)logf( (float)x );
+  case 'F':
+    return ff.fastlog(x);
+  default:
+    std::cout << "Bad function identifier: " << func << std::endl;
+    exit(1);
+  }
+}
+    
+// test that log is in range around 1.0
+bool unittest_range( char func, class FastFunc& ff) {
+
+  double x,y;
+  // test log 1.0
+  y = ut_calclog( 1.0, func, ff );
+  if (y == 0.0) {
+    std::cout << " ok : log(1.0) = 0.0 " << std::endl;
+  } else {
+    std::cout << " PROBLEM : log(1.0) = " << y << std::endl;
+    return false;
+  }
+
+  // test numbers very close to 1.0
+  int i_limit = 1564;  // float
+  if (func == 'd') i_limit = 3574;
+  for (int i = 0; i<10000; i++) {
+    x = exp( -(1+i/100.0) );
+    y = ut_calclog( 1.0 - x, func, ff );
+    if ( y >= 0.0 ) {
+      std::cout << (i >= i_limit ? " ok" : " PROBLEM") << " : log( 1.0 - " << x << " ) = " << y << " at i=" << i << std::endl;
+      return i >= i_limit;
+    }
+    y = ut_calclog( 1.0 + x, func, ff );
+    if ( y <= 0.0 ) {
+      std::cout << (i >= i_limit ? " ok" : " PROBLEM") << " : log( 1.0 + " << x << " ) = " << y << " at i=" << i << std::endl;
+      return i >= i_limit;
+    }
+  }
+  return true;  // never happens
+}
+
+bool unittest_maxdiff_monotone( char func, class FastFunc& ff) {    
+
+  double epsilon = 1.5e-7;
+  double maxdiff = 0.0;
+  double y0 = ut_calclog( 0.5 - epsilon, func, ff );
+  for (int i=0; i<(int)(2+1.0/epsilon); i++) {
+    double x = 0.5 + epsilon*i;
+    double y1 = log(x);
+    double y2 = ut_calclog( x, func, ff );
+    double diff = fabs(y1-y2);
+    if (diff > maxdiff) {
+      maxdiff = diff;
+    }
+    if (y2 <= y0) {
+      std::cout << " PROBLEM: not increasing at " << x << " (i=" << i << ")" << std::endl;
+      return false;
+    }
+    y0 = y2;
+  }
+  std::cout << " max abs diff across [0.5-1.5] = " << maxdiff << std::endl;
+}
+
+
+void unittest_log() {
+
+  class FastFunc ff;
+  for (int i=0; i<3; i++) {
+    char func = "lfF"[i];
+    std::cout << "Testing: " << func << "  [ l=log(dbl); f=log(float); F=fastlog(dbl) ]" << std::endl;
+    unittest_range( func, ff );
+    unittest_maxdiff_monotone( func, ff );
+  }
+}
+
+
+void speedtest_log() {
+
+  const int CASES=4;
+  const double epsilon=1e-7;
+  const double x[CASES] = {0.0, 1.0, 2.0, 3.0};
+  class FastFunc ff;
+  int i;
+  printf("x\t\tlog\t\tfastlog\n");
+  for (i=0; i<CASES; i++) {
+    printf("%1.9f\t%1.9f\t%1.9f\n", x[i], log(x[i]), ff.fastlog(x[i]));
+  }
+  double maxdiff = 0.0;
+  for (i=0; i<(int)(2+1.0/epsilon); i++) {
+    double y = 0.5 + epsilon*i;
+    double z1 = log(y);
+    double z2 = ff.fastlog(y);
+    double diff = fabs(z1-z2);
+    if (diff > maxdiff) {
+      maxdiff = diff;
+    }
+  }
+  std::cout << "max absolute difference across [0.5-1.5] = " << maxdiff << std::endl;
+}
+
+
+int main(int argc, char** argv) {
+  
+  const int CASES=10;
+  const int LLTEST=12;
+  const char* testnames[LLTEST+1] = {"nop\t","+\t","/\t","*\t","log()\t","logf()\t","fastlog()","exp()\t","fastexp()","raw sample","sample(1.0)","sample(1.0,0.1)","sample\t"};
+  const double rate[CASES] =   {1.0,      1.0, 1.0, 1.0,      1.0, 1.0, 10.0, 1.0,      1.0,  1.0};
+  const double growth[CASES] = {0.0,      0.0, 0.0, 1.0,      1.0, 1.0, 10.0, -1.0,     -1.0, -1.0};
+  const double limit[CASES] =  {INFINITY, 1.0, 0.1, INFINITY, 1.0, 0.1, 0.1,  INFINITY, 1.0,  0.1};
+
+  class MersenneTwister rg;
+
+  unittest_log();
+
+  speedtest_log();
+
+  printf("Test\t\tRate\tGrowth\tLimit\tTime\n");
+  for (int i=0; i<LLTEST + CASES; i++) {
+    clock_t start = clock(), diff;
+    double r = i>=LLTEST ? rate[i-LLTEST] : 0, g = i>=LLTEST ? growth[i-LLTEST] : 0, l = i>=LLTEST ? limit[i-LLTEST] : 0;
+    speedtest(i, r, g, l);
+    diff = clock() - start;
+    printf("%s\t%1.4f\t%1.4f\t%1.4f\t%ld\n",testnames[i>=LLTEST ? LLTEST : i],r,g,l,diff * 1000 / CLOCKS_PER_SEC);
+  }
+  return 0;
+}
+
diff --git a/src/scrm.cc b/src/scrm.cc
new file mode 100644
index 0000000..27fe937
--- /dev/null
+++ b/src/scrm.cc
@@ -0,0 +1,98 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <iostream>
+#include <ctime>
+#include <memory>
+
+#include "param.h"
+#include "forest.h"
+#include "random/random_generator.h"
+#include "random/mersenne_twister.h"
+
+
+#ifndef UNITTEST
+int main(int argc, char *argv[]){
+  try {
+    // Organize output
+    std::ostream *output = &std::cout;
+
+    // Parse command line arguments
+    Param user_para(argc, argv);
+    Model model = user_para.parse();
+    output->precision(user_para.precision());
+
+    // Print help if user asked for it
+    if (user_para.help()) {
+      user_para.printHelp(*output); 
+      return EXIT_SUCCESS;
+    }
+    if (user_para.version()) {
+      *output << "scrm " << VERSION << std::endl;
+      return EXIT_SUCCESS;
+    }
+
+    MersenneTwister rg(user_para.seed_is_set(), user_para.random_seed());
+    *output << user_para << std::endl;
+    *output << rg.seed() << std::endl;
+
+    if (user_para.print_model()) {
+      *output << model << std::endl;
+    }
+
+    // Create the forest
+    Forest forest = Forest(&model, &rg);
+
+    // Loop over the independent loci/chromosomes
+    for (size_t rep_i=0; rep_i < model.loci_number(); ++rep_i) {
+
+      // Mark the start of a new independent sample
+      *output << std::endl << "//" << std::endl;
+
+      // Now set up the ARG, and sample the initial tree
+      if ( user_para.read_init_genealogy() )
+        forest.readNewick ( user_para.init_genealogy[ rep_i % user_para.init_genealogy.size()] );
+      else forest.buildInitialTree();
+      forest.printSegmentSumStats(*output);
+
+      while (forest.next_base() < model.loci_length()) { 
+        // Sample next genealogy
+        forest.sampleNextGenealogy();
+        forest.printSegmentSumStats(*output);
+      }
+      
+      forest.printLocusSumStats(*output);
+      forest.clear();
+    }
+
+    // Clean-up and exit
+    rg.clearFastFunc();
+    return EXIT_SUCCESS;
+  }
+  catch (const std::exception &e)
+  {
+    std::cerr << "Error: " << e.what() << std::endl;
+    std::cerr << "Try 'scrm --help' for more information." << std::endl;
+    return EXIT_FAILURE;
+  }
+}
+#endif
diff --git a/src/summary_statistics/frequency_spectrum.cc b/src/summary_statistics/frequency_spectrum.cc
new file mode 100644
index 0000000..3540b2c
--- /dev/null
+++ b/src/summary_statistics/frequency_spectrum.cc
@@ -0,0 +1,43 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "frequency_spectrum.h"
+
+void FrequencySpectrum::calculate(const Forest &forest) {
+  // Calculate seg_sites even if it is not a summary statistic of its own
+  if (seg_sites_->position() != forest.next_base()) seg_sites_->calculate(forest);
+  assert(seg_sites_->position() == forest.next_base()); 
+
+  size_t haplotype;
+
+  for (size_t i = at_mutation_; i < seg_sites_->countMutations(); ++i) { 
+    haplotype = 0;
+    for (size_t j = 0; j < seg_sites_->getHaplotype(i)->size(); ++j) 
+      haplotype += (*(seg_sites_->getHaplotype(i)))[j];
+    sfs_.at(haplotype - 1) += 1; 
+  }
+
+  at_mutation_ = seg_sites_->countMutations();
+}
+
+void FrequencySpectrum::printLocusOutput(std::ostream &output) const {
+  output << "SFS: " << sfs_ << std::endl;
+}
diff --git a/src/summary_statistics/frequency_spectrum.h b/src/summary_statistics/frequency_spectrum.h
new file mode 100644
index 0000000..295ef19
--- /dev/null
+++ b/src/summary_statistics/frequency_spectrum.h
@@ -0,0 +1,66 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef scrm_src_summary_statistic_frequency_spectrum
+#define scrm_src_summary_statistic_frequency_spectrum
+
+#include <sstream>
+#include <iostream>
+#include <vector>
+
+#include "../macros.h"
+#include <cassert>
+
+#include "summary_statistic.h"
+#include "seg_sites.h"
+#include "../model.h"
+#include "../forest.h"
+
+class FrequencySpectrum : public SummaryStatistic
+{
+ public:
+   FrequencySpectrum(std::shared_ptr<SegSites> seg_sites, const Model &model) : seg_sites_(seg_sites) {
+     sfs_ = std::vector<size_t>(model.sample_size() - 1, 0);
+     at_mutation_ = 0;
+     //total_sfs_ = std::vector<size_t>(model_.sample_size() - 1, 0);
+   }
+
+   FrequencySpectrum(const FrequencySpectrum &sp) : seg_sites_(sp.seg_sites_) { }
+
+   //Virtual methods
+   void calculate(const Forest &forest);
+   void printLocusOutput(std::ostream &output) const;
+   void clear() { 
+     for (size_t i = 0; i < sfs_.size(); ++i) sfs_.at(i) = 0;
+     at_mutation_ = 0;
+   }
+   FrequencySpectrum* clone() const { return new FrequencySpectrum(*this); }
+   std::vector<size_t> const & sfs() const { return sfs_; }
+
+ private:
+   std::shared_ptr<SegSites> seg_sites_;
+   std::vector<size_t> sfs_;
+   //std::vector<size_t> total_sfs_;
+   size_t at_mutation_;
+};
+
+#endif
diff --git a/src/summary_statistics/newick_tree.cc b/src/summary_statistics/newick_tree.cc
new file mode 100644
index 0000000..2ab3ce1
--- /dev/null
+++ b/src/summary_statistics/newick_tree.cc
@@ -0,0 +1,80 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "newick_tree.h"
+
+
+void NewickTree::calculate(const Forest &forest) {
+  segment_length_ = forest.calcSegmentLength();
+  if (segment_length_ > 0.0) tree_ = generateTree(forest.local_root(), forest, has_rec_); 
+}
+
+
+void NewickTree::printSegmentOutput(std::ostream &output) const {
+  if (segment_length_ == 0.0) return;
+  if (has_rec_) output << "[" << segment_length_ << "]";
+  output << tree_ << ";" << std::endl;
+}
+
+
+/**
+ * @brief Prints a part of the tree in newick format
+ *
+ * @param node The root of the subtree that will be printed
+ *
+ * @return A part of the tree in newick format
+ */
+std::string NewickTree::generateTree(Node const* node, const Forest &forest, const bool use_buffer) {
+  // Use tree from buffer if possible
+  std::map<Node const*, NewickBuffer>::iterator it = buffer_.find(node);
+  if (use_buffer && it != buffer_.end()) {
+    if (it->second.recombination > node->last_change()) {
+      // Check that the buffered tree is correct.
+      assert(it->second.tree.compare(generateTree(node, forest, false)) == 0);
+      return it->second.tree;
+    }
+  }
+
+  // Generate a new tree
+  std::stringstream tree;
+  tree.precision(this->precision_);
+  tree.exceptions(std::ios::failbit); 
+
+  if (node->in_sample()) tree << node->label();
+  else { 
+    Node *left = node->getLocalChild1();
+    Node *right = node->getLocalChild2();
+
+    tree << "(" << generateTree(left, forest, use_buffer) << ":" <<
+           (node->height() - left->height()) * forest.model().scaling_factor() <<
+           "," << generateTree(right, forest, use_buffer) << ":" <<
+           (node->height() - right->height()) * forest.model().scaling_factor() << ")";
+
+    // And add to to the buffer
+    if (use_buffer) {
+      NewickBuffer buf = {forest.current_rec(), tree.str()};
+      buffer_[node] = buf; 
+    }
+  }
+
+  return tree.str();
+}
+
diff --git a/src/summary_statistics/newick_tree.h b/src/summary_statistics/newick_tree.h
new file mode 100644
index 0000000..e37ce41
--- /dev/null
+++ b/src/summary_statistics/newick_tree.h
@@ -0,0 +1,81 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef scrm_src_summary_statistic_newick_tree
+#define scrm_src_summary_statistic_newick_tree
+
+#include <sstream>
+#include <iostream>
+#include <string>
+#include <map>
+
+#include "summary_statistic.h"
+#include "../forest.h"
+
+
+/**
+ * @brief Save buffered trees along with the recombination number at which
+ * they where created. 
+ */
+struct NewickBuffer {
+  size_t recombination;  ///< The recombination at which the subtree was created.
+  std::string tree;      ///< The subtree itself.
+};
+
+class NewickTree : public SummaryStatistic
+{
+ public:
+  NewickTree() : NewickTree(6, true) { }
+  NewickTree(size_t precision) : NewickTree(precision, true) { }
+  NewickTree(size_t precision, bool has_recombination) { 
+    precision_ = precision; 
+    has_rec_ = has_recombination;
+  }
+
+  ~NewickTree() {}
+
+  //Virtual methods
+  void calculate(const Forest &forest);
+  void printSegmentOutput(std::ostream &output) const;
+  void printLocusOutput(std::ostream &output) const {};
+
+  NewickTree* clone() const { return new NewickTree(precision_, has_rec_); };
+
+  void clear() {
+    buffer_.clear();
+  }
+
+ private:
+  std::string generateTree(Node const* node, const Forest &forest, const bool use_buffer);
+  std::string tree_;
+  double segment_length_;
+  size_t precision_;
+  bool has_rec_;
+
+  /**
+   * A map to buffer already created subtrees indexed by their 
+   * root.
+   */
+  std::map<Node const*, NewickBuffer> buffer_;
+};
+
+#endif
diff --git a/src/summary_statistics/oriented_forest.cc b/src/summary_statistics/oriented_forest.cc
new file mode 100644
index 0000000..8aeef3b
--- /dev/null
+++ b/src/summary_statistics/oriented_forest.cc
@@ -0,0 +1,75 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "oriented_forest.h"
+
+void OrientedForest::calculate(const Forest &forest) {
+  segment_length_ = forest.calcSegmentLength();
+  if (segment_length_ == 0.0) return;
+  has_rec_ = forest.model().has_recombination();
+
+  size_t pos = 2*forest.sample_size()-2;
+  generateTreeData(forest.local_root(), pos, 0, forest.model().scaling_factor()); 
+}
+
+
+void OrientedForest::printSegmentOutput(std::ostream &output) const {
+  if (segment_length_ == 0.0) return;
+  output << "{" ;
+  if (has_rec_) output << "\"length\":" << segment_length_ << ", ";
+
+  // Print parents
+  output << "\"parents\":[" ;
+  for (int parent : parents_) { 
+    output << parent << ( parent != 0 ? "," : "" );
+  }
+  output << "], ";
+
+  // Print heights
+  output << "\"node_times\":[" ;
+  double tmrca = heights_.back();
+  for (double height : heights_) {
+    output << height << ( height != tmrca ? "," : "" );
+  }
+  output << "]}" << std::endl;
+}
+
+
+void OrientedForest::generateTreeData(Node const* node, size_t &pos, int parent_pos, const double scaling_factor) {
+  // Samples have a fixed position in the arrays, given by their label.
+  if (node->in_sample()) {
+    heights_.at(node->label()-1) = node->height() * scaling_factor;
+    parents_.at(node->label()-1) = parent_pos;
+    return;
+  }
+
+  // Otherwise take the position given by pos and decrease it.
+  heights_.at(pos) = node->height() * scaling_factor;
+  parents_.at(pos) = parent_pos;
+  parent_pos = pos--;
+
+  if (node->getLocalChild1() != NULL) {
+    generateTreeData(node->getLocalChild1(), pos, parent_pos+1, scaling_factor);
+    if (node->getLocalChild2() != NULL) {
+      generateTreeData(node->getLocalChild2(), pos, parent_pos+1, scaling_factor);
+    }
+  }
+}
diff --git a/src/summary_statistics/oriented_forest.h b/src/summary_statistics/oriented_forest.h
new file mode 100644
index 0000000..17b08e9
--- /dev/null
+++ b/src/summary_statistics/oriented_forest.h
@@ -0,0 +1,65 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef scrm_src_summary_statistic_oriented_forest
+#define scrm_src_summary_statistic_oriented_forest
+
+#include <sstream>
+#include <iostream>
+#include <vector>
+
+#include "summary_statistic.h"
+#include "../forest.h"
+
+class OrientedForest : public SummaryStatistic
+{
+ public:
+  OrientedForest(const size_t sample_size) {
+    parents_ = std::vector<int>(2*sample_size-1, 0);
+    heights_ = std::vector<double>(2*sample_size-1, 0.0);
+  }
+
+  //Virtual methods
+  void calculate(const Forest &forest);
+  void printLocusOutput(std::ostream &output) const {};
+  void printSegmentOutput(std::ostream &output) const;
+  void clear() { }
+
+  OrientedForest* clone() const {
+    return new OrientedForest(this->parents_.size());
+  }
+
+#ifdef UNITTEST
+  friend class TestSummaryStatistics;
+#endif
+
+ private:
+  OrientedForest() {}
+  void generateTreeData(Node const* node, size_t &pos, int parent_pos, const double scaling_factor);
+
+  std::vector<int> parents_;
+  std::vector<double> heights_;
+  double segment_length_;
+  bool has_rec_;
+};
+
+#endif
diff --git a/src/summary_statistics/seg_sites.cc b/src/summary_statistics/seg_sites.cc
new file mode 100644
index 0000000..970d5eb
--- /dev/null
+++ b/src/summary_statistics/seg_sites.cc
@@ -0,0 +1,81 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "seg_sites.h"
+
+void SegSites::calculate(const Forest &forest) {
+  if (forest.current_base() == 0.0) clear();
+  if (position() == forest.next_base()) return;
+  if (position() != forest.current_base()) 
+    throw std::logic_error("Problem simulating seg_sites: Did we skip a forest segment?");
+
+  double position_at = forest.current_base();
+  position_at += forest.random_generator()->sampleExpo(forest.getLocalTreeLength() * forest.model().mutation_rate());
+
+  while (position_at < forest.next_base()) {
+    TreePoint mutation = forest.samplePoint();
+    haplotypes_.push_back(getHaplotypes(mutation, forest));
+    if (forest.model().getSequenceScaling() == absolute) {
+      positions_.push_back(position_at);
+    } else {
+      positions_.push_back(position_at / forest.model().loci_length());
+    }
+    position_at += forest.random_generator()->sampleExpo(forest.getLocalTreeLength() * forest.model().mutation_rate());
+  }	
+
+  set_position(forest.next_base());
+}
+
+
+void SegSites::printLocusOutput(std::ostream &output) const {
+  output << "segsites: "<< countMutations() << std::endl;
+  if ( countMutations() == 0 ) return;
+
+  output << "positions: " << positions_ << std::endl;
+
+  for (size_t i = 0; i < haplotypes_.at(0).size(); i++){
+    for (size_t j = 0; j < haplotypes_.size(); j++){
+      output << haplotypes_[j][i];
+    }
+    output <<"\n";
+  }
+}
+
+
+std::valarray<bool> SegSites::getHaplotypes(TreePoint mutation, const Forest &forest) {
+  std::valarray<bool> haplotype(forest.model().sample_size());
+  traversal(mutation.base_node(), haplotype);
+  return haplotype;
+}
+
+
+void SegSites::traversal(Node const* node, std::valarray<bool> &haplotype) const {
+  if (node->in_sample()) {
+    haplotype[node->label()-1]=1;
+    return;
+  }
+  
+  Node *left = node->getLocalChild1();
+  Node *right = node->getLocalChild2();
+
+  if (left != NULL) traversal(left, haplotype);
+  if (right != NULL) traversal(right, haplotype);
+}
diff --git a/src/summary_statistics/seg_sites.h b/src/summary_statistics/seg_sites.h
new file mode 100644
index 0000000..6b1b35e
--- /dev/null
+++ b/src/summary_statistics/seg_sites.h
@@ -0,0 +1,75 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef scrm_src_summary_statistic_seg_sites
+#define scrm_src_summary_statistic_seg_sites
+
+#include <sstream>
+#include <iostream>
+#include <valarray>
+
+#include "summary_statistic.h"
+#include "../forest.h"
+#include "../tree_point.h"
+
+class SegSites : public SummaryStatistic
+{
+ public:
+  SegSites() { set_position(0.0); }
+  ~SegSites() {}
+
+#ifdef UNITTEST
+  friend class TestSummaryStatistics;
+#endif
+
+  //Virtual methods
+  void calculate(const Forest &forest);
+  void printLocusOutput(std::ostream &output) const;
+  SegSites* clone() const { return new SegSites(*this); }
+
+  void clear() { 
+    positions_.clear();
+    haplotypes_.clear();  
+    set_position(0.0);
+  };
+
+  size_t countMutations() const { return positions_.size(); };
+
+  double position() const { return position_; };
+  std::vector<double> const* positions() const { return &positions_; };
+
+  std::valarray<bool> const* getHaplotype(const size_t mutation) const {
+    return &(haplotypes_.at(mutation));
+  }
+
+ private:
+  std::valarray<bool> getHaplotypes(TreePoint mutation, const Forest &Forest); 
+
+  std::vector<double> positions_;
+  std::vector<std::valarray<bool>> haplotypes_;	
+  void traversal(Node const* node, std::valarray<bool> &haplotype) const;
+
+  void set_position(const double position) { position_ = position; };
+  double position_;
+};
+
+#endif
diff --git a/src/summary_statistics/summary_statistic.h b/src/summary_statistics/summary_statistic.h
new file mode 100644
index 0000000..e557a95
--- /dev/null
+++ b/src/summary_statistics/summary_statistic.h
@@ -0,0 +1,46 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef scrm_src_summary_statistic_summary_statistic
+#define scrm_src_summary_statistic_summary_statistic
+
+#include <iostream>
+#include <ostream>
+
+class Forest;
+
+class SummaryStatistic 
+{
+ public:
+   virtual ~SummaryStatistic() {};
+
+   // Virtual methods
+   virtual void calculate(const Forest &forest) =0;
+   virtual void printLocusOutput(std::ostream &output) const =0;
+   virtual void clear() =0;
+   virtual SummaryStatistic* clone() const =0; 
+
+   // Optional methods
+   virtual void printSegmentOutput(std::ostream &output) const { };
+};
+
+#endif
diff --git a/src/summary_statistics/tmrca.cc b/src/summary_statistics/tmrca.cc
new file mode 100644
index 0000000..1b16c4a
--- /dev/null
+++ b/src/summary_statistics/tmrca.cc
@@ -0,0 +1,34 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "tmrca.h"
+
+void TMRCA::calculate(const Forest &forest) {
+  if (forest.calcSegmentLength() == 0) return;
+  tmrca_.push_back(forest.getTMRCA(true));
+  tree_length_.push_back(forest.getLocalTreeLength(true));
+}
+
+void TMRCA::printLocusOutput(std::ostream &output) const {
+  for (size_t i = 0; i < tmrca_.size(); ++i) {
+    output << "time:\t" << tmrca_.at(i) << " \t" << tree_length_.at(i) << "\n";  
+  }
+}
diff --git a/src/summary_statistics/tmrca.h b/src/summary_statistics/tmrca.h
new file mode 100644
index 0000000..154ecdf
--- /dev/null
+++ b/src/summary_statistics/tmrca.h
@@ -0,0 +1,57 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef scrm_src_summary_statistic_tmrca
+#define scrm_src_summary_statistic_tmrca
+
+#include <sstream>
+#include <iostream>
+#include <vector>
+
+#include "summary_statistic.h"
+#include "../forest.h"
+
+class TMRCA : public SummaryStatistic
+{
+ public:
+   TMRCA() {};
+   ~TMRCA() {};
+
+   //Virtual methods
+   void calculate(const Forest &forest);
+   void printLocusOutput(std::ostream &output) const;
+   void clear() {
+     tmrca_.clear();
+     tree_length_.clear();
+   }
+   
+   TMRCA* clone() const { return new TMRCA(); } 
+
+   const std::vector<double> & tmrca() const { return tmrca_; }
+   const std::vector<double> & tree_length() const { return tree_length_; }
+
+ private:
+   std::vector<double> tmrca_;
+   std::vector<double> tree_length_;
+};
+
+#endif
diff --git a/src/time_interval.cc b/src/time_interval.cc
new file mode 100644
index 0000000..61d9a57
--- /dev/null
+++ b/src/time_interval.cc
@@ -0,0 +1,234 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "time_interval.h"
+
+/* --------------------------------------------------------------------
+ * TimeInterval
+ * -------------------------------------------------------------------*/
+
+TimeInterval::TimeInterval() {
+  this->tii_ = NULL;
+  this->start_height_ = 0;
+  this->end_height_ = 0;
+}
+
+
+TimeInterval::TimeInterval(TimeIntervalIterator* tii, double start_height, double end_height){
+  assert( tii != NULL );
+  this->tii_ = tii;
+  this->start_height_ = start_height;
+  this->end_height_ = end_height;
+}
+
+
+/* --------------------------------------------------------------------
+ * TimeIntervalIterator
+ * -------------------------------------------------------------------*/
+
+TimeIntervalIterator::TimeIntervalIterator(Forest *forest) {
+  // Used only for unit testing, and hence private.
+  this->forest_ = forest;
+  this->contemporaries_ = &(forest->contemporaries_);
+  this->contemporaries_->clear();
+  this->node_iterator_ = forest->nodes()->iterator();
+  this->good_ = false;
+  this->inside_node_ = NULL;
+  this->current_time_ = 0; 
+  forest->writable_model()->resetTime();
+}
+
+TimeIntervalIterator::TimeIntervalIterator(Forest* forest, 
+                                           Node* start_node) {
+
+  this->forest_ = forest;
+  this->contemporaries_ = &forest->contemporaries_;
+  this->model_ = forest->model_;
+
+  this->good_ = true;
+  this->inside_node_ = NULL;
+  this->node_iterator_ = forest->nodes()->iterator(start_node);
+  this->current_time_ = start_node->height();
+
+  model_->resetTime();
+  this->searchContemporaries(start_node);
+  
+  // Skip through model changes
+  while ( model_->getNextTime() <= current_time_ ) { 
+    model_->increaseTime();
+  }
+
+  next();
+}
+
+
+// Sets current_interval_ to the next time interval.
+void TimeIntervalIterator::next() {
+  if (this->inside_node_ != NULL) {
+    this->current_interval_.start_height_ = inside_node_->height();
+    this->inside_node_ = NULL;
+    return;
+  }
+
+  if (current_time_ == DBL_MAX) {
+    good_ = false;
+    return;
+  }
+
+  double start_height = this->current_time_;
+
+  // Ensure that both iterators point into the future to determine the end of the
+  // interval 
+  if ( start_height >= forest_->model().getNextTime() ) { 
+    model_->increaseTime();
+  }
+
+  if ( start_height >= node_iterator_.height() ) {
+    // Update contemporaries 
+    contemporaries()->replaceChildren(*node_iterator_);
+
+    // Pruning
+    while ( !(*node_iterator_)->is_last() ) {
+      // Prunes the next node BEFORE node_iterator_ gets there, 
+      // and does there not invalidate it.
+      if (!forest_->pruneNodeIfNeeded((*node_iterator_)->next())) break;
+    }
+
+    // Move node iterator forwards
+    ++node_iterator_;
+  }
+
+  double next_model_change_ = forest_->model().getNextTime();
+
+  assert( current_time_ <= next_model_change_ );
+  //std::cout << "current_time: " << current_time_ << " ni_height: " << node_iterator_.height() << std::endl;
+  assert( current_time_ <= node_iterator_.height() );
+
+  // Now determine the end of the interval
+  if ( node_iterator_.height() <= next_model_change_ ) {
+    current_time_ = node_iterator_.height();
+  } else  {
+    current_time_ = next_model_change_;
+  }
+  //std::cout << " Next Node: " << node_iterator_.height()
+  //          << " Next MC: " << next_model_change_ 
+  //          << " CT " << current_time_ << std::endl;
+
+  //Don't return TimeIntervals of length zero, as nothing can happen there...
+  if (start_height == current_time_) return next();
+  
+  this->current_interval_ = TimeInterval(this, 
+                                         start_height, 
+                                         current_time_);
+}
+
+void TimeIntervalIterator::searchContemporariesBottomUp(Node* node, const bool use_buffer) {
+  contemporaries()->clear();
+  Node* start_node = NULL;
+
+  if ( use_buffer ) {
+    assert( node->height() >= contemporaries()->buffer_time() ); 
+    // check if the buffered contemporaries are contemporaries of node
+    double highest_time = -1;
+    for (size_t pop = 0; pop < model()->population_number(); ++pop) {
+      auto end = contemporaries()->buffer_end(pop);
+      for (auto it = contemporaries()->buffer_begin(pop); it != end; ++it) {
+        assert(!(*it)->is_root());
+        //std::cout << "Checking " << *it << std::endl;
+        // Prune the node if needed
+        tmp_child_1_ = (*it);
+        tmp_child_2_ = (*it)->first_child();
+        while (tmp_child_1_->countChildren() == 1 && forest_->pruneNodeIfNeeded(tmp_child_1_)) {
+          tmp_child_1_ = tmp_child_2_;
+          if (tmp_child_1_ == NULL ) break;
+          tmp_child_2_ = tmp_child_2_->first_child();
+        }
+        if (tmp_child_1_ == NULL || forest_->pruneNodeIfNeeded(tmp_child_1_)) continue;
+
+        // And add it if it is a contemporary
+        if (tmp_child_1_->height() <= node->height() && node->height() < tmp_child_1_->parent_height()) {
+          contemporaries()->add(tmp_child_1_);
+        }
+
+        // Find the oldest buffered node
+        if (tmp_child_1_->height() > highest_time) {
+          highest_time = tmp_child_1_->height();
+          start_node = tmp_child_1_;
+        }
+      }
+    }
+    // The node after the oldest node in the buffer should be the first node
+    // above the buffers_height.
+    assert( start_node != NULL );
+    start_node = start_node->next();
+    assert( start_node->height() >= contemporaries()->buffer_time() );
+  } else {
+    start_node = forest()->nodes()->first(); 
+  }
+
+  for (NodeIterator ni = forest_->nodes()->iterator(start_node); *ni != node; ++ni) {
+    assert(ni.good());
+
+    // Check if *ni is a contemporary of node 
+    if ( (*ni)->parent_height() > node->height() ) {
+      // Is is; it may however be a node we need to prune
+      if ((*ni)->is_first()) tmp_prev_node_ = NULL;
+      else tmp_prev_node_ = (*ni)->previous();
+      tmp_child_1_ = (*ni)->first_child();
+
+      if (forest_->pruneNodeIfNeeded(*ni)) {
+        // Removing the node invalidates the ni
+        if (tmp_prev_node_ == NULL) ni = forest_->nodes()->iterator();
+        else ni = forest_->nodes()->iterator(tmp_prev_node_);
+
+        // Maybe a child of the node became a contemporary by removing the node
+        // This can only happen if the node has only one child.
+        if ( tmp_child_1_ != NULL && tmp_child_1_->parent_height() > node->height() ) { 
+          this->contemporaries()->add(tmp_child_1_);
+        }
+      } else {
+        // No pruning => Just add to contemporaries
+        this->contemporaries()->add(*ni);
+      }
+    }
+  }
+}
+
+
+
+// Recalculates the borders of the current interval. 
+// Used after one or more nodes where created inside the interval due to events
+// occurring within.
+void TimeIntervalIterator::recalculateInterval() {
+  if (!node_iterator_.good()) {
+    node_iterator_ = NodeIterator(forest_->nodes()->last());
+  } 
+  else {
+    // Set node iterator back to the node at the current start_height
+    while ( (*node_iterator_)->height() > current_interval_.start_height() ) --node_iterator_;
+    ++node_iterator_;
+  }
+
+  // Then go to the next node
+  current_interval_.end_height_ = (*node_iterator_)->height();
+  current_time_ = (*node_iterator_)->height();
+}
diff --git a/src/time_interval.h b/src/time_interval.h
new file mode 100644
index 0000000..c53cad0
--- /dev/null
+++ b/src/time_interval.h
@@ -0,0 +1,149 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef scrm_src_time_interval
+#define scrm_src_time_interval
+
+#include "macros.h" // Needs to be before cassert
+
+#include "forest.h"
+#include "contemporaries_container.h"
+#include "model.h"
+
+#ifdef UNITTEST
+#define TI_DEBUG
+#endif
+
+#ifndef NDEBUG
+#ifndef TI_DEBUG
+#define TI_DEBUG
+#endif
+#endif
+
+class Forest;
+class TimeIntervalIterator;
+
+class TimeInterval {
+ public:
+  friend class TimeIntervalIterator;
+
+#ifdef UNITTEST
+  friend class TestTimeInterval;
+  friend class Forest;
+#endif
+
+  TimeInterval();
+  TimeInterval(TimeIntervalIterator* tii, double start_height, double end_height);
+  ~TimeInterval() { };
+
+  double start_height()  const { return this->start_height_; };
+  double end_height()    const { return this->end_height_; };
+  double length()        const { return (end_height() - start_height()); };
+  const Forest &forest() const { return *(this->forest_); }
+
+  //std::unordered_set<Node*> &contemporaries(const size_t pop = 0);
+
+ private:
+  double start_height_;
+  double end_height_; 
+  Forest* forest_;
+  TimeIntervalIterator const* tii_;
+};
+
+
+/* WARNING: DON'T USE MULTIPLE OF THESE AT THE SAME TIME */
+class TimeIntervalIterator {
+ public:
+  TimeIntervalIterator(Forest* forest, Node* start_node);
+
+  void next();
+  bool good() const { return this->good_; }
+
+  TimeInterval operator*() const { return current_interval_; }
+  TimeInterval operator++() { next(); return current_interval_; }
+  TimeInterval operator++(int) { TimeInterval tmp = current_interval_;
+                          next();
+                          return tmp; }
+
+  // Splits the current interval in two parts by adding a node inside the interval;
+  // Only affects the event after the next "next()" which than represents the
+  // second part of the interval.
+  void splitCurrentInterval(Node* splitting_node, Node* del_node = NULL) {
+    this->inside_node_ = splitting_node;
+    if (del_node != NULL) contemporaries_->remove(del_node);
+  };
+
+  void recalculateInterval();
+
+  void searchContemporaries(Node* node);
+  void searchContemporariesBottomUp(Node* node, const bool use_buffer = false);
+
+  const Forest &forest() const { return *forest_; };
+
+#ifdef UNITTEST
+  friend class TestTimeInterval;
+#endif
+
+ private:
+  TimeIntervalIterator(Forest *forest);
+  TimeIntervalIterator( TimeIntervalIterator const &other );
+  TimeIntervalIterator& operator= ( TimeIntervalIterator const &other ); 
+
+  Forest* forest() { return forest_; }
+  ContemporariesContainer* contemporaries() { return contemporaries_; }
+  Model* model() { return model_; }
+
+  Forest* forest_;
+  ContemporariesContainer* contemporaries_;
+  Model* model_;
+
+  TimeInterval current_interval_;
+  double current_time_;
+  NodeIterator node_iterator_;
+
+  bool good_;
+  bool model_changed_;
+
+  Node* inside_node_;
+
+  // Temporary values
+  Node *tmp_child_1_, *tmp_child_2_, *tmp_prev_node_;
+};
+
+/** 
+ * Finds all nodes which code for branches at the height of a given node in the
+ * tree (i.e. the node's contemporaries). Saves this nodes in the contemporaries_
+ * member.
+ * 
+ * @param node Node for which we are searching contemporaries
+ * @return Nothing. Nodes are saved in contemporaries_.
+ */
+inline void TimeIntervalIterator::searchContemporaries(Node *node) {
+  // Prefer top-down search if the target is above .8 coalescence units in
+  // sample space. This is relatively high, but the iterative bottom-up approach
+  // is faster than the recursion.
+  if (node->height() >= contemporaries()->buffer_time()) {
+    searchContemporariesBottomUp(node, true);
+  } else {
+    searchContemporariesBottomUp(node);
+  }
+}
+
+#endif
diff --git a/src/tree_point.cc b/src/tree_point.cc
new file mode 100644
index 0000000..f99c21e
--- /dev/null
+++ b/src/tree_point.cc
@@ -0,0 +1,43 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "tree_point.h"
+
+TreePoint::TreePoint(Node* base_node, double height, bool relative) {
+  assert( base_node != NULL );
+  assert( height >= 0 );
+
+  base_node_ = base_node;
+  if (relative) {
+    relative_height_ = height;
+    height_ = base_node->height() + relative_height_;
+  } else {
+    relative_height_ = height - base_node->height();
+    height_ = height;
+  }
+  
+  //std::cout << base_node << ": " << base_node->height() 
+  //                       << " - " << base_node->parent_height() << std::endl;
+  assert( relative_height_ <= base_node->height_above() );
+  assert( relative_height_ >= 0 ); 
+}
+
diff --git a/src/tree_point.h b/src/tree_point.h
new file mode 100644
index 0000000..e3738db
--- /dev/null
+++ b/src/tree_point.h
@@ -0,0 +1,46 @@
+/*
+ * scrm is an implementation of the Sequential-Coalescent-with-Recombination Model.
+ * 
+ * Copyright (C) 2013, 2014 Paul R. Staab, Sha (Joe) Zhu, Dirk Metzler and Gerton Lunter
+ * 
+ * This file is part of scrm.
+ * 
+ * scrm 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef scrm_src_treepoint
+#define scrm_src_treepoint
+
+#include "macros.h" // Needs to be before cassert
+
+#include <cassert>
+#include "node.h"
+
+class TreePoint {
+public:
+  TreePoint() {};
+  TreePoint(Node* base_node, double height, bool relative);
+
+  Node*  base_node()       const { return base_node_; }
+  double relative_height() const { return relative_height_; }
+  double height()          const { return height_; }
+
+private:
+  Node*  base_node_;
+  double relative_height_;
+  double height_;
+};
+
+#endif
diff --git a/tests/README.md b/tests/README.md
new file mode 100644
index 0000000..3d0403c
--- /dev/null
+++ b/tests/README.md
@@ -0,0 +1,21 @@
+# Tests for scrm
+
+## Automatic tests
+scrm comes with a large number of tests and self checks which are automatically
+executed after each commit. These tests fall into three classes:
+
+- unit tests: Quick tests that ensure that the different building blocks of 
+  scrm work correctly. Before committing, you should ensure that scrm passes the
+  unit tests using `make test`.
+- debug self checks: scrm has a lot of assertions and self checks which are 
+  only active in debug mode. The little `test_binaries.sh` script executes a
+  number of different scenarios in debug mode to ensure that everything works
+  correctly. It also checks for memory leaks using valgrind. The script is
+  automatically executed an travis-CI.  
+- algorithm test: Here we check that the complete algorithm produces ARGs that
+  are equal in distribution to those produced by ms. They are also automatically
+  executed.
+
+## Manual test
+In the folder `manualtests`, there is a large number of expensive tests that we
+execute from time to time.
diff --git a/tests/algorithmtest/test_algorithm.cc b/tests/algorithmtest/test_algorithm.cc
new file mode 100644
index 0000000..3d51734
--- /dev/null
+++ b/tests/algorithmtest/test_algorithm.cc
@@ -0,0 +1,256 @@
+/*
+ * Long running tests that ensure that scrm produces correct results
+ * in various settings.
+ */
+
+#pragma GCC diagnostic ignored "-Wwrite-strings"
+
+#include <cppunit/TestCase.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <valarray>
+#include <cmath>
+
+#include "../../src/forest.h"
+#include "../../src/param.h"
+#include "../../src/random/mersenne_twister.h"
+
+
+class TestAlgorithm : public CppUnit::TestCase {
+
+	CPPUNIT_TEST_SUITE( TestAlgorithm );
+
+	CPPUNIT_TEST( testInitialTree );
+	CPPUNIT_TEST( testARG );
+	CPPUNIT_TEST( testPruning );
+	CPPUNIT_TEST( testMigration );
+	CPPUNIT_TEST( testSizeChange );
+	CPPUNIT_TEST( testGrowth );
+	CPPUNIT_TEST( testSplit );
+	CPPUNIT_TEST( testMerge );
+
+	CPPUNIT_TEST_SUITE_END();
+
+ private:
+  MersenneTwister *rg;
+
+  void testTree(Model &model, size_t replicates, 
+                double tmrca_mean, double tmrca_sd,
+                double tree_length_mean, double tree_length_sd) {
+    double tmrca[6] = { 0 }, tree_length[6] = { 0 };
+    
+    std::cout << "." << std::flush;
+
+    Forest forest = Forest(&model, this->rg);
+    for (size_t i = 0; i < replicates; ++i) {
+      // Check initial tree
+      forest.buildInitialTree();
+      tmrca[0] += forest.getTMRCA(true);
+      tree_length[0] += forest.getLocalTreeLength(true);
+
+      // Check after recombinations
+      if (model.recombination_rate() > 0) {
+        for (size_t j = 1; j <= 5; j++) {
+          while (forest.next_base() < j*5) {
+            forest.sampleNextGenealogy();
+          }
+          tmrca[j] += forest.getTMRCA(true);
+          tree_length[j] += forest.getLocalTreeLength(true);
+        }
+      }
+
+      // Clear Forest
+      forest.clear();
+    }
+
+    // Allow an relative error of 2.5%. It would be nice to calculate
+    // standard errors, but there's nothing in the std and I'm to lazy to
+    // implement very it myself...
+    for (int i = 0; i <= 5; ++i) {
+      if (i > 0 && tmrca[i] == 0 && tree_length[i] == 0) continue;
+      tmrca[i] /= replicates;
+      double SE = tmrca_sd / sqrt(replicates);
+      if (tmrca[i] < tmrca_mean - 4 * SE || tmrca_mean + 4 * SE < tmrca[i]) {
+        std::cout << std::endl 
+                  << "TMRCA outside expected range. Observed: " << tmrca[i] 
+                  << " Expected: " << tmrca_mean << std::endl;  
+        CPPUNIT_ASSERT( false );
+      }
+
+      tree_length[i] /= replicates; 
+      SE = tree_length_sd / sqrt(replicates);
+      if (tree_length[i] < tree_length_mean - 4 * SE || tree_length_mean + 4 * SE < tree_length[i]) {
+        std::cout << std::endl 
+                  << "Local Tree Length outside expected range. Observed: " << tree_length[i] 
+                  << " Expected: " << tree_length_mean << std::endl;  
+        CPPUNIT_ASSERT( false );
+      }
+    }
+  }
+
+ public:
+  void setUp() {
+    rg = new MersenneTwister(78361);
+  }
+
+  void tearDown() {
+    rg->clearFastFunc();
+    delete rg;
+  }
+
+  void testInitialTree() {
+    Model model = Model(5);
+    model.setRecombinationRate(0);
+    testTree(model, 10000, 0.8, 0.53, 2.08, 1.19); 
+
+    model = Model(10);
+    model.setRecombinationRate(0);
+    testTree(model, 10000, 0.9, 0.53, 2.83, 1.24); 
+
+    model = Model(20);
+    model.setRecombinationRate(0);
+    testTree(model, 10000, 0.95, 0.54, 3.55, 1.26); 
+  }
+
+  void testARG() {
+    Model model = Model(5);
+    model.setRecombinationRate(1, false, true);
+    testTree(model, 10000, 0.8, 0.53, 2.08, 1.19); 
+
+    model = Model(10);
+    model.setRecombinationRate(1, false, true);
+    testTree(model, 10000, 0.9, 0.53, 2.83, 1.24); 
+
+    model = Model(20);
+    model.setRecombinationRate(1, false, true);
+    testTree(model, 10000, 0.95, 0.54, 3.55, 1.26); 
+  }
+
+  void testPruning() {
+    Model model = Model(10);
+    model.setRecombinationRate(1, false, true);
+    model.set_window_length_seq(0);
+    testTree(model, 10000, 0.9, 0.53, 2.83, 1.24); 
+
+    model.set_window_length_seq(5);
+    testTree(model, 5000, 0.9, 0.53, 2.83, 1.24); 
+
+    model.set_window_length_seq(10);
+    testTree(model, 5000, 0.9, 0.53, 2.83, 1.24); 
+
+    model.disable_approximation();
+    model.set_window_length_rec(0);
+    testTree(model, 10000, 0.9, 0.53, 2.83, 1.24); 
+
+    model.set_window_length_rec(5);
+    testTree(model, 5000, 0.9, 0.53, 2.83, 1.24); 
+
+    model.set_window_length_rec(10);
+    testTree(model, 5000, 0.9, 0.53, 2.83, 1.24); 
+  }
+
+  void testMigration() {
+    Model model = Model(0);
+    model.setRecombinationRate(1, false, true);
+    model.set_population_number(2);
+    std::vector<size_t> sample_size;
+    sample_size.push_back(7);
+    sample_size.push_back(3);
+    model.addSampleSizes(0.0, sample_size);
+    model.addSymmetricMigration(0.0, 0.5, true, true);
+    model.finalize();
+    testTree(model, 2000, 2.76, 1.79, 7.82, 3.86); 
+
+    model = Model(0);
+    model.setRecombinationRate(1, false, true);
+    model.set_population_number(2);
+    model.addSampleSizes(0.0, sample_size);
+    model.addSymmetricMigration(0.0, 0.5, true, true);
+    model.addSymmetricMigration(0.3, 1.1, true, true);
+    model.set_window_length_seq(5);
+    model.finalize();
+    testTree(model, 2000, 2.24, 1.36, 6.73, 3.04); 
+
+    model = Model(0);
+    char *argv[] = { "scrm", "20", "10", "-I", "2", "10", "10", "-ma", "x", "5", "7", "x" };
+    model = Param(12, argv).parse();
+    testTree(model, 2000, 1.93, 1.09, 7.24, 2.56); 
+  }
+
+  void testSizeChange() {
+    Model model = Model(0);
+    char *argv[] = { "scrm", "10", "1", "-I", "3", "3", "3", "4", "0.5",                                                                                                                                                          "-eN", "0.1", "0.05", "-eN", "0.2", "0.5" };
+    model = Param(15, argv).parse();
+    model.setRecombinationRate(1, false, true);
+    testTree(model, 1000, 3.75, 2.68, 9.31, 5.67); 
+
+    model.set_window_length_seq(5);
+    testTree(model, 1000, 3.75, 2.68, 9.31, 5.67); 
+  }
+
+
+  void testGrowth() {
+    Model model = Model(10);
+    model.setRecombinationRate(1, false, true);
+    model.addGrowthRates(0.0, 5, true, true);
+    model.finalize();
+    testTree(model, 2500, 0.321, 0.089, 1.31, 0.28); 
+
+    char *argv0[] = { "scrm", "10", "30", "-G", "-0.5", "-eG", "0.75", "2" };
+    model = Param(8, argv0).parse();
+    model.setRecombinationRate(1, false, true);
+    model.set_window_length_seq(5);
+    testTree(model, 2500, 0.918, 0.38, 2.95, 1.00); 
+
+    char *argv[] = { "scrm", "4", "30", "-G", "-2.5", "-eN", "1", "0.25",
+                     "-eG", "2", "0.0", "-eN", "2.5", "0.25" };
+    model = Param(14, argv).parse();
+    model.setRecombinationRate(1, false, true);
+    testTree(model, 1000, 0.964, 0.34, 2.48, 0.97); 
+  }
+
+  void testSplit() {
+    Model model = Model(0);
+    model.setRecombinationRate(1, false, true);
+    model.set_population_number(2);
+    std::vector<size_t> sample_size;
+    sample_size.push_back(7);
+    sample_size.push_back(3);
+    model.addSampleSizes(0.0, sample_size);
+    model.addSymmetricMigration(0.0, 0.5, true, true);
+    model.addSingleMigrationEvent(1.0, 1, 0, 1.0, true); 
+    model.addSymmetricMigration(1.0, 0.0, true, true);
+    model.finalize();
+    testTree(model, 2500, 1.51, 0.55, 5.20, 1.44); 
+
+    char *argv[] = { "scrm", "15", "5", "-I", "3", "7", "3", "5", "0.5", "-ej", "0.5", "3", "2", "-ej", "1.0", "2", "1" };
+    model = Param(17, argv).parse();
+    model.setRecombinationRate(1, false, true);
+    testTree(model, 2500, 1.60, 0.54, 7.29, 1.48); 
+
+    model.set_window_length_seq(5);
+    testTree(model, 2500, 1.60, 0.54, 7.29, 1.48); 
+  }
+
+  void testMerge() {
+    Model model;
+    char *argv1[] = { "scrm", "20", "10", "-I", "2", "10", "10", "1.5", "-es", "1.6", "2", "0.5", "-eM", "2.0", "1" };
+    model = Param(15, argv1).parse();
+    model.setRecombinationRate(1, false, true);
+    testTree(model, 1000, 2.88, 2.26, 9.36, 4.87); 
+
+    model.set_window_length_seq(5);
+    testTree(model, 1000, 2.88, 2.26, 9.36, 4.87); 
+
+    char *argv2[] = { "scrm", "20", "10", "-I", "2", "10", "10", "1.5", "-es", "0.9", "1", "0.8", "-es", "1.6", "2", "0.5", "-eM", "2.0", "1" };
+    model = Param(19, argv2).parse();
+    model.setRecombinationRate(1, false, true);
+    testTree(model, 1000, 3.82, 3.32, 11.39, 7.09); 
+
+    model.set_window_length_seq(5);
+    testTree(model, 1000, 3.82, 3.32, 11.39, 7.09); 
+  }
+};
+
+//Uncomment this to activate the test
+CPPUNIT_TEST_SUITE_REGISTRATION( TestAlgorithm );
diff --git a/tests/cppunit/test_runner.cc b/tests/cppunit/test_runner.cc
new file mode 100644
index 0000000..c0fa2f0
--- /dev/null
+++ b/tests/cppunit/test_runner.cc
@@ -0,0 +1,35 @@
+/*
+ * Execute this program to run the test suite.
+ *
+ * Usually there's no need to change anything in here.
+ */
+#include <cppunit/TestResult.h>
+#include <cppunit/TestResultCollector.h>
+#include <cppunit/TestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/BriefTestProgressListener.h>
+#include <cppunit/CompilerOutputter.h>
+
+using namespace CppUnit;
+
+
+int main(void) {
+	TestResult controller;
+
+	TestResultCollector result;
+	controller.addListener(&result);
+
+	BriefTestProgressListener progress;
+	controller.addListener(&progress);
+
+	TestRunner runner;
+	runner.addTest( TestFactoryRegistry::getRegistry().makeTest() );
+	runner.run(controller);
+
+	CompilerOutputter outputter(&result, std::cerr);
+	outputter.write();
+
+	return result.wasSuccessful() ? 0 : 1;
+}
+
+// EOF
diff --git a/tests/cppunit/test_template.cc b/tests/cppunit/test_template.cc
new file mode 100644
index 0000000..e66732f
--- /dev/null
+++ b/tests/cppunit/test_template.cc
@@ -0,0 +1,36 @@
+/*
+ * A sample test case which can be used as a template.
+ */
+#include <cppunit/TestCase.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+
+class MyTest : public CppUnit::TestCase {
+
+	CPPUNIT_TEST_SUITE( MyTest );
+
+	CPPUNIT_TEST( testOneThing );
+	CPPUNIT_TEST( testAnother );
+	CPPUNIT_TEST( testException );
+
+	CPPUNIT_TEST_SUITE_END();
+
+	public:
+		void testOneThing() {
+			CPPUNIT_ASSERT( 1 == 1 );
+			CPPUNIT_ASSERT_MESSAGE("error message", 1 == 1 );
+		}
+		
+		void testAnother() {
+			CPPUNIT_ASSERT_EQUAL(1, 1);
+		}
+
+		void testException() {
+			CPPUNIT_ASSERT( 1 == 1 );
+		//	CPPUNIT_ASSERT_THROW(
+		//		throw std::exception(), std::exception );
+		}
+};
+
+//Uncomment this to activate the test
+//CPPUNIT_TEST_SUITE_REGISTRATION( MyTest );
diff --git a/tests/manualtests/LD/Untitled0.ipynb b/tests/manualtests/LD/Untitled0.ipynb
new file mode 100644
index 0000000..b27c9c4
--- /dev/null
+++ b/tests/manualtests/LD/Untitled0.ipynb
@@ -0,0 +1,2654 @@
+{
+ "metadata": {
+  "name": ""
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+  {
+   "cells": [
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "%pylab inline"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Populating the interactive namespace from numpy and matplotlib\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stderr",
+       "text": [
+        "WARNING: pylab import has clobbered these variables: ['pylab']\n",
+        "`%pylab --no-import-all` prevents importing * from pylab and numpy\n"
+       ]
+      }
+     ],
+     "prompt_number": 17
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "import pylab\n",
+      "import numpy as np"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 5
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "run ld_test.py"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 12\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 14\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 16\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 18\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 2\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 4\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 6\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 8\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 10\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 12\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 14\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 16\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 18\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 2\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 4\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 6\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 8\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 10\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 12\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 14\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 16\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 18\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 2\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 4\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 6\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 8\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 10\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 12\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 14\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 16\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 18\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 2\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 4\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 6\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 8\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 10\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 12\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 14\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 16\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 18\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 2\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 4\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 6\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 8\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 10\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 12\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 14\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 16\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 18\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 2\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 4\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 6\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 8\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 10\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 12\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 14\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 16\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 18\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 2\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 4\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 6\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 8\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 10\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 12\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 14\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 16\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 18\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 2\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 4\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 6\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 8\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 10\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 12\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 14\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 16\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 18\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 2\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 4\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 6\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 8\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 10\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 12\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 14\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 16\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 18\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 2\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 4\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 6\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 8\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 10\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 12\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 14\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 16\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 18\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 2\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 4\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 6\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 8\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 10\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 12\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 14\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 16\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 18\n"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "replicate: 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 100\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 200\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 300\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 400\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 500\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 600\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 700\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 800\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 900\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 100\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 200\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 300\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 400\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 500\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 600\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 700\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 800\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 900\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 100\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 200\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 300\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 400\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 500\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 600\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 700\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 800\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 900\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 100\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 200\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 300\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 400\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 500\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 600\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 700\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 800\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 900\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 100\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 200\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 300\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 400\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 500\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 600\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 700\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 800\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 900\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 100\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 200\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 300\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 400\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 500\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 600\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 700\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 800\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 900\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 100\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 200\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 300\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 400\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 500\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 600\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 700\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 800\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 900\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 100\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 200\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 300\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 400\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 500\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 600\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 700\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 800\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 900\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 100\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 200\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 300\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 400\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 500\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 600\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 700\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 800\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 900\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 100\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 200\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 300\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 400\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 500\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 600\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 700\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 800\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 900\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 100\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 200\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 300\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 400\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 500\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 600\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 700\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 800\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 900\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 0\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 100\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 200\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 300\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 400\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 500\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 600\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 700\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 800\n",
+        "replicate:"
+       ]
+      },
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        " 900\n"
+       ]
+      }
+     ],
+     "prompt_number": 10
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "print _msac[3]\n",
+      "print _scrmace5[3]\n",
+      "print _scrmac5e4[3]\n",
+      "print _scrmace4[3]\n",
+      "print _scrmace3[3]\n",
+      "print _scrmac[3]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "9921.62\n",
+        "791.41\n",
+        "516.07\n",
+        "333.25\n",
+        "293.9\n",
+        "289.35\n"
+       ]
+      }
+     ],
+     "prompt_number": 11
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "all_data = [ _msac, _scrmace5, _scrmac5e4, _scrmace4, _scrmace3,  _scrmac]\n",
+      "x = [data_i[0][-1] for data_i in all_data ] # tmrca\n",
+      "#x = [data_i[1][-1] for data_i in all_data ] # tmrc\n",
+      "#x = [data_i[2][-1] for data_i in all_data ] # clade\n",
+      "y = [data_i[3] for data_i in all_data]\n",
+      "#pylab.plot(x[1:4],log(y[1:4]))\n",
+      "#pylab.axis([min(x), max(x), log(min(y)), log(max(y))])\n",
+      "markers = [\"v\", \"o\", \"*\", \">\", \"<\", \"s\"]\n",
+      "pylab.title(\"Time vs accuracy\")\n",
+      "pylab.ylabel(\"log(Time)\")\n",
+      "pylab.xlabel(\"rho tmrca at delta = 10000\")\n",
+      "timelegend = ['ms', 'exact window = 100000', 'exact window = 50000', 'exact window = 10000', 'exact window = 1000', 'exact window = 0']\n",
+      "myl = []\n",
+      "for i, xi in enumerate(x):\n",
+      "    myl.append(pylab.plot( x[i], log(y[i]), markers[i]))\n",
+      "legend([ x[0] for x in myl],  timelegend, loc=2)\n",
+      "pylab.savefig(\"tmrca_timeVSacc.pdf\")"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAYwAAAEZCAYAAACEkhK6AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XdUVOfWB+DfICgi3Yp0USNNpCiChTEWDDF2vYIRFFsa\nGDVGTewxlliu7Wo0KmjUmIjmBhW7ErEgarASFbCBBUV6F9jfH36cyzgzMMgMDGQ/a81anjLv2YPn\nzJ5T3neLiIjAGGOMVUKjtgNgjDFWN3DCYIwxphBOGIwxxhTCCYMxxphCOGEwxhhTCCcMxhhjCuGE\nwdSKg4MDzp49W9thMMZk0KztANg/i66uLkQiEQAgNzcX2traaNCgAQBgy5YtuHXrVm2GxxirgIg7\n7rHaYm1tjW3btuH999+v7VDqpOLiYmhq8m8+VnP4khRTK1ZWVjh9+jQAYMGCBRgxYgTGjBkDfX19\ndOzYEfHx8 [...]
+       "text": [
+        "<matplotlib.figure.Figure at 0x10ffb2b90>"
+       ]
+      }
+     ],
+     "prompt_number": 84
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "    _use_paramD.exact_window_length = 1e3\n",
+      "    _scrmace3D = n_rep ( _use_paramD, scrm = True, prefix = \"Divergencescrme3out\")        \n",
+      "\n",
+      "    _use_paramD.exact_window_length = 1e4\n",
+      "    _scrmace4D = n_rep ( _use_paramD, scrm = True, prefix = \"Divergencescrme4out\")        \n",
+      "\n",
+      "    _use_paramD.exact_window_length = 5e4\n",
+      "    _scrmac5e4D = n_rep ( _use_paramD, scrm = True, prefix = \"Divergencescrm5e4out\")        \n",
+      "\n",
+      "    _use_paramD.exact_window_length = 1e5\n",
+      "    _scrmace5D = n_rep ( _use_paramD, scrm = True, prefix = \"Divergencescrme5out\")        \n"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": "*"
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "    # extract TMRCA from results and plot\n",
+      "    _rho = [ _msacD[0], _scrmace5D[0], _scrmace3D[0], _scrmacD[0] ]\n",
+      "    myfigures ( _use_param.small_delta, _rho, \"Divergencetmrca\", _legend, _colors)\n",
+      "    \n",
+      "    # extract TMRC\n",
+      "    _rho = [ _msacD[1], _scrmace5D[1], _scrmace3D[1], _scrmacD[1] ]\n",
+      "    myfigures ( _use_param.big_delta, _rho, \"Divergencetmrc\", _legend, _colors)\n",
+      "\n",
+      "    # extract clade\n",
+      "    _rho = [ _msacD[2], _scrmace5D[2], _scrmace3D[2], _scrmacD[2] ]\n",
+      "    myfigures ( _use_param.big_delta, _rho, \"Divergenceclade\", _legend, _colors)\n"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 68
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "all_dataD = [ _msacD, _scrmace5D, _scrmac5e4D, _scrmace4D, _scrmace3D,  _scrmacD]\n",
+      "#x = [data_i[0][-1] for data_i in all_dataD ] #tmrca\n",
+      "#x = [data_i[1][-1] for data_i in all_dataD ]  #tmrc\n",
+      "x = [data_i[2][-1] for data_i in all_dataD ]  #clade\n",
+      "y = [data_i[3] for data_i in all_dataD]\n",
+      "#pylab.plot(x[1:4],log(y[1:4]))\n",
+      "#pylab.axis([min(x), max(x), log(min(y)), log(max(y))])\n",
+      "markers = [\"v\", \"o\", \"*\", \">\", \"<\", \"s\"]\n",
+      "pylab.title(\"Time vs accuracy\")\n",
+      "pylab.ylabel(\"log(Time)\")\n",
+      "pylab.xlabel(\"rho clade at delta = 10000\")\n",
+      "timelegend = ['ms', 'exact window = 100000', 'exact window = 50000', 'exact window = 10000', 'exact window = 1000', 'exact window = 0']\n",
+      "myl = []\n",
+      "for i, xi in enumerate(x):\n",
+      "    myl.append(pylab.plot( x[i], log(y[i]), markers[i]))\n",
+      "legend([ x[0] for x in myl],  timelegend, loc=2)\n",
+      "pylab.savefig(\"clade_timeVSaccDivergence.pdf\")"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAYgAAAEZCAYAAACNebLAAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XdYFNf+P/D3YgGVbkFUmqBXuij2AtiImtgxgord3Jtv\n1Ghi1PyuJSYaTTRF07zXHjW5sSRRVOwoiT12jQYJotgi0gVE3c/vDx4mruyKyDbw/XqefR52zsyZ\nc2CYz86c2fNRiYiAiIjoCRambgAREZknBggiItKKAYKIiLRigCAiIq0YIIiISCsGCCIi0ooBgkzK\nz88PBw4cMHUziEiLyqZuAFVs1tbWUKlUAIB79+7BysoKlSpVAgD85z//wblz50zZPCJ6ChW/KEfG\n4uHhgWXLlqFTp06mbkq59PDhQ1SuzM90ZDy8xUQm5e7ujr179wIAZs2ahYiICAwdOhS2trYICAhA\nQkICPvzwQ [...]
+       "text": [
+        "<matplotlib.figure.Figure at 0x14cf6df50>"
+       ]
+      }
+     ],
+     "prompt_number": 80
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "print _msacD[3]\n",
+      "print _scrmace5D[3]\n",
+      "print _scrmac5e4D[3]\n",
+      "print _scrmace4D[3]\n",
+      "print _scrmace3D[3]\n",
+      "print _scrmacD[3]\n"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "49288.76\n",
+        "2951.88\n",
+        "1614.58\n",
+        "774.81\n",
+        "626.73\n",
+        "590.86\n"
+       ]
+      }
+     ],
+     "prompt_number": 81
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "%store all_data > alldata.txt"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Writing 'all_data' (list) to file 'alldata.txt'.\n"
+       ]
+      }
+     ],
+     "prompt_number": 82
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "%store all_dataD > alldataD.txt"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Writing 'all_dataD' (list) to file 'alldataD.txt'.\n"
+       ]
+      }
+     ],
+     "prompt_number": 83
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "whos"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Variable                 Type        Data/Info\n",
+        "----------------------------------------------\n",
+        "all_data                 list        n=6\n",
+        "all_dataD                list        n=6\n",
+        "cal_ac_TMRC_star         function    <function cal_ac_TMRC_star at 0x10663c578>\n",
+        "cal_ac_TMRC_star_2       function    <function cal_ac_TMRC_star_2 at 0x10663c6e0>\n",
+        "cal_ac_clade             function    <function cal_ac_clade at 0x10663c230>\n",
+        "cal_ac_clade_2           function    <function cal_ac_clade_2 at 0x10663c500>\n",
+        "data_i                   tuple       n=4\n",
+        "i                        int         5\n",
+        "m                        str         >\n",
+        "markers                  list        n=6\n",
+        "myfigures                function    <function myfigures at 0x10663c1b8>\n",
+        "myl                      list        n=6\n",
+        "n_rep                    function    <function n_rep at 0x10663c488>\n",
+        "os                       module      <module 'os' from '/Users<...>ts/lib/python2.7/os.pyc'>\n",
+        "parameter                classobj    __main__.parameter\n",
+        "pl                       module      <module 'pylab' from '/Us<...>site-packages/pylab.pyc'>\n",
+        "process_ms_scrm_output   function    <function process_ms_scrm_output at 0x106173320>\n",
+        "run_program              function    <function run_program at 0x105d3d050>\n",
+        "timelegend               list        n=6\n",
+        "x                        list        n=1\n",
+        "xi                       float       0.628154388567\n",
+        "y                        list        n=6\n"
+       ]
+      }
+     ],
+     "prompt_number": 63
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "def myfigures ( delta, rho, prefix, legend, colors):\n",
+      "    # rho is a list of MS, SCRM (pruned) and SCRM (full pruning) results\n",
+      "    # results is a list of autocorrelations, one for each delta\n",
+      "    #print legend\n",
+      "    l = [] \n",
+      "    fig,(ax1)=pylab.subplots(1,1)\n",
+      "    for i in range ( len (rho) ):\n",
+      "        #y_err = [np.std(yi)*1.96/np.sqrt(len(yi)) for yi in rho[i]]\n",
+      "        tmp1 = ax1.plot( delta, rho[i] , color = colors[i])\n",
+      "        l.append ( tmp1 )\n",
+      "    pylab.xlim( [np.min(delta), np.max(delta)] )\n",
+      "    pylab.title( prefix )\n",
+      "    pylab.xlabel(r'Distance between two sites $\\delta$')\n",
+      "    pylab.ylabel(r'Autocorrelation $\\rho$')\n",
+      "    pylab.legend ([ x[0] for x in l], legend, loc = 1)\n",
+      "    pylab.savefig( prefix+\".pdf\" )\n",
+      "    pylab.close()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 64
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "    _rho = [ _msac[0], _scrmace5[0], _scrmace3[0], _scrmac[0] ]\n",
+      "    myfigures ( _use_param.small_delta, _rho, \"tmrca\", _legend, _colors)\n",
+      "    \n",
+      "    # extract TMRC\n",
+      "    _rho = [ _msac[1], _scrmace5[1], _scrmace3[1], _scrmac[1] ]\n",
+      "    myfigures ( _use_param.big_delta, _rho, \"tmrc\", _legend, _colors)\n",
+      "\n",
+      "    # extract clade\n",
+      "    _rho = [ _msac[2], _scrmace5[2], _scrmace3[2], _scrmac[2] ]\n",
+      "    myfigures ( _use_param.big_delta, _rho, \"clade\", _legend, _colors)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 65
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "    \n",
+      "    # extract TMRCA from results and plot\n",
+      "    _rho = [ _msacD[0], _scrmace5D[0], _scrmace3D[0], _scrmacD[0] ]\n",
+      "    myfigures ( _use_param.small_delta, _rho, \"Divergencetmrca\", _legend, _colors)\n",
+      "    \n",
+      "    # extract TMRC\n",
+      "    _rho = [ _msacD[1], _scrmace5D[1], _scrmace3D[1], _scrmacD[1] ]\n",
+      "    myfigures ( _use_param.big_delta, _rho, \"Divergencetmrc\", _legend, _colors)\n",
+      "\n",
+      "    # extract clade\n",
+      "    _rho = [ _msacD[2], _scrmace5D[2], _scrmace3D[2], _scrmacD[2] ]\n",
+      "    myfigures ( _use_param.big_delta, _rho, \"Divergenceclade\", _legend, _colors)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 66
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 25,
+       "text": [
+        "<Container object of 3 artists>"
+       ]
+      },
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAXsAAAEACAYAAABS29YJAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGf1JREFUeJzt3X9wVNXdx/HPxo2VH1YLCMhunEASkoVgCE20trUuWowy\nEgWcNthRGyPN0MFKp3XotH8YZiohtc5ozbST6aAo1ZBOyxi1YbWRWdsOkChR6hjUyCR9lkV5GiEi\ngiYs5/kjDwvLTTa/dhNy7/s1s5O9e0/uPefL8rmbc+/uuowxRgAAW0sZ6w4AAJKPsAcAByDsAcAB\nCHsAcADCHgAcgLAHAAcYMOzvu+8+zZgxQwsWLOhz/XvvvafrrrtOl1xyiR577LGEdxAAMHIDhn1p\naakCgUC/66dOnaonn3xSP//5zxPaMQBA4gwY9tdff72+9rWv9bv+iiuuUEFBgVJTUxPaMQBA4jBn\nDwAOQNgDg [...]
+       "text": [
+        "<matplotlib.figure.Figure at 0x1067ab150>"
+       ]
+      }
+     ],
+     "prompt_number": 25
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 28,
+       "text": [
+        "10"
+       ]
+      }
+     ],
+     "prompt_number": 28
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Help on function mean in module numpy.core.fromnumeric:\n",
+        "\n",
+        "mean(a, axis=None, dtype=None, out=None, keepdims=False)\n",
+        "    Compute the arithmetic mean along the specified axis.\n",
+        "    \n",
+        "    Returns the average of the array elements.  The average is taken over\n",
+        "    the flattened array by default, otherwise over the specified axis.\n",
+        "    `float64` intermediate and return values are used for integer inputs.\n",
+        "    \n",
+        "    Parameters\n",
+        "    ----------\n",
+        "    a : array_like\n",
+        "        Array containing numbers whose mean is desired. If `a` is not an\n",
+        "        array, a conversion is attempted.\n",
+        "    axis : int, optional\n",
+        "        Axis along which the means are computed. The default is to compute\n",
+        "        the mean of the flattened array.\n",
+        "    dtype : data-type, optional\n",
+        "        Type to use in computing the mean.  For integer inputs, the default\n",
+        "        is `float64`; for floating point inputs, it is the same as the\n",
+        "        input dtype.\n",
+        "    out : ndarray, optional\n",
+        "        Alternate output array in which to place the result.  The default\n",
+        "        is ``None``; if provided, it must have the same shape as the\n",
+        "        expected output, but the type will be cast if necessary.\n",
+        "        See `doc.ufuncs` for details.\n",
+        "    keepdims : bool, optional\n",
+        "        If this is set to True, the axes which are reduced are left\n",
+        "        in the result as dimensions with size one. With this option,\n",
+        "        the result will broadcast correctly against the original `arr`.\n",
+        "    \n",
+        "    Returns\n",
+        "    -------\n",
+        "    m : ndarray, see dtype parameter above\n",
+        "        If `out=None`, returns a new array containing the mean values,\n",
+        "        otherwise a reference to the output array is returned.\n",
+        "    \n",
+        "    See Also\n",
+        "    --------\n",
+        "    average : Weighted average\n",
+        "    std, var, nanmean, nanstd, nanvar\n",
+        "    \n",
+        "    Notes\n",
+        "    -----\n",
+        "    The arithmetic mean is the sum of the elements along the axis divided\n",
+        "    by the number of elements.\n",
+        "    \n",
+        "    Note that for floating-point input, the mean is computed using the\n",
+        "    same precision the input has.  Depending on the input data, this can\n",
+        "    cause the results to be inaccurate, especially for `float32` (see\n",
+        "    example below).  Specifying a higher-precision accumulator using the\n",
+        "    `dtype` keyword can alleviate this issue.\n",
+        "    \n",
+        "    Examples\n",
+        "    --------\n",
+        "    >>> a = np.array([[1, 2], [3, 4]])\n",
+        "    >>> np.mean(a)\n",
+        "    2.5\n",
+        "    >>> np.mean(a, axis=0)\n",
+        "    array([ 2.,  3.])\n",
+        "    >>> np.mean(a, axis=1)\n",
+        "    array([ 1.5,  3.5])\n",
+        "    \n",
+        "    In single precision, `mean` can be inaccurate:\n",
+        "    \n",
+        "    >>> a = np.zeros((2, 512*512), dtype=np.float32)\n",
+        "    >>> a[0, :] = 1.0\n",
+        "    >>> a[1, :] = 0.1\n",
+        "    >>> np.mean(a)\n",
+        "    0.546875\n",
+        "    \n",
+        "    Computing the mean in float64 is more accurate:\n",
+        "    \n",
+        "    >>> np.mean(a, dtype=np.float64)\n",
+        "    0.55000000074505806\n",
+        "\n"
+       ]
+      }
+     ],
+     "prompt_number": 14
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 565,
+       "text": [
+        "[<matplotlib.lines.Line2D at 0x10889e3d0>]"
+       ]
+      },
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAX4AAAEACAYAAAC08h1NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XtYlHX+//HnCHhYMy3XNIGCEDk7jKJsVop5IE0tzDbU\nr2lS2cHN2nK1tjaqTaVsV41211w7uLXob3dtrVQyM9I8RCYaAZm6YIDlGUsxEbx/f3w2VlIR5XAP\nzOtxXXNdDjPMvAa83vPmM5/7fTssy7IQERGP0czuACIi0rBU+EVEPIwKv4iIh1HhFxHxMCr8IiIe\nRoVfRMTDnLPwT5gwgY4dOxIVFXXW+zzwwAMEBwfjdDrJysqq/Hp6ejqhoaEEBweTkpJSN4lFRKRW\nzln477jjDtLT0896+/Lly9mxYwfbt2/n5Zdf5t577wWgoqKCSZMmkZ6eTm5uLmlpaeTl5dVdchER\nuSDnLPzXX [...]
+       "text": [
+        "<matplotlib.figure.Figure at 0x10887d450>"
+       ]
+      }
+     ],
+     "prompt_number": 565
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 484
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 489,
+       "text": [
+        "array([   20.,   240.,   460.,   680.,   900.,  1120.,  1340.,  1560.,\n",
+        "        1780.,  2000.])"
+       ]
+      }
+     ],
+     "prompt_number": 489
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 548,
+       "text": [
+        "[[1, 2, 3], [4, 5, 6], [7, 8, 9]]"
+       ]
+      }
+     ],
+     "prompt_number": 548
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 549,
+       "text": [
+        "[[1, 4, 7], [2, 5, 8], [3, 6, 9]]"
+       ]
+      }
+     ],
+     "prompt_number": 549
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "pylab.hist(msac[0])\n",
+      "pylab.title(\"ETMRCA\")\n",
+      "pylab.figure()\n",
+      "pylab.hist(msac[1])\n",
+      "pylab.title(\"ETMRC\")\n",
+      "pylab.figure()\n",
+      "pylab.hist(msac[2])\n",
+      "pylab.title(\"Eclade\")\n"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "pyout",
+       "prompt_number": 4,
+       "text": [
+        "<matplotlib.text.Text at 0x2930950>"
+       ]
+      },
+      {
+       "output_type": "display_data",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAYAAAAEHCAYAAACncpHfAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAHfFJREFUeJzt3W9QVOf99/H3MexMYgU1k7A4u05xCg6uYiDxtzBt7Y1F\n/ENGJGNCio1g1E4GpxWb3NNJHiSFtqP0j/MbY0LrA5IBMg3apAGbRIYkdbUxDSQKpg2Zuk0xYZeF\n1hoqJjgonPuBd06DIiDg7sbzec3szHL+Xd9zAfvZPXudcwzTNE1ERMR2pkW6ABERiQwFgIiITSkA\nRERsSgEgImJTCgAREZtSAIiI2JQCQG4IiYmJTJ8+ndjYWOtx0003Wc9vueUWYmJirJ9TU1MBmDZt\nGk6nk8HBQWtbFy5cID4+nmnT/vvvkZWVxS233EJsbCy33XYba9euJRAIWPMHBgYoKytj/vz5zJgx\ng3nz5rF58 [...]
+      },
+      {
+       "output_type": "display_data",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAZAAAAEHCAYAAACA3BA3AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGrlJREFUeJzt3X9sleX9//HXwR4nDoqg9nSeg6u2p5YD5beFaEzqpzuI\nTSidYJUttijLEpha3eJk2R8rX6Otbm46tSExHZ9av7EF3NqO4Rmy2Dg3PUQw6igbR3aq7elpZyyV\nMiqFen3/IL2/IL8vek5reT6Sk/Rcva/7er8pnFfP/ePgMsYYAQBwnsaNdAEAgK8nAgQAYIUAAQBY\nIUAAAFYIEACAFQIEAGCFAMFFJSMjQ5dffrkmTpzoPC655BLn6/HjxyslJcV5npubK0kaN26cPB6P\nBgcHnX0dOXJEaWlpGjfu//8zys/P1/jx4zVx4kRdddVVWrp0qTo6OpzvDwwMqKKiQtnZ2ZowYYKu\nu+46rVq1S [...]
+      },
+      {
+       "output_type": "display_data",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAYAAAAEICAYAAABWJCMKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3X9Qm/dhx/G3XOlucWL8Iw4ikdyoMfKIbEJIPJlsTU8O\nFSZ05kid40J6MaRN2sGtob3tVm/5Izi3GbLlrrWT0q053GlsKXba1ZAuoTSZydb8kDucxDvLCXKG\nEyRAFxsT45gG/3j2B/ZT4zggMEjYz+d199zJj56v9HkwPJ9Hj55HshmGYSAiIpYzL90BREQkPVQA\nIiIWpQIQEbEoFYCIiEWpAERELEoFICJiUSoAkfN4PB5efvnlaY0NBAI0NTXNcCKR2aMCkCuWx+Nh\n/vz5LFiwwJweeeSRCcfYbDZsNtu0nu9Sxoqkgz3dAURmi81m45e//CV33XVXuqOIzEl6BSCW9Mwz\nz+Dz+cjIy [...]
+      }
+     ],
+     "prompt_number": 4
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "pylab.hist(scrmac[0])\n",
+      "pylab.title(\"ETMRCA\")\n",
+      "pylab.figure()\n",
+      "pylab.hist(scrmac[1])\n",
+      "pylab.title(\"ETMRC\")\n",
+      "pylab.figure()\n",
+      "pylab.hist(scrmac[2])\n",
+      "pylab.title(\"Eclade\")\n"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "pyout",
+       "prompt_number": 5,
+       "text": [
+        "<matplotlib.text.Text at 0x27abe90>"
+       ]
+      },
+      {
+       "output_type": "display_data",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAYAAAAEHCAYAAACncpHfAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAHSBJREFUeJzt3X9MXfXh//HnqdxEu0J/RLk095rRyO3obamgzYVs63Ib\nSmsxUkwVxVmorfsamq00mizzDx1km7BlZqlVtv6BBjCTdjqhU0tQ06uzm6At6CYmvXNUuZcLW22x\nVGloy/n+0Xk+0h/8uMClcF6P5Cb3nl/v95s33Nfl3Pf7HMM0TRMREbGdOdNdARERmR4KABERm1IA\niIjYlAJARMSmFAAiIjalABARsSkFgMwKycnJzJ07l/j4eOtxzTXXWM+vu+464uLirNdpaWkAzJkz\nB6fTyfnz561jnT17lsTERObM+b8/D7/fz3XXXUd8fDzXX389GzduJBQKWesHBwcpKytj6dKlzJs3\njyVLlrBt2 [...]
+      },
+      {
+       "output_type": "display_data",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAZMAAAEHCAYAAABr66s0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGvRJREFUeJzt3X1wVOXd//HPYvYnKCSKmk3dpY0kG8KGIIgERsdp2riI\nTAlUNIodE5ROZ6BqtL2t/FcYK0T7pFVz4zipE2PHhNo2iRZWhraZaivLCI4PhJlsbbDJZpN2gIQg\nCSHhuv/AnJ9REiBXyG7q+zVzZjjXnuuc77nG3Y/nMS5jjBEAABYmxbsAAMDER5gAAKwRJgAAa4QJ\nAMAaYQIAsEaYAACsESb4UklPT9cll1yiadOmOdNFF13k/HvKlClKSkpy5nNzcyVJkyZNksfj0cDA\ngLOukydPKjU1VZMm/f+vUX5+vqZMmaJp06bpyiuv1IoVK9Ta2up83tfXp40bNyorK0tTp07VNddc\no7Vr1+rjj [...]
+      },
+      {
+       "output_type": "display_data",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAYAAAAEICAYAAABWJCMKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3X9w2/V9x/GnwLqDlDg/CJZBSlGJ5RklJjGkSrornagr\nx3EXn2kyH6aHZSiUORuY3nZrNv6o022x2bhrEzL3VmY6zT3qBGhtw1LjwghbCyjU4ccWBaxwTmPJ\nskbimBji4vz47o8k3yXBsRU7lpJ8X4+7753y0fej7/vjU76vr74/bYZhGIiIiOVckekCREQkMxQA\nIiIWpQAQEbEoBYCIiEUpAERELEoBICJiUQoAkdO43W5efvnlSfX1+/00Nzdf4IpEpo8CQC5bbreb\nGTNmMHPmTHN6+OGHx+1js9mw2WyTWt5U+opkQlamCxCZLjabjRdeeIGvfvWrmS5F5KKkXwBiSU8+\n+SRer5fs7 [...]
+      }
+     ],
+     "prompt_number": 5
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "print mean(msac[0])-1.96*std(msac[0])/sqrt(10000), mean(msac[0])+1.96*std(msac[0])/sqrt(10000)\n",
+      "print mean(scrmac[0])-1.96*std(scrmac[0])/sqrt(10000), mean(scrmac[0])+1.96*std(scrmac[0])/sqrt(10000)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "0.93712381457 0.95245748657\n",
+        "0.92074541866 0.933899873302\n"
+       ]
+      }
+     ],
+     "prompt_number": 11
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "print mean(msac[1])-1.96*std(msac[1])/sqrt(10000), mean(msac[1])+1.96*std(msac[1])/sqrt(10000)\n",
+      "print mean(scrmac[1])-1.96*std(scrmac[1])/sqrt(10000), mean(scrmac[1])+1.96*std(scrmac[1])/sqrt(10000)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "1.29673001317e-05 1.40559319259e-05\n",
+        "1.28237041738e-05 1.38697309843e-05\n"
+       ]
+      }
+     ],
+     "prompt_number": 12
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "print mean(msac[2])-1.96*std(msac[2])/sqrt(10000), mean(msac[2])+1.96*std(msac[2])/sqrt(10000)\n",
+      "print mean(scrmac[2])-1.96*std(scrmac[2])/sqrt(10000), mean(scrmac[2])+1.96*std(scrmac[2])/sqrt(10000)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "0.920394154512 0.925992389933\n",
+        "0.970447540803 0.972946641419\n"
+       ]
+      }
+     ],
+     "prompt_number": 13
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": "*"
+    }
+   ],
+   "metadata": {}
+  }
+ ]
+}
\ No newline at end of file
diff --git a/tests/manualtests/LD/alldata.txt b/tests/manualtests/LD/alldata.txt
new file mode 100644
index 0000000..c4f3c26
--- /dev/null
+++ b/tests/manualtests/LD/alldata.txt
@@ -0,0 +1,204 @@
+[([1.0,
+   0.9240769302102003,
+   0.8757098371445482,
+   0.8426641947332318,
+   0.8188641521404078,
+   0.8010672127838415,
+   0.787299029660886,
+   0.776490228388853,
+   0.7678594540331249,
+   0.7607603986798227,
+   0.7548566039602547],
+  [1.0,
+   0.8716927800110638,
+   0.8034500434340082,
+   0.7585832951205806,
+   0.726401912704469,
+   0.7015579298724737,
+   0.6819411702329081,
+   0.6659944981657913,
+   0.6527355675591086,
+   0.6418086482965965,
+   0.6322533334677511],
+  [1.0,
+   0.7592380373373374,
+   0.6293345986973943,
+   0.5446143223671012,
+   0.48372031736947796,
+   0.4372222589949751,
+   0.40072080040241487,
+   0.37094698006042265,
+   0.3461728942540323,
+   0.3253830201816339,
+   0.3074357014141414],
+  9921.620000000012),
+ ([1.0,
+   0.9241025407947429,
+   0.8756404155238366,
+   0.8424453441792012,
+   0.8186088779068044,
+   0.8008529140365453,
+   0.7872377992499482,
+   0.7765330957024357,
+   0.7679291999831659,
+   0.7608370446837561,
+   0.7549103190520678],
+  [1.0,
+   0.8716401633445773,
+   0.8032052578633975,
+   0.7583309811257891,
+   0.7260257982188344,
+   0.7010562546896054,
+   0.6814822728114848,
+   0.6655864135739897,
+   0.6521303054467933,
+   0.6406018894393354,
+   0.6309295004437249],
+  [1.0,
+   0.7605388642642636,
+   0.6309636011022047,
+   0.5460953688064193,
+   0.4849691532128511,
+   0.4384254600000001,
+   0.40186851639839094,
+   0.3721856531722057,
+   0.347398519254032,
+   0.32650071927346125,
+   0.30851767767676763],
+  791.4099999999947),
+ ([1.0,
+   0.9240598345704764,
+   0.8757058321552814,
+   0.8425890496030712,
+   0.8188402808060693,
+   0.8010751273623608,
+   0.7873901426892016,
+   0.7765553614710498,
+   0.7679187369524735,
+   0.7608560063158574,
+   0.755006680181903],
+  [1.0,
+   0.8717046656474716,
+   0.8028496979466887,
+   0.7578753266719361,
+   0.7252625496843697,
+   0.6999820169704511,
+   0.6799118546832622,
+   0.6635705735586448,
+   0.650169106409669,
+   0.6387325181185204,
+   0.6288139101299863],
+  [1.0,
+   0.758911616916916,
+   0.6283457637274549,
+   0.5427955515546629,
+   0.4812509196787151,
+   0.4345965845226133,
+   0.3975272146881283,
+   0.3674825642497488,
+   0.34253033407258,
+   0.3217675015136227,
+   0.3038133787878789],
+  516.0699999999987),
+ ([1.0,
+   0.9240929035701031,
+   0.8757151146422743,
+   0.842606657902687,
+   0.8187392218759064,
+   0.8008970009230977,
+   0.7871948681926169,
+   0.7763897422535809,
+   0.767642019793229,
+   0.7605357188705497,
+   0.7546346265233809],
+  [1.0,
+   0.8728529367800608,
+   0.8042561196426212,
+   0.7588759487202804,
+   0.7259825179161017,
+   0.7005705320034072,
+   0.6806181146507488,
+   0.6646204712907169,
+   0.6508995809125945,
+   0.6397106239703739,
+   0.6302775000161587],
+  [1.0,
+   0.7597413217217212,
+   0.629908915330661,
+   0.5451010479438314,
+   0.48425893253012026,
+   0.438191604824121,
+   0.401807992957747,
+   0.37229735276938575,
+   0.34763352852822565,
+   0.32668232522704327,
+   0.30875085656565615],
+  333.249999999999),
+ ([1.0,
+   0.9240066953113502,
+   0.8740945770788368,
+   0.8384298348492837,
+   0.8122179775254499,
+   0.792459327827468,
+   0.7772392974305642,
+   0.7653870314595379,
+   0.7560135033886741,
+   0.748501281137374,
+   0.7424612586316129],
+  [1.0,
+   0.8704691229657302,
+   0.8003988431395836,
+   0.7547663484002998,
+   0.722303495638503,
+   0.6972536620309325,
+   0.6773280308366157,
+   0.6611874768498547,
+   0.6476137226786364,
+   0.6358205429304308,
+   0.6259892237194667],
+  [1.0,
+   0.7605535369369367,
+   0.6310537234468943,
+   0.546327414643932,
+   0.4854574530120479,
+   0.4392121634170857,
+   0.40257524175050285,
+   0.37259201621349464,
+   0.34786283356854864,
+   0.32702335993945475,
+   0.3091092332323231],
+  293.90000000000106),
+ ([1.0,
+   0.9217833525311909,
+   0.8698627263228774,
+   0.8336951322537327,
+   0.8075937067615357,
+   0.7881828026912965,
+   0.7734656970384525,
+   0.7621047698023948,
+   0.7532529573965395,
+   0.7462338921201853,
+   0.7405495314323782],
+  [1.0,
+   0.8724306093611603,
+   0.8032215461650588,
+   0.7578704388078444,
+   0.7249731992456103,
+   0.6997722844014461,
+   0.6797703093805324,
+   0.6634156760876493,
+   0.6496226666936192,
+   0.6379626019569281,
+   0.6281543885665657],
+  [1.0,
+   0.7616342341341331,
+   0.6322261656312621,
+   0.547942110431294,
+   0.48730637620481887,
+   0.44108518261306523,
+   0.40446807605633783,
+   0.37472568539778445,
+   0.349974978225807,
+   0.329176322704339,
+   0.31141886424242365],
+  289.3500000000003)]
diff --git a/tests/manualtests/LD/cluster/1Pop20sample.par b/tests/manualtests/LD/cluster/1Pop20sample.par
new file mode 100644
index 0000000..bf55b3c
--- /dev/null
+++ b/tests/manualtests/LD/cluster/1Pop20sample.par
@@ -0,0 +1,18 @@
+//Number of population samples (demes) 
+1 
+//Population effective sizes (number of genes) 
+20000 
+//Sample sizes 
+20
+//Growth rates : negative growth implies population expansion 
+0 
+//Number of migration matrices : 0 implies no migration between demes 
+0 
+//historical event: time, source, sink, migrants, new size, new growth rate, migr. matrix 
+0 historical event 
+//Number of independent loci [chromosome] 
+1 0 
+//Per chromosome: Number of linkage blocks 
+1 
+//per Block: data type, num loci, rec. rate and mut rate + optional parameters 
+DNA 10000001 0.00000001 0.00000002 
diff --git a/tests/manualtests/LD/cluster/1Pop6sample.par b/tests/manualtests/LD/cluster/1Pop6sample.par
new file mode 100644
index 0000000..d66bba2
--- /dev/null
+++ b/tests/manualtests/LD/cluster/1Pop6sample.par
@@ -0,0 +1,18 @@
+//Number of population samples (demes) 
+1 
+//Population effective sizes (number of genes) 
+20000 
+//Sample sizes 
+6
+//Growth rates : negative growth implies population expansion 
+0 
+//Number of migration matrices : 0 implies no migration between demes 
+0 
+//historical event: time, source, sink, migrants, new size, new growth rate, migr. matrix 
+0 historical event 
+//Number of independent loci [chromosome] 
+1 0 
+//Per chromosome: Number of linkage blocks 
+1 
+//per Block: data type, num loci, rec. rate and mut rate + optional parameters 
+DNA 10000001 0.00000001 0.00000002 
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizefastsimcoal_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizefastsimcoal_Processed
new file mode 100644
index 0000000..a9c5548
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizefastsimcoal_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7335089678015986, 0.5567575548433568, 0.4336954406151809, 0.34490014901825466, 0.27913439836051934, 0.22921595344763837, 0.1904893977091106, 0.16003964162711623, 0.13595500163358093, 0.11645126647248964, 0.1004781360566897, 0.08725547113548288, 0.07626893342414738, 0.06718409571715239, 0.05965775140066772, 0.053140739238526705, 0.04757319298654832, 0.042810851513830316, 0.03870924523922432, 0.035197986413255195]
+[1.0, 0.7334454234017104, 0.5566965748292979, 0.43363810504552347, 0.3448420091734892, 0.27908414228975426, 0.2291817515309952, 0.190475910342943, 0.16003982607823952, 0.1359675404076268, 0.11647248663263862, 0.10050101728659573, 0.08727095634174092, 0.07627846870969737, 0.06719742684053091, 0.059670223401523226, 0.053147942530188556, 0.04757435776780104, 0.04280730192537088, 0.03869936552279844, 0.03519283600110932]
+[0.0, 0.010207868873369049, 0.014944469981511976, 0.017051069199025683, 0.01837067369032674, 0.019499136388834628, 0.02007166099494938, 0.020311770394538794, 0.020456789237398965, 0.02052579713669628, 0.02073751393787655, 0.02085827087050204, 0.020708894504311848, 0.020446569457578886, 0.020338999349665314, 0.020380894746302607, 0.02014500327221203, 0.0200247269320006, 0.01970973381822506, 0.019443920892433565, 0.01949551684514833]
+[0.13493999999999903, 0.005421844704526322]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacs_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacs_Processed
new file mode 100644
index 0000000..358d505
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacs_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7332733447150076, 0.5561850029950813, 0.43314034109850597, 0.34445534254846105, 0.2784395459301201, 0.22836753901404, 0.18959397482460358, 0.15913288949138338, 0.1347755515559568, 0.11529315980607162, 0.09941715325620476, 0.0863020424843241, 0.07562787431828778, 0.06656070053685247, 0.058989049609097254, 0.052341893471439284, 0.04681162989027694, 0.04223402638077424, 0.03821399331356674, 0.034566313538388065]
+[1.0, 0.73320031660142, 0.5561104407040541, 0.43308286495743753, 0.3444298842192089, 0.27843598389386276, 0.22838325781465554, 0.18961984349643732, 0.15915654277483046, 0.1347911751328947, 0.11529499945102796, 0.0994131866635672, 0.08629876011322099, 0.0756265129342558, 0.06655982895047903, 0.05898625720410305, 0.05233272447196541, 0.0468010705505765, 0.04222262084325446, 0.03820263596317357, 0.03456034373781677]
+[0.0, 0.009797839525856574, 0.0149674136983739, 0.017477445963465767, 0.018876164242345197, 0.019727523006598503, 0.02049370508725204, 0.02085720651776369, 0.020999330866426094, 0.021053659598540334, 0.021025366405758295, 0.020801132249402096, 0.020761634855726893, 0.02073421435321902, 0.020780944072550916, 0.020815246333943077, 0.020673619050202475, 0.02048725314343389, 0.020126193355878164, 0.019752158992579844, 0.01964468245398]
+[0.3095100000000006, 0.028189712662600983]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain100000_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain100000_Processed
new file mode 100644
index 0000000..7733cb5
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain100000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7426523456650254, 0.5798272207122617, 0.4696495803142152, 0.39135119370920196, 0.3336007720976577, 0.28977020089550215, 0.2553917219097183, 0.2277682743839068, 0.20543261096976997, 0.18694561851651753, 0.17132715246572913, 0.1582455490585137, 0.1467620076677107, 0.13699463017900476, 0.12843555454767494, 0.1206280743766867, 0.11374080705611603, 0.10781150343273532, 0.10223242275670874, 0.09738027315194044]
+[1.0, 0.7430345382175916, 0.5802994258938495, 0.47011561473609703, 0.391783166534879, 0.3339912397618736, 0.2901148624106341, 0.2557165934332251, 0.22807185155387624, 0.20572496180733235, 0.18720582417429943, 0.17157390343962411, 0.1584913926500348, 0.14700374708964342, 0.1372226742368632, 0.12864389381652588, 0.12082318076011789, 0.11391231873453292, 0.1079845647069504, 0.10240658252757333, 0.09756117933740767]
+[0.0, 0.013570051832807725, 0.01887399785761406, 0.021337070460332785, 0.022674796447306144, 0.02343944335367118, 0.023818032692529474, 0.024297952047779268, 0.0243889338008214, 0.024508744770132818, 0.02446755406036913, 0.024694788431263895, 0.02481461679784155, 0.02490554747161811, 0.024879494912786074, 0.024822914282766877, 0.024716213864684852, 0.024722334485889334, 0.024743748097834004, 0.0246825510927472, 0.024779468505538815]
+[0.929199999999999, 0.1475356228169999]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain10000_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain10000_Processed
new file mode 100644
index 0000000..01736f9
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain10000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7421966900767153, 0.5791018999646635, 0.4687558425031105, 0.39002121494716463, 0.3312332476398775, 0.2857492366252535, 0.24972836288352965, 0.22068719576112403, 0.19681136949473063, 0.17672652314358975, 0.159809199289629, 0.14534229424560913, 0.13265769160862106, 0.12129176220657442, 0.11126295237134058, 0.10208504750045173, 0.09391099941172967, 0.08677547474068488, 0.08020689659526248, 0.0743638919077356]
+[1.0, 0.742245980033051, 0.579170726748727, 0.46884749132579057, 0.3901015371062758, 0.33129024125230944, 0.2857916580470203, 0.24976302456638902, 0.22072611486996013, 0.19683845058921587, 0.17673905126154188, 0.15981208922781806, 0.1453350529774887, 0.1326464419522669, 0.12127355133711389, 0.11123629302082033, 0.10205837119156838, 0.09389424473092037, 0.08676505528219094, 0.08019442380225038, 0.07432659938940779]
+[0.0, 0.011981402787989157, 0.017715854462953103, 0.02067373384202371, 0.022467181903757984, 0.02396081591370194, 0.02504765201545679, 0.02567377644648319, 0.02632787700818861, 0.027217124005006654, 0.02757078474335939, 0.027840742309512004, 0.027790579971978525, 0.02774075073707145, 0.027769275650282966, 0.027658840577376827, 0.027529480363363692, 0.027379363064341636, 0.027214384613484754, 0.027282303547863415, 0.027379771567409294]
+[0.3852600000000003, 0.04997331688011119]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain1000_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain1000_Processed
new file mode 100644
index 0000000..f6dea35
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain1000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7371866013603059, 0.5649964810801671, 0.4453029427522352, 0.35858249637142936, 0.2935215782763642, 0.2435807545960325, 0.20419565605721762, 0.1728543311080886, 0.14766887541683715, 0.12701728741881893, 0.11008308593112845, 0.09608172886744391, 0.08421698829458564, 0.0741118921666349, 0.06569848383519182, 0.05859590062863356, 0.0525987559269442, 0.047513987820320694, 0.04270548203866338, 0.038415977511983626]
+[1.0, 0.7370862891122851, 0.564858271973851, 0.4451619037664891, 0.3584526926382333, 0.2934116310350635, 0.2434932154816544, 0.20412943493116212, 0.17279345300184493, 0.14761355695593908, 0.12695745037535425, 0.11001590170621087, 0.09601530765126531, 0.08415234640670512, 0.07406469756990887, 0.06566653369692001, 0.05857348273733559, 0.052586430798491124, 0.0475117548914033, 0.04271575625475305, 0.03843234833109647]
+[0.0, 0.01121590585883689, 0.01802784759086111, 0.02188467211999899, 0.024216254743236555, 0.025559954686740778, 0.026174538542554235, 0.026284005474175337, 0.025901198267424885, 0.02550614088526207, 0.024910560794094823, 0.024134528810076272, 0.023490411817942248, 0.022983545096591895, 0.022668110292498777, 0.022557846787081663, 0.02231178907646746, 0.022029804176524816, 0.021630527787369076, 0.021236652658652787, 0.021026276854384678]
+[0.3110100000000004, 0.02546919511880969]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain30000_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain30000_Processed
new file mode 100644
index 0000000..0aea53c
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain30000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.740980651044885, 0.5776300234174461, 0.46727597075465493, 0.3889342507196278, 0.33120423723203496, 0.2873592696100781, 0.25295232361980263, 0.2254836109284527, 0.20329861029516744, 0.1851424647588003, 0.16972677588002508, 0.15645698697413235, 0.14491904537713507, 0.13502125547302488, 0.12613716263145852, 0.11817059514938437, 0.11110452722321934, 0.10479614741813871, 0.09908179337629722, 0.09404585690047322]
+[1.0, 0.741145381475588, 0.5778495438816397, 0.4675102375376312, 0.38917666300591275, 0.33143465906063446, 0.2875876900280379, 0.2531728800341301, 0.22567740632476216, 0.20346781344660217, 0.18529104697504165, 0.16985349826099982, 0.15657367485715754, 0.14503493462503803, 0.13515480188065931, 0.1262877724514739, 0.11832954810843788, 0.11125433209660443, 0.10493503421633582, 0.09921297592917186, 0.0941664950713741]
+[0.0, 0.012514955215715082, 0.017877785014129458, 0.020712400521449414, 0.022281406275793756, 0.023090594922651832, 0.023700878456590847, 0.024104235016689863, 0.024285948605237452, 0.024496280060732362, 0.02459104286406701, 0.02461998834912247, 0.024688732402457166, 0.024856186400789643, 0.02494389618537666, 0.024931090482068926, 0.024850615084265094, 0.02473913199548043, 0.024585259322366267, 0.024606974320121527, 0.024690730239883947]
+[0.5174099999999998, 0.07643946559206176]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain50000_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain50000_Processed
new file mode 100644
index 0000000..21e0a31
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain50000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7426952812194055, 0.5799424459730409, 0.46979887516120583, 0.39165955188891466, 0.33398031005528356, 0.29003601197491574, 0.2554757505772807, 0.2279024290331255, 0.20564063414373335, 0.18703829601927552, 0.17141918164886283, 0.1582844519931088, 0.14705773827344418, 0.1371255321231801, 0.12826688549055693, 0.12030190141559059, 0.11311841746500977, 0.10711518263108075, 0.10151923377395157, 0.09630888232786147]
+[1.0, 0.7429723166136644, 0.5803291616425518, 0.47019447212028986, 0.39203725557447844, 0.3343315826511152, 0.2903557472344106, 0.25574081255332304, 0.22809848602120464, 0.20579131426255814, 0.18717783868283489, 0.17155247616861252, 0.15841755454121798, 0.14717703827117157, 0.13720407670390017, 0.1283141918058655, 0.12032768269288517, 0.11313660863950901, 0.10712839319689062, 0.10151741372770176, 0.0962928194830363]
+[0.0, 0.013010888444376725, 0.01855188461706363, 0.021170224217819188, 0.022478080822035104, 0.023418853494897567, 0.023741062942055326, 0.023832422352504646, 0.024033972687253633, 0.024173642586222628, 0.02444893809414361, 0.024592037579039397, 0.024436658563419457, 0.024288147457428386, 0.02425227816432849, 0.023980652954801118, 0.023917304675566197, 0.023892160562290914, 0.023978427500842194, 0.02431586240191552, 0.02441618067526602]
+[0.6371799999999992, 0.09910826201684703]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain70000_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain70000_Processed
new file mode 100644
index 0000000..4737e96
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizemacsretain70000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7413466743510985, 0.5778875823423362, 0.46771957564593153, 0.38953693457110783, 0.33174943276599295, 0.2878051075690714, 0.25344825022827905, 0.22589226809793458, 0.20341463302148527, 0.18475719442654887, 0.16930201618570104, 0.1562836587919542, 0.1448650043476319, 0.13485575880723277, 0.1260190234604173, 0.11810843486529232, 0.11114966929136298, 0.10493429959752888, 0.09933752548012015, 0.09446460243969297]
+[1.0, 0.7416218994231166, 0.578240180694441, 0.4680834515011526, 0.38988005277986315, 0.3320585664961306, 0.28809068929646636, 0.2537119284243614, 0.22611478686264297, 0.20361112818390445, 0.18493834094785366, 0.16944926091394774, 0.15639671562857504, 0.1449712245816971, 0.1349647301519254, 0.12611553616996155, 0.11818933175320598, 0.11122124357722084, 0.10500270479366056, 0.0993995641310429, 0.09453881103632787]
+[0.0, 0.012581851417065698, 0.01835271902474101, 0.021087951267483418, 0.022671103984634504, 0.023658578487625804, 0.024274650470254927, 0.024706941809758916, 0.024987604072897476, 0.02537284110275229, 0.025338513367891887, 0.02526670155656639, 0.025141934729922617, 0.025019056906289992, 0.02480346991011857, 0.024788675282988133, 0.025062015419752254, 0.025339286178333975, 0.025584005914665957, 0.025706940402114, 0.025629093881486167]
+[0.7570899999999995, 0.1178203373785696]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizems_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizems_Processed
new file mode 100644
index 0000000..2146f83
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizems_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.74083411227638, 0.5762168462744437, 0.4635816925020751, 0.3824466250535421, 0.32163906136991205, 0.2749527103850136, 0.23830848761940254, 0.2088991826251471, 0.18497399951240684, 0.1650640929539788, 0.1482008664833955, 0.1338207826786369, 0.12139343241397475, 0.11100849603656414, 0.10188839255093071, 0.09390456553684468, 0.08679461662735521, 0.08052613445441793, 0.07486756902948428, 0.06972701192854441]
+[1.0, 0.7408119748051857, 0.5761981923823335, 0.4635660676653814, 0.38245275488911346, 0.3216601880440784, 0.274980711790873, 0.23833812827813092, 0.20892068480297626, 0.18497895360679922, 0.16505476199100608, 0.1481740863218399, 0.1337689796895666, 0.121335092453192, 0.11095455682978829, 0.10184160155376787, 0.09386925389651828, 0.0867635344354676, 0.08049738033145831, 0.0748370413766143, 0.06969353167351977]
+[0.0, 0.010601489836467174, 0.015334632948748705, 0.018121370333619335, 0.01988305249944143, 0.020664561824681755, 0.02120469778780964, 0.021687318192025056, 0.02164178412667776, 0.021605639757513076, 0.021246073127000692, 0.02119496244715925, 0.021047297140386296, 0.02118047168989868, 0.021263341693455933, 0.021224030855423338, 0.021234798407523306, 0.0209777357203808, 0.021013380558841197, 0.021055444546007773, 0.021067941017643473]
+[11.025889999999993, 1.066296491553827]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow0_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow0_Processed
new file mode 100644
index 0000000..750ba93
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow0_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7334526248730143, 0.5562383324110127, 0.43283839211192526, 0.34402664057556503, 0.27823457184868067, 0.22824307727747511, 0.18959313960594884, 0.15930831355826847, 0.1352123980584497, 0.11591694332511385, 0.10008097675352999, 0.08689183452747622, 0.07589712205882554, 0.06659004102280552, 0.05875725055628995, 0.052149562720852534, 0.046627458261825454, 0.04194150911410684, 0.03778174438867375, 0.03418311045119587]
+[1.0, 0.7333787785534763, 0.5561781835129225, 0.432809035171531, 0.3440105390674876, 0.2782270520920449, 0.22824383526388353, 0.18960782214206073, 0.1593297225226425, 0.13523002313714533, 0.11592745853730164, 0.100082789695147, 0.08688937850142844, 0.0759017836489512, 0.06659980591739817, 0.058767295736832266, 0.05215724851464301, 0.04664272903206191, 0.041961656191835325, 0.03780051479524704, 0.034189356718523495]
+[0.0, 0.010323413825876529, 0.015323185175716798, 0.017812687775887945, 0.01908305371113466, 0.01983212626146217, 0.020161053104682046, 0.020480782707310696, 0.020789177000640403, 0.02073852464819215, 0.0208097518830526, 0.020908219352114253, 0.02095513638452829, 0.021039259269122493, 0.020968356185669, 0.02101257801447866, 0.02115440069896658, 0.021121793200736986, 0.02079643153515965, 0.020478281479833237, 0.020130586318609978]
+[0.2544899999999995, 0.009805095614016227]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow100000_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow100000_Processed
new file mode 100644
index 0000000..258e76d
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow100000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7416525822467175, 0.5771112454161955, 0.46412946338018846, 0.3825877747453436, 0.3217573104640272, 0.27502343869495743, 0.23832383678273028, 0.20886944178265024, 0.18477395222165222, 0.1645380458071066, 0.14754538586561536, 0.13305929031218855, 0.12078703992996541, 0.11024536068853648, 0.1011181515210878, 0.09321943917768234, 0.08621349083728001, 0.079622968858348, 0.07378853066402986, 0.06864229724674371]
+[1.0, 0.7416127432775215, 0.577058844392151, 0.4640850963972691, 0.3825473970343538, 0.32170435191229213, 0.2749608149926137, 0.23825020705174407, 0.20879618159508956, 0.18468913910762225, 0.16444738031361245, 0.1474563360822655, 0.13296528008078393, 0.12069029176315575, 0.11013863466429001, 0.10099329439227049, 0.09308392999384067, 0.08608115528723806, 0.07949420542602399, 0.07367711317470658, 0.06855479737988418]
+[0.0, 0.010963759572202563, 0.01638157130718222, 0.01907909020305551, 0.020595535689793016, 0.021521574146918045, 0.02208707553093635, 0.02242539798985618, 0.022603412674575416, 0.02264894597715235, 0.02274632052536569, 0.022768998014859914, 0.022829517967660674, 0.022764504783521874, 0.022838492754033816, 0.022947950299461055, 0.022859671146999463, 0.022803538484100872, 0.022742230919099375, 0.022605422064296745, 0.022481080903066695]
+[0.905879999999999, 0.044730589086217014]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow10000_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow10000_Processed
new file mode 100644
index 0000000..86e201d
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow10000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7407591504315179, 0.5756733760980539, 0.46258808180861993, 0.3813987559301315, 0.32045546408083975, 0.27360196478070625, 0.23701967899089257, 0.20752271501983963, 0.18322399843926257, 0.16312964523103932, 0.14569296993799122, 0.13015487668314235, 0.11649871828241909, 0.10436380445397236, 0.0936862214245637, 0.08425765655555988, 0.07590201032868878, 0.06846475167059807, 0.06192788581518117, 0.05638425399794612]
+[1.0, 0.7406981864388511, 0.575616726129621, 0.4625305257428327, 0.38132944531119933, 0.32038358668655315, 0.27353706693771995, 0.23695985452389687, 0.20747305236329636, 0.18318476470402625, 0.16310438211365455, 0.14568260880745248, 0.13014982904066305, 0.11649630011159552, 0.10436603688024865, 0.09368159293582896, 0.08423888070976113, 0.07587362019128514, 0.06843604590841329, 0.06189094014725915, 0.056342600306648005]
+[0.0, 0.010354967112404837, 0.015218334674335495, 0.01800956637142773, 0.019715480580928965, 0.020569457584679554, 0.021078719137638664, 0.021438486730792315, 0.021497298086539926, 0.021485525721854984, 0.021556535094481095, 0.021670261291698946, 0.021753056311016913, 0.021711174291907685, 0.02160926294964128, 0.021370792727109053, 0.02115534877661642, 0.021316295104886706, 0.021489228902722098, 0.021474593580065166, 0.02155130755961556]
+[0.308350000000001, 0.012384567008983369]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow1000_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow1000_Processed
new file mode 100644
index 0000000..a4e2c60
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow1000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7409246181784505, 0.5706478130808816, 0.4488999871096994, 0.35946832964953196, 0.29239037019966835, 0.24090670006734463, 0.2006919877702657, 0.16878751511403184, 0.14322762742600087, 0.12247810373886564, 0.10577717722404653, 0.09212023030919166, 0.08067342772889466, 0.07105850522341799, 0.06301194298871376, 0.0560916266066423, 0.05002479979041069, 0.04476750593655284, 0.04022351021506974, 0.036172024668402886]
+[1.0, 0.7408277210532348, 0.5705244253032521, 0.4487736629927573, 0.3593653751517142, 0.2923006189279184, 0.24081827687347138, 0.20060685300915695, 0.16871181225133156, 0.1431607230117896, 0.12241201084921509, 0.10571043937369187, 0.09205209156125552, 0.08060550534355174, 0.07099232333077049, 0.06294632162289528, 0.05603241772897824, 0.04997317063803093, 0.04472240846878894, 0.04018212920237925, 0.03613070909338473]
+[0.0, 0.01033612134397788, 0.015143705306730555, 0.017751193143749892, 0.019189751322109212, 0.020001910980757164, 0.02036153442901953, 0.02060011395573871, 0.020844649732094843, 0.020959698084319297, 0.02107789994354614, 0.021204106056029615, 0.02112926076204727, 0.02098957130053223, 0.020976366481340585, 0.021041405189860942, 0.02090113995508121, 0.020725329149813856, 0.020713644924679045, 0.020866608324620603, 0.02094181254644918]
+[0.2601999999999993, 0.009703607576566516]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow30000_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow30000_Processed
new file mode 100644
index 0000000..cef8559
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow30000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7409150229748404, 0.5757664259088648, 0.46267622316824597, 0.38112025949175776, 0.32043460883554453, 0.2739572947213842, 0.23709559999590965, 0.20752705058458695, 0.18345180848047588, 0.16349955976075356, 0.14669606418827116, 0.1324022488666594, 0.12022595527949671, 0.1098244509990811, 0.10083350431295171, 0.09289445381608058, 0.08579274197923573, 0.07958379528746634, 0.07419837808373668, 0.06948969576172756]
+[1.0, 0.7408605781567714, 0.5757023852373684, 0.4625998796246659, 0.3810330641747874, 0.32035000377085493, 0.2738674692881883, 0.23700947452840662, 0.20743307614117748, 0.1833505451351172, 0.16340208160829062, 0.14659767070460217, 0.13229614901890105, 0.12012167952877792, 0.10971829902151342, 0.10073373037986348, 0.09280679072722428, 0.08571201562349512, 0.07949944253868173, 0.07411176107328843, 0.06939170280685132]
+[0.0, 0.010501661476624386, 0.015620730616115738, 0.018292870830274297, 0.020036181452528744, 0.020832464566615964, 0.0210260052328252, 0.021126979082441478, 0.021119353728606346, 0.021393537566302783, 0.021601333749407148, 0.02171066933310078, 0.02176935896970903, 0.02175441972650999, 0.02179569288412937, 0.02169906690428307, 0.021509062021900532, 0.021314791710535953, 0.021136952123372917, 0.021160737036969395, 0.021185231754995208]
+[0.43268000000000023, 0.019391173249703075]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow3000_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow3000_Processed
new file mode 100644
index 0000000..ce51657
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow3000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.741620707800179, 0.5767116325162611, 0.46379430356603096, 0.37985594698278563, 0.3140612804883338, 0.26190481289224554, 0.22027397573432156, 0.18693122831476539, 0.15953848505037746, 0.13693630620907402, 0.11821424205674286, 0.1026483866986423, 0.08993316955938815, 0.07919350661560733, 0.06982917473501116, 0.062107252345616544, 0.055718965390176005, 0.049978898884297324, 0.045028448996321996, 0.040691144129140835]
+[1.0, 0.74154503982763, 0.576609998810111, 0.4636800879203364, 0.3797350129849832, 0.31394953296664874, 0.26181851932254346, 0.22022162497535788, 0.18690093065107044, 0.1595184866962848, 0.1369208583849252, 0.11820399033495727, 0.1026425838589993, 0.08993136742529943, 0.07918048106271205, 0.06981360769411725, 0.06209101726313741, 0.055706277920048425, 0.049967979316604585, 0.04501524046665132, 0.04067670992640133]
+[0.0, 0.010601888285314966, 0.015477718750844832, 0.017848255068123056, 0.01914388143518352, 0.01997086725241158, 0.02049510658552277, 0.020893544621822645, 0.021095047952362018, 0.021344058922180845, 0.021367061126572925, 0.02136895627692656, 0.02135930173891783, 0.021505483946517502, 0.021541989650009155, 0.021645002548262116, 0.02171671809893064, 0.021485353861002282, 0.021387817846775126, 0.021298677041160424, 0.021238129908640855]
+[0.28085000000000043, 0.011626585913328097]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow50000_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow50000_Processed
new file mode 100644
index 0000000..5ec48b4
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow50000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7409009309946815, 0.5758120348496486, 0.4627475700715925, 0.38137349462804443, 0.32052497615040304, 0.27356998336086646, 0.23665099301829925, 0.20724339449652013, 0.18326939381063853, 0.16335301842642166, 0.14652567373311823, 0.13238505308651113, 0.1201282186983731, 0.10952750204329567, 0.10038288091859854, 0.0924047422886495, 0.08525122072904948, 0.07903602959039388, 0.07350536209483081, 0.06848447331595105]
+[1.0, 0.740874177626375, 0.575786138256506, 0.462727148514778, 0.3813532930359998, 0.3205019976884581, 0.27353641060656264, 0.23661463193258883, 0.20720088131661485, 0.18321621785273418, 0.1633126069579774, 0.14650010415357884, 0.13237610060260765, 0.12012792103712368, 0.1095356085695173, 0.10040036392206687, 0.09242443197454529, 0.0852667149328507, 0.07904678903558032, 0.07350874246126782, 0.06848594624227652]
+[0.0, 0.010476039128790958, 0.015590485248285041, 0.01826130354467712, 0.01998996178570763, 0.021250856390365128, 0.022153832451945514, 0.02256602162571755, 0.022675032416272483, 0.02268562651394732, 0.022673667646743452, 0.02253892210799643, 0.02252413975246634, 0.022417133410416647, 0.02214016112220513, 0.022009834921775124, 0.02196897581803899, 0.021943965947420818, 0.02207852760723596, 0.022300282925217928, 0.022540522112522946]
+[0.5412399999999983, 0.02423762364589398]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow5000_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow5000_Processed
new file mode 100644
index 0000000..b0ce95e
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow5000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7410289415775779, 0.575916640919898, 0.4632152678633031, 0.3818892558186193, 0.32096514058205344, 0.2724964461503198, 0.23239042279080524, 0.19920328880965663, 0.17160288632391862, 0.14853255279598884, 0.12904013812981482, 0.11281060978816525, 0.09904137213674963, 0.08722960325698174, 0.07720105716523606, 0.06851126562045409, 0.06080090951651834, 0.054250159975763754, 0.048576264014227225, 0.044002883218419664]
+[1.0, 0.7409705337748782, 0.575842843157384, 0.46312416416862395, 0.38179857614220253, 0.320872374794629, 0.2724024187175543, 0.23228973645221046, 0.19910216604702638, 0.17149482950997308, 0.1484326909275953, 0.12893605311332418, 0.11271077239027003, 0.09895077180291173, 0.08715306591544834, 0.077132075464891, 0.06845032364132717, 0.06074518028079406, 0.05419587326396008, 0.04852225537478945, 0.04394839876426964]
+[0.0, 0.010529755832025369, 0.015018207864712028, 0.017328322502872716, 0.01888281627465343, 0.0199224260143674, 0.020667509970418597, 0.021147204695858433, 0.021396666918712032, 0.02148660127568993, 0.021538312515568363, 0.021485359209879845, 0.02142079870178019, 0.021381061645774926, 0.02122577168714783, 0.0210960685182405, 0.02089711843797147, 0.020845111534810577, 0.020792249961890854, 0.02087082917516279, 0.021029791739816887]
+[0.2920000000000012, 0.011357816691600565]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow500_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow500_Processed
new file mode 100644
index 0000000..3918f1d
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow500_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7395121566892053, 0.5652858885980531, 0.44240884724451873, 0.3528738290218838, 0.28590170669808246, 0.2347588181190309, 0.19489644282089028, 0.16356319602140612, 0.13863843778312723, 0.11866460983004515, 0.10252103369646332, 0.08908391930376926, 0.07804018623484436, 0.06877035975127851, 0.06096378992850739, 0.054215230465213204, 0.04831125384076772, 0.04332637830220733, 0.03901723295948911, 0.035416285553777155]
+[1.0, 0.7393835073852367, 0.5651329244062703, 0.44226094333659133, 0.3527448497220271, 0.2857949859423048, 0.2346664910221099, 0.19482033661277331, 0.16349967202517132, 0.1385759511086999, 0.11860827240580231, 0.10247462971991886, 0.08904714842423603, 0.0780049644327256, 0.06873841971954454, 0.060929350186284266, 0.05418167916831509, 0.04827089821299972, 0.043285301173223364, 0.03898104897899401, 0.03538348910093292]
+[0.0, 0.010566453980750824, 0.015531267796605129, 0.01789409764720999, 0.01885149847917294, 0.019328787238803245, 0.019619304326091054, 0.01984804010775297, 0.020327051433270227, 0.020686738079086536, 0.020878944643145145, 0.021021900784991283, 0.021091656349071196, 0.021021358162416917, 0.021076537565608445, 0.02103792340629081, 0.021069918754115124, 0.020977393805211818, 0.020854309234050405, 0.020668356972773697, 0.020613687485510887]
+[0.26768000000000075, 0.010120158101531777]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow70000_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow70000_Processed
new file mode 100644
index 0000000..c2c77f1
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow70000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7411749749956231, 0.5757755980288607, 0.4625159031944954, 0.3811878533552985, 0.3206309060397885, 0.2741152791590595, 0.23746217937939082, 0.20793510403912524, 0.18351742274544117, 0.16352248289995164, 0.14673676575132832, 0.13253422733232617, 0.1203206306135659, 0.11004987533203678, 0.10121517985720915, 0.09333727493843914, 0.08632973304088323, 0.07996278455997458, 0.07441445580440736, 0.06949546459639765]
+[1.0, 0.7411226524300514, 0.575700457311488, 0.46241983141319537, 0.3810754926258232, 0.32051292711059, 0.2739987767085147, 0.23735523223444024, 0.20783793650255378, 0.1834196277514233, 0.16342841294975843, 0.14664298902012482, 0.1324444183706462, 0.12023739941772539, 0.10997546204749556, 0.10114887872843262, 0.09327168246904133, 0.0862683622058521, 0.07989361413376495, 0.07433716345867661, 0.06941277920258863]
+[0.0, 0.010750913149252346, 0.01592608278594468, 0.018797004524597687, 0.020295837893412202, 0.021165735052919948, 0.021729587059865555, 0.022437660923206357, 0.02294820902886929, 0.023310181915984822, 0.02340688464151287, 0.02333031061777536, 0.023011042529942967, 0.02281879151931301, 0.02283903314916626, 0.02279979755520188, 0.022672762353286004, 0.02257727554155903, 0.022654348669158903, 0.022627815184107055, 0.02245355191533201]
+[0.694390000000002, 0.03455760263675695]
diff --git a/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow7000_Processed b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow7000_Processed
new file mode 100644
index 0000000..1479729
--- /dev/null
+++ b/tests/manualtests/LD/cluster/6sample_processed/Constantpopsizescrmwindow7000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7412168567119716, 0.5768475276204649, 0.46392474400921174, 0.38283614223129886, 0.3224961138662508, 0.2758171139967283, 0.2386939033892875, 0.20784988442033794, 0.1811250719972533, 0.1584640768536411, 0.13889663442968375, 0.12208489224354378, 0.10786252441003591, 0.09560986766314475, 0.08494939402667981, 0.07569805324811317, 0.06780997220244064, 0.06097061625724591, 0.055001534232698227, 0.049852093730621175]
+[1.0, 0.7411650009826063, 0.5767811965623665, 0.46385033989161284, 0.38275314530069643, 0.32241290714254106, 0.27573713093867996, 0.23860418411248568, 0.20775871945438057, 0.181047524487757, 0.15840116037717117, 0.13885857304720678, 0.12207103016953717, 0.10785511406309277, 0.09560080502964653, 0.08492622100136782, 0.07566596291132562, 0.06777509465991564, 0.06094131884351538, 0.05497775862407332, 0.049833116830036994]
+[0.0, 0.010414618142054749, 0.015381292024032973, 0.017996786699745887, 0.019383003455670518, 0.02015201334944339, 0.02027841912447035, 0.02025592794280071, 0.020356276280814323, 0.020603910889273297, 0.020841376174203067, 0.021037724743316354, 0.0212458729867195, 0.021280471985139257, 0.021403351019306908, 0.0215549905791637, 0.021788744445708236, 0.0217913822410212, 0.021736135303826815, 0.02156409450386326, 0.021245493145821137]
+[0.3029000000000023, 0.010981347822558087]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizefastsimcoal_Processed b/tests/manualtests/LD/cluster/Constantpopsizefastsimcoal_Processed
new file mode 100644
index 0000000..f91d9aa
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizefastsimcoal_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7243775300015043, 0.5425611440815619, 0.4165328958824117, 0.3261529614074926, 0.25957950760232734, 0.20955099892504417, 0.17133058721438363, 0.1414693627475885, 0.11803237233609196, 0.09935107915803157, 0.08423909563776673, 0.07184279608997815, 0.061581140665377836, 0.053087442187692464, 0.04599783286531609, 0.039980473526355656, 0.03496753810463444, 0.030876753525886765, 0.027374061329584726, 0.024538935383411526, 0.02184312351114393, 0.019520125266542617, 0.0174912517247185, 0. [...]
+[1.0, 0.7242637587173805, 0.5424448771619065, 0.416435266136729, 0.3260728279116408, 0.2595178258750776, 0.20950359826291606, 0.17129080729779836, 0.1414254185226608, 0.11797733258743924, 0.09929284988181146, 0.08417730721659049, 0.07178612066813529, 0.0615353721998468, 0.053053570706921085, 0.04597049940337092, 0.039954206763830005, 0.034932975429899135, 0.030832925982499024, 0.027329479670543538, 0.024507457645764893, 0.02182421525468922, 0.019504013655955704, 0.017472818210413965, 0.0 [...]
+[0.0, 0.010006306641869736, 0.014540426043946085, 0.01653388231514388, 0.01763638877252143, 0.018463605939813693, 0.019039041180199966, 0.019262509572144006, 0.01921539164418125, 0.019268812718793153, 0.019409049327846494, 0.019394423445336213, 0.0192898315650703, 0.019086820894284776, 0.0186986336990071, 0.018401710695162474, 0.018179745680255325, 0.018011586776125417, 0.018108275208874057, 0.018451864918623714, 0.01863906518407317, 0.018810810996327528, 0.018964401404645406, 0.01911891 [...]
+[0.6842100000000011, 0.020074259637655224]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizemacs_Processed b/tests/manualtests/LD/cluster/Constantpopsizemacs_Processed
new file mode 100644
index 0000000..358d505
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizemacs_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7332733447150076, 0.5561850029950813, 0.43314034109850597, 0.34445534254846105, 0.2784395459301201, 0.22836753901404, 0.18959397482460358, 0.15913288949138338, 0.1347755515559568, 0.11529315980607162, 0.09941715325620476, 0.0863020424843241, 0.07562787431828778, 0.06656070053685247, 0.058989049609097254, 0.052341893471439284, 0.04681162989027694, 0.04223402638077424, 0.03821399331356674, 0.034566313538388065]
+[1.0, 0.73320031660142, 0.5561104407040541, 0.43308286495743753, 0.3444298842192089, 0.27843598389386276, 0.22838325781465554, 0.18961984349643732, 0.15915654277483046, 0.1347911751328947, 0.11529499945102796, 0.0994131866635672, 0.08629876011322099, 0.0756265129342558, 0.06655982895047903, 0.05898625720410305, 0.05233272447196541, 0.0468010705505765, 0.04222262084325446, 0.03820263596317357, 0.03456034373781677]
+[0.0, 0.009797839525856574, 0.0149674136983739, 0.017477445963465767, 0.018876164242345197, 0.019727523006598503, 0.02049370508725204, 0.02085720651776369, 0.020999330866426094, 0.021053659598540334, 0.021025366405758295, 0.020801132249402096, 0.020761634855726893, 0.02073421435321902, 0.020780944072550916, 0.020815246333943077, 0.020673619050202475, 0.02048725314343389, 0.020126193355878164, 0.019752158992579844, 0.01964468245398]
+[0.3095100000000006, 0.028189712662600983]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizemacsretain0_Processed b/tests/manualtests/LD/cluster/Constantpopsizemacsretain0_Processed
new file mode 100644
index 0000000..41d1f3b
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizemacsretain0_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7237847388249016, 0.5414368268647574, 0.41551942113008977, 0.3254753325205462, 0.2592215597516827, 0.20915746431189644, 0.17065798760361478, 0.14076401509577577, 0.11713440339108931, 0.09829979412936007, 0.08307907025492434, 0.07048377569002263, 0.06010412693133504, 0.051545948286035606, 0.044694233796830164, 0.03908900280209849, 0.03432789091882597, 0.030240568559209362, 0.0267103099023525, 0.02359683193367406, 0.021012995106669177, 0.018841941156020597, 0.016912092788621047, 0. [...]
+[1.0, 0.7236884502913432, 0.5413428371400613, 0.41544056138633434, 0.3254132328977352, 0.2591701882181167, 0.2091115304377619, 0.17061759821775482, 0.14072005737131257, 0.11708706072133704, 0.09825422784724137, 0.08304138585268574, 0.07044618842116293, 0.06006966442539637, 0.05152063304435766, 0.04468139382928406, 0.03908100921391825, 0.034319547882904575, 0.03022864849662682, 0.026695885258841565, 0.023580165308460015, 0.020990513753529644, 0.018826012689715156, 0.01690253600401597, 0.0 [...]
+[0.0, 0.010086156077880904, 0.014620628637963536, 0.016838281576137034, 0.017998765425784203, 0.01855357050832857, 0.01885447372915256, 0.019056638334907245, 0.01923197776417342, 0.01922173760313484, 0.019033319490632108, 0.019008066786879056, 0.01917245219044236, 0.01943689110080192, 0.0195972456155152, 0.01973377792079508, 0.019620299864920004, 0.019337796217419632, 0.019316451683539338, 0.019183785275839076, 0.01901807122861624, 0.018855814537359086, 0.018759663488014708, 0.0186541783 [...]
+[0.6170900000000014, 0.024852201109760965]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizemacsretain100000_Processed b/tests/manualtests/LD/cluster/Constantpopsizemacsretain100000_Processed
new file mode 100644
index 0000000..4fe654a
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizemacsretain100000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7330419653526885, 0.5669310850970853, 0.45594172838393476, 0.37777214223156785, 0.32105846961528234, 0.27811455952641706, 0.24481297693610599, 0.2180782979522165, 0.19652904386747908, 0.1785389108892151, 0.16356158840678658, 0.15072558008109813, 0.13979666137763577, 0.1304555130997109, 0.1221675076594823, 0.11497175654375778, 0.10837073460215761, 0.10282309146282738, 0.09770162275524584, 0.09280335481945609, 0.08838040030369791, 0.08459986579218993, 0.08111560361136169, 0.0776156 [...]
+[1.0, 0.7333353007894409, 0.5672823452052012, 0.45627808476105264, 0.37807221099624394, 0.3213270699782423, 0.27834718297914246, 0.24502513463855935, 0.21826545564573308, 0.19670401131233792, 0.1787079531010657, 0.1637283438977836, 0.15088695901912383, 0.13995096866924323, 0.13059857637417766, 0.12231084068271847, 0.11509380929847642, 0.10846365673161157, 0.1028842828863981, 0.09774935897454197, 0.09283574602631525, 0.08840801194135846, 0.08462803689355858, 0.0811508892861289, 0.07766307 [...]
+[0.0, 0.013486126604321651, 0.018893227639796593, 0.02181060894639389, 0.023131469258631278, 0.02360028965634936, 0.024038295729684463, 0.02434596187986085, 0.02444113063853672, 0.024416359435069486, 0.024486488016650678, 0.024468069687435593, 0.024275251337404987, 0.024229820067359048, 0.02419085545215932, 0.024172746489843508, 0.024076502376850984, 0.02416773722315248, 0.024283208272505657, 0.024178470028845288, 0.0240472606646111, 0.02396875245682847, 0.02380868035197095, 0.0238054658 [...]
+[2.1760300000000026, 0.24961037458407048]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizemacsretain10000_Processed b/tests/manualtests/LD/cluster/Constantpopsizemacsretain10000_Processed
new file mode 100644
index 0000000..1f456ce
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizemacsretain10000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7329701381672368, 0.5665909791612574, 0.45548751404930987, 0.3770278424131447, 0.3194065732369363, 0.27551909610358993, 0.24089721032602057, 0.2129283522232058, 0.18985766261748172, 0.1706174184480888, 0.15414155127444795, 0.13976916155990043, 0.12713895057514135, 0.11593291041723501, 0.1060686909106835, 0.09711883835364009, 0.08894102225127079, 0.08179062307053636, 0.07519172125649394, 0.06895080668094565, 0.06341099619292653, 0.05837020765339547, 0.05378160453721458, 0.04953157 [...]
+[1.0, 0.7330227883296812, 0.566652944503916, 0.4555540680982492, 0.3770837203836077, 0.3194364867509899, 0.2755369541539279, 0.24089474488172313, 0.21289901996180924, 0.18981157431812462, 0.17055421481451752, 0.1540573417692521, 0.13966784659687065, 0.1270473092361064, 0.11584670525205941, 0.10596942722403753, 0.09700652401045923, 0.08882527531379364, 0.0816764340963057, 0.07507678759920129, 0.06883512112614204, 0.06328571730528962, 0.05824547512689675, 0.05365324242001063, 0.04939550517 [...]
+[0.0, 0.011493995039907485, 0.016674070757118173, 0.018923713335822587, 0.020276553082158602, 0.021314800569703043, 0.02217490169789826, 0.02283573227024034, 0.02322367791266661, 0.023731810339228616, 0.024107571920973802, 0.02431044824683455, 0.024452919399539755, 0.024561329758920437, 0.024885833807878066, 0.025252297588811166, 0.025638108231324484, 0.025934451837782067, 0.026013526603760675, 0.026132329907406878, 0.025889315336435972, 0.025443986237086453, 0.02519611694364486, 0.02526 [...]
+[0.8163900000000001, 0.0770393918719507]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizemacsretain1000_Processed b/tests/manualtests/LD/cluster/Constantpopsizemacsretain1000_Processed
new file mode 100644
index 0000000..9a94b20
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizemacsretain1000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7297599381647855, 0.5551201977708642, 0.4340541354528787, 0.3461872899835394, 0.2803911299161359, 0.22982934457627294, 0.1900077598399678, 0.15839821699321863, 0.13315138515165076, 0.11267048764010083, 0.09591528958744869, 0.08212335889480957, 0.07070078872701534, 0.06130794548650279, 0.05346970070220361, 0.046820167944817886, 0.04109981830842923, 0.03630934217648931, 0.0322554561441224, 0.02868272476204251, 0.02539061937287176, 0.022612688290129468, 0.020446636778650766, 0.01867 [...]
+[1.0, 0.7296835349882086, 0.555026624144933, 0.4339523995318519, 0.3460953333620158, 0.2803065892960135, 0.22975048418158148, 0.18993183227305294, 0.15833357258176936, 0.13309113842850093, 0.11261544196614666, 0.09587466184647261, 0.08208177147014499, 0.07066248052527331, 0.061271628317952895, 0.053439868894545335, 0.04679657753990061, 0.041074435549393086, 0.03627562268407168, 0.032219864799812634, 0.02864348487901842, 0.02534583668971869, 0.022572036143885178, 0.020406336987069635, 0.0 [...]
+[0.0, 0.011036877902969774, 0.01780657369788039, 0.022115125485574177, 0.023999368791622382, 0.024942736188266146, 0.025191184011332367, 0.02502696278137738, 0.024631217788579074, 0.02416093354411102, 0.023781686033826563, 0.023457330648938804, 0.02312450923564513, 0.022952446134273333, 0.02273871344946043, 0.02231785125810902, 0.021742176549788605, 0.02115296541881952, 0.020992658417357958, 0.020881462495553126, 0.020797562170658694, 0.020525314508369343, 0.02015796773802489, 0.01990175 [...]
+[0.6383099999999995, 0.033275274604426544]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizemacsretain30000_Processed b/tests/manualtests/LD/cluster/Constantpopsizemacsretain30000_Processed
new file mode 100644
index 0000000..f7cd67d
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizemacsretain30000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.733318263866994, 0.5672383064443925, 0.4563272540697702, 0.3783940726274112, 0.3212766818986271, 0.27807821026095486, 0.2443477362601038, 0.2176233426043472, 0.19586707447461565, 0.17800540417244817, 0.16322556103130184, 0.15065548299072773, 0.13980186845555617, 0.1301147047525375, 0.1218000719743119, 0.11448753449820644, 0.10785842075055575, 0.1022170536458403, 0.09700323251252589, 0.09209958903147278, 0.08750489717422752, 0.08350615757148541, 0.0800617318328147, 0.0768012445750 [...]
+[1.0, 0.7334994848342978, 0.5674563035802547, 0.456541085411608, 0.3785832842087679, 0.3214688815341574, 0.27826479270367516, 0.24450661386666844, 0.21774660581884622, 0.19599145052967623, 0.1781193239290877, 0.16332499213082496, 0.15072974167660155, 0.13984145453163857, 0.13012925548401658, 0.12179827772229082, 0.11446887556130193, 0.10782725355482776, 0.10217941429825443, 0.09695190897692645, 0.09203681971899447, 0.08745166056335181, 0.08345004810248549, 0.0800030116943233, 0.076756808 [...]
+[0.0, 0.012357672186154715, 0.017221775731836277, 0.01996668316417471, 0.0216160377904256, 0.02264246366723984, 0.02315920454619662, 0.023596614172567747, 0.02368410966107803, 0.0235197582926294, 0.023541254688701843, 0.023603315520642418, 0.023564221525140087, 0.02353798905849874, 0.023893916267169215, 0.024058171225381682, 0.023917564187266593, 0.023911326167346713, 0.023743481392006084, 0.02318472700845797, 0.02287540455234419, 0.02270335608234022, 0.02263718363172137, 0.0224307454693 [...]
+[1.1546400000000012, 0.13015095235917404]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizemacsretain3000_Processed b/tests/manualtests/LD/cluster/Constantpopsizemacsretain3000_Processed
new file mode 100644
index 0000000..10bb0b9
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizemacsretain3000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.732278836796659, 0.5636461582890689, 0.4489166795798966, 0.3660387933774626, 0.30354193231585697, 0.25442078996719053, 0.21535586459028602, 0.18349472992922902, 0.15741252573608838, 0.13569434618466183, 0.11766811656131414, 0.10272109667529268, 0.08966978550239058, 0.07849643951588384, 0.06907807940915862, 0.060876394878508544, 0.05364409450100586, 0.047609154732781774, 0.04233676360501896, 0.03767506168447303, 0.033678943783911716, 0.03010891488497744, 0.0269255600826839, 0.0242 [...]
+[1.0, 0.7322566269836989, 0.5636284901214115, 0.44890297864189943, 0.36603073137245723, 0.3035454888826874, 0.2544279841589899, 0.21536061320522346, 0.18349867055736907, 0.15742158307863904, 0.13571333545390202, 0.11769676078253685, 0.10276436063794418, 0.08972212348948681, 0.07855631306264631, 0.06914486223232746, 0.060941024353271846, 0.05370535172630889, 0.047663293109899765, 0.04238187103327494, 0.037722436382011705, 0.03372624200072896, 0.030162595178430045, 0.026980979096859162, 0. [...]
+[0.0, 0.010740470456838324, 0.01594646437972681, 0.019531036464462546, 0.02229686521049754, 0.024108440938811967, 0.025656375956551215, 0.026945114767690546, 0.027550216478839862, 0.027655997269181984, 0.02747685472454761, 0.02721289051481767, 0.026805184376316255, 0.026239415504967303, 0.025507087986152144, 0.024808760677644672, 0.024367514696388426, 0.023912192130629905, 0.023396850701918766, 0.022983510063237084, 0.0226893356284051, 0.022402161536239206, 0.022133055402567655, 0.021606 [...]
+[0.6797899999999992, 0.04623046506363538]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizemacsretain50000_Processed b/tests/manualtests/LD/cluster/Constantpopsizemacsretain50000_Processed
new file mode 100644
index 0000000..816a5dc
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizemacsretain50000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7335491623440177, 0.5672905450525926, 0.4563110846981205, 0.37829870216036243, 0.3209270373404815, 0.27760901322344483, 0.24401887834203087, 0.21712531661320963, 0.19555992045487955, 0.17782683035743505, 0.162882610499107, 0.15012151717428046, 0.1391315804344909, 0.12965728188870207, 0.12124445368433104, 0.11390997257712814, 0.10727826760280866, 0.10156572894134291, 0.09613010430005492, 0.09141582895915941, 0.08705846504775834, 0.0829625260102265, 0.0792526338367965, 0.0761768434 [...]
+[1.0, 0.7338209906732003, 0.567650125449399, 0.4567129989059654, 0.3786983407845462, 0.32129801062353097, 0.27794994080238633, 0.24433339510950144, 0.2174050631623137, 0.19581055912164894, 0.17804787212560763, 0.1630602357871174, 0.15027105095967885, 0.13925993800524467, 0.12977656061401457, 0.12136470042751829, 0.11401438697849856, 0.10736055978193056, 0.1016428497333746, 0.09621912687801552, 0.09149107882139698, 0.08712177272310535, 0.08302318483227163, 0.07932775161519506, 0.076263371 [...]
+[0.0, 0.013063330425625342, 0.018457504234060135, 0.021191898057623813, 0.022829541982350633, 0.023348696935366016, 0.023787163568173352, 0.02411294132868639, 0.024260446876095375, 0.02439671673670421, 0.02420629145330388, 0.02426141398822741, 0.024248371922973366, 0.024156899171932308, 0.02418843751036087, 0.024444692713877267, 0.02461315425956162, 0.02471464157034858, 0.02455400141121877, 0.02426149765524308, 0.024107897330283984, 0.02421067434204402, 0.024207850654032134, 0.0238683111 [...]
+[1.4658099999999994, 0.17211142873150484]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizemacsretain5000_Processed b/tests/manualtests/LD/cluster/Constantpopsizemacsretain5000_Processed
new file mode 100644
index 0000000..a5149a8
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizemacsretain5000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.732793051458726, 0.5656959769298147, 0.4533524227352122, 0.37319869209226186, 0.31329111878250815, 0.26671984058293574, 0.2293183461065978, 0.1990623131518846, 0.1737642916149272, 0.15246926672572206, 0.1343328418666027, 0.11868099655341158, 0.1051702350505257, 0.09356682744478764, 0.08331635413931521, 0.07435366209438773, 0.06662707943037224, 0.05980142250895657, 0.05385558425035644, 0.04834532371648086, 0.04352762617120063, 0.03934343079315345, 0.03546966776885159, 0.0320074677 [...]
+[1.0, 0.7327858880594459, 0.5656660969320734, 0.4532951119803758, 0.3731257325481783, 0.3132162862002018, 0.2666563217459872, 0.22925906867340462, 0.19900348002140877, 0.17371259165397654, 0.1524284486917844, 0.1342961216657315, 0.11865616485370196, 0.10515361185120824, 0.09354388925105622, 0.0832969805149138, 0.07434335501849604, 0.06662818295123929, 0.059828519370001214, 0.053896540932197104, 0.04838790518760328, 0.04356392178064904, 0.03937895738079941, 0.03550477935611721, 0.03202985 [...]
+[0.0, 0.010929853141642814, 0.015629252015512733, 0.018400861974409412, 0.02054394206793677, 0.022126912711474645, 0.023838670936896015, 0.025084781958782245, 0.025798806462576745, 0.02620881844749695, 0.026561922995105514, 0.02685003195174627, 0.026755389771175617, 0.02653267000411161, 0.026135011236265042, 0.025586207425613745, 0.025201866933291447, 0.024850929927412568, 0.024274320999786863, 0.023511111712288174, 0.02294693272466256, 0.022644870818179355, 0.02233821815756996, 0.021934 [...]
+[0.7221000000000006, 0.0527730044625091]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizemacsretain500_Processed b/tests/manualtests/LD/cluster/Constantpopsizemacsretain500_Processed
new file mode 100644
index 0000000..11e3a8a
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizemacsretain500_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.727493186038517, 0.5495106707458456, 0.4260952833143975, 0.33700593029672465, 0.2706439143614837, 0.22017893983352085, 0.18089151814253102, 0.1500994931530588, 0.12559887268554168, 0.10592094634610832, 0.08984789297922477, 0.07657826995473196, 0.065497632201239, 0.05631845803870819, 0.048893029820921995, 0.04273819480885359, 0.03743991528981308, 0.03294079674234759, 0.029197821898162005, 0.0257940791262404, 0.022730103372863304, 0.020116451439392734, 0.018033758155023585, 0.01614 [...]
+[1.0, 0.7274169377717907, 0.5494342203689853, 0.4260199767716247, 0.3369362175305373, 0.2705793708048592, 0.2201193265586232, 0.18084140640206542, 0.15005294410337372, 0.12554682372056197, 0.10586384293460176, 0.08980301433939267, 0.07654506390523914, 0.06546924983128571, 0.05629698374564599, 0.04887543249632707, 0.04271804727122883, 0.03741439604057482, 0.03290391106162649, 0.029152528038922345, 0.02575223034277545, 0.022688204785294958, 0.020084310263714912, 0.018014974442936576, 0.016 [...]
+[0.0, 0.010881341885293968, 0.017359346586361624, 0.02080008816046248, 0.022387317309499544, 0.02277911476509323, 0.022862011434333966, 0.02280122861508429, 0.022365202007624298, 0.021917955931391484, 0.021534732706711992, 0.021368568554277562, 0.021337268714591275, 0.021238867556934875, 0.020964601144991105, 0.02072976619867019, 0.020561090829028805, 0.02032375752140314, 0.020172322315121078, 0.01992146092673497, 0.01987437935866248, 0.019756577700959007, 0.01949679258675934, 0.01907304 [...]
+[0.6282500000000003, 0.027878979536561346]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizemacsretain70000_Processed b/tests/manualtests/LD/cluster/Constantpopsizemacsretain70000_Processed
new file mode 100644
index 0000000..e376293
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizemacsretain70000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7324365086349865, 0.565740179460841, 0.454628466914002, 0.37668038464250286, 0.3198359707058577, 0.27688148003552115, 0.24342945403579339, 0.2165471316492135, 0.19445881710872448, 0.17644488533967356, 0.161630037218438, 0.14909300859128735, 0.13817555573017792, 0.12830861189783888, 0.11973995428258839, 0.11260063956516764, 0.10630040698759963, 0.10077538082641749, 0.0955587139484835, 0.09084687579911753, 0.08625836690048236, 0.08212684477794331, 0.07876739423238092, 0.07548681247 [...]
+[1.0, 0.7327687244956306, 0.5661575728652453, 0.45503033718286157, 0.3770430203225495, 0.32016792741067635, 0.2771908860962919, 0.24371747047765613, 0.21681030794891512, 0.19469990135061047, 0.17666491227280876, 0.16182975922466003, 0.1492836030259529, 0.13835168530033173, 0.12845810692986295, 0.1198764935838216, 0.11274731705556162, 0.10644822384491462, 0.1009151193775016, 0.09569244980314626, 0.0909800934669028, 0.08640084484504014, 0.08227101316385521, 0.07891520740532258, 0.075641548 [...]
+[0.0, 0.01374103034916372, 0.019442515588251906, 0.022118168956704848, 0.02340532360675559, 0.02379501368288547, 0.024041306080763426, 0.024333490148772695, 0.0242748050498503, 0.02423422644005142, 0.024206978481248184, 0.024397272045267572, 0.024546082178552253, 0.024516425408653456, 0.024176291195492215, 0.023992625747245602, 0.02394583318319332, 0.023722695544132106, 0.023569201022126236, 0.023410236350653747, 0.023485857479935403, 0.023735570657562842, 0.023733286738771373, 0.0237700 [...]
+[1.7572400000000004, 0.21143931138745217]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizemacsretain7000_Processed b/tests/manualtests/LD/cluster/Constantpopsizemacsretain7000_Processed
new file mode 100644
index 0000000..9d6b5f8
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizemacsretain7000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7325328738688359, 0.5658373454347495, 0.4544471931849621, 0.37555638928391505, 0.3172253730953999, 0.2720224821093657, 0.23632319936265742, 0.20729461840719973, 0.1830814091501503, 0.16260680990198487, 0.14508737684029982, 0.1302099342173746, 0.1171126237582692, 0.1053509198948879, 0.09480733424866232, 0.08536341676885029, 0.07684490418984713, 0.06966269312286986, 0.06350654779923241, 0.05792080052150385, 0.05282863144475302, 0.048170571122625676, 0.04384048183306569, 0.039840725 [...]
+[1.0, 0.7325633139201055, 0.5658711743507859, 0.4544731943993036, 0.37557713524415864, 0.31724747243903245, 0.2720496720455446, 0.23634434993678397, 0.2073031473623576, 0.18307594091317472, 0.16259134601077746, 0.14506709532650078, 0.13017854574605764, 0.11707050780332284, 0.10530094700820011, 0.09475644648883225, 0.08532796902829715, 0.0768256179696181, 0.06965679775605037, 0.0635124526864197, 0.057920949789763636, 0.05281755824589583, 0.04815827177882967, 0.043829111833848945, 0.039822 [...]
+[0.0, 0.010776052587076873, 0.01562301792129641, 0.01818615282765361, 0.02006037751544426, 0.02167727980931282, 0.02289377113065884, 0.023844995720083823, 0.024729705055763666, 0.02530352338746691, 0.025649411757948708, 0.02598037012299089, 0.026414651894567962, 0.026444820970583375, 0.02645125364709187, 0.026238440055568444, 0.02587729317426617, 0.02538579603175693, 0.02492030266666901, 0.02463414059582707, 0.02435554337562608, 0.024435541570026396, 0.024431352979915687, 0.0241816901047 [...]
+[0.7602499999999993, 0.06379998040752037]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizems_Processed b/tests/manualtests/LD/cluster/Constantpopsizems_Processed
new file mode 100644
index 0000000..f2bd226
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizems_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7325305467990485, 0.5639731579617292, 0.44989902543124016, 0.36818856210213174, 0.30771787614888335, 0.26145347526338875, 0.22547097358347531, 0.1966860297556939, 0.17315528347597633, 0.15352569961885162, 0.13721492570023203, 0.1235640883388776, 0.11202024098246365, 0.10197492922427355, 0.09347743217763779, 0.08599769446592051, 0.07937818947553855, 0.07349625178100343, 0.06821366663400678, 0.06377497132083021, 0.05947548287514641, 0.055733569905903405, 0.05247510876934775, 0.0494 [...]
+[1.0, 0.7325349946178449, 0.5639705391681546, 0.4498764492046018, 0.36814634720215766, 0.3076653195651736, 0.2613931144601828, 0.22540499456929897, 0.1966192371942432, 0.17308404552123774, 0.153454367065439, 0.13714426264303478, 0.12348869082203648, 0.11194564434337333, 0.10190455766868267, 0.09342029720454767, 0.08595262871838812, 0.07934043812502722, 0.07346570048995277, 0.06818753015596728, 0.06374871751262465, 0.059446454433802344, 0.05570358393717199, 0.05244703032411032, 0.04947058 [...]
+[0.0, 0.010434747813048623, 0.015609221498152779, 0.01781607187327418, 0.019067281043721962, 0.020076073020631118, 0.020803251322765552, 0.021272908341247003, 0.021602533280380327, 0.02186914323250688, 0.022010251085152744, 0.02214696880405323, 0.022133674742713876, 0.021966333153661314, 0.02200482799898865, 0.02210272804419013, 0.02227525441473519, 0.022406162121834217, 0.022364640058403693, 0.02228181424617619, 0.0223520753375325, 0.022408333198020595, 0.022528653070540975, 0.022223165 [...]
+[27.984920000000013, 1.8648805306506901]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizeparam b/tests/manualtests/LD/cluster/Constantpopsizeparam
new file mode 100644
index 0000000..fa8f3a4
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizeparam
@@ -0,0 +1,22 @@
+case: Constantpopsize
+nsam: 6
+replicate: 1000
+seqlen: 10000001
+rho: 4000
+job: Constantpopsizems_
+job: Constantpopsizescrmwindow100000_
+job: Constantpopsizescrmwindow70000_
+job: Constantpopsizescrmwindow50000_
+job: Constantpopsizescrmwindow30000_
+job: Constantpopsizescrmwindow10000_
+job: Constantpopsizescrmwindow7000_
+job: Constantpopsizescrmwindow5000_
+job: Constantpopsizescrmwindow3000_
+job: Constantpopsizescrmwindow1000_
+job: Constantpopsizescrmwindow500_
+job: Constantpopsizescrmwindow0_
+job: Constantpopsizefastsimcoal_
+job: Constantpopsizemacs_
+job: Constantpopsizemacsretain1000_
+job: Constantpopsizemacsretain10000_
+job: Constantpopsizemacsretain100000_
diff --git a/tests/manualtests/LD/cluster/Constantpopsizescrmwindow0_Processed b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow0_Processed
new file mode 100644
index 0000000..fe1fb17
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow0_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7236867013577923, 0.5413480431127244, 0.41529068276060366, 0.3251959325482139, 0.2590102303422396, 0.20906117576982328, 0.1707085439331447, 0.14076262391717495, 0.11716159352186738, 0.09849495494855191, 0.08335878920798011, 0.07101300136391668, 0.06108277451350335, 0.052795969081400294, 0.04573689368425031, 0.03990317493900491, 0.03473718832048811, 0.030405769898702684, 0.026658000844579158, 0.023451361697086802, 0.020813827018347938, 0.018555991798515345, 0.016436804755798225, 0 [...]
+[1.0, 0.7235888390898279, 0.5412473086606335, 0.41521304359486666, 0.32513647889417846, 0.2589636844102834, 0.20903200466780714, 0.17069459087638855, 0.14075813602569204, 0.11716096135756751, 0.09849715420010582, 0.08336315665765266, 0.07101213095200823, 0.06107826552014448, 0.052791626955558786, 0.045726811365593464, 0.03988004105243997, 0.03470606133641692, 0.03037108500646746, 0.026630988102881805, 0.023439522164482196, 0.02081705520098143, 0.01856048583432286, 0.016448410308910713, 0 [...]
+[0.0, 0.01040163063338081, 0.015317963167517828, 0.017625386716165037, 0.018653982977823048, 0.01937067678211355, 0.019700101008488395, 0.019714225493296114, 0.0196343778333925, 0.019535953848293625, 0.01952944238134771, 0.019639257287838482, 0.019667420950571016, 0.019651327652304394, 0.01982809098152659, 0.019903785222738953, 0.01972201255831709, 0.019753950292539568, 0.019741106585774246, 0.01956551386589026, 0.019266261202342913, 0.01878906755209803, 0.018606054163351322, 0.018519916 [...]
+[1.0711499999999978, 0.029532651421773765]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizescrmwindow100000_Processed b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow100000_Processed
new file mode 100644
index 0000000..9757236
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow100000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7317391471998114, 0.5627688413228308, 0.44826888037791485, 0.36661321196462765, 0.30633635988637786, 0.2604468156790112, 0.2244813860572697, 0.1958943876476957, 0.17256091633155415, 0.153209194075657, 0.13700094863821916, 0.12328679181365858, 0.11159149491944831, 0.101789640479239, 0.09334222296549566, 0.0858405829843153, 0.07917288878223293, 0.07316594775247229, 0.06775210026239037, 0.06296454161389173, 0.058668646659174505, 0.054786837026339984, 0.05130337380058328, 0.048070477 [...]
+[1.0, 0.7317118513446126, 0.5627474846968928, 0.4482508061596026, 0.366584238684851, 0.30630537981273237, 0.2604233458911497, 0.22446991457861654, 0.19588604258971304, 0.17254970024964328, 0.15319437991333226, 0.13698907754900666, 0.12328281410472622, 0.11158202181444692, 0.10177214380198325, 0.09333514439176573, 0.08583607031018593, 0.07917335128089166, 0.07317269483291916, 0.06775494391908626, 0.06296059676902578, 0.05865559612100443, 0.054773263636137735, 0.05128844405755738, 0.048057 [...]
+[0.0, 0.010520635335713614, 0.015118072978796858, 0.017665542477622483, 0.019033328504038494, 0.020094706718914685, 0.020766397928695713, 0.02121344551883801, 0.02147064536375321, 0.02195488259357396, 0.02206985693716791, 0.021899178702019777, 0.021798270140877138, 0.021614277577330362, 0.021682769302064073, 0.021559960537648235, 0.021624201748225876, 0.021992012695886402, 0.02209509803702487, 0.022071215226774087, 0.0221467099756707, 0.02197623215808976, 0.021797193683371675, 0.02172513 [...]
+[2.140089999999999, 0.0760453279301233]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizescrmwindow10000_Processed b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow10000_Processed
new file mode 100644
index 0000000..ed9788a
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow10000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7320880459216418, 0.5632125460789839, 0.4486481975223306, 0.36717544712476397, 0.3067485266226323, 0.2606954867083994, 0.22480248915559448, 0.19585602427913845, 0.17232270408064593, 0.1531678698315906, 0.13653086117327906, 0.12134389996117088, 0.10786630295063736, 0.0960396907607016, 0.08565955252491063, 0.07647980296173087, 0.06839776380951557, 0.061195136574288427, 0.055028953262872216, 0.049499323399121616, 0.0448762689322541, 0.04069308689961466, 0.03683232973421832, 0.033416 [...]
+[1.0, 0.7320191565329391, 0.5631239779607881, 0.4485516437218029, 0.3670772572445134, 0.3066661768034439, 0.2606273263285859, 0.22473984433743327, 0.19578980684464117, 0.17224174415498383, 0.15308658377565082, 0.13644887326405644, 0.12127271522732032, 0.1078083168674679, 0.09598881320916354, 0.08560722415235379, 0.07641401281177106, 0.06832583899691709, 0.06111665582222108, 0.054943233243983175, 0.04941822724437801, 0.04480412811280823, 0.040625299616813666, 0.0367765719307182, 0.0333664 [...]
+[0.0, 0.010473580237971354, 0.015332685076372296, 0.01798054567521478, 0.019510118018463522, 0.020488359919117412, 0.020898792730618117, 0.02101146233684284, 0.02095306423695627, 0.02108705831894741, 0.021097896708379756, 0.02105203766381942, 0.020908415988312716, 0.020758179320930083, 0.020549351062305883, 0.020483549453937336, 0.020604234820763196, 0.020574353201781706, 0.02042146523339368, 0.020360319869848053, 0.020365907572376538, 0.020293022173700888, 0.020236685867805613, 0.020407 [...]
+[1.1572399999999996, 0.031183046676038648]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizescrmwindow1000_Processed b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow1000_Processed
new file mode 100644
index 0000000..df35b5f
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow1000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7327141668304127, 0.5584911556633094, 0.4344509711598272, 0.3432575219090695, 0.27519790272845296, 0.2233297383731312, 0.18301082161555768, 0.15138273436326521, 0.12637750765795544, 0.10636774759444005, 0.09009229091484075, 0.07694574047437604, 0.06617342337629305, 0.057067440700838905, 0.04946035541379239, 0.043134898043028516, 0.037767070806601126, 0.03324662634939133, 0.02942011641277052, 0.026244137914371017, 0.023507752022044796, 0.021278952928269704, 0.019220472650203893, 0 [...]
+[1.0, 0.732611235331332, 0.5583502497346461, 0.43430335022635935, 0.3431188730775281, 0.27507654376553375, 0.22323386571175916, 0.18293722417338212, 0.15132134805105044, 0.12632319845044812, 0.10632845839556568, 0.09005197273059297, 0.07689464964939688, 0.06611412585818897, 0.057004329328332236, 0.049391804953888854, 0.043052336239025046, 0.03769025771698918, 0.033182449430006936, 0.029350417111334327, 0.026168272550994565, 0.02343631431774137, 0.021201061836915294, 0.019138488572745867, [...]
+[0.0, 0.00991174266590244, 0.014558305598435723, 0.01715947371634256, 0.018499411762806842, 0.019085487467050376, 0.019325376750698085, 0.019459498983342538, 0.01983942864973797, 0.019926531222583317, 0.019836268011826173, 0.0198217902702671, 0.019715636357066635, 0.019502529405202945, 0.01925226857705449, 0.019110561103695023, 0.019137533521203964, 0.01932400719977118, 0.019456019071653164, 0.019547646489929984, 0.019614203160491225, 0.01965578617874206, 0.019576080570877504, 0.01946054 [...]
+[1.0757200000000002, 0.026166421230271446]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizescrmwindow30000_Processed b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow30000_Processed
new file mode 100644
index 0000000..e320878
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow30000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7325380059437596, 0.5637248548696434, 0.4493794994490604, 0.3677737206094186, 0.3073633786970189, 0.2611957371322493, 0.2251272326144597, 0.19640320099142147, 0.1731839959340425, 0.15401132380869131, 0.13791919635693836, 0.12413627889325525, 0.11224457825852452, 0.10205510675727147, 0.093190702701239, 0.08541758071061657, 0.0787649487152856, 0.07295144322866362, 0.0676965596404661, 0.06295217251588617, 0.05882997996294633, 0.05506658951287861, 0.051505493551315853, 0.048309442809 [...]
+[1.0, 0.732501757871609, 0.5637003155363819, 0.44935924004660543, 0.36776210267105214, 0.30735507095183356, 0.2611778184431591, 0.22510883105117194, 0.19639851463120483, 0.1731961893017823, 0.15403259862848287, 0.1379427664541688, 0.12415607751496945, 0.11226584219650994, 0.10207451223688398, 0.09320489995494435, 0.0854226335216242, 0.07876057568763146, 0.0729340913531003, 0.0676603723765407, 0.06290578314366017, 0.05877734450461657, 0.05501870256722373, 0.05146645353620436, 0.0482799587 [...]
+[0.0, 0.010940789830020376, 0.015959916810755072, 0.018240410949202018, 0.01967534434587951, 0.02060703999601498, 0.02134277403495699, 0.022120768715973536, 0.022409863545421536, 0.02264590776959252, 0.022577161105572875, 0.02228484239717464, 0.022100346075998537, 0.021794710663506623, 0.021713904937747896, 0.021487748023939726, 0.02132640924858275, 0.021203844988740127, 0.020922223848541383, 0.021039006956807278, 0.021115394199772267, 0.020977786144333765, 0.020877054389048723, 0.020858 [...]
+[1.3481399999999903, 0.038723899597018815]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizescrmwindow3000_Processed b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow3000_Processed
new file mode 100644
index 0000000..bcea8df
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow3000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.732164060391309, 0.5635068832598635, 0.44903857336205066, 0.364337071600938, 0.2983822360021538, 0.24647172046225457, 0.20509887696005868, 0.17190085503145872, 0.14488966316204624, 0.12282571138156897, 0.10486719196563044, 0.09029337030454813, 0.07832430328167833, 0.06818969405040208, 0.05950716874831091, 0.05225700761917881, 0.04596964207073071, 0.04047372864551176, 0.03571527386923968, 0.03145052988214266, 0.027714789322917065, 0.024597036843368256, 0.0218234300351434, 0.019410 [...]
+[1.0, 0.7320734450186042, 0.563387024297944, 0.4489312813282483, 0.36424169131572115, 0.2983023998123836, 0.24641061222744573, 0.20505295273542642, 0.1718622092488322, 0.14485740128137886, 0.12280765181138115, 0.10485997991428418, 0.09028377900015702, 0.07830943432541654, 0.06816513170203853, 0.05947898600106832, 0.05222525988235145, 0.045941012316399556, 0.040452598997289944, 0.03569639678281122, 0.03143303791222093, 0.02770123948945018, 0.02458964051784396, 0.021819214366909572, 0.0194 [...]
+[0.0, 0.010311022237198382, 0.015286408252181083, 0.0175976080843899, 0.01918763689852428, 0.020191050887917096, 0.02074225271110086, 0.02107527692901668, 0.02126879876580142, 0.021127630364232916, 0.02086352514341386, 0.0204721252672178, 0.020032933000455826, 0.01972299517500584, 0.01962116847036862, 0.019648404405114193, 0.019616021389753574, 0.019575072586029932, 0.01974690303501873, 0.020013241455052996, 0.020083367993449175, 0.020127067839688484, 0.020255494381925795, 0.020269365388 [...]
+[1.0948300000000046, 0.029667677698127906]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizescrmwindow50000_Processed b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow50000_Processed
new file mode 100644
index 0000000..30f2966
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow50000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7322924834656442, 0.5636635204337295, 0.4494899294214329, 0.36799282325030636, 0.3077727877735919, 0.261923549691612, 0.22578164862823183, 0.19687730972085135, 0.1736066722415485, 0.1543000315973227, 0.13824099404334086, 0.12469238686933988, 0.11289832205180818, 0.10288683741339337, 0.09418665116476277, 0.08662673220240481, 0.07988573183585704, 0.0739735685558192, 0.06839738439423236, 0.06322298604941103, 0.058824423108504435, 0.055034519092558354, 0.05176034997880474, 0.04862843 [...]
+[1.0, 0.7322771512602212, 0.5636483827559574, 0.44945997032037804, 0.3679539003612691, 0.3077468023868288, 0.261913138732068, 0.22577700069325565, 0.19686385241151758, 0.17359447673462663, 0.15428269257326904, 0.1382112964578783, 0.12465971785827314, 0.11286782879913389, 0.10286381301724963, 0.09416920048788781, 0.08660784435923287, 0.07987368005114281, 0.07396152752426631, 0.0683877497649434, 0.06321867740644029, 0.05881203670468286, 0.055015319273258846, 0.05173470959813908, 0.04859450 [...]
+[0.0, 0.01066212037204298, 0.01550767955147015, 0.018231891936725843, 0.01961303745050753, 0.020514236181337138, 0.021151928867293977, 0.021580910480589428, 0.021760382390112253, 0.021751472307146233, 0.02187738304519424, 0.021957735265209753, 0.021882866024466624, 0.021712712063195805, 0.02154190059565318, 0.02139289248631023, 0.02149679078787171, 0.021652204975569144, 0.021741180599024065, 0.021655392693787648, 0.0216082235118972, 0.021530138796168177, 0.021541983838984653, 0.021453229 [...]
+[1.5565999999999858, 0.046998297841517676]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizescrmwindow5000_Processed b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow5000_Processed
new file mode 100644
index 0000000..a608070
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow5000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7325056016593354, 0.5637242238927118, 0.4494703185200584, 0.36798803540440383, 0.30745731044472313, 0.25957019723047187, 0.21978302326597488, 0.18694546921808425, 0.1598743000219737, 0.13732765176086756, 0.11863246070629097, 0.1028987655483825, 0.08955316534204945, 0.0783658487425173, 0.06886791791694809, 0.06067413205364624, 0.05357698452585004, 0.047527439168157555, 0.04238901526376519, 0.03777288503665494, 0.03371268863527065, 0.03034054771470348, 0.027252766461499517, 0.02452 [...]
+[1.0, 0.7324314503847992, 0.5636314982628619, 0.4493763232240077, 0.3678941344956219, 0.3073722120093269, 0.25949495018942975, 0.21970586076112292, 0.18685405068332672, 0.15977767544203966, 0.1372462564129361, 0.11857437456350904, 0.10285014977762308, 0.08952171115079158, 0.07833694691009477, 0.06884266799817505, 0.06064405942916389, 0.053538750616924195, 0.047487729499673774, 0.04235215811878977, 0.037746359981235024, 0.03368510267311257, 0.030316441500090326, 0.027237034572465065, 0.02 [...]
+[0.0, 0.010378845936727936, 0.015025797631347327, 0.017198638480750195, 0.01845323055774471, 0.019129394400710837, 0.019742076048596215, 0.01982762405580836, 0.019968605762270546, 0.019906264768049048, 0.019926034515691308, 0.020186846937889767, 0.02033116542595465, 0.02046448300120142, 0.02040476096457764, 0.020432238093999428, 0.02058274098258049, 0.020536419274646743, 0.02052316794749955, 0.020694536266327872, 0.020712378409618454, 0.0205519955856929, 0.020458043269268072, 0.020211425 [...]
+[1.111650000000004, 0.030912416599159522]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizescrmwindow500_Processed b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow500_Processed
new file mode 100644
index 0000000..a1096ab
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow500_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7298277428492564, 0.5507437657543277, 0.42515726214326216, 0.33420228731912005, 0.2666474139190856, 0.21544895174520662, 0.1760758891650364, 0.14534140902501647, 0.12100318856328345, 0.10168966802615019, 0.08624183690699841, 0.07345480560489827, 0.06276262879974469, 0.05383979775095857, 0.04648903340133337, 0.040595703568980374, 0.035501598990494584, 0.031196184063794253, 0.027461376489711073, 0.024055072740439335, 0.021196382288135737, 0.018841916998319445, 0.01678227686897268,  [...]
+[1.0, 0.7297049805974498, 0.5506077388612347, 0.4250302696716655, 0.33408085687615974, 0.26653603423003913, 0.21534957774522373, 0.17599437752562047, 0.14526757544812915, 0.12093259237369597, 0.10162374514210609, 0.08618585853731928, 0.07340290453949155, 0.062715029801538, 0.05378891153539199, 0.04643163474602158, 0.04054061833066413, 0.03544154493773021, 0.03113157151018543, 0.027392840889584914, 0.023975605741552008, 0.021106694389617982, 0.01874249098174325, 0.016684298421874792, 0.01 [...]
+[0.0, 0.01001906448646724, 0.01482554023600946, 0.017325252521456377, 0.018663733621385643, 0.019203801381459943, 0.01966967874728848, 0.019871679017713348, 0.02000078071231438, 0.01987935754881229, 0.019801367542065202, 0.01967278377040695, 0.019580189076873904, 0.019805433185537517, 0.019940092580798735, 0.01985392263381244, 0.01980046231687606, 0.019769187883163626, 0.019676393707631294, 0.019437448508440376, 0.019280134914487542, 0.01925527477122192, 0.019216362446665202, 0.019241940 [...]
+[1.074199999999999, 0.029195205085767194]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizescrmwindow70000_Processed b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow70000_Processed
new file mode 100644
index 0000000..522d696
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow70000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7322720634519406, 0.5633610187280057, 0.4490526796907898, 0.36745109384376706, 0.3069154449579744, 0.26048253123104, 0.2241042223898561, 0.19517217931149297, 0.17156907792060158, 0.15235348491454206, 0.13635748183517735, 0.12278359550194619, 0.11132808604555987, 0.10157143075379825, 0.0929342197886178, 0.08537126829348901, 0.07863239267933136, 0.0726764078486119, 0.06749586774042853, 0.06257196701131358, 0.05808831991800172, 0.05413525873849584, 0.05051565941217819, 0.04732499208 [...]
+[1.0, 0.7322260658831342, 0.5632999243276198, 0.44897308757301563, 0.3673742178030572, 0.3068300745107534, 0.260387008655309, 0.22400231768052567, 0.19508070874631034, 0.17147168554472408, 0.15225559004992378, 0.1362649142382854, 0.12270732892897311, 0.11126478496395555, 0.10151557330437826, 0.09287584931929965, 0.08530904908051795, 0.07857993758119569, 0.07262732060938808, 0.06743807366521277, 0.06251213651947755, 0.0580270846738278, 0.0540772966562819, 0.05046122153039236, 0.0472771200 [...]
+[0.0, 0.010914619996943181, 0.015717609655339103, 0.01807548875561027, 0.019222109145329996, 0.019941376336214234, 0.020585802888260583, 0.02110779541941763, 0.02149153088811223, 0.021741277574400638, 0.02184827089075894, 0.02190642359746506, 0.02196286639085093, 0.021983928224998565, 0.022045207742068456, 0.021961293129066764, 0.021939129360822388, 0.021933928974927023, 0.021912567319664178, 0.02192675363341278, 0.02197412318123799, 0.022294197916240974, 0.02245724549733925, 0.022490556 [...]
+[1.7788499999999918, 0.05518493906855385]
diff --git a/tests/manualtests/LD/cluster/Constantpopsizescrmwindow7000_Processed b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow7000_Processed
new file mode 100644
index 0000000..453cf1a
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Constantpopsizescrmwindow7000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7324806216267213, 0.5640230342976367, 0.44976707662885357, 0.368042100746856, 0.307503211765332, 0.26136567475634087, 0.22514590925174574, 0.1948764745436646, 0.16902704618785597, 0.1468802920095599, 0.12808854781551168, 0.11195864832169647, 0.09798336811831879, 0.08602591012259922, 0.07569069298740158, 0.06668643996470112, 0.05890732980123672, 0.0523431327492304, 0.04647000865630543, 0.04147246398508892, 0.037293317710196734, 0.03362641734020918, 0.030292740205274584, 0.02725084 [...]
+[1.0, 0.7324111590479498, 0.5639318539294242, 0.44967603375741044, 0.3679578193689067, 0.30742133121442444, 0.26130498059147333, 0.22509599826086402, 0.19483538235587905, 0.16898874224272237, 0.14684240687622407, 0.12804610799709748, 0.11191400182343512, 0.0979360279104181, 0.08598525196344294, 0.0756434661757463, 0.06663470647694668, 0.058849557100005875, 0.0522831498656662, 0.0464106976213308, 0.04141180000496331, 0.03723422098412114, 0.033569289355169535, 0.030239803147240743, 0.02720 [...]
+[0.0, 0.010388040160860769, 0.01479716372586039, 0.01694431310023729, 0.01816901040506154, 0.01913340876299788, 0.019872474375215794, 0.020415738430847576, 0.020652467618722012, 0.020877229513455737, 0.020971317258774148, 0.020977610870135253, 0.02092742894290973, 0.02084249962165863, 0.02077519199174902, 0.02085615113755504, 0.020948705283756454, 0.021230947252984075, 0.02129259582190121, 0.021270666144347253, 0.02135028146990741, 0.021362116265575475, 0.021240634359738584, 0.0211187011 [...]
+[1.1297799999999996, 0.031921021286919926]
diff --git a/tests/manualtests/LD/cluster/Divergence_test/Dpopparam b/tests/manualtests/LD/cluster/Divergence_test/Dpopparam
new file mode 100644
index 0000000..bb7a3ed
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Divergence_test/Dpopparam
@@ -0,0 +1,12 @@
+case: Dpop
+nsam: 6
+replicate: 1000
+seqlen: 10000001
+rho: 4000
+divergence: 1
+job: Dpopms_
+job: Dpopscrmwindow100000_
+job: Dpopscrmwindow50000_
+job: Dpopscrmwindow10000_
+job: Dpopscrmwindow1000_
+job: Dpopscrmwindow0_
diff --git a/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_ms.sh b/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_ms.sh
new file mode 100755
index 0000000..42ae745
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_ms.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N ms 
+#$ -t 1-1000
+#$ -j y
+
+case=Dpop
+nsam=6
+replicate=1000
+seqlen=10000001
+rho=4000 # This is equal to r * seqlen * 4 * Ne, which is 1e-8 * 1e7 * 4 * 1e4
+
+cmd="${nsam} 1 -T -r ${rho} ${seqlen} -I 2 3 3 -ej 1 2 1 "
+rep=$(expr $SGE_TASK_ID )
+
+#######################
+program=ms
+#######################
+job=${case}${program}_
+
+prefix=${job}${rep}
+mkdir ${prefix}
+fileprefix=${prefix}"/"${prefix}
+{ time -p ${program} ${cmd} > ${fileprefix} -seed ${rep} ${rep} ${rep} ;} 2> ${fileprefix}time.text
+tree_file_name=${fileprefix}"Trees"
+tree_freq_name=${fileprefix}"TreeFreq"
+tmrca_name=${fileprefix}"Tmrca"
+first_coal_name=${fileprefix}"FirstCoal"
+
+grep ';' ${fileprefix} | sed -e "s/\\[.*\\]//g" > ${tree_file_name}
+grep ";" ${fileprefix} | sed -e "s/\\[//g" | sed -e "s/\\].*;//g" > ${tree_freq_name}
+hybrid-Lambda -gt ${tree_file_name} -tmrca ${tmrca_name}
+hybrid-Lambda -gt ${tree_file_name} -firstcoal ${first_coal_name}
+
+outdir="/well/bsg/joezhu/"
+mv ${prefix} ${outdir}
diff --git a/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_scrm0.sh b/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_scrm0.sh
new file mode 100755
index 0000000..1672727
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_scrm0.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm0 
+#$ -t 1-1000
+#$ -j y
+
+case=Dpop
+nsam=6
+replicate=1000
+seqlen=10000001
+rho=4000 # This is equal to r * seqlen * 4 * Ne, which is 1e-8 * 1e7 * 4 * 1e4
+
+cmd="${nsam} 1 -T -r ${rho} ${seqlen} -I 2 3 3 -ej 1 2 1 "
+rep=$(expr $SGE_TASK_ID )
+#######################
+exact_window_i=0
+program=scrm
+#######################
+
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+mkdir ${prefix}
+fileprefix=${prefix}"/"${prefix}
+{ time -p ${program} ${cmd} > ${fileprefix} -seed ${rep} -l ${exact_window_i} ;} 2> ${fileprefix}time.text
+tree_file_name=${fileprefix}"Trees"
+tree_freq_name=${fileprefix}"TreeFreq"
+tmrca_name=${fileprefix}"Tmrca"
+first_coal_name=${fileprefix}"FirstCoal"
+
+grep ';' ${fileprefix} | sed -e "s/\\[.*\\]//g" > ${tree_file_name}
+grep ";" ${fileprefix} | sed -e "s/\\[//g" | sed -e "s/\\].*;//g" > ${tree_freq_name}
+hybrid-Lambda -gt ${tree_file_name} -tmrca ${tmrca_name}
+hybrid-Lambda -gt ${tree_file_name} -firstcoal ${first_coal_name}
+
+outdir="/well/bsg/joezhu/"
+mv ${prefix} ${outdir}
diff --git a/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_scrm1000.sh b/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_scrm1000.sh
new file mode 100755
index 0000000..0a04924
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_scrm1000.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm1000 
+#$ -t 1-1000
+#$ -j y
+
+case=Dpop
+nsam=6
+replicate=1000
+seqlen=10000001
+rho=4000 # This is equal to r * seqlen * 4 * Ne, which is 1e-8 * 1e7 * 4 * 1e4
+
+cmd="${nsam} 1 -T -r ${rho} ${seqlen} -I 2 3 3 -ej 1 2 1 "
+rep=$(expr $SGE_TASK_ID )
+#######################
+exact_window_i=1000
+program=scrm
+#######################
+
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+mkdir ${prefix}
+fileprefix=${prefix}"/"${prefix}
+{ time -p ${program} ${cmd} > ${fileprefix} -seed ${rep} -l ${exact_window_i} ;} 2> ${fileprefix}time.text
+tree_file_name=${fileprefix}"Trees"
+tree_freq_name=${fileprefix}"TreeFreq"
+tmrca_name=${fileprefix}"Tmrca"
+first_coal_name=${fileprefix}"FirstCoal"
+
+grep ';' ${fileprefix} | sed -e "s/\\[.*\\]//g" > ${tree_file_name}
+grep ";" ${fileprefix} | sed -e "s/\\[//g" | sed -e "s/\\].*;//g" > ${tree_freq_name}
+hybrid-Lambda -gt ${tree_file_name} -tmrca ${tmrca_name}
+hybrid-Lambda -gt ${tree_file_name} -firstcoal ${first_coal_name}
+
+outdir="/well/bsg/joezhu/"
+mv ${prefix} ${outdir}
diff --git a/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_scrm10000.sh b/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_scrm10000.sh
new file mode 100755
index 0000000..3ef9611
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_scrm10000.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm10000 
+#$ -t 1-1000
+#$ -j y
+
+case=Dpop
+nsam=6
+replicate=1000
+seqlen=10000001
+rho=4000 # This is equal to r * seqlen * 4 * Ne, which is 1e-8 * 1e7 * 4 * 1e4
+
+cmd="${nsam} 1 -T -r ${rho} ${seqlen} -I 2 3 3 -ej 1 2 1 "
+rep=$(expr $SGE_TASK_ID )
+#######################
+exact_window_i=10000
+program=scrm
+#######################
+
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+mkdir ${prefix}
+fileprefix=${prefix}"/"${prefix}
+{ time -p ${program} ${cmd} > ${fileprefix} -seed ${rep} -l ${exact_window_i} ;} 2> ${fileprefix}time.text
+tree_file_name=${fileprefix}"Trees"
+tree_freq_name=${fileprefix}"TreeFreq"
+tmrca_name=${fileprefix}"Tmrca"
+first_coal_name=${fileprefix}"FirstCoal"
+
+grep ';' ${fileprefix} | sed -e "s/\\[.*\\]//g" > ${tree_file_name}
+grep ";" ${fileprefix} | sed -e "s/\\[//g" | sed -e "s/\\].*;//g" > ${tree_freq_name}
+hybrid-Lambda -gt ${tree_file_name} -tmrca ${tmrca_name}
+hybrid-Lambda -gt ${tree_file_name} -firstcoal ${first_coal_name}
+
+outdir="/well/bsg/joezhu/"
+mv ${prefix} ${outdir}
diff --git a/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_scrm100000.sh b/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_scrm100000.sh
new file mode 100755
index 0000000..d614a09
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_scrm100000.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm100000 
+#$ -t 1-1000
+#$ -j y
+
+case=Dpop
+nsam=6
+replicate=1000
+seqlen=10000001
+rho=4000 # This is equal to r * seqlen * 4 * Ne, which is 1e-8 * 1e7 * 4 * 1e4
+
+cmd="${nsam} 1 -T -r ${rho} ${seqlen} -I 2 3 3 -ej 1 2 1 "
+rep=$(expr $SGE_TASK_ID )
+#######################
+exact_window_i=100000
+program=scrm
+#######################
+
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+mkdir ${prefix}
+fileprefix=${prefix}"/"${prefix}
+{ time -p ${program} ${cmd} > ${fileprefix} -seed ${rep} -l ${exact_window_i} ;} 2> ${fileprefix}time.text
+tree_file_name=${fileprefix}"Trees"
+tree_freq_name=${fileprefix}"TreeFreq"
+tmrca_name=${fileprefix}"Tmrca"
+first_coal_name=${fileprefix}"FirstCoal"
+
+grep ';' ${fileprefix} | sed -e "s/\\[.*\\]//g" > ${tree_file_name}
+grep ";" ${fileprefix} | sed -e "s/\\[//g" | sed -e "s/\\].*;//g" > ${tree_freq_name}
+hybrid-Lambda -gt ${tree_file_name} -tmrca ${tmrca_name}
+hybrid-Lambda -gt ${tree_file_name} -firstcoal ${first_coal_name}
+
+outdir="/well/bsg/joezhu/"
+mv ${prefix} ${outdir}
diff --git a/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_scrm50000.sh b/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_scrm50000.sh
new file mode 100755
index 0000000..c725603
--- /dev/null
+++ b/tests/manualtests/LD/cluster/Divergence_test/Dsubmit_scrm50000.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm50000 
+#$ -t 1-1000
+#$ -j y
+
+case=Dpop
+nsam=6
+replicate=1000
+seqlen=10000001
+rho=4000 # This is equal to r * seqlen * 4 * Ne, which is 1e-8 * 1e7 * 4 * 1e4
+
+cmd="${nsam} 1 -T -r ${rho} ${seqlen} -I 2 3 3 -ej 1 2 1 "
+rep=$(expr $SGE_TASK_ID )
+#######################
+exact_window_i=50000
+program=scrm
+#######################
+
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+mkdir ${prefix}
+fileprefix=${prefix}"/"${prefix}
+{ time -p ${program} ${cmd} > ${fileprefix} -seed ${rep} -l ${exact_window_i} ;} 2> ${fileprefix}time.text
+tree_file_name=${fileprefix}"Trees"
+tree_freq_name=${fileprefix}"TreeFreq"
+tmrca_name=${fileprefix}"Tmrca"
+first_coal_name=${fileprefix}"FirstCoal"
+
+grep ';' ${fileprefix} | sed -e "s/\\[.*\\]//g" > ${tree_file_name}
+grep ";" ${fileprefix} | sed -e "s/\\[//g" | sed -e "s/\\].*;//g" > ${tree_freq_name}
+hybrid-Lambda -gt ${tree_file_name} -tmrca ${tmrca_name}
+hybrid-Lambda -gt ${tree_file_name} -firstcoal ${first_coal_name}
+
+outdir="/well/bsg/joezhu/"
+mv ${prefix} ${outdir}
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizefastsimcoal_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizefastsimcoal_Processed
new file mode 100644
index 0000000..bb1baef
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizefastsimcoal_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7243775300015043, 0.5425611440815619, 0.4165328958824117, 0.3261529614074926, 0.25957950760232734, 0.20955099892504417, 0.17133058721438363, 0.1414693627475885, 0.11803237233609196, 0.09935107915803157, 0.08423909563776673, 0.07184279608997815, 0.061581140665377836, 0.053087442187692464, 0.04599783286531609, 0.039980473526355656, 0.03496753810463444, 0.030876753525886765, 0.027374061329584726, 0.024538935383411526]
+[1.0, 0.7242637587173805, 0.5424448771619065, 0.416435266136729, 0.3260728279116408, 0.2595178258750776, 0.20950359826291606, 0.17129080729779836, 0.1414254185226608, 0.11797733258743924, 0.09929284988181146, 0.08417730721659049, 0.07178612066813529, 0.0615353721998468, 0.053053570706921085, 0.04597049940337092, 0.039954206763830005, 0.034932975429899135, 0.030832925982499024, 0.027329479670543538, 0.024507457645764893]
+[0.0, 0.010006306641869736, 0.014540426043946085, 0.01653388231514388, 0.01763638877252143, 0.018463605939813693, 0.019039041180199966, 0.019262509572144006, 0.01921539164418125, 0.019268812718793153, 0.019409049327846494, 0.019394423445336213, 0.0192898315650703, 0.019086820894284776, 0.0186986336990071, 0.018401710695162474, 0.018179745680255325, 0.018011586776125417, 0.018108275208874057, 0.018451864918623714, 0.01863906518407317]
+[0.6842100000000011, 0.020074259637655224]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacs_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacs_Processed
new file mode 100644
index 0000000..358d505
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacs_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7332733447150076, 0.5561850029950813, 0.43314034109850597, 0.34445534254846105, 0.2784395459301201, 0.22836753901404, 0.18959397482460358, 0.15913288949138338, 0.1347755515559568, 0.11529315980607162, 0.09941715325620476, 0.0863020424843241, 0.07562787431828778, 0.06656070053685247, 0.058989049609097254, 0.052341893471439284, 0.04681162989027694, 0.04223402638077424, 0.03821399331356674, 0.034566313538388065]
+[1.0, 0.73320031660142, 0.5561104407040541, 0.43308286495743753, 0.3444298842192089, 0.27843598389386276, 0.22838325781465554, 0.18961984349643732, 0.15915654277483046, 0.1347911751328947, 0.11529499945102796, 0.0994131866635672, 0.08629876011322099, 0.0756265129342558, 0.06655982895047903, 0.05898625720410305, 0.05233272447196541, 0.0468010705505765, 0.04222262084325446, 0.03820263596317357, 0.03456034373781677]
+[0.0, 0.009797839525856574, 0.0149674136983739, 0.017477445963465767, 0.018876164242345197, 0.019727523006598503, 0.02049370508725204, 0.02085720651776369, 0.020999330866426094, 0.021053659598540334, 0.021025366405758295, 0.020801132249402096, 0.020761634855726893, 0.02073421435321902, 0.020780944072550916, 0.020815246333943077, 0.020673619050202475, 0.02048725314343389, 0.020126193355878164, 0.019752158992579844, 0.01964468245398]
+[0.3095100000000006, 0.028189712662600983]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain0_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain0_Processed
new file mode 100644
index 0000000..1d9cfc3
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain0_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7237847388249016, 0.5414368268647574, 0.41551942113008977, 0.3254753325205462, 0.2592215597516827, 0.20915746431189644, 0.17065798760361478, 0.14076401509577577, 0.11713440339108931, 0.09829979412936007, 0.08307907025492434, 0.07048377569002263, 0.06010412693133504, 0.051545948286035606, 0.044694233796830164, 0.03908900280209849, 0.03432789091882597, 0.030240568559209362, 0.0267103099023525, 0.02359683193367406]
+[1.0, 0.7236884502913432, 0.5413428371400613, 0.41544056138633434, 0.3254132328977352, 0.2591701882181167, 0.2091115304377619, 0.17061759821775482, 0.14072005737131257, 0.11708706072133704, 0.09825422784724137, 0.08304138585268574, 0.07044618842116293, 0.06006966442539637, 0.05152063304435766, 0.04468139382928406, 0.03908100921391825, 0.034319547882904575, 0.03022864849662682, 0.026695885258841565, 0.023580165308460015]
+[0.0, 0.010086156077880904, 0.014620628637963536, 0.016838281576137034, 0.017998765425784203, 0.01855357050832857, 0.01885447372915256, 0.019056638334907245, 0.01923197776417342, 0.01922173760313484, 0.019033319490632108, 0.019008066786879056, 0.01917245219044236, 0.01943689110080192, 0.0195972456155152, 0.01973377792079508, 0.019620299864920004, 0.019337796217419632, 0.019316451683539338, 0.019183785275839076, 0.01901807122861624]
+[0.6170900000000014, 0.024852201109760965]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain100000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain100000_Processed
new file mode 100644
index 0000000..af6da83
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain100000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7330419653526885, 0.5669310850970853, 0.45594172838393476, 0.37777214223156785, 0.32105846961528234, 0.27811455952641706, 0.24481297693610599, 0.2180782979522165, 0.19652904386747908, 0.1785389108892151, 0.16356158840678658, 0.15072558008109813, 0.13979666137763577, 0.1304555130997109, 0.1221675076594823, 0.11497175654375778, 0.10837073460215761, 0.10282309146282738, 0.09770162275524584, 0.09280335481945609]
+[1.0, 0.7333353007894409, 0.5672823452052012, 0.45627808476105264, 0.37807221099624394, 0.3213270699782423, 0.27834718297914246, 0.24502513463855935, 0.21826545564573308, 0.19670401131233792, 0.1787079531010657, 0.1637283438977836, 0.15088695901912383, 0.13995096866924323, 0.13059857637417766, 0.12231084068271847, 0.11509380929847642, 0.10846365673161157, 0.1028842828863981, 0.09774935897454197, 0.09283574602631525]
+[0.0, 0.013486126604321651, 0.018893227639796593, 0.02181060894639389, 0.023131469258631278, 0.02360028965634936, 0.024038295729684463, 0.02434596187986085, 0.02444113063853672, 0.024416359435069486, 0.024486488016650678, 0.024468069687435593, 0.024275251337404987, 0.024229820067359048, 0.02419085545215932, 0.024172746489843508, 0.024076502376850984, 0.02416773722315248, 0.024283208272505657, 0.024178470028845288, 0.0240472606646111]
+[2.1760300000000026, 0.24961037458407048]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain10000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain10000_Processed
new file mode 100644
index 0000000..c5c74e4
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain10000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7329701381672368, 0.5665909791612574, 0.45548751404930987, 0.3770278424131447, 0.3194065732369363, 0.27551909610358993, 0.24089721032602057, 0.2129283522232058, 0.18985766261748172, 0.1706174184480888, 0.15414155127444795, 0.13976916155990043, 0.12713895057514135, 0.11593291041723501, 0.1060686909106835, 0.09711883835364009, 0.08894102225127079, 0.08179062307053636, 0.07519172125649394, 0.06895080668094565]
+[1.0, 0.7330227883296812, 0.566652944503916, 0.4555540680982492, 0.3770837203836077, 0.3194364867509899, 0.2755369541539279, 0.24089474488172313, 0.21289901996180924, 0.18981157431812462, 0.17055421481451752, 0.1540573417692521, 0.13966784659687065, 0.1270473092361064, 0.11584670525205941, 0.10596942722403753, 0.09700652401045923, 0.08882527531379364, 0.0816764340963057, 0.07507678759920129, 0.06883512112614204]
+[0.0, 0.011493995039907485, 0.016674070757118173, 0.018923713335822587, 0.020276553082158602, 0.021314800569703043, 0.02217490169789826, 0.02283573227024034, 0.02322367791266661, 0.023731810339228616, 0.024107571920973802, 0.02431044824683455, 0.024452919399539755, 0.024561329758920437, 0.024885833807878066, 0.025252297588811166, 0.025638108231324484, 0.025934451837782067, 0.026013526603760675, 0.026132329907406878, 0.025889315336435972]
+[0.8163900000000001, 0.0770393918719507]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain1000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain1000_Processed
new file mode 100644
index 0000000..16751f3
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain1000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7297599381647855, 0.5551201977708642, 0.4340541354528787, 0.3461872899835394, 0.2803911299161359, 0.22982934457627294, 0.1900077598399678, 0.15839821699321863, 0.13315138515165076, 0.11267048764010083, 0.09591528958744869, 0.08212335889480957, 0.07070078872701534, 0.06130794548650279, 0.05346970070220361, 0.046820167944817886, 0.04109981830842923, 0.03630934217648931, 0.0322554561441224, 0.02868272476204251]
+[1.0, 0.7296835349882086, 0.555026624144933, 0.4339523995318519, 0.3460953333620158, 0.2803065892960135, 0.22975048418158148, 0.18993183227305294, 0.15833357258176936, 0.13309113842850093, 0.11261544196614666, 0.09587466184647261, 0.08208177147014499, 0.07066248052527331, 0.061271628317952895, 0.053439868894545335, 0.04679657753990061, 0.041074435549393086, 0.03627562268407168, 0.032219864799812634, 0.02864348487901842]
+[0.0, 0.011036877902969774, 0.01780657369788039, 0.022115125485574177, 0.023999368791622382, 0.024942736188266146, 0.025191184011332367, 0.02502696278137738, 0.024631217788579074, 0.02416093354411102, 0.023781686033826563, 0.023457330648938804, 0.02312450923564513, 0.022952446134273333, 0.02273871344946043, 0.02231785125810902, 0.021742176549788605, 0.02115296541881952, 0.020992658417357958, 0.020881462495553126, 0.020797562170658694]
+[0.6383099999999995, 0.033275274604426544]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain30000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain30000_Processed
new file mode 100644
index 0000000..e1d55ba
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain30000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.733318263866994, 0.5672383064443925, 0.4563272540697702, 0.3783940726274112, 0.3212766818986271, 0.27807821026095486, 0.2443477362601038, 0.2176233426043472, 0.19586707447461565, 0.17800540417244817, 0.16322556103130184, 0.15065548299072773, 0.13980186845555617, 0.1301147047525375, 0.1218000719743119, 0.11448753449820644, 0.10785842075055575, 0.1022170536458403, 0.09700323251252589, 0.09209958903147278]
+[1.0, 0.7334994848342978, 0.5674563035802547, 0.456541085411608, 0.3785832842087679, 0.3214688815341574, 0.27826479270367516, 0.24450661386666844, 0.21774660581884622, 0.19599145052967623, 0.1781193239290877, 0.16332499213082496, 0.15072974167660155, 0.13984145453163857, 0.13012925548401658, 0.12179827772229082, 0.11446887556130193, 0.10782725355482776, 0.10217941429825443, 0.09695190897692645, 0.09203681971899447]
+[0.0, 0.012357672186154715, 0.017221775731836277, 0.01996668316417471, 0.0216160377904256, 0.02264246366723984, 0.02315920454619662, 0.023596614172567747, 0.02368410966107803, 0.0235197582926294, 0.023541254688701843, 0.023603315520642418, 0.023564221525140087, 0.02353798905849874, 0.023893916267169215, 0.024058171225381682, 0.023917564187266593, 0.023911326167346713, 0.023743481392006084, 0.02318472700845797, 0.02287540455234419]
+[1.1546400000000012, 0.13015095235917404]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain3000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain3000_Processed
new file mode 100644
index 0000000..0ff6c1f
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain3000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.732278836796659, 0.5636461582890689, 0.4489166795798966, 0.3660387933774626, 0.30354193231585697, 0.25442078996719053, 0.21535586459028602, 0.18349472992922902, 0.15741252573608838, 0.13569434618466183, 0.11766811656131414, 0.10272109667529268, 0.08966978550239058, 0.07849643951588384, 0.06907807940915862, 0.060876394878508544, 0.05364409450100586, 0.047609154732781774, 0.04233676360501896, 0.03767506168447303]
+[1.0, 0.7322566269836989, 0.5636284901214115, 0.44890297864189943, 0.36603073137245723, 0.3035454888826874, 0.2544279841589899, 0.21536061320522346, 0.18349867055736907, 0.15742158307863904, 0.13571333545390202, 0.11769676078253685, 0.10276436063794418, 0.08972212348948681, 0.07855631306264631, 0.06914486223232746, 0.060941024353271846, 0.05370535172630889, 0.047663293109899765, 0.04238187103327494, 0.037722436382011705]
+[0.0, 0.010740470456838324, 0.01594646437972681, 0.019531036464462546, 0.02229686521049754, 0.024108440938811967, 0.025656375956551215, 0.026945114767690546, 0.027550216478839862, 0.027655997269181984, 0.02747685472454761, 0.02721289051481767, 0.026805184376316255, 0.026239415504967303, 0.025507087986152144, 0.024808760677644672, 0.024367514696388426, 0.023912192130629905, 0.023396850701918766, 0.022983510063237084, 0.0226893356284051]
+[0.6797899999999992, 0.04623046506363538]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain50000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain50000_Processed
new file mode 100644
index 0000000..d29f2c7
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain50000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7335491623440177, 0.5672905450525926, 0.4563110846981205, 0.37829870216036243, 0.3209270373404815, 0.27760901322344483, 0.24401887834203087, 0.21712531661320963, 0.19555992045487955, 0.17782683035743505, 0.162882610499107, 0.15012151717428046, 0.1391315804344909, 0.12965728188870207, 0.12124445368433104, 0.11390997257712814, 0.10727826760280866, 0.10156572894134291, 0.09613010430005492, 0.09141582895915941]
+[1.0, 0.7338209906732003, 0.567650125449399, 0.4567129989059654, 0.3786983407845462, 0.32129801062353097, 0.27794994080238633, 0.24433339510950144, 0.2174050631623137, 0.19581055912164894, 0.17804787212560763, 0.1630602357871174, 0.15027105095967885, 0.13925993800524467, 0.12977656061401457, 0.12136470042751829, 0.11401438697849856, 0.10736055978193056, 0.1016428497333746, 0.09621912687801552, 0.09149107882139698]
+[0.0, 0.013063330425625342, 0.018457504234060135, 0.021191898057623813, 0.022829541982350633, 0.023348696935366016, 0.023787163568173352, 0.02411294132868639, 0.024260446876095375, 0.02439671673670421, 0.02420629145330388, 0.02426141398822741, 0.024248371922973366, 0.024156899171932308, 0.02418843751036087, 0.024444692713877267, 0.02461315425956162, 0.02471464157034858, 0.02455400141121877, 0.02426149765524308, 0.024107897330283984]
+[1.4658099999999994, 0.17211142873150484]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain5000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain5000_Processed
new file mode 100644
index 0000000..72c9526
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain5000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.732793051458726, 0.5656959769298147, 0.4533524227352122, 0.37319869209226186, 0.31329111878250815, 0.26671984058293574, 0.2293183461065978, 0.1990623131518846, 0.1737642916149272, 0.15246926672572206, 0.1343328418666027, 0.11868099655341158, 0.1051702350505257, 0.09356682744478764, 0.08331635413931521, 0.07435366209438773, 0.06662707943037224, 0.05980142250895657, 0.05385558425035644, 0.04834532371648086]
+[1.0, 0.7327858880594459, 0.5656660969320734, 0.4532951119803758, 0.3731257325481783, 0.3132162862002018, 0.2666563217459872, 0.22925906867340462, 0.19900348002140877, 0.17371259165397654, 0.1524284486917844, 0.1342961216657315, 0.11865616485370196, 0.10515361185120824, 0.09354388925105622, 0.0832969805149138, 0.07434335501849604, 0.06662818295123929, 0.059828519370001214, 0.053896540932197104, 0.04838790518760328]
+[0.0, 0.010929853141642814, 0.015629252015512733, 0.018400861974409412, 0.02054394206793677, 0.022126912711474645, 0.023838670936896015, 0.025084781958782245, 0.025798806462576745, 0.02620881844749695, 0.026561922995105514, 0.02685003195174627, 0.026755389771175617, 0.02653267000411161, 0.026135011236265042, 0.025586207425613745, 0.025201866933291447, 0.024850929927412568, 0.024274320999786863, 0.023511111712288174, 0.02294693272466256]
+[0.7221000000000006, 0.0527730044625091]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain500_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain500_Processed
new file mode 100644
index 0000000..669deca
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain500_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.727493186038517, 0.5495106707458456, 0.4260952833143975, 0.33700593029672465, 0.2706439143614837, 0.22017893983352085, 0.18089151814253102, 0.1500994931530588, 0.12559887268554168, 0.10592094634610832, 0.08984789297922477, 0.07657826995473196, 0.065497632201239, 0.05631845803870819, 0.048893029820921995, 0.04273819480885359, 0.03743991528981308, 0.03294079674234759, 0.029197821898162005, 0.0257940791262404]
+[1.0, 0.7274169377717907, 0.5494342203689853, 0.4260199767716247, 0.3369362175305373, 0.2705793708048592, 0.2201193265586232, 0.18084140640206542, 0.15005294410337372, 0.12554682372056197, 0.10586384293460176, 0.08980301433939267, 0.07654506390523914, 0.06546924983128571, 0.05629698374564599, 0.04887543249632707, 0.04271804727122883, 0.03741439604057482, 0.03290391106162649, 0.029152528038922345, 0.02575223034277545]
+[0.0, 0.010881341885293968, 0.017359346586361624, 0.02080008816046248, 0.022387317309499544, 0.02277911476509323, 0.022862011434333966, 0.02280122861508429, 0.022365202007624298, 0.021917955931391484, 0.021534732706711992, 0.021368568554277562, 0.021337268714591275, 0.021238867556934875, 0.020964601144991105, 0.02072976619867019, 0.020561090829028805, 0.02032375752140314, 0.020172322315121078, 0.01992146092673497, 0.01987437935866248]
+[0.6282500000000003, 0.027878979536561346]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain70000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain70000_Processed
new file mode 100644
index 0000000..1acc158
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain70000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7324365086349865, 0.565740179460841, 0.454628466914002, 0.37668038464250286, 0.3198359707058577, 0.27688148003552115, 0.24342945403579339, 0.2165471316492135, 0.19445881710872448, 0.17644488533967356, 0.161630037218438, 0.14909300859128735, 0.13817555573017792, 0.12830861189783888, 0.11973995428258839, 0.11260063956516764, 0.10630040698759963, 0.10077538082641749, 0.0955587139484835, 0.09084687579911753]
+[1.0, 0.7327687244956306, 0.5661575728652453, 0.45503033718286157, 0.3770430203225495, 0.32016792741067635, 0.2771908860962919, 0.24371747047765613, 0.21681030794891512, 0.19469990135061047, 0.17666491227280876, 0.16182975922466003, 0.1492836030259529, 0.13835168530033173, 0.12845810692986295, 0.1198764935838216, 0.11274731705556162, 0.10644822384491462, 0.1009151193775016, 0.09569244980314626, 0.0909800934669028]
+[0.0, 0.01374103034916372, 0.019442515588251906, 0.022118168956704848, 0.02340532360675559, 0.02379501368288547, 0.024041306080763426, 0.024333490148772695, 0.0242748050498503, 0.02423422644005142, 0.024206978481248184, 0.024397272045267572, 0.024546082178552253, 0.024516425408653456, 0.024176291195492215, 0.023992625747245602, 0.02394583318319332, 0.023722695544132106, 0.023569201022126236, 0.023410236350653747, 0.023485857479935403]
+[1.7572400000000004, 0.21143931138745217]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain7000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain7000_Processed
new file mode 100644
index 0000000..c840a30
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizemacsretain7000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7325328738688359, 0.5658373454347495, 0.4544471931849621, 0.37555638928391505, 0.3172253730953999, 0.2720224821093657, 0.23632319936265742, 0.20729461840719973, 0.1830814091501503, 0.16260680990198487, 0.14508737684029982, 0.1302099342173746, 0.1171126237582692, 0.1053509198948879, 0.09480733424866232, 0.08536341676885029, 0.07684490418984713, 0.06966269312286986, 0.06350654779923241, 0.05792080052150385]
+[1.0, 0.7325633139201055, 0.5658711743507859, 0.4544731943993036, 0.37557713524415864, 0.31724747243903245, 0.2720496720455446, 0.23634434993678397, 0.2073031473623576, 0.18307594091317472, 0.16259134601077746, 0.14506709532650078, 0.13017854574605764, 0.11707050780332284, 0.10530094700820011, 0.09475644648883225, 0.08532796902829715, 0.0768256179696181, 0.06965679775605037, 0.0635124526864197, 0.057920949789763636]
+[0.0, 0.010776052587076873, 0.01562301792129641, 0.01818615282765361, 0.02006037751544426, 0.02167727980931282, 0.02289377113065884, 0.023844995720083823, 0.024729705055763666, 0.02530352338746691, 0.025649411757948708, 0.02598037012299089, 0.026414651894567962, 0.026444820970583375, 0.02645125364709187, 0.026238440055568444, 0.02587729317426617, 0.02538579603175693, 0.02492030266666901, 0.02463414059582707, 0.02435554337562608]
+[0.7602499999999993, 0.06379998040752037]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizems_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizems_Processed
new file mode 100644
index 0000000..6a77040
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizems_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7325305467990485, 0.5639731579617292, 0.44989902543124016, 0.36818856210213174, 0.30771787614888335, 0.26145347526338875, 0.22547097358347531, 0.1966860297556939, 0.17315528347597633, 0.15352569961885162, 0.13721492570023203, 0.1235640883388776, 0.11202024098246365, 0.10197492922427355, 0.09347743217763779, 0.08599769446592051, 0.07937818947553855, 0.07349625178100343, 0.06821366663400678, 0.06377497132083021]
+[1.0, 0.7325349946178449, 0.5639705391681546, 0.4498764492046018, 0.36814634720215766, 0.3076653195651736, 0.2613931144601828, 0.22540499456929897, 0.1966192371942432, 0.17308404552123774, 0.153454367065439, 0.13714426264303478, 0.12348869082203648, 0.11194564434337333, 0.10190455766868267, 0.09342029720454767, 0.08595262871838812, 0.07934043812502722, 0.07346570048995277, 0.06818753015596728, 0.06374871751262465]
+[0.0, 0.010434747813048623, 0.015609221498152779, 0.01781607187327418, 0.019067281043721962, 0.020076073020631118, 0.020803251322765552, 0.021272908341247003, 0.021602533280380327, 0.02186914323250688, 0.022010251085152744, 0.02214696880405323, 0.022133674742713876, 0.021966333153661314, 0.02200482799898865, 0.02210272804419013, 0.02227525441473519, 0.022406162121834217, 0.022364640058403693, 0.02228181424617619, 0.0223520753375325]
+[27.984920000000013, 1.8648805306506901]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow0_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow0_Processed
new file mode 100644
index 0000000..552d056
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow0_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7236867013577923, 0.5413480431127244, 0.41529068276060366, 0.3251959325482139, 0.2590102303422396, 0.20906117576982328, 0.1707085439331447, 0.14076262391717495, 0.11716159352186738, 0.09849495494855191, 0.08335878920798011, 0.07101300136391668, 0.06108277451350335, 0.052795969081400294, 0.04573689368425031, 0.03990317493900491, 0.03473718832048811, 0.030405769898702684, 0.026658000844579158, 0.023451361697086802]
+[1.0, 0.7235888390898279, 0.5412473086606335, 0.41521304359486666, 0.32513647889417846, 0.2589636844102834, 0.20903200466780714, 0.17069459087638855, 0.14075813602569204, 0.11716096135756751, 0.09849715420010582, 0.08336315665765266, 0.07101213095200823, 0.06107826552014448, 0.052791626955558786, 0.045726811365593464, 0.03988004105243997, 0.03470606133641692, 0.03037108500646746, 0.026630988102881805, 0.023439522164482196]
+[0.0, 0.01040163063338081, 0.015317963167517828, 0.017625386716165037, 0.018653982977823048, 0.01937067678211355, 0.019700101008488395, 0.019714225493296114, 0.0196343778333925, 0.019535953848293625, 0.01952944238134771, 0.019639257287838482, 0.019667420950571016, 0.019651327652304394, 0.01982809098152659, 0.019903785222738953, 0.01972201255831709, 0.019753950292539568, 0.019741106585774246, 0.01956551386589026, 0.019266261202342913]
+[1.0711499999999978, 0.029532651421773765]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow100000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow100000_Processed
new file mode 100644
index 0000000..64ec016
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow100000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7317391471998114, 0.5627688413228308, 0.44826888037791485, 0.36661321196462765, 0.30633635988637786, 0.2604468156790112, 0.2244813860572697, 0.1958943876476957, 0.17256091633155415, 0.153209194075657, 0.13700094863821916, 0.12328679181365858, 0.11159149491944831, 0.101789640479239, 0.09334222296549566, 0.0858405829843153, 0.07917288878223293, 0.07316594775247229, 0.06775210026239037, 0.06296454161389173]
+[1.0, 0.7317118513446126, 0.5627474846968928, 0.4482508061596026, 0.366584238684851, 0.30630537981273237, 0.2604233458911497, 0.22446991457861654, 0.19588604258971304, 0.17254970024964328, 0.15319437991333226, 0.13698907754900666, 0.12328281410472622, 0.11158202181444692, 0.10177214380198325, 0.09333514439176573, 0.08583607031018593, 0.07917335128089166, 0.07317269483291916, 0.06775494391908626, 0.06296059676902578]
+[0.0, 0.010520635335713614, 0.015118072978796858, 0.017665542477622483, 0.019033328504038494, 0.020094706718914685, 0.020766397928695713, 0.02121344551883801, 0.02147064536375321, 0.02195488259357396, 0.02206985693716791, 0.021899178702019777, 0.021798270140877138, 0.021614277577330362, 0.021682769302064073, 0.021559960537648235, 0.021624201748225876, 0.021992012695886402, 0.02209509803702487, 0.022071215226774087, 0.0221467099756707]
+[2.140089999999999, 0.0760453279301233]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow10000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow10000_Processed
new file mode 100644
index 0000000..1cf09b1
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow10000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7320880459216418, 0.5632125460789839, 0.4486481975223306, 0.36717544712476397, 0.3067485266226323, 0.2606954867083994, 0.22480248915559448, 0.19585602427913845, 0.17232270408064593, 0.1531678698315906, 0.13653086117327906, 0.12134389996117088, 0.10786630295063736, 0.0960396907607016, 0.08565955252491063, 0.07647980296173087, 0.06839776380951557, 0.061195136574288427, 0.055028953262872216, 0.049499323399121616]
+[1.0, 0.7320191565329391, 0.5631239779607881, 0.4485516437218029, 0.3670772572445134, 0.3066661768034439, 0.2606273263285859, 0.22473984433743327, 0.19578980684464117, 0.17224174415498383, 0.15308658377565082, 0.13644887326405644, 0.12127271522732032, 0.1078083168674679, 0.09598881320916354, 0.08560722415235379, 0.07641401281177106, 0.06832583899691709, 0.06111665582222108, 0.054943233243983175, 0.04941822724437801]
+[0.0, 0.010473580237971354, 0.015332685076372296, 0.01798054567521478, 0.019510118018463522, 0.020488359919117412, 0.020898792730618117, 0.02101146233684284, 0.02095306423695627, 0.02108705831894741, 0.021097896708379756, 0.02105203766381942, 0.020908415988312716, 0.020758179320930083, 0.020549351062305883, 0.020483549453937336, 0.020604234820763196, 0.020574353201781706, 0.02042146523339368, 0.020360319869848053, 0.020365907572376538]
+[1.1572399999999996, 0.031183046676038648]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow1000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow1000_Processed
new file mode 100644
index 0000000..f1a06fe
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow1000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7327141668304127, 0.5584911556633094, 0.4344509711598272, 0.3432575219090695, 0.27519790272845296, 0.2233297383731312, 0.18301082161555768, 0.15138273436326521, 0.12637750765795544, 0.10636774759444005, 0.09009229091484075, 0.07694574047437604, 0.06617342337629305, 0.057067440700838905, 0.04946035541379239, 0.043134898043028516, 0.037767070806601126, 0.03324662634939133, 0.02942011641277052, 0.026244137914371017]
+[1.0, 0.732611235331332, 0.5583502497346461, 0.43430335022635935, 0.3431188730775281, 0.27507654376553375, 0.22323386571175916, 0.18293722417338212, 0.15132134805105044, 0.12632319845044812, 0.10632845839556568, 0.09005197273059297, 0.07689464964939688, 0.06611412585818897, 0.057004329328332236, 0.049391804953888854, 0.043052336239025046, 0.03769025771698918, 0.033182449430006936, 0.029350417111334327, 0.026168272550994565]
+[0.0, 0.00991174266590244, 0.014558305598435723, 0.01715947371634256, 0.018499411762806842, 0.019085487467050376, 0.019325376750698085, 0.019459498983342538, 0.01983942864973797, 0.019926531222583317, 0.019836268011826173, 0.0198217902702671, 0.019715636357066635, 0.019502529405202945, 0.01925226857705449, 0.019110561103695023, 0.019137533521203964, 0.01932400719977118, 0.019456019071653164, 0.019547646489929984, 0.019614203160491225]
+[1.0757200000000002, 0.026166421230271446]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow30000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow30000_Processed
new file mode 100644
index 0000000..f7b4ed2
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow30000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7325380059437596, 0.5637248548696434, 0.4493794994490604, 0.3677737206094186, 0.3073633786970189, 0.2611957371322493, 0.2251272326144597, 0.19640320099142147, 0.1731839959340425, 0.15401132380869131, 0.13791919635693836, 0.12413627889325525, 0.11224457825852452, 0.10205510675727147, 0.093190702701239, 0.08541758071061657, 0.0787649487152856, 0.07295144322866362, 0.0676965596404661, 0.06295217251588617]
+[1.0, 0.732501757871609, 0.5637003155363819, 0.44935924004660543, 0.36776210267105214, 0.30735507095183356, 0.2611778184431591, 0.22510883105117194, 0.19639851463120483, 0.1731961893017823, 0.15403259862848287, 0.1379427664541688, 0.12415607751496945, 0.11226584219650994, 0.10207451223688398, 0.09320489995494435, 0.0854226335216242, 0.07876057568763146, 0.0729340913531003, 0.0676603723765407, 0.06290578314366017]
+[0.0, 0.010940789830020376, 0.015959916810755072, 0.018240410949202018, 0.01967534434587951, 0.02060703999601498, 0.02134277403495699, 0.022120768715973536, 0.022409863545421536, 0.02264590776959252, 0.022577161105572875, 0.02228484239717464, 0.022100346075998537, 0.021794710663506623, 0.021713904937747896, 0.021487748023939726, 0.02132640924858275, 0.021203844988740127, 0.020922223848541383, 0.021039006956807278, 0.021115394199772267]
+[1.3481399999999903, 0.038723899597018815]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow3000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow3000_Processed
new file mode 100644
index 0000000..e0a9b00
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow3000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.732164060391309, 0.5635068832598635, 0.44903857336205066, 0.364337071600938, 0.2983822360021538, 0.24647172046225457, 0.20509887696005868, 0.17190085503145872, 0.14488966316204624, 0.12282571138156897, 0.10486719196563044, 0.09029337030454813, 0.07832430328167833, 0.06818969405040208, 0.05950716874831091, 0.05225700761917881, 0.04596964207073071, 0.04047372864551176, 0.03571527386923968, 0.03145052988214266]
+[1.0, 0.7320734450186042, 0.563387024297944, 0.4489312813282483, 0.36424169131572115, 0.2983023998123836, 0.24641061222744573, 0.20505295273542642, 0.1718622092488322, 0.14485740128137886, 0.12280765181138115, 0.10485997991428418, 0.09028377900015702, 0.07830943432541654, 0.06816513170203853, 0.05947898600106832, 0.05222525988235145, 0.045941012316399556, 0.040452598997289944, 0.03569639678281122, 0.03143303791222093]
+[0.0, 0.010311022237198382, 0.015286408252181083, 0.0175976080843899, 0.01918763689852428, 0.020191050887917096, 0.02074225271110086, 0.02107527692901668, 0.02126879876580142, 0.021127630364232916, 0.02086352514341386, 0.0204721252672178, 0.020032933000455826, 0.01972299517500584, 0.01962116847036862, 0.019648404405114193, 0.019616021389753574, 0.019575072586029932, 0.01974690303501873, 0.020013241455052996, 0.020083367993449175]
+[1.0948300000000046, 0.029667677698127906]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow50000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow50000_Processed
new file mode 100644
index 0000000..c06ed99
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow50000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7322924834656442, 0.5636635204337295, 0.4494899294214329, 0.36799282325030636, 0.3077727877735919, 0.261923549691612, 0.22578164862823183, 0.19687730972085135, 0.1736066722415485, 0.1543000315973227, 0.13824099404334086, 0.12469238686933988, 0.11289832205180818, 0.10288683741339337, 0.09418665116476277, 0.08662673220240481, 0.07988573183585704, 0.0739735685558192, 0.06839738439423236, 0.06322298604941103]
+[1.0, 0.7322771512602212, 0.5636483827559574, 0.44945997032037804, 0.3679539003612691, 0.3077468023868288, 0.261913138732068, 0.22577700069325565, 0.19686385241151758, 0.17359447673462663, 0.15428269257326904, 0.1382112964578783, 0.12465971785827314, 0.11286782879913389, 0.10286381301724963, 0.09416920048788781, 0.08660784435923287, 0.07987368005114281, 0.07396152752426631, 0.0683877497649434, 0.06321867740644029]
+[0.0, 0.01066212037204298, 0.01550767955147015, 0.018231891936725843, 0.01961303745050753, 0.020514236181337138, 0.021151928867293977, 0.021580910480589428, 0.021760382390112253, 0.021751472307146233, 0.02187738304519424, 0.021957735265209753, 0.021882866024466624, 0.021712712063195805, 0.02154190059565318, 0.02139289248631023, 0.02149679078787171, 0.021652204975569144, 0.021741180599024065, 0.021655392693787648, 0.0216082235118972]
+[1.5565999999999858, 0.046998297841517676]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow5000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow5000_Processed
new file mode 100644
index 0000000..0be3034
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow5000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7325056016593354, 0.5637242238927118, 0.4494703185200584, 0.36798803540440383, 0.30745731044472313, 0.25957019723047187, 0.21978302326597488, 0.18694546921808425, 0.1598743000219737, 0.13732765176086756, 0.11863246070629097, 0.1028987655483825, 0.08955316534204945, 0.0783658487425173, 0.06886791791694809, 0.06067413205364624, 0.05357698452585004, 0.047527439168157555, 0.04238901526376519, 0.03777288503665494]
+[1.0, 0.7324314503847992, 0.5636314982628619, 0.4493763232240077, 0.3678941344956219, 0.3073722120093269, 0.25949495018942975, 0.21970586076112292, 0.18685405068332672, 0.15977767544203966, 0.1372462564129361, 0.11857437456350904, 0.10285014977762308, 0.08952171115079158, 0.07833694691009477, 0.06884266799817505, 0.06064405942916389, 0.053538750616924195, 0.047487729499673774, 0.04235215811878977, 0.037746359981235024]
+[0.0, 0.010378845936727936, 0.015025797631347327, 0.017198638480750195, 0.01845323055774471, 0.019129394400710837, 0.019742076048596215, 0.01982762405580836, 0.019968605762270546, 0.019906264768049048, 0.019926034515691308, 0.020186846937889767, 0.02033116542595465, 0.02046448300120142, 0.02040476096457764, 0.020432238093999428, 0.02058274098258049, 0.020536419274646743, 0.02052316794749955, 0.020694536266327872, 0.020712378409618454]
+[1.111650000000004, 0.030912416599159522]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow500_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow500_Processed
new file mode 100644
index 0000000..d07d3a4
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow500_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7298277428492564, 0.5507437657543277, 0.42515726214326216, 0.33420228731912005, 0.2666474139190856, 0.21544895174520662, 0.1760758891650364, 0.14534140902501647, 0.12100318856328345, 0.10168966802615019, 0.08624183690699841, 0.07345480560489827, 0.06276262879974469, 0.05383979775095857, 0.04648903340133337, 0.040595703568980374, 0.035501598990494584, 0.031196184063794253, 0.027461376489711073, 0.024055072740439335]
+[1.0, 0.7297049805974498, 0.5506077388612347, 0.4250302696716655, 0.33408085687615974, 0.26653603423003913, 0.21534957774522373, 0.17599437752562047, 0.14526757544812915, 0.12093259237369597, 0.10162374514210609, 0.08618585853731928, 0.07340290453949155, 0.062715029801538, 0.05378891153539199, 0.04643163474602158, 0.04054061833066413, 0.03544154493773021, 0.03113157151018543, 0.027392840889584914, 0.023975605741552008]
+[0.0, 0.01001906448646724, 0.01482554023600946, 0.017325252521456377, 0.018663733621385643, 0.019203801381459943, 0.01966967874728848, 0.019871679017713348, 0.02000078071231438, 0.01987935754881229, 0.019801367542065202, 0.01967278377040695, 0.019580189076873904, 0.019805433185537517, 0.019940092580798735, 0.01985392263381244, 0.01980046231687606, 0.019769187883163626, 0.019676393707631294, 0.019437448508440376, 0.019280134914487542]
+[1.074199999999999, 0.029195205085767194]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow70000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow70000_Processed
new file mode 100644
index 0000000..cf21a1a
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow70000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7322720634519406, 0.5633610187280057, 0.4490526796907898, 0.36745109384376706, 0.3069154449579744, 0.26048253123104, 0.2241042223898561, 0.19517217931149297, 0.17156907792060158, 0.15235348491454206, 0.13635748183517735, 0.12278359550194619, 0.11132808604555987, 0.10157143075379825, 0.0929342197886178, 0.08537126829348901, 0.07863239267933136, 0.0726764078486119, 0.06749586774042853, 0.06257196701131358]
+[1.0, 0.7322260658831342, 0.5632999243276198, 0.44897308757301563, 0.3673742178030572, 0.3068300745107534, 0.260387008655309, 0.22400231768052567, 0.19508070874631034, 0.17147168554472408, 0.15225559004992378, 0.1362649142382854, 0.12270732892897311, 0.11126478496395555, 0.10151557330437826, 0.09287584931929965, 0.08530904908051795, 0.07857993758119569, 0.07262732060938808, 0.06743807366521277, 0.06251213651947755]
+[0.0, 0.010914619996943181, 0.015717609655339103, 0.01807548875561027, 0.019222109145329996, 0.019941376336214234, 0.020585802888260583, 0.02110779541941763, 0.02149153088811223, 0.021741277574400638, 0.02184827089075894, 0.02190642359746506, 0.02196286639085093, 0.021983928224998565, 0.022045207742068456, 0.021961293129066764, 0.021939129360822388, 0.021933928974927023, 0.021912567319664178, 0.02192675363341278, 0.02197412318123799]
+[1.7788499999999918, 0.05518493906855385]
diff --git a/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow7000_Processed b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow7000_Processed
new file mode 100644
index 0000000..131d67d
--- /dev/null
+++ b/tests/manualtests/LD/cluster/LD2E4/Constantpopsizescrmwindow7000_Processed
@@ -0,0 +1,4 @@
+[1.0, 0.7324806216267213, 0.5640230342976367, 0.44976707662885357, 0.368042100746856, 0.307503211765332, 0.26136567475634087, 0.22514590925174574, 0.1948764745436646, 0.16902704618785597, 0.1468802920095599, 0.12808854781551168, 0.11195864832169647, 0.09798336811831879, 0.08602591012259922, 0.07569069298740158, 0.06668643996470112, 0.05890732980123672, 0.0523431327492304, 0.04647000865630543, 0.04147246398508892]
+[1.0, 0.7324111590479498, 0.5639318539294242, 0.44967603375741044, 0.3679578193689067, 0.30742133121442444, 0.26130498059147333, 0.22509599826086402, 0.19483538235587905, 0.16898874224272237, 0.14684240687622407, 0.12804610799709748, 0.11191400182343512, 0.0979360279104181, 0.08598525196344294, 0.0756434661757463, 0.06663470647694668, 0.058849557100005875, 0.0522831498656662, 0.0464106976213308, 0.04141180000496331]
+[0.0, 0.010388040160860769, 0.01479716372586039, 0.01694431310023729, 0.01816901040506154, 0.01913340876299788, 0.019872474375215794, 0.020415738430847576, 0.020652467618722012, 0.020877229513455737, 0.020971317258774148, 0.020977610870135253, 0.02092742894290973, 0.02084249962165863, 0.02077519199174902, 0.02085615113755504, 0.020948705283756454, 0.021230947252984075, 0.02129259582190121, 0.021270666144347253, 0.02135028146990741]
+[1.1297799999999996, 0.031921021286919926]
diff --git a/tests/manualtests/LD/cluster/fastsimcoal_process.py b/tests/manualtests/LD/cluster/fastsimcoal_process.py
new file mode 100755
index 0000000..30fb768
--- /dev/null
+++ b/tests/manualtests/LD/cluster/fastsimcoal_process.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+import sys
+if __name__ == "__main__":
+    prefix = sys.argv[1]
+    seqlen = int(sys.argv[2])
+    _4Ne = float(40000.0)    
+
+    tmrca_in_name  = prefix + "Tmrcaraw"
+    tmrca_out_name = prefix + "Tmrca"
+    tmrca = [ float(x)/_4Ne for x in open( tmrca_in_name, "r" )]
+    print "len(tmrca) = ", len(tmrca)
+    tmrca_out = open( tmrca_out_name, "w")
+    for tmrca_i in tmrca:
+        tmrca_out.write(`tmrca_i`+"\n")
+    tmrca_out.close()
+
+    bl_in_name  = prefix + "BLraw"
+    bl_out_name = prefix + "BL"
+    bl = [ float(x)/_4Ne for x in open( bl_in_name, "r" )]
+    print "len(bl) = ", len(bl)
+    bl_out = open( bl_out_name, "w")
+    for bl_i in bl:
+        bl_out.write(`bl_i`+"\n")
+    bl_out.close()
+    
+    freq_in_name  = prefix + "change"
+    freq_out_name = prefix + "TreeFreq"
+    change = [ int(x) for x in open ( freq_in_name, "r" ) ]
+    change.append(seqlen)
+    #print change
+    
+    freq_out = open( freq_out_name, "w")
+    freq = [] 
+    for i in range(1, len(change)):
+        freq.append( change[i] - change[i-1]) 
+        freq_out.write(`change[i] - change[i-1]` + "\n")
+    freq_out.close()
+    #print freq
+    print "len(freq) = ", len(freq)
diff --git a/tests/manualtests/LD/cluster/fastsimcoal_sim.sh b/tests/manualtests/LD/cluster/fastsimcoal_sim.sh
new file mode 100755
index 0000000..750338e
--- /dev/null
+++ b/tests/manualtests/LD/cluster/fastsimcoal_sim.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N fastsimcoal 
+#$ -t 1-1000
+#$ -j y
+
+
+source parameters_preset
+
+
+fsc_param_file=1Pop20sample.par
+
+program=fastsimcoal
+
+job=${case}${program}_
+
+#for rep in $(seq 1 1 10)
+    #do 
+prefix=${job}${rep}
+mkdir ${top_dir}"/"${prefix}
+fileprefix=${top_dir}"/"${prefix}"/"${prefix}
+
+infile=${prefix}.par
+outfile=${prefix}"/"${prefix}_1_true_trees.trees    
+cp ${fsc_param_file} ${infile}
+echo ${fileprefix}
+{ time -p ${program} -i ${infile} -n 1 -T --seed ${rep} > ${prefix}dummy ;} 2> ${fileprefix}timedummy.text
+sed -e "/No/d" ${fileprefix}timedummy.text > ${fileprefix}time.text
+
+grep ");" ${outfile} | sed -e "s/tree.*pos_/\\[/g" -e "s/ = \\[&U\\] /\\]/g" > ${fileprefix}
+
+tree_file_name=${fileprefix}"Trees"
+tree_change_name=${fileprefix}"change"
+tree_freq_name=${fileprefix}"TreeFreq"
+tmrca_raw_name=${fileprefix}"Tmrcaraw"
+bl_raw_name=${fileprefix}"BLraw"
+
+grep ';' ${fileprefix} | sed -e "s/\\[.*\\]//g" > ${tree_file_name}
+grep ";" ${fileprefix} | sed -e "s/\\[//g" | sed -e "s/\\].*;//g" > ${tree_change_name}    
+hybrid-Lambda -gt ${tree_file_name} -tmrca ${tmrca_raw_name}
+hybrid-Lambda -gt ${tree_file_name} -bl ${bl_raw_name}
+./fastsimcoal_process.py ${fileprefix} 10000001
+
+rm ${infile} ${outfile} ${fileprefix} ${tree_file_name} ${fileprefix}timedummy.text ${tree_change_name} ${tmrca_raw_name} ${prefix}dummy ${bl_raw_name}
+rm -r ${prefix}
+
+    
+    #done
diff --git a/tests/manualtests/LD/cluster/launchall.sh b/tests/manualtests/LD/cluster/launchall.sh
new file mode 100755
index 0000000..47f2869
--- /dev/null
+++ b/tests/manualtests/LD/cluster/launchall.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+#joblist=("fastsimcoal_sim.sh" \
+#"submit_ms.sh" \
+#"macs_retain0.sh" "macs_retain500.sh" "macs_retain1000.sh" \
+#"macs_retain3000.sh" "macs_retain5000.sh" "macs_retain7000.sh" "macs_retain10000.sh" \
+#"macs_retain30000.sh" "macs_retain50000.sh" "macs_retain70000.sh" "macs_retain100000.sh" \
+#"macs_retain300000.sh" "macs_retain500000.sh" "macs_retain700000.sh" "macs_retain1000000.sh" \
+#"submit_scrm0.sh" "submit_scrm500.sh" "submit_scrm1000.sh" \
+#"submit_scrm3000.sh" "submit_scrm5000.sh" "submit_scrm7000.sh" "submit_scrm10000.sh" \
+#"submit_scrm30000.sh" "submit_scrm50000.sh" "submit_scrm70000.sh" "submit_scrm100000.sh" \
+#"submit_scrm300000.sh" "submit_scrm500000.sh" "submit_scrm700000.sh" "submit_scrm1000000.sh" \
+#)
+
+joblist=("submit_scrm0.sh" "submit_scrm500.sh" "submit_scrm1000.sh" \
+"submit_scrm3000.sh" "submit_scrm5000.sh" "submit_scrm7000.sh" "submit_scrm10000.sh" \
+"submit_scrm30000.sh" "submit_scrm50000.sh" "submit_scrm70000.sh" "submit_scrm100000.sh" \
+"submit_scrm300000.sh" "submit_scrm500000.sh" "submit_scrm700000.sh" "submit_scrm1000000.sh" \
+)
+
+#joblist=("submit_scrm300000.sh" "submit_scrm500000.sh" "submit_scrm700000.sh" "submit_scrm1000000.sh" \
+#"macs_retain300000.sh" "macs_retain500000.sh" "macs_retain700000.sh" "macs_retain1000000.sh" \
+#)
+
+for jobi in $(seq 0 1 32)
+    do
+    echo ${joblist[${jobi}]}
+    qsub ${joblist[${jobi}]}
+    done
diff --git a/tests/manualtests/LD/cluster/ld_test.py b/tests/manualtests/LD/cluster/ld_test.py
new file mode 100755
index 0000000..45f37da
--- /dev/null
+++ b/tests/manualtests/LD/cluster/ld_test.py
@@ -0,0 +1,404 @@
+#!/usr/bin/env python
+
+import numpy as np
+import os
+import sys
+import pylab
+from scipy.integrate import simps, trapz
+
+__mydebug__       = False
+__fix_ms_seed__   = False
+__fix_scrm_seed__ = False
+
+# exact_windows_length [0, 10e2, 10e3, 10e4, -1]
+
+class parameter:
+    def __init__( self, nsam = 6, replicate = 100, seqlen = 1e7, rho = 1e-8 , exact_window_length = 0 , divergence = 0, jobs = []): 
+        """
+        Define simulation parameters
+        """
+        self.nsam      = nsam
+        self.rep       = replicate
+        self.seqlen    = seqlen # 10e7
+        #self.theta     = 7 * 10e-10 * seqlen * 4 * 10000
+        #self.rho       = rho * (self.seqlen-1) * 4 * 10000
+        self.rho       = rho
+        self.exact_window_length = exact_window_length
+        self.divergence = divergence
+        self.jobs = jobs
+        
+        
+        delta_points = 20
+        big_delta_max = 2e5
+        #big_delta_max = 1e4
+        small_delta_max = 2e4
+        #small_delta_max = big_delta_max
+        self.big_delta = np.linspace( 0, int(big_delta_max+1), delta_points )
+        #self.big_delta = range( 0, int(big_delta_max+1), 10000 )
+        self.small_delta = np.linspace( 0, int(small_delta_max+1), delta_points )
+
+    
+    def printing ( self ):
+        """
+        Check simulation parameters
+        """
+        print "sample size:       ", self.nsam
+        print "replicate:         ",   self.rep
+        print "Sequence length:   ", self.seqlen
+        print "recombination rate:", self.rho
+        print "jobs:", self.jobs
+        
+    
+    #def define_command ( self, scrm = False ):        
+        #cmd = `self.nsam` + " 1 " + " -T " + " -r " + `self.rho` + " " + `int(self.seqlen)`
+        #if self.divergence > 0: cmd += " -I 2 " + `self.nsam/2` + " " + `self.nsam/2` + " -ej 1 2 1 "
+        #if scrm :  cmd += " -l " + `int(self.exact_window_length)`
+        #if __fix_ms_seed__ :   cmd += " -seed 2 2 2 "
+        #if __fix_scrm_seed__ :   cmd += " -seed 2 "
+        #if __mydebug__: print cmd
+        ##print cmd
+        #return cmd
+        
+        
+        
+
+def extract_all_info ( job_prefix, num_rep):
+    data = []
+    #print "total num_rep = ", num_rep
+    for rep in range(1, num_rep+1):
+        #print "replicate:",rep
+        out = extract_info ( job_prefix, rep )
+        # (tree_freq, tmrca, first_coal_time, clade, runtime)
+        data.append( out )
+    #print data
+    return data
+    
+    
+    
+def extract_info (job_prefix, ith_rep): 
+    prefix = job_prefix + `ith_rep` + "/" + job_prefix + `ith_rep`
+    tree_file_name  = prefix + "Trees"
+    tree_freq_name  = prefix + "TreeFreq"
+    tmrca_name      = prefix + "Tmrca"
+    first_coal_name = prefix + "FirstCoal"
+    tree_freq = [ float(x) for x in open( tree_freq_name, "r" ) ]
+    
+    tmrca = [ float(x) for x in open( tmrca_name, "r" )]
+    
+    first_coal_file = open( first_coal_name, "r" )
+    first_coal_time = []
+    clade = []
+    #for line in first_coal_file:
+        #first_coal_time.append( float(line.split()[0]) )        
+        #clade.append( line.split()[1] )
+    first_coal_file.close()
+    
+    timeFile_name = prefix+"time.text"
+    runtime = float(open( timeFile_name, "r").readlines()[1].strip("user").strip('\n'))
+    #print runtime
+
+    return  tree_freq, tmrca, first_coal_time, clade, runtime
+
+
+def cal_ac_TMRC_star (tree_freq, tmrca, avg_tmrca, delta):
+
+    seqlen = sum(tree_freq)
+
+    cumfreq = [0]
+    shifted_cumfreq = [] 
+    for x in tree_freq : 
+        cumfreq.append(cumfreq[-1] + x)
+        shifted_cumfreq.append(cumfreq[-1] - delta)
+    cumfreq.pop(0)
+
+    n = int(seqlen - delta)
+    ac = 0
+    var = 0
+    
+    if __mydebug__:
+        print tree_freq
+        print cumfreq
+        print shifted_cumfreq        
+        print "seqence length = ", seqlen
+        print "i should iterate until ", n, "trees"
+    
+    T1_index = 0
+    T2_index = 0 # use while loop to determine the initial T2_index
+    while delta > cumfreq[T2_index]: # need to check again ...
+        T2_index += 1
+    about_to = False
+    for i in range( n ): 
+        if __mydebug__ & ((not i < cumfreq[T1_index]) | (not i < shifted_cumfreq[T2_index])):
+            print "before", i, T1_index,  T2_index
+            print "-------------------------------"
+            about_to = True
+        if i >= cumfreq[T1_index]: T1_index += 1
+        term1 = tmrca[T1_index] - avg_tmrca
+        if i >= shifted_cumfreq[T2_index]: T2_index += 1
+        term2 = tmrca[T2_index] - avg_tmrca
+        if __mydebug__ & about_to:
+            print "after ", i, T1_index,  T2_index
+            about_to = False
+        #print i, T1_index, term1, T2_index, term2
+        ac += term1 * term2
+        var += term1 * term1
+    ac /= float(n)
+    var /= float(n)
+    return ac, var
+
+
+def cal_ac_TMRC_star_2 (tree_freq, tmrca, avg_tmrca, delta):
+
+    seqlen = int(sum(tree_freq))
+    #print seqlen
+    cumfreq = [0]
+    for x in tree_freq : 
+        cumfreq.append(cumfreq[-1] + x)
+    cumfreq.pop(0)
+
+    n = int(seqlen - delta)
+    ac = 0
+    var = 0
+    
+    T1_index = 0
+    T2_index = 0 # use while loop to determine the initial T2_index
+    while delta > cumfreq[T2_index]: # need to check again ...
+        T2_index += 1
+    i = 0
+    while i < n:
+        distance = min( cumfreq[T1_index] - i, 
+                        cumfreq[T2_index] - delta - i )
+        distance = min( distance, n - i )
+        term1 = tmrca[T1_index] - avg_tmrca
+        term2 = tmrca[T2_index] - avg_tmrca
+        ac += term1 * term2 * distance
+        var += term1 * term1 * distance
+        i += distance            
+        if i >= cumfreq[T1_index]: T1_index += 1
+        if i + delta >= cumfreq[T2_index]: T2_index += 1
+    ac /= float(n)
+    var /= float(n)
+    return ac, var
+
+
+def cal_ac_clade_2 (tree_freq, clade, delta ):
+    seqlen = sum(tree_freq)
+    cumfreq = [0]
+    for x in tree_freq : 
+        cumfreq.append(cumfreq[-1] + x)
+    cumfreq.pop(0)
+    n = int(seqlen - delta)
+    ac = 0.0
+    length = 0.0
+    T1_index = 0
+    T2_index = 0 # use while loop to determine the initial T2_index
+    while delta > cumfreq[T2_index]: # need to check again ...
+        T2_index += 1
+    i = 0
+    while i < n:
+        distance = min( cumfreq[T1_index] - i, 
+                        cumfreq[T2_index] - delta - i )
+        distance = min( distance, n - i )
+        term1 = clade[T1_index]  
+        term2 = clade[T2_index]  
+        ac += distance if term1 == term2 else 0
+        length += distance
+        i += distance            
+        if i >= cumfreq[T1_index]: T1_index += 1
+        if i + delta >= cumfreq[T2_index]: T2_index += 1
+
+    ac /= float(n)
+    length /= float(n)   # this should be 1
+    return ac, length
+
+    
+    
+def cal_ac_clade (tree_freq, clade, delta ):
+    seqlen = sum(tree_freq)
+    cumfreq = [0]
+    shifted_cumfreq = [] 
+    for x in tree_freq : 
+        cumfreq.append(cumfreq[-1] + x)
+        shifted_cumfreq.append(cumfreq[-1] - delta)
+    cumfreq.pop(0)
+    #print cumfreq, shifted_cumfreq
+    n = int(seqlen - delta)
+    ac = 0.0
+    length = 0.0
+    T1_index = 0
+    T2_index = 0 # use while loop to determine the initial T2_index
+    while delta > cumfreq[T2_index]: # need to check again ...
+        T2_index += 1
+    for i in range( n ):        
+        T1_index += 0 if i < cumfreq[T1_index] else 1
+        term1 = clade[T1_index] 
+        T2_index += 0 if i < shifted_cumfreq[T2_index] else 1
+        term2 = clade[T2_index] 
+        #print i, T1_index, term1, T2_index, term2
+        ac += 1 if term1 == term2 else 0
+        length += 1
+    ac /= float(n)
+    length /= float(n)   # this should be 1
+    return ac, length
+    
+
+        
+def process_data ( data , small_delta, big_delta) :
+    # compute the average Tmrca and Tmrc
+    #tree_freq, tmrca, first_coal_time, clade, runtime
+    tot_tmrca = 0
+    #tot_tmrc = 0
+    tot_time = 0
+    tot_runtime = 0
+    for d in data:
+        tot_runtime += d[4]
+        for i, duration_i in enumerate( d[0] ):   # d[0] : tree_freq, duration of the tree
+            tmrca_i = d[1][i]                     # d[1] : tmrca
+            #tmrc_i = d[2][i]                      # d[2] : tmrc
+            tot_time += duration_i                # d[0] : duration of the tree
+            tot_tmrca += tmrca_i * duration_i     # JOE changed from tot_tmrca += tmrca_i
+            #tot_tmrc += tmrc_i * duration_i       # JOE changed from tot_tmrc += tmrc_i
+    avg_tmrca = tot_tmrca / tot_time
+    #avg_tmrc = tot_tmrc / tot_time
+    
+    ac_TMRC = []    
+    ac_clade = []
+    
+    # COMMENT OUT THE FOLLOWING, THE LINES ALL LAY ON TOP OF EACH OTHER FOR THE MOST RECENT COALECENT EVENTS
+    #for delta_i in big_delta:
+        #print "processing delta:", delta_i
+        #cum_ac_TMRC = 0
+        #cum_var_TMRC = 0
+        #cum_ac_clade = 0
+        #cum_length_clade = 0
+        #for d in data:
+            #ac, var = cal_ac_TMRC_star_2( d[0], d[2], avg_tmrc, delta_i )
+            #cum_ac_TMRC += ac
+            #cum_var_TMRC += var
+            #ac, length = cal_ac_clade_2( d[0], d[3], delta_i )
+            #cum_ac_clade += ac
+            #cum_length_clade += length
+        #ac_TMRC.append( cum_ac_TMRC / cum_var_TMRC )
+        #ac_clade.append( cum_ac_clade / cum_length_clade )
+        
+    ac_TMRCA  = []    
+    for delta_i in small_delta:
+        print "processing delta:", delta_i        
+        cum_ac_TMRCA = 0
+        cum_var_TMRCA = 0
+        for d in data:
+            ac, var = cal_ac_TMRC_star_2( d[0], d[1], avg_tmrca, delta_i )
+            cum_ac_TMRCA += ac
+            cum_var_TMRCA += var
+        ac_TMRCA.append( cum_ac_TMRCA / cum_var_TMRCA )
+
+    return ac_TMRCA, ac_TMRC, ac_clade, tot_runtime
+    
+
+def myfigures ( delta, rho, prefix, legend, colors):
+    # rho is a list of MS, SCRM (pruned) and SCRM (full pruning) results
+    # results is a list of autocorrelations, one for each delta
+    #print legend
+    l = [] 
+    fig,(ax1)=pylab.subplots(1,1)
+    for i in range ( len (rho) ):
+        #y_err = [np.std(yi)*1.96/np.sqrt(len(yi)) for yi in rho[i]]
+        tmp1 = ax1.plot( delta, rho[i] , color = colors[i])
+        l.append ( tmp1 )
+    pylab.xlim( [np.min(delta), np.max(delta)] )
+    #pylab.title( prefix + " of " + `len(delta)` + " delta points" )
+    pylab.xlabel(r'Distance between two sites $\delta$')
+    pylab.ylabel(r'Autocorrelation $\rho$')
+    pylab.legend ([ x[0] for x in l], legend, loc = 1)
+    pylab.savefig( prefix+".pdf" )
+    pylab.close()
+
+
+def time_figure(accuracy, time, prefix, legend, colors):
+    x = accuracy
+    y = time
+    markers = ["v", "o", "*", ">", "<", "s", "^", "+" , "D", "H"]
+    #pylab.title("Time vs accuracy")
+    pylab.ylabel("Time")
+    pylab.xlabel("Accuracy")
+    #pylab.xlabel("rho tmrca at delta = 10000")
+    myl = []
+    for i, xi in enumerate(x):
+        myl.append(pylab.plot( x[i], np.log(y[i]), markers[i]))
+    my_axes = pylab.gca()
+    yticks = my_axes.get_yticks()
+    ylabels = ["%.5g" % (np.exp(float(y))) for y in yticks]
+    my_axes.set_yticklabels(ylabels)    
+    pylab.legend( [ lx[0] for lx in myl ] ,  legend, loc=1, numpoints=1)
+    pylab.savefig( prefix+"_timeVSacc.pdf")
+    pylab.close()
+
+
+def read_param_file ( experiment_name ):
+    top_param = parameter()
+    experiment_file = open( experiment_name, "r" )
+    for line in experiment_file:
+        if   line.split()[0] == "case:":          top_param.case       = line.split()[1]
+        elif line.split()[0] == "nsam:":          top_param.nsam    = line.split()[1]
+        elif line.split()[0] == "replicate:":     top_param.rep = int(line.split()[1])
+        elif line.split()[0] == "seqlen:":        top_param.seqlen    = int(line.split()[1])
+        elif line.split()[0] == "rho:":           top_param.rho = float(line.split()[1])
+        elif line.split()[0] == "divergence:":    top_param.divergence    = int(line.split()[1])
+        elif line.split()[0] == "job:":    top_param.jobs.append( line.split()[1] )
+    experiment_file.close()
+    
+    top_param.printing()
+    return top_param
+
+def calculate_acurrcy(data_matrix, delta, obj_index =0 ): # obj_index is index for processed data, 0: tmrca, 1: TMRC, 2: clade
+    accuracy = []
+    ms_ld = data_matrix[0][obj_index]    
+    print ms_ld
+    for data_i in data_matrix:
+        programs_ld = data_i[0]
+        y = np.array([ ms_ld[i] - programs_ld[i] for i in range(len(ms_ld))] )
+        accuracy.append(np.abs(simps(y, x = delta)))
+    return accuracy
+
+def calculate_acurrcy_array( data_array, delta): # obj_index is index for processed data, 0: tmrca, 1: TMRC, 2: clade
+    accuracy = []
+    ms_ld = data_array[0]
+    for data_i in data_array:
+        #programs_ld = data_i[0]
+        y = np.array([ ms_ld[i] - data_i[i] for i in range(len(ms_ld))] )
+        accuracy.append(np.abs(simps(y, x = delta)))
+    return accuracy
+    
+if __name__ == "__main__":
+    _use_param = read_param_file ( sys.argv[1] )
+    _use_param.printing()
+    
+    processed_data = []
+    for job in _use_param.jobs:
+        print job
+        data = extract_all_info (job, _use_param.rep)
+        #compute_averge_T (data)
+        processed_data.append( process_data (data, _use_param.small_delta,  _use_param.big_delta) )
+    
+    _legend = [ job[len(_use_param.case):-1] for job in _use_param.jobs ]
+    _colors = [ "orange", "purple", "green",  "red",  "blue", "black",  "yellow", "cyan", "magenta"]
+
+    for job_i, job in enumerate(_use_param.jobs):
+        print job_i
+        f = open ( job+"tmrcaRho", "w" )
+        f.write(`processed_data[job_i][0]`+"\n")
+        f.close()
+        f = open ( job+"time", "w" )
+        f.write(`processed_data[job_i][3]`+"\n")
+        f.close()
+        #print job
+
+    
+    myfigures ( _use_param.small_delta, [ data_i[0] for data_i in processed_data ] , _use_param.case+"tmrca", _legend, _colors)
+    #myfigures ( _use_param.big_delta, [ data_i[1] for data_i in processed_data ] , _use_param.case+"tmrc", _legend, _colors)
+    #myfigures ( _use_param.big_delta, [ data_i[2] for data_i in processed_data ] , _use_param.case+"clade", _legend, _colors)
+
+    time_figure ( calculate_acurrcy(processed_data, _use_param.small_delta) , [ data_i[3] for data_i in processed_data ] , _use_param.case+"tmrca", _legend, _colors)
+    #time_figure ( [ data_i[0][-1] for data_i in processed_data ] , [ data_i[3] for data_i in processed_data ] , _use_param.case+"tmrca", _legend, _colors)
+    #time_figure ( [ data_i[1][-1] for data_i in processed_data ] , [ data_i[3] for data_i in processed_data ] , _use_param.case+"tmrc", _legend, _colors)
+    #time_figure ( [ data_i[2][-1] for data_i in processed_data ] , [ data_i[3] for data_i in processed_data ] , _use_param.case+"clade", _legend, _colors)
diff --git a/tests/manualtests/LD/cluster/macs_process.py b/tests/manualtests/LD/cluster/macs_process.py
new file mode 100755
index 0000000..1d0d019
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_process.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+import sys
+if __name__ == "__main__":
+    prefix = sys.argv[1]
+    seqlen = float(sys.argv[2])
+    
+    freq_in_name  = prefix + "change"
+    freq_out_name = prefix + "TreeFreq"
+    change = [ float(x)*seqlen for x in open ( freq_in_name, "r" ) ]
+    change.append(seqlen)
+    #print change
+    
+    freq_out = open( freq_out_name, "w")
+    freq = [] 
+    for i in range(1, len(change)):
+        freq.append( change[i] - change[i-1]) 
+        freq_out.write(`int(change[i] - change[i-1])` + "\n")
+    freq_out.close()
+    #print numpy.sum(freq)
diff --git a/tests/manualtests/LD/cluster/macs_process.src b/tests/manualtests/LD/cluster/macs_process.src
new file mode 100644
index 0000000..40b5fff
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_process.src
@@ -0,0 +1,24 @@
+job=${case}${program}retain${retain}_
+prefix=${job}${rep}
+mkdir ${top_dir}"/"${prefix}
+fileprefix=${top_dir}"/"${prefix}"/"${prefix}
+cmd="${nsam} ${seqlen} -r 0.0004 -s ${rep} -h ${retain} "
+echo ${cmd}    
+{ time -p ${program} ${cmd} ;} 2> ${fileprefix}
+
+
+grep "real" ${fileprefix} > ${fileprefix}time.text
+grep "user" ${fileprefix} >> ${fileprefix}time.text
+grep "Tree:" ${fileprefix} | sed "s/,ARG:.*//g" > ${fileprefix}dummy
+
+tree_change_name=${fileprefix}"change"
+tmrca_name=${fileprefix}"Tmrca"
+bl_name=${fileprefix}"BL"
+#first_coal_name=${fileprefix}"FirstCoal"
+
+sed "s/Tree:.*pos://g" ${fileprefix}dummy | sed "s/,len:.*//g" > ${tree_change_name}
+sed "s/Tree:.*len://g" ${fileprefix}dummy | sed "s/,TMRCA:.*//g" > ${bl_name}
+sed "s/Tree:.*TMRCA://g" ${fileprefix}dummy > ${tmrca_name}
+#touch ${first_coal_name}    
+./macs_process.py ${fileprefix} ${seqlen}
+rm ${fileprefix} ${fileprefix}dummy ${tree_change_name}
diff --git a/tests/manualtests/LD/cluster/macs_retain0.sh b/tests/manualtests/LD/cluster/macs_retain0.sh
new file mode 100755
index 0000000..ecf28ce
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_retain0.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N macsretain0
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+program=macs
+retain=0
+source macs_process.src
diff --git a/tests/manualtests/LD/cluster/macs_retain1000.sh b/tests/manualtests/LD/cluster/macs_retain1000.sh
new file mode 100755
index 0000000..3faeef6
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_retain1000.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N macs_retain1000
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+program=macs
+retain=1000
+source macs_process.src
diff --git a/tests/manualtests/LD/cluster/macs_retain10000.sh b/tests/manualtests/LD/cluster/macs_retain10000.sh
new file mode 100755
index 0000000..d3566a1
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_retain10000.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N macs_retain10000
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+program=macs
+retain=10000
+source macs_process.src
diff --git a/tests/manualtests/LD/cluster/macs_retain100000.sh b/tests/manualtests/LD/cluster/macs_retain100000.sh
new file mode 100755
index 0000000..ae40414
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_retain100000.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N macs_retain100000
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+program=macs
+retain=100000
+source macs_process.src
diff --git a/tests/manualtests/LD/cluster/macs_retain1000000.sh b/tests/manualtests/LD/cluster/macs_retain1000000.sh
new file mode 100755
index 0000000..ebf553b
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_retain1000000.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N macs_retain1000000
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+program=macs
+retain=1000000
+source macs_process.src
diff --git a/tests/manualtests/LD/cluster/macs_retain3000.sh b/tests/manualtests/LD/cluster/macs_retain3000.sh
new file mode 100755
index 0000000..303ea99
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_retain3000.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N macs_retain3000
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+program=macs
+
+retain=3000
+source macs_process.src
diff --git a/tests/manualtests/LD/cluster/macs_retain30000.sh b/tests/manualtests/LD/cluster/macs_retain30000.sh
new file mode 100755
index 0000000..d711e38
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_retain30000.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N macs_retain30000
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+program=macs
+retain=30000
+source macs_process.src
diff --git a/tests/manualtests/LD/cluster/macs_retain300000.sh b/tests/manualtests/LD/cluster/macs_retain300000.sh
new file mode 100755
index 0000000..b9994ec
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_retain300000.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N macs_retain300000
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+program=macs
+retain=300000
+source macs_process.src
diff --git a/tests/manualtests/LD/cluster/macs_retain500.sh b/tests/manualtests/LD/cluster/macs_retain500.sh
new file mode 100755
index 0000000..afa5073
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_retain500.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N macs_retain500
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+program=macs
+
+retain=500
+source macs_process.src
diff --git a/tests/manualtests/LD/cluster/macs_retain5000.sh b/tests/manualtests/LD/cluster/macs_retain5000.sh
new file mode 100755
index 0000000..cd919da
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_retain5000.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N macs_retain5000
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+program=macs
+retain=5000
+source macs_process.src
diff --git a/tests/manualtests/LD/cluster/macs_retain50000.sh b/tests/manualtests/LD/cluster/macs_retain50000.sh
new file mode 100755
index 0000000..8b57af5
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_retain50000.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N macs_retain50000
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+program=macs
+retain=50000
+source macs_process.src
diff --git a/tests/manualtests/LD/cluster/macs_retain500000.sh b/tests/manualtests/LD/cluster/macs_retain500000.sh
new file mode 100755
index 0000000..5db9e54
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_retain500000.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N macs_retain500000
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+program=macs
+retain=500000
+source macs_process.src
diff --git a/tests/manualtests/LD/cluster/macs_retain7000.sh b/tests/manualtests/LD/cluster/macs_retain7000.sh
new file mode 100755
index 0000000..05b8692
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_retain7000.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N macs_retain7000
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+program=macs
+retain=7000
+
+source macs_process.src
diff --git a/tests/manualtests/LD/cluster/macs_retain70000.sh b/tests/manualtests/LD/cluster/macs_retain70000.sh
new file mode 100755
index 0000000..f1a4bcf
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_retain70000.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N macs_retain70000
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+program=macs
+
+retain=70000
+
+source macs_process.src
diff --git a/tests/manualtests/LD/cluster/macs_retain700000.sh b/tests/manualtests/LD/cluster/macs_retain700000.sh
new file mode 100755
index 0000000..8fe0ed0
--- /dev/null
+++ b/tests/manualtests/LD/cluster/macs_retain700000.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N macs_retain700000
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+program=macs
+retain=700000
+source macs_process.src
diff --git a/tests/manualtests/LD/cluster/parameters_preset b/tests/manualtests/LD/cluster/parameters_preset
new file mode 100644
index 0000000..b59c865
--- /dev/null
+++ b/tests/manualtests/LD/cluster/parameters_preset
@@ -0,0 +1,10 @@
+casefile=toyparam.src
+source ${casefile}
+
+top_dir="/well/gerton/joezhu/LD_test"
+rep=$(expr $SGE_TASK_ID )
+
+#top_dir="toy_test"
+#rep=10
+
+cmd="${nsam} 1 -T -r ${rho} ${seqlen}"
diff --git a/tests/manualtests/LD/cluster/plot_new.py b/tests/manualtests/LD/cluster/plot_new.py
new file mode 100644
index 0000000..9193f0f
--- /dev/null
+++ b/tests/manualtests/LD/cluster/plot_new.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python
+import pylab as plt
+from scipy.integrate import simps, trapz
+import numpy as np
+
+class job:
+    def __init__(self, jobname):
+        f = open ( jobname, "r" ) 
+        self.ac = [float(x) for x in f.readline().strip('[').strip(']\n').split(',') ]
+        self.ac_mean = [float(x) for x in f.readline().strip('[').strip(']\n').split(',') ]
+        self.ac_std = [float(x) for x in f.readline().strip('[').strip(']\n').split(',') ]
+        line = f.readline()
+        self.time_mean = float(line.strip('[').strip(']\n').split(',')[0])
+        self.time_std  = float(line.strip('[').strip(']\n').split(',')[1])
+    
+    def printing(self):
+        print self.ac
+        print self.ac_mean
+        print self.ac_std
+        print self.time_mean
+        print self.time_std
+        
+    def diff_from_ms(self, ms_ac, delta):
+        y = np.array([ np.abs(ms_ac[i] - self.ac[i]) for i in range(len(ms_ac))] )
+        self.dev = np.abs(simps(y, x = delta))
+        #print self.dev
+
+delta = range( 0, int(2e4+1), 1000 )
+
+prefix = "Constantpopsize"
+suffix = "_Processed"
+ms_case = [""]
+fastsimcoal_case = [""]
+scrm_case = [ "window" + `x` for x in [0, 500, 1000, 3000, 5000, 7000, 10000, 30000, 50000, 70000, 100000] ]
+macs_case = [ "retain" + `x` for x in [0, 500, 1000, 3000, 5000, 7000, 10000, 30000, 50000, 70000, 100000] ]
+macs_case.insert(0,"")
+program = ["ms", "fastsimcoal", "scrm", "macs"]
+case = [ms_case, fastsimcoal_case, scrm_case, macs_case]
+joblist = []
+
+ms = job("Constantpopsizems_Processed")
+#ms.printing()
+
+fig1 = plt.figure(figsize=(9, 6), dpi=80)
+ax1 = fig1.add_subplot(111)
+
+fig2 = plt.figure(figsize=(12, 8), dpi=80)
+ax2 = fig2.add_subplot(111)
+
+fig3 = plt.figure(figsize=(9, 6), dpi=80)
+ax3 = fig3.add_subplot(111)
+
+#ax1.plot ( delta, ms.ac , linewidth=3.0, color = "black")
+#ax1.errorbar ( delta, ms.ac, yerr = [ x/(1000**0.5) *1.96 for x in ms.ac_std ] )
+
+linestyles = ['-', '-.', '--', ':']
+colors = [ "blue", "red", "green",  "purple", "black",  "yellow", "cyan", "magenta", "orange"]
+markers = ["v", "o", "*", ">", "<", "s", "^", "+" , "D", "H", "d","x"]
+legendlist1 = []
+l1 = []
+
+legendlist2 = []
+l2 = []
+
+legendlist3 = []
+l3 = []
+
+for i, program_i in enumerate ( program ):
+    color_j = 0
+    program_dev = []
+    program_time = []
+    program_time_err = []
+    for j, case_j in enumerate ( case[i] ):
+        current_job2 = job( prefix + program_i + case_j + suffix )
+        current_job2.diff_from_ms (ms.ac, delta) 
+        program_dev.append ( current_job2.dev)
+        program_time.append (current_job2.time_mean)
+        program_time_err.append( current_job2.time_std  ) 
+        #current_dot = ax2.plot ( current_job2.dev, np.log(current_job2.time_mean), markers[j], color = colors[i])
+        current_dot = ax2.plot ( current_job2.dev, current_job2.time_mean, markers[j], color = colors[i])
+        l2.append(current_dot)
+        legendlist2.append(program_i + case_j)
+        if j % 3 == 0:
+            current_job = job( prefix + program_i + case_j + suffix )
+            legendlist1.append( program_i + case_j)
+            current_line = ax1.plot ( delta, current_job.ac, linestyles[i], color = colors[color_j] )
+#           ax1.errorbar ( delta, current_job.ac, yerr = [ x/(1000**0.5) *1.96 for x in current_job.ac_std ],
+#                        fmt='.', color = colors[color_j] )
+            l1.append(current_line)
+            relative_ac = [ np.abs(ms.ac[ac_i] - current_job.ac[ac_i]) for ac_i in range(len(ms.ac))]
+            current_line3 = ax3.plot ( delta, relative_ac, linestyles[i], color = colors[color_j] )
+ #           ax3.errorbar ( delta, relative_ac, yerr = [ x/(1000**0.5) *1.96 for x in current_job.ac_std ],
+ #                         fmt='.', color = colors[color_j] )
+            l3.append(current_line3)
+            color_j += 1
+            
+    #ax2.errorbar ( program_dev, np.log(program_time), yerr = program_time_err, color = colors[i])
+    ax2.plot ( program_dev, program_time, color = colors[i])
+    #ax2.errorbar ( program_dev, program_time, yerr = program_time_err, color = colors[i])
+    
+ms_line = ax1.plot ( delta, ms.ac,  linewidth=2.0, color = "black")    
+#ax1.errorbar ( delta, ms.ac, yerr = [ x/(1000**0.5) *1.96 for x in current_job.ac_std ],
+                          #fmt='.', color = colors[color_j] )
+l1[0] = ms_line                          
+
+relative_ac = [ float(0) for ac_i in range(len(ms.ac))]
+ms_line3 = ax3.plot ( delta, relative_ac,  linewidth=2.0, color = "black")    
+#ax3.errorbar ( delta, relative_ac, yerr = [ x/(1000**0.5) *1.96 for x in ms.ac_std ],
+                          #fmt='.', color = "black" )
+l3[0] = ms_line3
+                              
+ax1.legend ([ x[0] for x in l1], legendlist1, loc = 1)        
+ax1.axis([0,20000, 0, 1]) 
+ax1.set_xlabel(r'Distance between two sites $\delta$')
+ax1.set_ylabel(r'Autocorrelation $\rho$')
+fig1.savefig("TMRCArhoLD.pdf")
+
+ax3.legend ([ x[0] for x in l1], legendlist1, loc = 1)        
+ax3.axis([0,30000, -.01, 0.06]) 
+ax3.set_xlabel(r'Distance between two sites $\delta$')
+ax3.set_ylabel(r'Error in Autocorrelation $\rho$')
+fig3.savefig("RelativeTMRCArhoLD.pdf")
+
+
+ax2.set_xlim ([-10, 1300])
+ax2.set_ylim ([0.1, 14])
+#ax2.axis([-10, 1300, -2.5, np.log(ms.time_mean)*1.1] )
+#yticks = ax2.get_yticks()
+#print yticks
+#ylabels = ["%.5g" % (np.exp(float(y))) for y in yticks]
+#ax2.set_yticklabels(ylabels) 
+ax2.set_yscale('log')
+ax2.legend ([ x[0] for x in l2], legendlist2, loc = 1, numpoints=1)        
+ax2.set_ylabel("Time (sec)")
+ax2.set_xlabel("Deviation")
+fig2.savefig("time_vs_dev.pdf")
diff --git a/tests/manualtests/LD/cluster/plotting.py b/tests/manualtests/LD/cluster/plotting.py
new file mode 100755
index 0000000..c898d60
--- /dev/null
+++ b/tests/manualtests/LD/cluster/plotting.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+import ld_test as ld
+
+import sys
+
+if __name__ == "__main__":
+    _use_param = ld.read_param_file ( sys.argv[1] )
+    _use_param.printing()
+    
+    processed_data = []
+    runtime = []
+    for job in _use_param.jobs:
+        print job
+        f = open ( job+"tmrcaRho", "r" )        
+        processed_data.append( [float(x) for x in f.readline().strip('[').strip(']\n').split(',') ] )
+        f.close()
+        f = open ( job+"time", "r" )
+        runtime.append( float( f.readline().strip() ) )
+        f.close()
+    print runtime
+    _legend = [ job[len(_use_param.case):-1] for job in _use_param.jobs ]
+    _colors = [ "orange", "purple", "green",  "red",  "blue", "black",  "yellow", "cyan", "magenta", "pink"]
+
+    
+    ld.myfigures ( _use_param.small_delta, processed_data , _use_param.case+"tmrca", _legend, _colors)
+    ld.time_figure ( ld.calculate_acurrcy_array(processed_data, _use_param.small_delta) , runtime , _use_param.case+"tmrca", _legend, _colors)
+
+    
+    print "Done"
diff --git a/tests/manualtests/LD/cluster/process_actions.src b/tests/manualtests/LD/cluster/process_actions.src
new file mode 100644
index 0000000..b4ea6a9
--- /dev/null
+++ b/tests/manualtests/LD/cluster/process_actions.src
@@ -0,0 +1,17 @@
+#!/bin/bash
+dir=${top_dir}"/"${prefix}
+rm -r ${dir}
+mkdir ${dir}
+fileprefix=${dir}"/"${prefix}
+{ time -p ${program} ${cmd} > ${fileprefix} ;} 2> ${fileprefix}time.text
+tree_file_name=${fileprefix}"Trees"
+tree_freq_name=${fileprefix}"TreeFreq"
+tmrca_name=${fileprefix}"Tmrca"
+bl_name=${fileprefix}"BL"
+#first_coal_name=${fileprefix}"FirstCoal"
+
+grep ';' ${fileprefix} | sed -e "s/\\[.*\\]//g" > ${tree_file_name}
+grep ";" ${fileprefix} | sed -e "s/\\[//g" | sed -e "s/\\].*;//g" > ${tree_freq_name}
+hybrid-Lambda -gt ${tree_file_name} -tmrca ${tmrca_name}
+hybrid-Lambda -gt ${tree_file_name} -bl ${bl_name}
+rm ${fileprefix} ${tree_file_name}
diff --git a/tests/manualtests/LD/cluster/process_data.py b/tests/manualtests/LD/cluster/process_data.py
new file mode 100755
index 0000000..c3e8725
--- /dev/null
+++ b/tests/manualtests/LD/cluster/process_data.py
@@ -0,0 +1,338 @@
+#!/usr/bin/env python
+
+#import numpy as np
+import os
+import sys
+#import pylab
+#from scipy.integrate import simps, trapz
+
+__mydebug__       = False
+__fix_ms_seed__   = False
+__fix_scrm_seed__ = False
+
+# exact_windows_length [0, 10e2, 10e3, 10e4, -1]
+
+def mean( x ):
+    return sum(x)*1.0 / float(len(x))
+
+def std( x ):
+    mu = mean(x)
+    dev = sum ( [ (xi - mu)**2 for xi in x ] )
+    return (dev/float(len(x)) )**0.5 
+
+class parameter:
+    def __init__( self, nsam = 6, replicate = 100, seqlen = 1e7, rho = 1e-8 , exact_window_length = 0 , divergence = 0, jobs = []): 
+        """
+        Define simulation parameters
+        """
+        self.nsam      = nsam
+        self.rep       = replicate
+        self.seqlen    = seqlen # 10e7
+        #self.theta     = 7 * 10e-10 * seqlen * 4 * 10000
+        #self.rho       = rho * (self.seqlen-1) * 4 * 10000
+        self.rho       = rho
+        self.exact_window_length = exact_window_length
+        self.divergence = divergence
+        self.jobs = jobs
+        
+        
+        #delta_points = 20
+        delta_points = 1000 # changed on June 4th
+        big_delta_max = 2e5
+        #big_delta_max = 1e4
+        #small_delta_max = 1e5 # changed on May 26th
+        small_delta_max = 1e6 # changed on June 4th
+        #small_delta_max = big_delta_max
+        #self.big_delta = np.linspace( 0, int(big_delta_max+1), delta_points )
+        #self.big_delta = range( 0, int(big_delta_max+1), 10000 )
+        #self.small_delta = np.linspace( 0, int(small_delta_max+1), delta_points )
+        self.small_delta = range( 0, int(small_delta_max+1), 1000 )
+    
+    def printing ( self ):
+        """
+        Check simulation parameters
+        """
+        print "sample size:       ", self.nsam
+        print "replicate:         ",   self.rep
+        print "Sequence length:   ", self.seqlen
+        print "recombination rate:", self.rho
+        print "jobs:", self.jobs
+        
+
+def extract_all_info ( job_prefix, num_rep, process_BL = False):
+    data = []
+    for rep in range(1, num_rep+1):
+        out = extract_info ( job_prefix, rep, process_BL )
+        data.append( out )
+    return data
+    
+    
+def extract_info (job_prefix, ith_rep, process_BL = False ): 
+    prefix = job_prefix + `ith_rep` + "/" + job_prefix + `ith_rep`
+    tree_file_name  = prefix + "Trees"
+    tree_freq_name  = prefix + "TreeFreq"
+    
+    tmrca_name      = prefix + "Tmrca"
+    if process_BL:
+        tmrca_name      = prefix + "BL"
+    
+    tree_freq = [ float(x) for x in open( tree_freq_name, "r" ) ]    
+    tmrca = [ float(x) for x in open( tmrca_name, "r" )]
+    timeFile_name = prefix+"time.text"
+    runtime = float(open( timeFile_name, "r").readlines()[1].strip("user").strip('\n'))
+    return  tree_freq, tmrca, runtime
+
+
+#def cal_ac_TMRC_star (tree_freq, tmrca, avg_tmrca, delta):
+
+    #seqlen = sum(tree_freq)
+
+    #cumfreq = [0]
+    #shifted_cumfreq = [] 
+    #for x in tree_freq : 
+        #cumfreq.append(cumfreq[-1] + x)
+        #shifted_cumfreq.append(cumfreq[-1] - delta)
+    #cumfreq.pop(0)
+
+    #n = int(seqlen - delta)
+    #ac = 0
+    #var = 0
+    
+    #if __mydebug__:
+        #print tree_freq
+        #print cumfreq
+        #print shifted_cumfreq        
+        #print "seqence length = ", seqlen
+        #print "i should iterate until ", n, "trees"
+    
+    #T1_index = 0
+    #T2_index = 0 # use while loop to determine the initial T2_index
+    #while delta > cumfreq[T2_index]: # need to check again ...
+        #T2_index += 1
+    #about_to = False
+    #for i in range( n ): 
+        #if __mydebug__ & ((not i < cumfreq[T1_index]) | (not i < shifted_cumfreq[T2_index])):
+            #print "before", i, T1_index,  T2_index
+            #print "-------------------------------"
+            #about_to = True
+        #if i >= cumfreq[T1_index]: T1_index += 1
+        #term1 = tmrca[T1_index] - avg_tmrca
+        #if i >= shifted_cumfreq[T2_index]: T2_index += 1
+        #term2 = tmrca[T2_index] - avg_tmrca
+        #if __mydebug__ & about_to:
+            #print "after ", i, T1_index,  T2_index
+            #about_to = False
+        ##print i, T1_index, term1, T2_index, term2
+        #ac += term1 * term2
+        #var += term1 * term1
+    #ac /= float(n)
+    #var /= float(n)
+    #return ac, var
+
+
+def cal_ac_TMRC_star_2 (tree_freq, tmrca, avg_tmrca, delta):
+
+    seqlen = int(sum(tree_freq))
+    #print seqlen
+    cumfreq = [0]
+    for x in tree_freq : 
+        cumfreq.append(cumfreq[-1] + x)
+    cumfreq.pop(0)
+
+    n = int(seqlen - delta)
+    ac = 0
+    var = 0
+    
+    T1_index = 0
+    T2_index = 0 # use while loop to determine the initial T2_index
+    while delta > cumfreq[T2_index]: # need to check again ...
+        T2_index += 1
+    i = 0
+    while i < n:
+        distance = min( cumfreq[T1_index] - i, 
+                        cumfreq[T2_index] - delta - i )
+        distance = min( distance, n - i )
+        term1 = tmrca[T1_index] - avg_tmrca
+        term2 = tmrca[T2_index] - avg_tmrca
+        ac += term1 * term2 * distance
+        var += term1 * term1 * distance
+        i += distance            
+        if i >= cumfreq[T1_index]: T1_index += 1
+        if i + delta >= cumfreq[T2_index]: T2_index += 1
+    ac /= float(n)
+    var /= float(n)
+    return ac, var
+
+
+def process_time (data) :
+    run_time_array = []
+    for d in data:
+        run_time_array.append ( d[2] )
+    return mean(run_time_array), std(run_time_array)
+        
+def process_data ( data , delta ) :
+    # compute the average Tmrca 
+    tot_tmrca = 0
+    tot_time = 0
+    for d in data:
+        for i, duration_i in enumerate( d[0] ):   # d[0] : tree_freq, duration of the tree
+            tmrca_i = d[1][i]                     # d[1] : tmrca
+            tot_time += duration_i                # d[0] : duration of the tree
+            tot_tmrca += tmrca_i * duration_i     # JOE changed from tot_tmrca += tmrca_i
+    avg_tmrca = tot_tmrca / tot_time
+            
+    ac_TMRCA  = []    
+    ac_mean   = []
+    ac_std    = []
+    
+    for delta_i in delta:
+        print "processing delta:", delta_i        
+        cum_ac_TMRCA = 0
+        cum_var_TMRCA = 0
+    
+        ratio = []
+        for d in data:
+            ac, var = cal_ac_TMRC_star_2( d[0], d[1], avg_tmrca, delta_i )
+            cum_ac_TMRCA += ac
+            cum_var_TMRCA += var
+            ratio.append( ac/var )
+        ac_mean.append( mean(ratio) )
+        ac_std.append ( std (ratio) )         
+            
+        ac_TMRCA.append( cum_ac_TMRCA / cum_var_TMRCA )
+
+    return ac_TMRCA, ac_mean, ac_std
+    
+
+#def myfigures ( delta, rho, prefix, legend, colors):
+    ## rho is a list of MS, SCRM (pruned) and SCRM (full pruning) results
+    ## results is a list of autocorrelations, one for each delta
+    ##print legend
+    #l = [] 
+    #fig,(ax1)=pylab.subplots(1,1)
+    #for i in range ( len (rho) ):
+        ##y_err = [np.std(yi)*1.96/np.sqrt(len(yi)) for yi in rho[i]]
+        #tmp1 = ax1.plot( delta, rho[i] , color = colors[i])
+        #l.append ( tmp1 )
+    #pylab.xlim( [np.min(delta), np.max(delta)] )
+    ##pylab.title( prefix + " of " + `len(delta)` + " delta points" )
+    #pylab.xlabel(r'Distance between two sites $\delta$')
+    #pylab.ylabel(r'Autocorrelation $\rho$')
+    #pylab.legend ([ x[0] for x in l], legend, loc = 1)
+    #pylab.savefig( prefix+".pdf" )
+    #pylab.close()
+
+
+#def time_figure(accuracy, time, prefix, legend, colors):
+    #x = accuracy
+    #y = time
+    #markers = ["v", "o", "*", ">", "<", "s", "^", "+" , "D", "H"]
+    ##pylab.title("Time vs accuracy")
+    #pylab.ylabel("Time")
+    #pylab.xlabel("Accuracy")
+    ##pylab.xlabel("rho tmrca at delta = 10000")
+    #myl = []
+    #for i, xi in enumerate(x):
+        #myl.append(pylab.plot( x[i], np.log(y[i]), markers[i]))
+    #my_axes = pylab.gca()
+    #yticks = my_axes.get_yticks()
+    #ylabels = ["%.5g" % (np.exp(float(y))) for y in yticks]
+    #my_axes.set_yticklabels(ylabels)    
+    #pylab.legend( [ lx[0] for lx in myl ] ,  legend, loc=1, numpoints=1)
+    #pylab.savefig( prefix+"_timeVSacc.pdf")
+    #pylab.close()
+
+
+def read_param_file ( experiment_name ):
+    top_param = parameter()
+    experiment_file = open( experiment_name, "r" )
+    for line in experiment_file:
+        if   line.split()[0] == "case:":          top_param.case       = line.split()[1]
+        elif line.split()[0] == "nsam:":          top_param.nsam    = line.split()[1]
+        elif line.split()[0] == "replicate:":     top_param.rep = int(line.split()[1])
+        elif line.split()[0] == "seqlen:":        top_param.seqlen    = int(line.split()[1])
+        elif line.split()[0] == "rho:":           top_param.rho = float(line.split()[1])
+        elif line.split()[0] == "divergence:":    top_param.divergence    = int(line.split()[1])
+        elif line.split()[0] == "job:":    top_param.jobs.append( line.split()[1] )
+    experiment_file.close()
+    
+    top_param.printing()
+    return top_param
+
+def calculate_acurrcy(data_matrix, delta, obj_index =0 ): # obj_index is index for processed data, 0: tmrca, 1: TMRC, 2: clade
+    accuracy = []
+    ms_ld = data_matrix[0][obj_index]    
+    print ms_ld
+    for data_i in data_matrix:
+        programs_ld = data_i[0]
+        y = np.array([ ms_ld[i] - programs_ld[i] for i in range(len(ms_ld))] )
+        accuracy.append(np.abs(simps(y, x = delta)))
+    return accuracy
+
+def calculate_acurrcy_array( data_array, delta): # obj_index is index for processed data, 0: tmrca, 1: TMRC, 2: clade
+    accuracy = []
+    ms_ld = data_array[0]
+    for data_i in data_array:
+        #programs_ld = data_i[0]
+        y = np.array([ ms_ld[i] - data_i[i] for i in range(len(ms_ld))] )
+        accuracy.append(np.abs(simps(y, x = delta)))
+    return accuracy
+    
+if __name__ == "__main__":
+    _use_param = read_param_file ( sys.argv[1] )
+    _use_param.printing()
+    
+    for job in _use_param.jobs:
+        
+        print job, "TMRCA"
+        data = extract_all_info (job, _use_param.rep)
+        #print "len(data) = ", len(data)
+        #print "len(data[0]) = ", len(data[0])
+        #print data
+        processed_data = process_data (data, _use_param.small_delta)
+        mean_time, std_time = process_time (data)
+        f = open ( job+"Processed_TMRCA", "w" )
+        f.write(`processed_data[0]`+"\n")
+        f.write(`processed_data[1]`+"\n")
+        f.write(`processed_data[2]`+"\n")
+        f.write(`[mean_time, std_time]`+"\n")
+        f.close()
+
+
+        print job, "BL"
+        data = extract_all_info (job, _use_param.rep, True)
+        #print "len(data) = ", len(data)
+        #print "len(data[0]) = ", len(data[0])
+        #print data
+        processed_data = process_data (data, _use_param.small_delta)
+        mean_time, std_time = process_time (data)
+        f = open ( job+"Processed_BL", "w" )
+        f.write(`processed_data[0]`+"\n")
+        f.write(`processed_data[1]`+"\n")
+        f.write(`processed_data[2]`+"\n")
+        f.write(`[mean_time, std_time]`+"\n")
+        f.close()
+
+
+        #print "sum over sum = ", processed_data[0]
+        #print "mean = ", processed_data[1]
+        #print "std = ", processed_data[2]
+        #print "mean and std of time " , 
+        #print "time = ", processed_data[3]
+    
+    #_legend = [ job[len(_use_param.case):-1] for job in _use_param.jobs ]
+    #_colors = [ "orange", "purple", "green",  "red",  "blue", "black",  "yellow", "cyan", "magenta"]
+
+    #for job_i, job in enumerate(_use_param.jobs):
+        #print job_i
+        #f = open ( job+"tmrcaRho", "w" )
+        #f.write(`processed_data[job_i][0]`+"\n")
+        #f.close()
+        #f = open ( job+"time", "w" )
+        #f.write(`processed_data[job_i][3]`+"\n")
+        #f.close()
+        ##print job
+
+    
+    #myfigures ( _use_param.small_delta, [ data_i[0] for data_i in processed_data ] , _use_param.case+"tmrca", _legend, _colors)
+    #time_figure ( calculate_acurrcy(processed_data, _use_param.small_delta) , [ data_i[3] for data_i in processed_data ] , _use_param.case+"tmrca", _legend, _colors)
diff --git a/tests/manualtests/LD/cluster/process_data.sh b/tests/manualtests/LD/cluster/process_data.sh
new file mode 100755
index 0000000..a48e16a
--- /dev/null
+++ b/tests/manualtests/LD/cluster/process_data.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q long.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N process_data.sh
+#$ -t 1-32
+#$ -j y
+
+replicate=1000
+case="Constantpopsize"
+
+#joblist=("ms" \
+"scrmwindow1000000" "scrmwindow700000" "scrmwindow500000" "scrmwindow300000" \
+#"scrmwindow100000" "scrmwindow70000" "scrmwindow50000" "scrmwindow30000" \
+#"scrmwindow10000" "scrmwindow7000" "scrmwindow5000" "scrmwindow3000" \
+#"scrmwindow1000" "scrmwindow500" "scrmwindow0" \
+#"macsretain1000000" "macsretain700000" "macsretain500000" "macsretain300000" \
+#"macsretain100000" "macsretain70000" "macsretain50000" "macsretain30000" \
+#"macsretain10000" "macsretain7000" "macsretain5000" "macsretain3000" \
+#"macsretain1000" "macsretain500" "macsretain0" \
+#"fastsimcoal")
+
+joblist=("scrmwindow1000000" "scrmwindow700000" "scrmwindow500000" "scrmwindow300000" \
+"scrmwindow100000" "scrmwindow70000" "scrmwindow50000" "scrmwindow30000" \
+"scrmwindow10000" "scrmwindow7000" "scrmwindow5000" "scrmwindow3000" \
+"scrmwindow1000" "scrmwindow500" "scrmwindow0" )
+
+#joblist=("scrmwindow1000000" "scrmwindow700000" "scrmwindow500000" "scrmwindow300000" \
+#"macsretain1000000" "macsretain700000" "macsretain500000" "macsretain300000" )
+
+rep=$(expr $SGE_TASK_ID - 1)
+#rep=0
+#for rep in $(seq 0 1 16)
+    #do
+    Job=${case}${joblist[${rep}]}
+    JobParamFile=${Job}param
+echo -e "case: ${case}\n\
+nsam: 20\n\
+replicate: ${replicate}\n\
+seqlen: 10000001\n\
+rho: 4000\n\
+job: ${Job}_" > ${JobParamFile}
+    python process_data.py ${JobParamFile}
+    #done
+
diff --git a/tests/manualtests/LD/cluster/submit_ms.sh b/tests/manualtests/LD/cluster/submit_ms.sh
new file mode 100755
index 0000000..bf7c6f9
--- /dev/null
+++ b/tests/manualtests/LD/cluster/submit_ms.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e msErrFiles
+#$ -o msOutFiles
+#$ -N ms 
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+#######################
+program=ms
+job=${case}${program}_
+prefix=${job}${rep}
+cmd="${cmd} -seed ${rep} ${rep} ${rep}"
+#######################
+source process_actions.src
+
diff --git a/tests/manualtests/LD/cluster/submit_scrm0.sh b/tests/manualtests/LD/cluster/submit_scrm0.sh
new file mode 100755
index 0000000..2b3f6de
--- /dev/null
+++ b/tests/manualtests/LD/cluster/submit_scrm0.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm0 
+#$ -t 1-1000
+#$ -j y
+
+
+source parameters_preset
+
+#######################
+exact_window_i=0
+program=scrm
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+cmd="${cmd} -l ${exact_window_i} -seed ${rep} "
+#######################
+source process_actions.src
diff --git a/tests/manualtests/LD/cluster/submit_scrm1000.sh b/tests/manualtests/LD/cluster/submit_scrm1000.sh
new file mode 100755
index 0000000..088cafb
--- /dev/null
+++ b/tests/manualtests/LD/cluster/submit_scrm1000.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm1000 
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+#######################
+exact_window_i=1000
+program=scrm
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+cmd="${cmd} -l ${exact_window_i} -seed ${rep} "
+#######################
+source process_actions.src
diff --git a/tests/manualtests/LD/cluster/submit_scrm10000.sh b/tests/manualtests/LD/cluster/submit_scrm10000.sh
new file mode 100755
index 0000000..f5eb336
--- /dev/null
+++ b/tests/manualtests/LD/cluster/submit_scrm10000.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm10000 
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+#######################
+exact_window_i=10000
+program=scrm
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+cmd="${cmd} -l ${exact_window_i} -seed ${rep} "
+#######################
+source process_actions.src
diff --git a/tests/manualtests/LD/cluster/submit_scrm100000.sh b/tests/manualtests/LD/cluster/submit_scrm100000.sh
new file mode 100755
index 0000000..d38f93b
--- /dev/null
+++ b/tests/manualtests/LD/cluster/submit_scrm100000.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm100000 
+#$ -t 1-1000
+#$ -j y
+
+
+source parameters_preset
+#######################
+exact_window_i=100000
+program=scrm
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+cmd="${cmd} -l ${exact_window_i} -seed ${rep} "
+#######################
+source process_actions.src
+
diff --git a/tests/manualtests/LD/cluster/submit_scrm1000000.sh b/tests/manualtests/LD/cluster/submit_scrm1000000.sh
new file mode 100755
index 0000000..34bd302
--- /dev/null
+++ b/tests/manualtests/LD/cluster/submit_scrm1000000.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm1000000 
+#$ -t 1-1000
+#$ -j y
+
+
+source parameters_preset
+#######################
+exact_window_i=1000000
+program=scrm
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+cmd="${cmd} -l ${exact_window_i} -seed ${rep} "
+#######################
+source process_actions.src
+
diff --git a/tests/manualtests/LD/cluster/submit_scrm3000.sh b/tests/manualtests/LD/cluster/submit_scrm3000.sh
new file mode 100755
index 0000000..db179ba
--- /dev/null
+++ b/tests/manualtests/LD/cluster/submit_scrm3000.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm3000 
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+#######################
+exact_window_i=3000
+program=scrm
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+cmd="${cmd} -l ${exact_window_i} -seed ${rep} "
+#######################
+source process_actions.src
diff --git a/tests/manualtests/LD/cluster/submit_scrm30000.sh b/tests/manualtests/LD/cluster/submit_scrm30000.sh
new file mode 100755
index 0000000..03f68d1
--- /dev/null
+++ b/tests/manualtests/LD/cluster/submit_scrm30000.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm30000 
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+#######################
+exact_window_i=30000
+program=scrm
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+cmd="${cmd} -l ${exact_window_i} -seed ${rep} "
+#######################
+source process_actions.src
diff --git a/tests/manualtests/LD/cluster/submit_scrm300000.sh b/tests/manualtests/LD/cluster/submit_scrm300000.sh
new file mode 100755
index 0000000..1f4f983
--- /dev/null
+++ b/tests/manualtests/LD/cluster/submit_scrm300000.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm300000 
+#$ -t 1-1000
+#$ -j y
+
+
+source parameters_preset
+#######################
+exact_window_i=300000
+program=scrm
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+cmd="${cmd} -l ${exact_window_i} -seed ${rep} "
+#######################
+source process_actions.src
+
diff --git a/tests/manualtests/LD/cluster/submit_scrm500.sh b/tests/manualtests/LD/cluster/submit_scrm500.sh
new file mode 100755
index 0000000..661e9be
--- /dev/null
+++ b/tests/manualtests/LD/cluster/submit_scrm500.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm500
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+#######################
+exact_window_i=500
+program=scrm
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+cmd="${cmd} -l ${exact_window_i} -seed ${rep} "
+#######################
+source process_actions.src
diff --git a/tests/manualtests/LD/cluster/submit_scrm5000.sh b/tests/manualtests/LD/cluster/submit_scrm5000.sh
new file mode 100755
index 0000000..5f5a33d
--- /dev/null
+++ b/tests/manualtests/LD/cluster/submit_scrm5000.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm5000
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+#######################
+exact_window_i=5000
+program=scrm
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+cmd="${cmd} -l ${exact_window_i} -seed ${rep} "
+#######################
+source process_actions.src
diff --git a/tests/manualtests/LD/cluster/submit_scrm50000.sh b/tests/manualtests/LD/cluster/submit_scrm50000.sh
new file mode 100755
index 0000000..c0da937
--- /dev/null
+++ b/tests/manualtests/LD/cluster/submit_scrm50000.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm50000 
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+#######################
+exact_window_i=50000
+program=scrm
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+cmd="${cmd} -l ${exact_window_i} -seed ${rep} "
+#######################
+source process_actions.src
diff --git a/tests/manualtests/LD/cluster/submit_scrm500000.sh b/tests/manualtests/LD/cluster/submit_scrm500000.sh
new file mode 100755
index 0000000..2bf2b07
--- /dev/null
+++ b/tests/manualtests/LD/cluster/submit_scrm500000.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm500000 
+#$ -t 1-1000
+#$ -j y
+
+
+source parameters_preset
+#######################
+exact_window_i=500000
+program=scrm
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+cmd="${cmd} -l ${exact_window_i} -seed ${rep} "
+#######################
+source process_actions.src
+
diff --git a/tests/manualtests/LD/cluster/submit_scrm7000.sh b/tests/manualtests/LD/cluster/submit_scrm7000.sh
new file mode 100755
index 0000000..ee233b6
--- /dev/null
+++ b/tests/manualtests/LD/cluster/submit_scrm7000.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm7000
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+#######################
+exact_window_i=7000
+program=scrm
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+cmd="${cmd} -l ${exact_window_i} -seed ${rep} "
+#######################
+source process_actions.src
diff --git a/tests/manualtests/LD/cluster/submit_scrm70000.sh b/tests/manualtests/LD/cluster/submit_scrm70000.sh
new file mode 100755
index 0000000..54b4651
--- /dev/null
+++ b/tests/manualtests/LD/cluster/submit_scrm70000.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm70000 
+#$ -t 1-1000
+#$ -j y
+
+source parameters_preset
+#######################
+exact_window_i=70000
+program=scrm
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+cmd="${cmd} -l ${exact_window_i} -seed ${rep} "
+#######################
+source process_actions.src
diff --git a/tests/manualtests/LD/cluster/submit_scrm700000.sh b/tests/manualtests/LD/cluster/submit_scrm700000.sh
new file mode 100755
index 0000000..2730d9f
--- /dev/null
+++ b/tests/manualtests/LD/cluster/submit_scrm700000.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm700000 
+#$ -t 1-1000
+#$ -j y
+
+
+source parameters_preset
+#######################
+exact_window_i=700000
+program=scrm
+job=${case}${program}window${exact_window_i}_
+prefix=${case}${program}window${exact_window_i}_${rep}
+cmd="${cmd} -l ${exact_window_i} -seed ${rep} "
+#######################
+source process_actions.src
+
diff --git a/tests/manualtests/LD/cluster/toyparam b/tests/manualtests/LD/cluster/toyparam
new file mode 100644
index 0000000..ff8db77
--- /dev/null
+++ b/tests/manualtests/LD/cluster/toyparam
@@ -0,0 +1,13 @@
+case: Constantpopsize
+nsam: 6
+replicate: 10
+seqlen: 10000001
+rho: 4000
+job: Constantpopsizems_
+job: Constantpopsizemacsretain1000_
+job: Constantpopsizemacsretain10000_
+job: Constantpopsizemacsretain100000_
+job: Constantpopsizemacs_
+job: Constantpopsizescrmwindow100000_
+job: Constantpopsizescrmwindow0_
+job: Constantpopsizefastsimcoal_
diff --git a/tests/manualtests/LD/cluster/toyparam.src b/tests/manualtests/LD/cluster/toyparam.src
new file mode 100644
index 0000000..5bf4a2c
--- /dev/null
+++ b/tests/manualtests/LD/cluster/toyparam.src
@@ -0,0 +1,9 @@
+nsam=20
+case=Constantpopsize
+#case=Constantpopsize${nsam}Sample
+replicate=1000
+#seqlen=50000001 # fail!!!!
+#rho=20000 # This is equal to r * seqlen * 4 * Ne, which is 1e-8 * 1e7 * 4 * 1e4
+
+seqlen=10000001
+rho=4000 # This is equal to r * seqlen * 4 * Ne, which is 1e-8 * 1e7 * 4 * 1e4
diff --git a/tests/manualtests/LD/ld_test.py b/tests/manualtests/LD/ld_test.py
new file mode 100755
index 0000000..51ccc7c
--- /dev/null
+++ b/tests/manualtests/LD/ld_test.py
@@ -0,0 +1,406 @@
+#!/usr/bin/env python
+
+import pylab as pl
+import numpy as np
+import os
+import sys
+import pylab
+
+__mydebug__       = False
+__fix_ms_seed__   = False
+__fix_scrm_seed__ = False
+
+# exact_windows_length [0, 10e2, 10e3, 10e4, -1]
+
+class parameter:
+    def __init__( self, nsam = 6, replicate = 100, seqlen = 1e7, rho = 1e-8 , exact_window_length = 0 , divergence = False): 
+        """
+        Define simulation parameters
+        """
+        self.nsam      = nsam
+        self.rep       = replicate
+        self.seqlen    = seqlen # 10e7
+        #self.theta     = 7 * 10e-10 * seqlen * 4 * 10000
+        self.rho       = rho * (self.seqlen-1) * 4 * 10000
+        self.exact_window_length = exact_window_length
+        self.divergence = divergence
+        
+        big_delta_max = 1e5
+        small_delta_max = 1e4
+        self.big_delta = range( 0, int(big_delta_max+1), 10000 )
+        self.small_delta = range( 0, int(small_delta_max+1), 1000 )
+
+    
+    def printing ( self ):
+        """
+        Check simulation parameters
+        """
+        print "sample size:       ", self.nsam
+        print "replicate:         ",   self.replicate
+        print "Sequence length:   ", self.seqlen
+        print "recombination rate:", self.rho
+        
+    
+    def define_command ( self, scrm = False ):        
+        cmd = `self.nsam` + " 1 " + " -T " + " -r " + `self.rho` + " " + `int(self.seqlen)`
+        if self.divergence: cmd += " -I 2 " + `self.nsam/2` + " " + `self.nsam/2` + " -ej 1 2 1 "
+        if scrm :  cmd += " -l " + `int(self.exact_window_length)`
+        if __fix_ms_seed__ :   cmd += " -seed 2 2 2 "
+        if __fix_scrm_seed__ :   cmd += " -seed 2 "
+        if __mydebug__: print cmd
+        #print cmd
+        return cmd
+        
+        
+        
+def run_program ( param, scrm = False, prefix = "msout" ):
+    program = "{ time -p "
+    program += "ms" if not scrm else "scrm"
+    program += " " + param.define_command( scrm ) + " > " + prefix + " ;} 2> "+prefix+"time.text"
+    #print program        
+    os.system ( program )    
+    return prefix
+    
+    
+def process_ms_scrm_output ( prefix ):
+    tree_file_name  = prefix + "Trees"
+    tree_freq_name  = prefix + "TreeFreq"
+    tmrca_name      = prefix + "Tmrca"
+    first_coal_name = prefix + "FirstCoal"
+    
+    grep_tree       = "grep \';\' " + prefix + " | sed -e 's/\\[.*\\]//g' > " + tree_file_name  
+    grep_freq       = "grep \';\' " + prefix + " | sed -e 's/\\[//g' | sed -e 's/\\].*;//g' > " + tree_freq_name
+    grep_tmrca      = "hybrid-Lambda -gt " + tree_file_name + " -log -tmrca " + tmrca_name
+    grep_first_coal = "hybrid-Lambda -gt " + tree_file_name + " -log -firstcoal " + first_coal_name
+    
+    os.system( grep_tree       )
+    os.system( grep_freq       )
+    os.system( grep_tmrca      )
+    os.system( grep_first_coal )
+    
+    tree_freq = [ float(x) for x in open( tree_freq_name, "r" ) ]
+    
+    tmrca = [ float(x) for x in open( tmrca_name, "r" )]
+    
+    first_coal_file = open( first_coal_name, "r" )
+    first_coal_time = []
+    clade = []
+    for line in first_coal_file:
+        first_coal_time.append( float(line.split()[0]) )        
+        clade.append( line.split()[1] )
+    first_coal_file.close()
+    
+    timeFile_name = prefix+"time.text"
+    runtime = float(open( timeFile_name, "r").readlines()[1].strip("user").strip('\n'))
+    #print runtime
+
+    return  tree_freq, tmrca, first_coal_time, clade, runtime
+
+
+def cal_ac_TMRC_star (tree_freq, tmrca, avg_tmrca, delta):
+
+    seqlen = sum(tree_freq)
+
+    cumfreq = [0]
+    shifted_cumfreq = [] 
+    for x in tree_freq : 
+        cumfreq.append(cumfreq[-1] + x)
+        shifted_cumfreq.append(cumfreq[-1] - delta)
+    cumfreq.pop(0)
+
+    n = int(seqlen - delta)
+    ac = 0
+    var = 0
+    
+    if __mydebug__:
+        print tree_freq
+        print cumfreq
+        print shifted_cumfreq        
+        print "seqence length = ", seqlen
+        print "i should iterate until ", n, "trees"
+    
+    T1_index = 0
+    T2_index = 0 # use while loop to determine the initial T2_index
+    while delta > cumfreq[T2_index]: # need to check again ...
+        T2_index += 1
+    about_to = False
+    for i in range( n ): 
+        if __mydebug__ & ((not i < cumfreq[T1_index]) | (not i < shifted_cumfreq[T2_index])):
+            print "before", i, T1_index,  T2_index
+            print "-------------------------------"
+            about_to = True
+        if i >= cumfreq[T1_index]: T1_index += 1
+        term1 = tmrca[T1_index] - avg_tmrca
+        if i >= shifted_cumfreq[T2_index]: T2_index += 1
+        term2 = tmrca[T2_index] - avg_tmrca
+        if __mydebug__ & about_to:
+            print "after ", i, T1_index,  T2_index
+            about_to = False
+        #print i, T1_index, term1, T2_index, term2
+        ac += term1 * term2
+        var += term1 * term1
+    ac /= float(n)
+    var /= float(n)
+    return ac, var
+
+
+def cal_ac_TMRC_star_2 (tree_freq, tmrca, avg_tmrca, delta):
+
+    seqlen = sum(tree_freq)
+
+    cumfreq = [0]
+    for x in tree_freq : 
+        cumfreq.append(cumfreq[-1] + x)
+    cumfreq.pop(0)
+
+    n = int(seqlen - delta)
+    ac = 0
+    var = 0
+    
+    T1_index = 0
+    T2_index = 0 # use while loop to determine the initial T2_index
+    while delta > cumfreq[T2_index]: # need to check again ...
+        T2_index += 1
+    i = 0
+    while i < n:
+        distance = min( cumfreq[T1_index] - i, 
+                        cumfreq[T2_index] - delta - i )
+        distance = min( distance, n - i )
+        term1 = tmrca[T1_index] - avg_tmrca
+        term2 = tmrca[T2_index] - avg_tmrca
+        ac += term1 * term2 * distance
+        var += term1 * term1 * distance
+        i += distance            
+        if i >= cumfreq[T1_index]: T1_index += 1
+        if i + delta >= cumfreq[T2_index]: T2_index += 1
+    ac /= float(n)
+    var /= float(n)
+    return ac, var
+
+
+def cal_ac_clade_2 (tree_freq, clade, delta ):
+    seqlen = sum(tree_freq)
+    cumfreq = [0]
+    for x in tree_freq : 
+        cumfreq.append(cumfreq[-1] + x)
+    cumfreq.pop(0)
+    n = int(seqlen - delta)
+    ac = 0.0
+    length = 0.0
+    T1_index = 0
+    T2_index = 0 # use while loop to determine the initial T2_index
+    while delta > cumfreq[T2_index]: # need to check again ...
+        T2_index += 1
+    i = 0
+    while i < n:
+        distance = min( cumfreq[T1_index] - i, 
+                        cumfreq[T2_index] - delta - i )
+        distance = min( distance, n - i )
+        term1 = clade[T1_index]  
+        term2 = clade[T2_index]  
+        ac += distance if term1 == term2 else 0
+        length += distance
+        i += distance            
+        if i >= cumfreq[T1_index]: T1_index += 1
+        if i + delta >= cumfreq[T2_index]: T2_index += 1
+
+    ac /= float(n)
+    length /= float(n)   # this should be 1
+    return ac, length
+
+    
+    
+def cal_ac_clade (tree_freq, clade, delta ):
+    seqlen = sum(tree_freq)
+    cumfreq = [0]
+    shifted_cumfreq = [] 
+    for x in tree_freq : 
+        cumfreq.append(cumfreq[-1] + x)
+        shifted_cumfreq.append(cumfreq[-1] - delta)
+    cumfreq.pop(0)
+    #print cumfreq, shifted_cumfreq
+    n = int(seqlen - delta)
+    ac = 0.0
+    length = 0.0
+    T1_index = 0
+    T2_index = 0 # use while loop to determine the initial T2_index
+    while delta > cumfreq[T2_index]: # need to check again ...
+        T2_index += 1
+    for i in range( n ):        
+        T1_index += 0 if i < cumfreq[T1_index] else 1
+        term1 = clade[T1_index] 
+        T2_index += 0 if i < shifted_cumfreq[T2_index] else 1
+        term2 = clade[T2_index] 
+        #print i, T1_index, term1, T2_index, term2
+        ac += 1 if term1 == term2 else 0
+        length += 1
+    ac /= float(n)
+    length /= float(n)   # this should be 1
+    return ac, length
+    
+    
+def n_rep ( param, scrm, prefix ):
+
+    reps = param.rep
+
+    # first collect all the data
+    data = []
+    for rep in range(reps):
+        if rep%(reps/10) == 0: print "replicate:",rep
+        out = run_program ( param, scrm, prefix)
+        # (tree_freq, tmrca, first_coal_time, clade, runtime)
+        data.append( process_ms_scrm_output ( out ) )
+        
+    # compute the average Tmrca and Tmrc
+    tot_tmrca = 0
+    tot_tmrc = 0
+    tot_time = 0
+    tot_runtime = 0
+    for d in data:
+        tot_runtime += d[4]
+        for i, duration_i in enumerate( d[0] ):
+            tmrca_i = d[1][i]
+            tmrc_i = d[2][i]
+            tot_tmrca += tmrca_i
+            tot_tmrc += tmrc_i
+            tot_time += duration_i
+    avg_tmrca = tot_tmrca / tot_time
+    avg_tmrc = tot_tmrc / tot_time
+
+    ac_TMRC = []    
+    ac_clade = []
+    for delta_i in param.big_delta:
+        cum_ac_TMRC = 0
+        cum_var_TMRC = 0
+        cum_ac_clade = 0
+        cum_length_clade = 0
+        for d in data:
+            ac, var = cal_ac_TMRC_star_2( d[0], d[2], avg_tmrc, delta_i )
+            cum_ac_TMRC += ac
+            cum_var_TMRC += var
+            ac, length = cal_ac_clade_2( d[0], d[3], delta_i )
+            cum_ac_clade += ac
+            cum_length_clade += length
+        ac_TMRC.append( cum_ac_TMRC / cum_var_TMRC )
+        ac_clade.append( cum_ac_clade / cum_length_clade )
+        
+    ac_TMRCA  = []    
+    for delta_i in param.small_delta:        
+        cum_ac_TMRCA = 0
+        cum_var_TMRCA = 0
+        for d in data:
+            ac, var = cal_ac_TMRC_star_2( d[0], d[1], avg_tmrc, delta_i )
+            cum_ac_TMRCA += ac
+            cum_var_TMRCA += var
+        ac_TMRCA.append( cum_ac_TMRCA / cum_var_TMRCA )
+
+    return ac_TMRCA, ac_TMRC, ac_clade, tot_runtime
+    
+
+#def n_rep ( param, scrm , prefix):
+    #ac = []
+    
+    #for i in range( param.rep ):
+        #if i%10 == 0: print i
+        #ac.append ( one_single_rep ( param, scrm, prefix ) )
+    ## ac[0] = ac_TMRCA, which has length of 10
+    
+    #Etmrca = [] # two dimension [i][j] i is ith replication, j is the Etmrca associated with delta[j]
+    #Efirst_coal = []
+    #Eclade = []
+    
+    #time = [ x[3] for x in ac ]
+    
+    #for i in range( len(param.big_delta) ):
+        #Etmrca.append( [ x[0][i] for x in ac ] ) # x is one single repicate, x[0] is the ac_TMRCA, x[0][i] is the ith Etmrca associated with delta[i]
+        #Efirst_coal.append( [ x[1][i] for x in ac ] )
+        #Eclade.append ( [ x[2][i] for x in ac ] )
+        
+    #return Etmrca, Efirst_coal, Eclade, time
+
+
+def myfigures ( delta, rho, prefix, legend, colors):
+    # rho is a list of MS, SCRM (pruned) and SCRM (full pruning) results
+    # results is a list of autocorrelations, one for each delta
+    #print legend
+    l = [] 
+    fig,(ax1)=pylab.subplots(1,1)
+    for i in range ( len (rho) ):
+        #y_err = [np.std(yi)*1.96/np.sqrt(len(yi)) for yi in rho[i]]
+        tmp1 = ax1.plot( delta, rho[i] , color = colors[i])
+        l.append ( tmp1 )
+    pylab.xlim( [np.min(delta), np.max(delta)] )
+    pylab.title( prefix )
+    pylab.xlabel(r'Distance between two sites $\delta$')
+    pylab.ylabel(r'Autocorrelation $\rho$')
+    pylab.legend ([ x[0] for x in l], legend, loc = 1)
+    pylab.savefig( prefix+".pdf" )
+    pylab.close()
+
+
+if __name__ == "__main__":
+
+    _use_param = parameter(nsam = 6, replicate = 1000, seqlen = 1e7, rho = 1e-8)         
+    _msac = n_rep ( _use_param, scrm = False, prefix = "msout")        
+    _scrmac = n_rep ( _use_param, scrm = True, prefix = "scrmout") 
+    
+    _use_param.exact_window_length = 1e3
+    _scrmace3 = n_rep ( _use_param, scrm = True, prefix = "scrme3out")        
+
+    _use_param.exact_window_length = 1e4
+    _scrmace4 = n_rep ( _use_param, scrm = True, prefix = "scrme4out")      
+
+    _use_param.exact_window_length = 5e4
+    _scrmac5e4 = n_rep ( _use_param, scrm = True, prefix = "scrm5e4out")      
+
+    _use_param.exact_window_length = 1e5
+    _scrmace5 = n_rep ( _use_param, scrm = True, prefix = "scrme5out")        
+    
+    _legend = ["ms", "exact window = 10000", "exact window = 1000", "exact window = 0"]
+    _colors = ["red", "green", "blue", "black"]
+    
+    # extract TMRCA from results and plot
+    _rho = [ _msac[0], _scrmace5[0], _scrmace3[0], _scrmac[0] ]
+    myfigures ( _use_param.small_delta, _rho, "tmrca", _legend, _colors)
+    
+    # extract TMRC
+    _rho = [ _msac[1], _scrmace5[1], _scrmace3[1], _scrmac[1] ]
+    myfigures ( _use_param.big_delta, _rho, "tmrc", _legend, _colors)
+
+    # extract clade
+    _rho = [ _msac[2], _scrmace5[2], _scrmace3[2], _scrmac[2] ]
+    myfigures ( _use_param.big_delta, _rho, "clade", _legend, _colors)
+    
+    
+    ########################## Divergence
+    _use_paramD = parameter(nsam = 6, replicate = 1000, seqlen = 1e7, rho = 1e-8, divergence = True)         
+    _msacD = n_rep ( _use_paramD, scrm = False, prefix = "Divergencemsout")        
+    _scrmacD = n_rep ( _use_paramD, scrm = True, prefix = "Divergencescrmout") 
+    
+    _use_paramD.exact_window_length = 1e3
+    _scrmace3D = n_rep ( _use_paramD, scrm = True, prefix = "Divergencescrme3out")        
+
+    _use_paramD.exact_window_length = 1e4
+    _scrmace4D = n_rep ( _use_paramD, scrm = True, prefix = "Divergencescrme4out")        
+
+    _use_paramD.exact_window_length = 5e4
+    _scrmac5e4D = n_rep ( _use_paramD, scrm = True, prefix = "Divergencescrm5e4out")        
+
+    _use_paramD.exact_window_length = 1e5
+    _scrmace5D = n_rep ( _use_paramD, scrm = True, prefix = "Divergencescrme5out")        
+    
+    
+    # extract TMRCA from results and plot
+    _rho = [ _msacD[0], _scrmace5D[0], _scrmace3D[0], _scrmacD[0] ]
+    myfigures ( _use_param.small_delta, _rho, "Divergencetmrca", _legend, _colors)
+    
+    # extract TMRC
+    _rho = [ _msacD[1], _scrmace5D[1], _scrmace3D[1], _scrmacD[1] ]
+    myfigures ( _use_param.big_delta, _rho, "Divergencetmrc", _legend, _colors)
+
+    # extract clade
+    _rho = [ _msacD[2], _scrmace5D[2], _scrmace3D[2], _scrmacD[2] ]
+    myfigures ( _use_param.big_delta, _rho, "Divergenceclade", _legend, _colors)
+    #except:
+        ##print "Usage: %s  <seqlen>  <position_file_name>  <psmc_input_file_prefix>" % sys.argv[0]
+        #sys.exit(1)
diff --git a/tests/manualtests/README b/tests/manualtests/README
new file mode 100644
index 0000000..8167dcd
--- /dev/null
+++ b/tests/manualtests/README
@@ -0,0 +1,222 @@
+Testing files for comparing statistics between ms output and scrm ouput
+
+CHECKING THE INITIAL TREE
+	
+* Checking -T option
+(Good 19Jan14) ##############################################
+(GOOD 17 May 14)
+(GOOD 1 June 14)
+	Compare TMRCA
+		./ms_vs_scrm-tmrca.sh
+	
+	Output file:
+		test-tmrca/compareTMRCA
+		test-tmrca/*.pdf
+		
+(Good 19Jan14) ##############################################
+(GOOD 17 May 14)
+(GOOD 1 June 14)
+	Compare total branch length
+		./ms_vs_scrm-bl.sh
+	
+	Output file:
+		test-bl/compareBL
+		test-bl/*.pdf
+
+
+(Good 19Jan14) ##############################################
+(GOOD 17 May 14)
+(GOOD 1 June 14)
+	Compare number of segregating sites (mutations)
+	./ms_vs_scrm-seg.sh 
+	
+	Output file:
+		test-seg/compareSEG
+		test-seg/*.pdf
+
+* Checking segregating sites data
+(Good 27Jan14) ##############################################
+(GOOD 17 May 14)
+(GOOD 31 May 14)
+
+	Compare summary statistics of the segregating site statistics (see ms manual section: Using ms with sample_stats)
+	./ms_vs_scrm_SEG_samplestats.sh
+	
+	Output file:
+		test-SEGsamplestats/compareSEG
+		test-SEGsamplestats/*.pdf
+
+CHECK TMRCA TOTAL BL SEG IN THE FOLLOWING CASES
+
+* Checking -ma option	
+(Good 28Jan14) ##############################################
+(GOOD 17 May 14)
+(GOOD 31 May 14)
+
+	Compare TMRCA and total branch length, and segregating sites for migration
+	./ms_vs_scrm-mig.sh
+	
+	Output file:
+		test-mig/compareMIG  
+		test-mig/*.pdf
+        
+(Good 27Feb 14) ##############################################
+(GOOD 17 May 14)
+(GOOD 31 May 14)
+
+	Compare TMRCA and total branch length, and segregating sites for migration BETWEEN TWO SEQUENCES
+	./ms_vs_scrm-mig_more.sh
+	
+	Output file:
+		test-mig-more/compareMIG  
+		test-mig-more/*.pdf
+        
+			
+* Checking the population structure, -eN option
+(Good 19Jan14) ##############################################
+(GOOD 17 May 14)
+(GOOD 31 May 14)
+	Compare TMRCA and total branch length, and segregating sites for Population structure
+	./ms_vs_scrm_pop_struct.sh 
+
+	Output file:
+		test-POP/comparePop
+		test-POP/*.pdf
+
+NOTE: Tajima's D only works when sample at least 3 individuals. Therefore, case 1 and 2 in the experiment would not work as the sample sizes are only 2
+
+* Checking -ma option with -eN option
+(Good 28Jan14) ##############################################
+(GOOD 17 May 14)
+(GOOD 31 May 14)
+	Compare TMRCA and total branch length, and segregating sites for migration
+	./ms_vs_scrm-mig-popsize.sh 
+	
+	Output file:
+		test-mig-popsize/compareMIG  
+		test-mig-popsize/*.pdf
+
+* Checking the sub population structure, -en, and -ej options
+(GOOD 13Feb14)##############################################
+(GOOD 17 May 14)
+(GOOD 31 May 14)
+
+	Compare TMRCA and total branch length, and segregating sites for migration
+    ./ms_vs_scrm_subpop_struct.sh
+    
+    Output file:
+        test-SUBPOP/compareSubPop
+        test-SUBPOP/*pdf
+
+* Checking growth rate, -G, -eG, and -eg option
+(GOOD 10APR14)##############################################
+(GOOD 17 May 14)
+(GOOD 31 May 14)
+
+    Compare TMRCA and total branch length, and segregating sites for migration
+    ./ms_vs_scrm_growth.sh 
+    
+    Output file:
+        test-GROWTH/compareGrowth
+        test-GROWTH/*pdf
+
+
+WITH RECOMBINATION
+	
+(Good 27Jan14)	##############################################
+(retest 17 May 14)
+(GOOD 1 June 14)
+	Compare TMRCA
+	Compare total branch length
+
+	./ms_vs_scrm-tmrca-wit-recomb.sh
+	
+	Output file:
+        test-tmrca-recomb/compareTMRCA-RECOMB
+        test-tmrca-recomb/compareBL-RECOMB
+        test-tmrca-recomb/*pdf
+	
+	
+(Good Feb 10)	##############################################
+(GOOD 1 June 14)
+	Compare number of segregating sites (mutations)
+	./ms_vs_scrm-seg_wit_recomb.sh 
+    
+    Output file:
+        test-seg-recomb/compareSEG-RECOMB 
+        test-seg-recomb/*pdf
+
+NOTE: for most of the cases, there is no significant difference on number of segreating sites. However, if there are only two lineages. The frequncy of few mutations differ.    
+
+
+* Checking -ma option with -r option
+(Good 27Feb14) ##############################################
+(GOOD 17 May 14)
+(GOOD 31 May 14)
+	Compare TMRCA and total branch length, and segregating sites for migration
+	./ms_vs_scrm-mig_recomb.sh
+	
+	Output file:
+		test-mig-recomb/compareMIG  
+		test-mig-recomb/*.pdf
+        
+(Good 27Feb14) ##############################################
+(GOOD 31 May 14)
+
+	Compare TMRCA and total branch length, and segregating sites for migration BETWEEN TWO SEQUENCES
+	./ms_vs_scrm-mig_more_recomb.sh
+	
+	Output file:
+		test-mig-pair/compareMIG  
+		test-mig-pair/*.pdf
+        
+
+        
+	##############################################
+	Compare spectrum
+	Compare the Spectrum of the segregating sites, frequencies of observing a k mutation...
+ (In process 18Jan14, need to check 19Jan14)   
+    ./spectrum.sh
+
+    ./spectrum-wit-recomb.sh
+    
+    Output file:
+        test-spectrum/compareSPEC
+
+test-spectrum-recomb/    
+
+
+* Checking growth rate with recombination, -G, -eG, and -eg option
+(GOOD 1 June 14)##############################################
+    Compare TMRCA and total branch length, and segregating sites for migration
+    ./ms_vs_scrm_growth-recomb.sh 
+    
+    Output file:
+        test-GROWTH-recomb/compareGrowth
+        test-GROWTH-recomb/*pdf
+	
+	
+RECOMBINATION ONLY
+	
+(GOOD 18Jan14)	##############################################
+	Compare number of recombination
+	./ms_vs_scrm-recomb.sh
+	
+    Output file:
+        test-recomb/compareRECOMB
+        test-recomb/*pdf
+	
+	
+	##############################################
+	Compare LD
+	
+	##############################################
+	Pairwise differences, see Excoffier and Foll 2011, Supplementary information. 
+!!! Need to test for the two island model
+	./pairwise_test.sh
+	
+	
+	
+	
+
+
diff --git a/tests/manualtests/bl_r.src b/tests/manualtests/bl_r.src
new file mode 100644
index 0000000..7123891
--- /dev/null
+++ b/tests/manualtests/bl_r.src
@@ -0,0 +1,17 @@
+echo "rm(list=ls());
+#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+msdata=read.table(\"msbl\")\$V1;
+scrmdata=read.table(\"scrmbl\")\$V1;
+test=ks.test(msdata,scrmdata)
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(ecdf(msdata), xlim=range(c(msdata, scrmdata)),col=\"red\", main=currentcase)
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+cat(paste(currentcase,figuretitle , \"\n\",\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",test\$statistic,format(test\$p.value,digits=4), 
+sep=\"\t\"),file=\"${COMPAREFILE}\",append=TRUE);cat(\"\n\",file=\"${COMPAREFILE}\",append=TRUE);" > bl.r
diff --git a/tests/manualtests/chisq_r.src b/tests/manualtests/chisq_r.src
new file mode 100644
index 0000000..79a2d81
--- /dev/null
+++ b/tests/manualtests/chisq_r.src
@@ -0,0 +1,36 @@
+		echo "rm(list=ls());
+		#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+msdata=read.table(paste(\"ms\",\"data\",sep=\"\"))\$V1;
+scrmdata=read.table(paste(\"scrm\",\"data\",sep=\"\"))\$V1;
+		#ee=ee_seg(${nsam},${t});
+		#sdv=sd_seg_norecomb(${nsam},${t});
+		datamax=max(msdata,scrmdata);
+		mstable=table(factor(msdata,levels=1:datamax))
+		scrmtable=table(factor(scrmdata,levels=1:datamax))
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(as.numeric(names(mstable)), mstable/length(msdata),pch=16,col=\"red\",ylab=\"Frequency\",xlab=figuretitle);
+points(as.numeric(names(scrmtable)), scrmtable/length(scrmdata),pch=16,col=\"blue\")
+
+ms_newtable=table(msdata);
+scrm_mstable=table(factor(scrmdata,levels=names(table(msdata))));
+combined_scrm_ms_test=chisq.test(cbind(scrm_mstable, ms_newtable));
+
+scrm_newtable=table(scrmdata);
+ms_scrmtable=table(factor(msdata,levels=names(table(scrmdata))));
+combined_ms_scrm_test=chisq.test(cbind(scrm_newtable, ms_scrmtable));
+
+legend(\"topright\",c(paste(\"Test 1 Statistics = \",combined_scrm_ms_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_scrm_ms_test\$p.value,digits=4),sep=\"\"),paste(\"Test 2 Statistics = \",combined_ms_scrm_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_ms_scrm_test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+
+dev.off();
+
+#cat(paste(${nsam},${t},\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+cat(paste(currentcase, figuretitle , \"\n\",\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"||\",
+format(combined_scrm_ms_test\$statistic,digits=4),format(combined_scrm_ms_test\$p.value,scientific = TRUE),\"||\",
+format(combined_ms_scrm_test\$statistic,digits=4),format(combined_ms_scrm_test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${COMPAREFILE}\",append=TRUE);cat(\"\n\",file=\"${COMPAREFILE}\",append=TRUE);
+" > chisq.r
diff --git a/tests/manualtests/fun_src.r b/tests/manualtests/fun_src.r
new file mode 100644
index 0000000..c272409
--- /dev/null
+++ b/tests/manualtests/fun_src.r
@@ -0,0 +1,84 @@
+library(pracma)
+
+# Expected value of TMRCA of n taxa, Wakeley 2008 (3.23)
+ee_tmrca=function(n){
+	return (1-1/n);
+}
+
+# Standard deviation of TMRCA of n taxa, Wakeley 2008 (3.26) Hein 2005 (1.32)
+sd_tmrca=function(n){
+	i=seq(2,n,1);
+	return(sqrt( sum(1/i^2/(i-1)^2)));
+}
+
+# Expected value of total branch length of n taxa, Wakeley 2008 (3.24)
+ee_bl=function(n){
+	i=seq(1,n-1,1);
+	return (sum(1/i));
+}
+
+# Standard deviation of total branch length of n taxa, Wakeley 2008 (3.25)
+sd_bl=function(n){
+	i=seq(1,n-1,1);
+	return(sqrt( sum(1/i^2)));
+}
+
+# Expected value of number of segregating sites (mutations) of n taxa with rate theta, Wakeley 2008 (4.7)
+ee_seg=function(n, theta){
+	i=seq(1,n-1,1);
+	return(theta*sum(1/i));
+}
+
+# Standard deviation of number of segregating sites (mutations) of n taxa with rate theta, Wakeley 2008 (4.8)
+sd_seg_norecomb=function(n, theta){
+	i=seq(1,n-1,1);
+	return(sqrt( ee_seg(n,theta) + theta^2*sum(1/i^2)));
+}
+
+
+f2x=function(x){
+	return ( (x+18)/(x^2+13*x+18) );
+}
+
+fnx=function(x,n){
+#	return (n/(2*x*(n-1)));
+	i=seq(1,n-1,1);
+	return(f2x(x)*sum(1/i^2));
+}
+
+
+f2x_integrand=function(x,rho){
+	return ( (rho-x)*f2x(x));
+}
+
+fnx_integrand=function(x,rho,n){
+	return ( (rho-x)*fnx(x,n=n));
+}
+
+sd_seg_recomb=function(n, theta, rho){
+#	if (n==2){
+		return ( sqrt( ee_seg(n, theta) + theta^2 * 2 /rho^2 *quad(f2x_integrand, xa=0, xb=rho, rho=rho) ) ); # Hein 2005 5.25
+#	#	return ( sqrt( theta + theta^2 * 2 /rho^2 *quad(seg_integrand, xa=0, xb=rho, rho=rho) ) ); #Wakeley 2008 7.20, maybe wrong
+#	}
+#	else{
+#		return ( sqrt( ee_seg(n, theta) + theta^2 * 2 /rho^2 *quad(fnx_integrand, xa=0, xb=rho, rho=rho, n=n) ) );
+#	}
+}
+
+
+
+
+sd_recomb=function(rho,n){
+#	if (n==2){
+		return( sqrt(ee_seg(n, rho) + 2 * quad(f2x_integrand, xa=0, xb=rho, rho=rho) ) );
+#	}
+#	else{
+#		return( sqrt( ee_seg(n, rho) + 2 * quad(fnx_integrand, xa=0, xb=rho, rho=rho, n=n) ) );
+#	}
+}
+
+
+PSk=function(n, k, theta){
+	i=seq(2,n,1);
+	return ( sum( (-1)^i * choose(n-1, i-1) * (i-1)/(theta+i-1) * (theta/(theta+i-1)^k) ));
+}
diff --git a/tests/manualtests/ks_r.src b/tests/manualtests/ks_r.src
new file mode 100644
index 0000000..bde81d6
--- /dev/null
+++ b/tests/manualtests/ks_r.src
@@ -0,0 +1,20 @@
+echo "rm(list=ls());
+#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+msdata=read.table(paste(\"ms\",\"data\",sep=\"\"))\$V1;
+scrmdata=read.table(paste(\"scrm\",\"data\",sep=\"\"))\$V1;
+#ee=1#ee_tmrca(${nsam});
+#sdv=1#sd_tmrca(${nsam});
+test=ks.test(msdata,scrmdata)
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(ecdf(msdata), xlim=range(c(msdata, scrmdata)),col=\"red\", main=currentcase)
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+#cat(paste(currentcase,\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+cat(paste(currentcase, figuretitle , \"\n\",\"|\",
+format(mean(msdata),scientific = TRUE),format(sd(msdata),scientific = TRUE),\"||\",
+format(mean(scrmdata),scientific = TRUE),format(sd(scrmdata),scientific = TRUE),\"|\",format(test\$statistic,scientific = TRUE),format(test\$p.value,scientific = TRUE), 
+sep=\"\t\"),file=\"${COMPAREFILE}\",append=TRUE);cat(\"\n\",file=\"${COMPAREFILE}\",append=TRUE);" > ks.r
diff --git a/tests/manualtests/ms_first_vs_last.sh b/tests/manualtests/ms_first_vs_last.sh
new file mode 100755
index 0000000..a572870
--- /dev/null
+++ b/tests/manualtests/ms_first_vs_last.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+#Compare summary statistics of ms simulation for the initial genealogy and the final genealogy for TMRCA with recombination events
+
+mkdir test-ms-first_vs_last
+cd test-ms-first_vs_last
+rm *pdf
+
+compareFirstLast=compareFirstLast
+rm ${compareFirstLast}
+
+
+echo "rm(list=ls());
+currentcase=scan(\"current_case\",what=\"\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+
+firstdata=read.table(\"msfirsttmrca\")\$V1;
+lastdata=read.table(\"mslasttmrca\")\$V1;
+test=ks.test(firstdata,lastdata)
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(ecdf(firstdata), xlim=range(c(firstdata, lastdata)),col=\"red\", main=currentcase)
+plot(ecdf(lastdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"first\",\"last\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+cat(paste(currentcase,figuretitle,\"|\",
+format(mean(firstdata),digits=4),format(sd(firstdata),digits=4),\"|\",
+format(mean(lastdata),digits=4),format(sd(lastdata),digits=4),\"|\",test\$statistic,format(test\$p.value,digits=4), 
+sep=\"\t\"),file=\"${compareFirstLast}\",append=TRUE);cat(\"\n\",file=\"${compareFirstLast}\",append=TRUE);" > tmrca.r
+
+seqlen=100000
+
+rep=100000
+
+msNsample=(2 4 6)
+msr=(10 20)
+mst=(10 5)
+
+for t in "${mst[@]}"
+	do
+	for r in "${msr[@]}"
+		do
+		for nsam in "${msNsample[@]}"
+			do
+			rm current_case ms*Trees ms*tmrca figuretitle
+			prefix=ms${nsam}sample${r}rho${t}theta
+			echo ${prefix}
+			echo "${prefix}" > current_case
+			#rm ms* scrm*
+			ms ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} -T | tail -n +4 | gawk '/^\/\//{f="xx"++d} f{print > f} '
+			for file in $(seq 1 1 ${rep})
+				do 
+				grep ";" xx${file} | sed -e 's/\[.*\]//g' | head -1 >> msfirstTrees
+				grep ";" xx${file} | sed -e 's/\[.*\]//g' | tail -1 >> mslastTrees
+				done
+				#hybrid-Lambda -gt msfirstTrees -bl msfirstbl
+			find . -name "xx*" -print0 | xargs -0 rm
+			hybrid-Lambda -gt msfirstTrees -tmrca msfirsttmrca
+			hybrid-Lambda -gt mslastTrees -tmrca mslasttmrca
+			echo "TMRCA" > figuretitle
+			R CMD BATCH tmrca.r
+			rm ms*tmrca
+			hybrid-Lambda -gt msfirstTrees -bl msfirsttmrca
+			hybrid-Lambda -gt mslastTrees -bl mslasttmrca
+			echo "BL" > figuretitle
+			R CMD BATCH tmrca.r
+			
+			done
+		done
+	done
diff --git a/tests/manualtests/ms_vs_scrm-bl.sh b/tests/manualtests/ms_vs_scrm-bl.sh
new file mode 100755
index 0000000..5ef9af0
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-bl.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+#Compare summary statistics of ms and scrm for BL, number of mutation, and number of recombination
+
+mkdir test-bl
+cd test-bl
+rm *pdf
+
+msNsample=(2 3 4 7 10 20)
+
+rep=100000
+
+## compare BL
+compareBL=compareBL
+rm ${compareBL}
+echo -e "compare BL for ${rep} replicates \n\t|Theoretical\t\t|\t ms \t\t|\t scrm\t\t|\tKS test\nNsam\t|\tmean\tstdv\t|\tmean\tstdv\t|\tmean\tstdv \t|\tstats\tp-value" >${compareBL}
+#theta=10
+
+npop=1000000
+for nsam in "${msNsample[@]}"
+	do
+	prefix=${nsam}sample
+	out=${prefix}out
+	bl=${prefix}bl
+	Trees=${prefix}Trees
+	ms ${nsam} ${rep} -T | tail -n +4 | grep -v "//" > ms${out}
+	cat ms${out} | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+	hybrid-Lambda -gt ms${Trees} -bl ms${bl}
+	scrm ${nsam} ${rep} -T | tail -n +4 | grep -v "//" > scrm${out}
+	cat scrm${out} | grep ";" | sed -e 's/\[.*\]//g' > scrm${Trees}
+	hybrid-Lambda -gt scrm${Trees} -bl scrm${bl}
+	echo "rm(list=ls());
+source(\"../fun_src.r\");
+msdata=read.table(\"ms${bl}\")\$V1;
+scrmdata=read.table(\"scrm${bl}\")\$V1;
+ee=ee_bl(${nsam});
+sdv=sd_bl(${nsam});
+test=ks.test(msdata,scrmdata)
+pdf(paste($nsam,\"sampleBL-KStest.pdf\",sep=\"\"));
+plot(ecdf(msdata), xlim=range(c(msdata, scrmdata)),col=\"red\", main=paste($nsam,\"sample BL KS test\",sep=\"\"))
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+cat(paste(${nsam},\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",test\$statistic,format(test\$p.value,digits=4), 
+sep=\"\t\"),file=\"${compareBL}\",append=TRUE);cat(\"\n\",file=\"${compareBL}\",append=TRUE);" > dummy.r
+	R CMD BATCH dummy.r
+	rm ms${out} ms${Trees} ms${bl} scrm${out} scrm${Trees} scrm${bl} 
+	done
+
diff --git a/tests/manualtests/ms_vs_scrm-mig-popsize.sh b/tests/manualtests/ms_vs_scrm-mig-popsize.sh
new file mode 100755
index 0000000..0b69eba
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-mig-popsize.sh
@@ -0,0 +1,120 @@
+#!/bin/bash
+
+#Compare summary statistics of ms and scrm for migration
+
+dir=test-mig-popsize
+mkdir ${dir}
+cd ${dir}
+rm -rf *pdf
+
+
+rep=10000
+
+## compare TMRCA
+COMPAREFILE=compareMIG
+rm ${COMPAREFILE}
+
+
+theta=10
+
+source ../chisq_r.src
+
+source ../ks_r.src
+
+source ../tmrca_r.src
+
+source ../bl_r.src
+
+source ../process_sample_stats.src	
+	
+	
+#case 1 
+#2 sub population, 2 samples from each subpopulation, mutation rate is 5
+echo "2groups2sam2sam_mig5" > current_case
+rm ms* scrm*
+
+#ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -T | tail -n +4 | grep -v "//" | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+
+ms 4 ${rep} -t ${theta} -I 2 2 2 5.0 -eN 0.4 10.01 -eN 1 0.01 -T -L > msout
+scrm 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -eN 0.4 10.01 -eN 1 0.01 -T -L > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+#case 2 
+#2 sub population, 6 samples from subpopulation 1, and 5 samples from subpopulation 2, with rate 10 from 1 to 2, and rate 5 from 2 to 1
+
+echo "2groups6sam5sam_mig_x_10_5_x" > current_case
+rm ms* scrm*
+	
+ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 10.0 5.0 x -eN .5 0.01 -T -L > msout
+scrm 4 ${rep} -t ${theta} -I 2 2 2 -ma x 10.0 5.0 x -eN .5 0.01 -T -L > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+
+#case 3
+#3 sub population, 10 samples from subpopulation 1, and 4 samples from subpopulation 2, and 1 sample from the third with rate 5
+
+echo "3groups10sam4sam1sam_mig_sym10" > current_case
+rm ms* scrm*
+	
+ms 15 ${rep} -t ${theta} -I 3 10 4 1 10.0 -eN 0.5 10.0 -T -L > msout
+scrm 15 ${rep} -t ${theta} -I 3 10 4 1 -ma x 5.0 5.0 5.0 x 5.0 5.0 5.0 x -eN 0.5 10.0 -T -L > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+#case 4
+#3 sub population, 10 samples from subpopulation 1, and 4 samples from subpopulation 2, and 1 sample from the third with rate 5
+
+echo "3groups10sam4sam1sam_mig_offdiag5" > current_case
+rm ms* scrm*
+
+	
+ms 15 ${rep} -t ${theta} -I 3 10 4 1 -ma x 5.0 5.0 5.0 x 5.0 5.0 5.0 x -eN 0.8 15  -T -L > msout
+scrm 15 ${rep} -t ${theta} -I 3 10 4 1 -ma x 5.0 5.0 5.0 x 5.0 5.0 5.0 x -eN 0.8 15  -T -L > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+
+
+#case 5
+#3 sub population, 10 samples from subpopulation 1, and 4 samples from subpopulation 2, and 1 sample from the third with rate matrix on manual page 5
+
+echo "3groups10sam4sam1sam_mig_x123x456x" > current_case
+
+rm ms* scrm*
+	
+ms 15 ${rep} -t ${theta} -I 3 10 4 1 -ma x 1.0 2.0 3.0 x 4.0 5.0 6.0 x -eN 1 .1 -eN 3 10 -T -L > msout
+scrm 15 ${rep} -t ${theta} -I 3 10 4 1 -ma x 1.0 2.0 3.0 x 4.0 5.0 6.0 x -eN 1 .1 -eN 3 10 -T -L > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
diff --git a/tests/manualtests/ms_vs_scrm-mig.sh b/tests/manualtests/ms_vs_scrm-mig.sh
new file mode 100755
index 0000000..81e482e
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-mig.sh
@@ -0,0 +1,120 @@
+#!/bin/bash
+
+#Compare summary statistics of ms and scrm for migration
+
+mkdir test-mig
+cd test-mig
+rm *pdf
+
+
+rep=100000
+
+## compare TMRCA
+COMPAREFILE=compareMIG
+rm ${COMPAREFILE}
+
+theta=10
+
+
+source ../chisq_r.src
+
+source ../ks_r.src
+
+source ../tmrca_r.src
+
+source ../bl_r.src
+
+source ../process_sample_stats.src
+
+
+	
+#case 1 
+#2 sub population, 2 samples from each subpopulation, mutation rate is 5
+echo "2groups2sam2sam_mig5" > current_case
+rm ms* scrm*
+
+#ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -T | tail -n +4 | grep -v "//" | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+
+ms 4 ${rep} -t ${theta} -I 2 2 2 5.0 -T -L > msout
+scrm 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -T -L > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+#case 2 
+#2 sub population, 6 samples from subpopulation 1, and 5 samples from subpopulation 2, with rate 10 from 1 to 2, and rate 5 from 2 to 1
+
+echo "2groups6sam5sam_mig_x_10_5_x" > current_case
+rm ms* scrm*
+	
+ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 10.0 5.0 x -T -L > msout
+scrm 4 ${rep} -t ${theta} -I 2 2 2 -ma x 10.0 5.0 x -T -L > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+
+#case 3
+#3 sub population, 10 samples from subpopulation 1, and 4 samples from subpopulation 2, and 1 sample from the third with rate 5
+
+echo "3groups10sam4sam1sam_mig_sym10" > current_case
+rm ms* scrm*
+	
+ms 15 ${rep} -t ${theta} -I 3 10 4 1 10.0 -T -L > msout
+scrm 15 ${rep} -t ${theta} -I 3 10 4 1 -ma x 5.0 5.0 5.0 x 5.0 5.0 5.0 x -T -L > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+#case 4
+#3 sub population, 10 samples from subpopulation 1, and 4 samples from subpopulation 2, and 1 sample from the third with rate 5
+
+echo "3groups10sam4sam1sam_mig_offdiag5" > current_case
+rm ms* scrm*
+
+	
+ms 15 ${rep} -t ${theta} -I 3 10 4 1 -ma x 5.0 5.0 5.0 x 5.0 5.0 5.0 x -T -L > msout
+scrm 15 ${rep} -t ${theta} -I 3 10 4 1 -ma x 5.0 5.0 5.0 x 5.0 5.0 5.0 x -T -L > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+
+
+#case 5
+#3 sub population, 10 samples from subpopulation 1, and 4 samples from subpopulation 2, and 1 sample from the third with rate matrix on manual page 5
+
+echo "3groups10sam4sam1sam_mig_x123x456x" > current_case
+
+rm ms* scrm*
+	
+ms 15 ${rep} -t ${theta} -I 3 10 4 1 -ma x 1.0 2.0 3.0 x 4.0 5.0 6.0 x -T -L > msout
+scrm 15 ${rep} -t ${theta} -I 3 10 4 1 -ma x 1.0 2.0 3.0 x 4.0 5.0 6.0 x -T -L > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
diff --git a/tests/manualtests/ms_vs_scrm-mig_more.sh b/tests/manualtests/ms_vs_scrm-mig_more.sh
new file mode 100755
index 0000000..93ee7bf
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-mig_more.sh
@@ -0,0 +1,103 @@
+#!/bin/bash
+
+#Compare summary statistics of ms and scrm for migration
+
+dir=test-mig-more
+mkdir ${dir}
+cd ${dir}
+rm *pdf
+
+
+rep=100000
+
+## compare TMRCA
+COMPAREFILE=compareMIG
+rm ${COMPAREFILE}
+
+
+theta=10
+
+source ../chisq_r.src
+
+source ../ks_r.src
+
+source ../tmrca_r.src
+
+source ../bl_r.src
+
+source ../process_sample_stats.src	
+	
+	
+#case 1 
+#2 sub population, 1 sample from each subpopulation, mutation rate is 5
+echo "2groups1sam1sam_case1_mig5" > current_case
+rm ms* scrm*
+
+#ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -T | tail -n +4 | grep -v "//" | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+
+ms 2 ${rep} -t ${theta} -I 2 1 1 5.0 -T -L > msout
+scrm 2 ${rep} -t ${theta} -I 2 1 1 -ma x 5.0 5.0 x -T -L > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+#case 2
+#2 sub population, 1 sample from each subpopulation, mutation rate is 5
+echo "2groups1sam1sam_case2_mig5" > current_case
+rm ms* scrm*
+
+#ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -T | tail -n +4 | grep -v "//" | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+
+ms 2 ${rep} -t ${theta} -I 2 1 1 5.0 -T -L > msout
+scrm 2 ${rep} -t ${theta} -I 2 1 1 5.0 -T -L > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+
+#case 3
+#2 sub population, 1 sample from each subpopulation, mutation rate is 5
+echo "2groups1sam1sam_case3_mig5" > current_case
+rm ms* scrm*
+
+#ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -T | tail -n +4 | grep -v "//" | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+
+ms 2 ${rep} -t ${theta} -I 2 1 1 -ma x 5 0 x -ej 2.0 2 1 -T -L > msout
+scrm 2 ${rep} -t ${theta} -I 2 1 1 -ma x 5 0 x -ej 2.0 2 1 -T -L > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+#case 3
+#2 sub population, 1 sample from each subpopulation, mutation rate is 5
+echo "2groups1sam1sam_case4_mig5" > current_case
+rm ms* scrm*
+
+#ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -T | tail -n +4 | grep -v "//" | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+
+ms 2 ${rep} -t ${theta} -I 2 1 1 -ma x 0 5 x -ej 2.0 2 1 -T -L > msout
+scrm 2 ${rep} -t ${theta} -I 2 1 1 -ma x 0 5 x -ej 2.0 2 1 -T -L > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
diff --git a/tests/manualtests/ms_vs_scrm-mig_more_recomb.sh b/tests/manualtests/ms_vs_scrm-mig_more_recomb.sh
new file mode 100755
index 0000000..b6029c9
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-mig_more_recomb.sh
@@ -0,0 +1,265 @@
+#!/bin/bash
+
+#Compare summary statistics of ms and scrm for migration
+
+mkdir test-mig-pair
+cd test-mig-pair
+rm *pdf
+
+
+rep=10000
+seqlen=100000
+#msr=(10 20 10 50)
+r=10
+
+## compare TMRCA
+compareMIG=compareMIG
+rm ${comparePop}
+
+
+#rm ${compareTMRCA}
+#rm ${compareBL}
+#echo -e "compare TMRCA for ${rep} replicates 
+#\t|\t ms \t\t|\t scrm\t\t|\tKS test
+#Case\t|\tmean\tstdv\t|\tmean\tstdv \t|\tstats\tp-value" >${compareTMRCA}
+
+#echo -e "compare BL for ${rep} replicates 
+#\t|\t ms \t\t|\t scrm\t\t|\tKS test
+#Case\t|\tmean\tstdv\t|\tmean\tstdv \t|\tstats\tp-value" >${compareBL}
+
+theta=10
+
+		echo "rm(list=ls());
+		#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+msdata=read.table(paste(\"ms\",\"data\",sep=\"\"))\$V1;
+scrmdata=read.table(paste(\"scrm\",\"data\",sep=\"\"))\$V1;
+		#ee=ee_seg(${nsam},${t});
+		#sdv=sd_seg_norecomb(${nsam},${t});
+		datamax=max(msdata,scrmdata);
+		mstable=table(factor(msdata,levels=1:datamax))
+		scrmtable=table(factor(scrmdata,levels=1:datamax))
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(as.numeric(names(mstable)), mstable/length(msdata),pch=16,col=\"red\",ylab=\"Frequency\",xlab=figuretitle);
+points(as.numeric(names(scrmtable)), scrmtable/length(scrmdata),pch=16,col=\"blue\")
+
+ms_newtable=table(msdata);
+scrm_mstable=table(factor(scrmdata,levels=names(table(msdata))));
+combined_scrm_ms_test=chisq.test(cbind(scrm_mstable, ms_newtable));
+
+scrm_newtable=table(scrmdata);
+ms_scrmtable=table(factor(msdata,levels=names(table(scrmdata))));
+combined_ms_scrm_test=chisq.test(cbind(scrm_newtable, ms_scrmtable));
+
+legend(\"topright\",c(paste(\"Test 1 Statistics = \",combined_scrm_ms_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_scrm_ms_test\$p.value,digits=4),sep=\"\"),paste(\"Test 2 Statistics = \",combined_ms_scrm_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_ms_scrm_test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+
+dev.off();
+
+#cat(paste(${nsam},${t},\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+cat(paste(currentcase, figuretitle , \"\n\",\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"||\",
+format(combined_scrm_ms_test\$statistic,digits=4),format(combined_scrm_ms_test\$p.value,scientific = TRUE),\"||\",
+format(combined_ms_scrm_test\$statistic,digits=4),format(combined_ms_scrm_test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareMIG}\",append=TRUE);cat(\"\n\",file=\"${compareMIG}\",append=TRUE);
+" > chisq.r
+
+echo "rm(list=ls());
+#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+msdata=read.table(paste(\"ms\",\"data\",sep=\"\"))\$V1;
+scrmdata=read.table(paste(\"scrm\",\"data\",sep=\"\"))\$V1;
+#ee=1#ee_tmrca(${nsam});
+#sdv=1#sd_tmrca(${nsam});
+test=ks.test(msdata,scrmdata)
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(ecdf(msdata), xlim=range(c(msdata, scrmdata)),col=\"red\", main=currentcase)
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+#cat(paste(currentcase,\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+cat(paste(currentcase, figuretitle , \"\n\",\"|\",
+format(mean(msdata),scientific = TRUE),format(sd(msdata),scientific = TRUE),\"||\",
+format(mean(scrmdata),scientific = TRUE),format(sd(scrmdata),scientific = TRUE),\"|\",format(test\$statistic,scientific = TRUE),format(test\$p.value,scientific = TRUE), 
+sep=\"\t\"),file=\"${compareMIG}\",append=TRUE);cat(\"\n\",file=\"${compareMIG}\",append=TRUE);" > ks.r
+
+echo "rm(list=ls());
+#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+msdata=read.table(\"mstmrca\")\$V1;
+scrmdata=read.table(\"scrmtmrca\")\$V1;
+#ee=ee_tmrca(${nsam});
+#sdv=sd_tmrca(${nsam});
+test=ks.test(msdata,scrmdata)
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(ecdf(msdata), xlim=range(c(msdata, scrmdata)),col=\"red\", main=currentcase)
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+cat(paste(currentcase,figuretitle , \"\n\",\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",test\$statistic,format(test\$p.value,digits=4), 
+sep=\"\t\"),file=\"${compareMIG}\",append=TRUE);cat(\"\n\",file=\"${compareMIG}\",append=TRUE);" > tmrca.r
+
+echo "rm(list=ls());
+#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+msdata=read.table(\"msbl\")\$V1;
+scrmdata=read.table(\"scrmbl\")\$V1;
+test=ks.test(msdata,scrmdata)
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(ecdf(msdata), xlim=range(c(msdata, scrmdata)),col=\"red\", main=currentcase)
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+cat(paste(currentcase,figuretitle , \"\n\",\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",test\$statistic,format(test\$p.value,digits=4), 
+sep=\"\t\"),file=\"${compareMIG}\",append=TRUE);cat(\"\n\",file=\"${compareMIG}\",append=TRUE);" > bl.r
+
+
+foo(){
+    #cut -f 2 mstime > mstmrca
+	#cut -f 2 scrmtime > scrmtmrca
+	echo "TMRCA" > figuretitle
+	R CMD BATCH tmrca.r
+
+    #cut -f 3 mstime > msbl
+	#cut -f 3 scrmtime > scrmbl
+	echo "BL" > figuretitle
+	R CMD BATCH bl.r
+
+	cut -f 6 ms_stats > msdata
+	cut -f 6 scrm_stats > scrmdata
+	echo "Tajima_D" > figuretitle
+	R CMD BATCH ks.r
+
+	cut -f 2 ms_stats > msdata
+	cut -f 2 scrm_stats > scrmdata
+	echo "Pairewise_difference" > figuretitle
+	R CMD BATCH chisq.r
+
+	cut -f 8 ms_stats > msdata
+	cut -f 8 scrm_stats > scrmdata
+	echo "theta_H" > figuretitle
+	R CMD BATCH chisq.r
+
+	cut -f 10 ms_stats > msdata
+	cut -f 10 scrm_stats > scrmdata
+	echo "H" > figuretitle
+	R CMD BATCH chisq.r
+	}
+	
+mstime(){
+    cat msout | gawk '/^\/\//{f="xx"++d} f{print > f} '
+    for file in $(seq 1 1 ${rep})
+        do 
+        grep ";" xx${file} | sed -e 's/\[.*\]//g' | tail -1 >> msTrees
+        done
+        hybrid-Lambda -gt msTrees -tmrca mstmrca
+        hybrid-Lambda -gt msTrees -bl msbl
+        find . -name "xx*" -print0 | xargs -0 rm    
+    }	
+    
+scrmtime(){
+    cat scrmout | gawk '/^\/\//{f="xx"++d} f{print > f} '
+    for file in $(seq 1 1 ${rep})
+        do 
+        grep ";" xx${file} | sed -e 's/\[.*\]//g' | tail -1 >> scrmTrees
+        done
+        hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+        hybrid-Lambda -gt scrmTrees -bl scrmbl
+        find . -name "xx*" -print0 | xargs -0 rm    
+    }	
+	
+	
+#case 1 
+#2 sub population, 1 sample from each subpopulation, mutation rate is 5
+echo "2groups1sam1sam_case1_mig5" > current_case
+rm ms* scrm*
+
+#ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -T | tail -n +4 | grep -v "//" | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+
+ms 2 ${rep} -t ${theta} -r ${r} ${seqlen} -I 2 1 1 5.0 -T > msout
+mstime 
+
+scrm 2 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 1 1 -ma x 5.0 5.0 x -T  > scrmout
+scrmtime
+
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+#cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+#case 2
+#2 sub population, 1 sample from each subpopulation, mutation rate is 5
+echo "2groups1sam1sam_case2_mig5" > current_case
+rm ms* scrm*
+
+#ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -T | tail -n +4 | grep -v "//" | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+
+ms 2 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 1 1 5.0 -T > msout
+mstime
+
+scrm 2 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 1 1 5.0 -T -L > scrmout
+scrmtime
+
+
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+#cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+
+#case 3
+#2 sub population, 1 sample from each subpopulation, mutation rate is 5
+echo "2groups1sam1sam_case3_mig5" > current_case
+rm ms* scrm*
+
+#ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -T | tail -n +4 | grep -v "//" | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+
+ms 2 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 1 1 -ma x 5 0 x -ej 0.5 2 1 -T > msout
+mstime
+
+scrm 2 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 1 1 -ma x 5 0 x -ej 0.5 2 1 -T -L > scrmout
+scrmtime
+
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+#cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+#case 3
+#2 sub population, 1 sample from each subpopulation, mutation rate is 5
+echo "2groups1sam1sam_case4_mig5" > current_case
+rm ms* scrm*
+
+#ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -T | tail -n +4 | grep -v "//" | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+
+ms 2 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 1 1 -ma x 0 5 x -ej 0.5 2 1 -T > msout
+mstime
+
+scrm 2 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 1 1 -ma x 0 5 x -ej 0.5 2 1 -T -L > scrmout
+scrmtime
+
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+#cat scrmout | grep "time:" >  scrmtime
+
+foo
+
diff --git a/tests/manualtests/ms_vs_scrm-mig_recomb.sh b/tests/manualtests/ms_vs_scrm-mig_recomb.sh
new file mode 100755
index 0000000..619f25f
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-mig_recomb.sh
@@ -0,0 +1,167 @@
+#!/bin/bash
+
+#Compare summary statistics of ms and scrm for migration
+
+dir=test-mig-recomb
+mkdir ${dir}
+cd ${dir}
+rm *pdf
+
+
+rep=10000
+seqlen=100000
+#msr=(10 20 10 50)
+r=10
+
+## compare TMRCA
+COMPAREFILE=compareMIG
+rm ${COMPAREFILE}
+
+
+theta=10
+
+
+source ../chisq_r.src
+
+source ../ks_r.src
+
+source ../tmrca_r.src
+
+source ../bl_r.src
+
+source ../process_sample_stats.src	
+
+#foo(){
+    ##cut -f 2 mstime > mstmrca
+	##cut -f 2 scrmtime > scrmtmrca
+	#echo "TMRCA" > figuretitle
+	#R CMD BATCH tmrca.r
+
+    ##cut -f 3 mstime > msbl
+	##cut -f 3 scrmtime > scrmbl
+	#echo "BL" > figuretitle
+	#R CMD BATCH bl.r
+
+	#cut -f 6 ms_stats > msdata
+	#cut -f 6 scrm_stats > scrmdata
+	#echo "Tajima_D" > figuretitle
+	#R CMD BATCH ks.r
+
+	#cut -f 2 ms_stats > msdata
+	#cut -f 2 scrm_stats > scrmdata
+	#echo "Pairewise_difference" > figuretitle
+	#R CMD BATCH chisq.r
+
+	#cut -f 8 ms_stats > msdata
+	#cut -f 8 scrm_stats > scrmdata
+	#echo "theta_H" > figuretitle
+	#R CMD BATCH chisq.r
+
+	#cut -f 10 ms_stats > msdata
+	#cut -f 10 scrm_stats > scrmdata
+	#echo "H" > figuretitle
+	#R CMD BATCH chisq.r
+	#}
+	
+
+	
+#case 1 
+#2 sub population, 2 samples from each subpopulation, mutation rate is 5
+echo "2groups2sam2sam_mig5" > current_case
+rm ms* scrm*
+
+#ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -T | tail -n +4 | grep -v "//" | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+
+ms 4 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 2 2 5.0 -T > msout
+mstime
+
+scrm 4 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 2 2 -ma x 5.0 5.0 x -T -L > scrmout
+scrmtime
+
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+#case 2 
+#2 sub population, 6 samples from subpopulation 1, and 5 samples from subpopulation 2, with rate 10 from 1 to 2, and rate 5 from 2 to 1
+
+echo "2groups6sam5sam_mig_x_10_5_x" > current_case
+rm ms* scrm*
+	
+ms 4 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 2 2 -ma x 10.0 5.0 x -T > msout
+mstime
+
+scrm 4 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 2 2 -ma x 10.0 5.0 x -T -L > scrmout
+scrmtime
+
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+
+#case 3
+#3 sub population, 10 samples from subpopulation 1, and 4 samples from subpopulation 2, and 1 sample from the third with rate 5
+
+echo "3groups10sam4sam1sam_mig_sym10" > current_case
+rm ms* scrm*
+	
+ms 15 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 3 10 4 1 10.0 -T > msout
+mstime
+
+scrm 15 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 3 10 4 1 -ma x 5.0 5.0 5.0 x 5.0 5.0 5.0 x -T -L > scrmout
+scrmtime
+
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+#case 4
+#3 sub population, 10 samples from subpopulation 1, and 4 samples from subpopulation 2, and 1 sample from the third with rate 5
+
+echo "3groups10sam4sam1sam_mig_offdiag5" > current_case
+rm ms* scrm*
+
+	
+ms 15 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 3 10 4 1 -ma x 5.0 5.0 5.0 x 5.0 5.0 5.0 x -T > msout
+mstime
+
+scrm 15 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 3 10 4 1 -ma x 5.0 5.0 5.0 x 5.0 5.0 5.0 x -T -L > scrmout
+scrmtime
+
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+
+
+#case 5
+#3 sub population, 10 samples from subpopulation 1, and 4 samples from subpopulation 2, and 1 sample from the third with rate matrix on manual page 5
+
+echo "3groups10sam4sam1sam_mig_x123x456x" > current_case
+
+rm ms* scrm*
+	
+ms 15 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 3 10 4 1 -ma x 1.0 2.0 3.0 x 4.0 5.0 6.0 x -T > msout
+mstime
+
+scrm 15 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 3 10 4 1 -ma x 1.0 2.0 3.0 x 4.0 5.0 6.0 x -T -L > scrmout
+scrmtime
+
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
diff --git a/tests/manualtests/ms_vs_scrm-prune-tmrca.sh b/tests/manualtests/ms_vs_scrm-prune-tmrca.sh
new file mode 100755
index 0000000..0ab090f
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-prune-tmrca.sh
@@ -0,0 +1,173 @@
+#!/bin/bash
+
+#Compare summary statistics of ms and scrm for TMRCA with recombination events
+mkdir test-tmrca-prune-recomb
+cd test-tmrca-prune-recomb
+
+
+seqlen=100000
+
+rep=10000
+
+
+echo -e "rm(list=ls());
+for (i in (1:${rep})){
+	p=read.table(paste(\"xx\",i,\"Trees_freq\",sep=\"\"))\$V1/${seqlen}; 
+	T=read.table(paste(\"xx\",i,\"Trees_tmrca\",sep=\"\")); 
+	bl=read.table(paste(\"xx\",i,\"Trees_bl\",sep=\"\")); 
+	cat(paste(sum(T*p),sum(T^2*p),sum(T^3*p),sum(T^4*p),sep=\"\t\") ,file=\"tmrca_moments\",append=TRUE);
+	cat(\"\n\",file=\"tmrca_moments\",append=TRUE);
+	cat(paste(sum(bl*p),sum(bl^2*p),sum(bl^3*p),sum(bl^4*p),sep=\"\t\") ,file=\"bl_moments\",append=TRUE);
+	cat(\"\n\",file=\"bl_moments\",append=TRUE);
+	}" > compute_moments.r
+
+msNsample=(7 10 20)
+msr=(10 20 50 100)
+#mst=(10 20 50 100 10)
+
+#msNsample=(3)
+#msr=(10)
+#mst=(10)
+
+
+## compare TMRCA
+compareTMRCA=compareTMRCA-RECOMB
+rm ${compareTMRCA}
+
+## compare total branch length
+compareBL=compareBL-RECOMB
+rm ${compareBL}
+
+rm *pdf
+#theta=10
+echo -e "compare TMRCA for ${rep} replicates \n\t\t|\t1st\t\t\t|\t2nd\t\t\t|\t3rd\t\t\t|\t4th\t\t\t
+\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" > ${compareTMRCA}
+
+echo -e "compare total branch length for ${rep} replicates \n\t\t|\t1st\t\t\t|\t2nd\t\t\t|\t3rd\t\t\t|\t4th\t\t\t
+\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" > ${compareBL}
+rm tmrca_moments
+rm bl_moments
+
+
+for r in "${msr[@]}"
+    do
+    for nsam in "${msNsample[@]}"
+        do
+        rm ms_tmrca_moments
+        rm scrm_tmrca_moments
+        
+        rm ms_bl_moments
+        rm scrm_bl_moments
+        
+        prefix=${nsam}sample${r}rho
+        out=${prefix}out
+        segrecomb=${prefix}segRecomb
+
+        ms ${nsam} ${rep} -r ${r} ${seqlen} -T | tail -n +4 | gawk '/^\/\//{f="xx"++d} f{print > f} '
+        for file in $(seq 1 1 ${rep})
+            do 
+            grep ";" xx${file} | sed -e 's/\[.*\]//g' > xxTrees
+            hybrid-Lambda -gt xxTrees -tmrca xx${file}Trees_tmrca
+            hybrid-Lambda -gt xxTrees -bl xx${file}Trees_bl
+            grep ";" xx${file} | sed -e 's/\[//g' -e 's/\].*;//g' > xx${file}Trees_freq
+
+            done
+            R CMD BATCH compute_moments.r
+            find . -name "xx*" -print0 | xargs -0 rm
+            mv tmrca_moments ms_tmrca_moments
+            mv bl_moments ms_bl_moments
+            
+            
+        scrm ${nsam} ${rep} -r ${r} ${seqlen} -T -l 10000 | tail -n +4 | gawk '/^\/\//{f="xx"++d} f{print > f} '
+        for file in $(seq 1 1 ${rep})
+            do 
+            grep ";" xx${file} | sed -e 's/\[.*\]//g' > xxTrees
+            hybrid-Lambda -gt xxTrees -tmrca xx${file}Trees_tmrca
+            hybrid-Lambda -gt xxTrees -bl xx${file}Trees_bl
+            grep ";" xx${file} | sed -e 's/\[//g' -e 's/\].*;//g' > xx${file}Trees_freq
+
+            done
+            R CMD BATCH compute_moments.r
+            find . -name "xx*" -print0 | xargs -0 rm
+            mv tmrca_moments scrm_tmrca_moments
+            mv bl_moments scrm_bl_moments
+
+            echo "rm(list=ls());
+msdata=read.table(\"ms_tmrca_moments\");
+scrmdata=read.table(\"scrm_tmrca_moments\");
+m1test=ks.test(msdata\$V1,scrmdata\$V1)
+m2test=ks.test(msdata\$V2,scrmdata\$V2)
+m3test=ks.test(msdata\$V3,scrmdata\$V3)
+m4test=ks.test(msdata\$V4,scrmdata\$V4)
+pdf(paste($nsam,\"sampleTMRCA\",\"recomb\",${r},\"-KStest.pdf\",sep=\"\"));
+par(mfrow=c(2,2))
+plot(ecdf(msdata\$V1), xlim=range(c(msdata\$V1, scrmdata\$V1)),col=\"red\", main=\"1st Moment\")
+plot(ecdf(scrmdata\$V1), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m1test\$statistic,sep=\"\"), paste(\"p-value = \",format(m1test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V2), xlim=range(c(msdata\$V2, scrmdata\$V2)),col=\"red\", main=\"2nd Moment\")
+plot(ecdf(scrmdata\$V2), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m2test\$statistic,sep=\"\"), paste(\"p-value = \",format(m2test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V3), xlim=range(c(msdata\$V3, scrmdata\$V3)),col=\"red\", main=\"3rd Moment\")
+plot(ecdf(scrmdata\$V3), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m3test\$statistic,sep=\"\"), paste(\"p-value = \",format(m3test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V4), xlim=range(c(msdata\$V4, scrmdata\$V4)),col=\"red\", main=\"4th Moment\")
+plot(ecdf(scrmdata\$V4), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m4test\$statistic,sep=\"\"), paste(\"p-value = \",format(m4test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+dev.off();
+cat(paste(${nsam},${r},\"|\",
+format(m1test\$statistic,digits=4),format(m1test\$p.value,scientific = TRUE),\"|\",
+format(m2test\$statistic,digits=4),format(m2test\$p.value,scientific = TRUE),\"|\",
+format(m3test\$statistic,digits=4),format(m3test\$p.value,scientific = TRUE),\"|\",
+format(m4test\$statistic,digits=4),format(m4test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareTMRCA}\",append=TRUE);cat(\"\n\",file=\"${compareTMRCA}\",append=TRUE);
+
+rm(list=ls());
+msdata=read.table(\"ms_bl_moments\");
+scrmdata=read.table(\"scrm_bl_moments\");
+m1test=ks.test(msdata\$V1,scrmdata\$V1)
+m2test=ks.test(msdata\$V2,scrmdata\$V2)
+m3test=ks.test(msdata\$V3,scrmdata\$V3)
+m4test=ks.test(msdata\$V4,scrmdata\$V4)
+pdf(paste($nsam,\"sampleBLmut\",\"recomb\",${r},\"-KStest.pdf\",sep=\"\"));
+par(mfrow=c(2,2))
+plot(ecdf(msdata\$V1), xlim=range(c(msdata\$V1, scrmdata\$V1)),col=\"red\", main=\"1st Moment\")
+plot(ecdf(scrmdata\$V1), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m1test\$statistic,sep=\"\"), paste(\"p-value = \",format(m1test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V2), xlim=range(c(msdata\$V2, scrmdata\$V2)),col=\"red\", main=\"2nd Moment\")
+plot(ecdf(scrmdata\$V2), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m2test\$statistic,sep=\"\"), paste(\"p-value = \",format(m2test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V3), xlim=range(c(msdata\$V3, scrmdata\$V3)),col=\"red\", main=\"3rd Moment\")
+plot(ecdf(scrmdata\$V3), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m3test\$statistic,sep=\"\"), paste(\"p-value = \",format(m3test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V4), xlim=range(c(msdata\$V4, scrmdata\$V4)),col=\"red\", main=\"4th Moment\")
+plot(ecdf(scrmdata\$V4), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m4test\$statistic,sep=\"\"), paste(\"p-value = \",format(m4test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+dev.off();
+cat(paste(${nsam},${r},\"|\",
+format(m1test\$statistic,digits=4),format(m1test\$p.value,scientific = TRUE),\"|\",
+format(m2test\$statistic,digits=4),format(m2test\$p.value,scientific = TRUE),\"|\",
+format(m3test\$statistic,digits=4),format(m3test\$p.value,scientific = TRUE),\"|\",
+format(m4test\$statistic,digits=4),format(m4test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareBL}\",append=TRUE);cat(\"\n\",file=\"${compareBL}\",append=TRUE);
+" > dummy.r
+    R CMD BATCH dummy.r
+        done
+    done
+	
+	
diff --git a/tests/manualtests/ms_vs_scrm-prune_mig_recomb.sh b/tests/manualtests/ms_vs_scrm-prune_mig_recomb.sh
new file mode 100755
index 0000000..7f41426
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-prune_mig_recomb.sh
@@ -0,0 +1,265 @@
+#!/bin/bash
+
+#Compare summary statistics of ms and scrm for migration
+
+mkdir test-prune-mig-pair
+cd test-prune-mig-pair
+rm *pdf
+
+
+rep=10000
+seqlen=1000000
+#msr=(10 20 10 50)
+r=100
+
+## compare TMRCA
+compareMIG=compareMIG
+rm ${comparePop}
+
+
+#rm ${compareTMRCA}
+#rm ${compareBL}
+#echo -e "compare TMRCA for ${rep} replicates 
+#\t|\t ms \t\t|\t scrm\t\t|\tKS test
+#Case\t|\tmean\tstdv\t|\tmean\tstdv \t|\tstats\tp-value" >${compareTMRCA}
+
+#echo -e "compare BL for ${rep} replicates 
+#\t|\t ms \t\t|\t scrm\t\t|\tKS test
+#Case\t|\tmean\tstdv\t|\tmean\tstdv \t|\tstats\tp-value" >${compareBL}
+
+theta=100
+
+		echo "rm(list=ls());
+		#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+msdata=read.table(paste(\"ms\",\"data\",sep=\"\"))\$V1;
+scrmdata=read.table(paste(\"scrm\",\"data\",sep=\"\"))\$V1;
+		#ee=ee_seg(${nsam},${t});
+		#sdv=sd_seg_norecomb(${nsam},${t});
+		datamax=max(msdata,scrmdata);
+		mstable=table(factor(msdata,levels=1:datamax))
+		scrmtable=table(factor(scrmdata,levels=1:datamax))
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(as.numeric(names(mstable)), mstable/length(msdata),pch=16,col=\"red\",ylab=\"Frequency\",xlab=figuretitle);
+points(as.numeric(names(scrmtable)), scrmtable/length(scrmdata),pch=16,col=\"blue\")
+
+ms_newtable=table(msdata);
+scrm_mstable=table(factor(scrmdata,levels=names(table(msdata))));
+combined_scrm_ms_test=chisq.test(cbind(scrm_mstable, ms_newtable));
+
+scrm_newtable=table(scrmdata);
+ms_scrmtable=table(factor(msdata,levels=names(table(scrmdata))));
+combined_ms_scrm_test=chisq.test(cbind(scrm_newtable, ms_scrmtable));
+
+legend(\"topright\",c(paste(\"Test 1 Statistics = \",combined_scrm_ms_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_scrm_ms_test\$p.value,digits=4),sep=\"\"),paste(\"Test 2 Statistics = \",combined_ms_scrm_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_ms_scrm_test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+
+dev.off();
+
+#cat(paste(${nsam},${t},\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+cat(paste(currentcase, figuretitle , \"\n\",\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"||\",
+format(combined_scrm_ms_test\$statistic,digits=4),format(combined_scrm_ms_test\$p.value,scientific = TRUE),\"||\",
+format(combined_ms_scrm_test\$statistic,digits=4),format(combined_ms_scrm_test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareMIG}\",append=TRUE);cat(\"\n\",file=\"${compareMIG}\",append=TRUE);
+" > chisq.r
+
+echo "rm(list=ls());
+#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+msdata=read.table(paste(\"ms\",\"data\",sep=\"\"))\$V1;
+scrmdata=read.table(paste(\"scrm\",\"data\",sep=\"\"))\$V1;
+#ee=1#ee_tmrca(${nsam});
+#sdv=1#sd_tmrca(${nsam});
+test=ks.test(msdata,scrmdata)
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(ecdf(msdata), xlim=range(c(msdata, scrmdata)),col=\"red\", main=currentcase)
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+#cat(paste(currentcase,\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+cat(paste(currentcase, figuretitle , \"\n\",\"|\",
+format(mean(msdata),scientific = TRUE),format(sd(msdata),scientific = TRUE),\"||\",
+format(mean(scrmdata),scientific = TRUE),format(sd(scrmdata),scientific = TRUE),\"|\",format(test\$statistic,scientific = TRUE),format(test\$p.value,scientific = TRUE), 
+sep=\"\t\"),file=\"${compareMIG}\",append=TRUE);cat(\"\n\",file=\"${compareMIG}\",append=TRUE);" > ks.r
+
+echo "rm(list=ls());
+#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+msdata=read.table(\"mstmrca\")\$V1;
+scrmdata=read.table(\"scrmtmrca\")\$V1;
+#ee=ee_tmrca(${nsam});
+#sdv=sd_tmrca(${nsam});
+test=ks.test(msdata,scrmdata)
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(ecdf(msdata), xlim=range(c(msdata, scrmdata)),col=\"red\", main=currentcase)
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+cat(paste(currentcase,figuretitle , \"\n\",\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",test\$statistic,format(test\$p.value,digits=4), 
+sep=\"\t\"),file=\"${compareMIG}\",append=TRUE);cat(\"\n\",file=\"${compareMIG}\",append=TRUE);" > tmrca.r
+
+echo "rm(list=ls());
+#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+msdata=read.table(\"msbl\")\$V1;
+scrmdata=read.table(\"scrmbl\")\$V1;
+test=ks.test(msdata,scrmdata)
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(ecdf(msdata), xlim=range(c(msdata, scrmdata)),col=\"red\", main=currentcase)
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+cat(paste(currentcase,figuretitle , \"\n\",\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",test\$statistic,format(test\$p.value,digits=4), 
+sep=\"\t\"),file=\"${compareMIG}\",append=TRUE);cat(\"\n\",file=\"${compareMIG}\",append=TRUE);" > bl.r
+
+
+foo(){
+    #cut -f 2 mstime > mstmrca
+	#cut -f 2 scrmtime > scrmtmrca
+	echo "TMRCA" > figuretitle
+	R CMD BATCH tmrca.r
+
+    #cut -f 3 mstime > msbl
+	#cut -f 3 scrmtime > scrmbl
+	echo "BL" > figuretitle
+	R CMD BATCH bl.r
+
+	cut -f 6 ms_stats > msdata
+	cut -f 6 scrm_stats > scrmdata
+	echo "Tajima_D" > figuretitle
+	R CMD BATCH ks.r
+
+	cut -f 2 ms_stats > msdata
+	cut -f 2 scrm_stats > scrmdata
+	echo "Pairewise_difference" > figuretitle
+	R CMD BATCH chisq.r
+
+	cut -f 8 ms_stats > msdata
+	cut -f 8 scrm_stats > scrmdata
+	echo "theta_H" > figuretitle
+	R CMD BATCH chisq.r
+
+	cut -f 10 ms_stats > msdata
+	cut -f 10 scrm_stats > scrmdata
+	echo "H" > figuretitle
+	R CMD BATCH chisq.r
+	}
+	
+mstime(){
+    cat msout | gawk '/^\/\//{f="xx"++d} f{print > f} '
+    for file in $(seq 1 1 ${rep})
+        do 
+        grep ";" xx${file} | sed -e 's/\[.*\]//g' | tail -1 >> msTrees
+        done
+        hybrid-Lambda -gt msTrees -tmrca mstmrca
+        hybrid-Lambda -gt msTrees -bl msbl
+        find . -name "xx*" -print0 | xargs -0 rm    
+    }	
+    
+scrmtime(){
+    cat scrmout | gawk '/^\/\//{f="xx"++d} f{print > f} '
+    for file in $(seq 1 1 ${rep})
+        do 
+        grep ";" xx${file} | sed -e 's/\[.*\]//g' | tail -1 >> scrmTrees
+        done
+        hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+        hybrid-Lambda -gt scrmTrees -bl scrmbl
+        find . -name "xx*" -print0 | xargs -0 rm    
+    }	
+	
+	
+#case 1 
+#2 sub population, 1 sample from each subpopulation, mutation rate is 5
+echo "2groups1sam1sam_case1_mig5" > current_case
+rm ms* scrm*
+
+#ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -T | tail -n +4 | grep -v "//" | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+
+ms 2 ${rep} -t ${theta} -r ${r} ${seqlen} -I 2 1 1 5.0 -T > msout
+mstime 
+
+scrm 2 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 1 1 -ma x 5.0 5.0 x -T -l 10000 > scrmout
+scrmtime
+
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+#cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+#case 2
+#2 sub population, 1 sample from each subpopulation, mutation rate is 5
+echo "2groups1sam1sam_case2_mig5" > current_case
+rm ms* scrm*
+
+#ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -T | tail -n +4 | grep -v "//" | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+
+ms 2 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 1 1 5.0 -T > msout
+mstime
+
+scrm 2 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 1 1 5.0 -T -L -l 10000> scrmout
+scrmtime
+
+
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+#cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+
+#case 3
+#2 sub population, 1 sample from each subpopulation, mutation rate is 5
+echo "2groups1sam1sam_case3_mig5" > current_case
+rm ms* scrm*
+
+#ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -T | tail -n +4 | grep -v "//" | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+
+ms 2 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 1 1 -ma x 5 0 x -ej 0.5 2 1 -T > msout
+mstime
+
+scrm 2 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 1 1 -ma x 5 0 x -ej 0.5 2 1 -T -L -l 10000 > scrmout
+scrmtime
+
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+#cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+#case 3
+#2 sub population, 1 sample from each subpopulation, mutation rate is 5
+echo "2groups1sam1sam_case4_mig5" > current_case
+rm ms* scrm*
+
+#ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 5.0 5.0 x -T | tail -n +4 | grep -v "//" | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+
+ms 2 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 1 1 -ma x 0 5 x -ej 0.5 2 1 -T > msout
+mstime
+
+scrm 2 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 1 1 -ma x 0 5 x -ej 0.5 2 1 -T -L -l 10000 > scrmout
+scrmtime
+
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+#cat scrmout | grep "time:" >  scrmtime
+
+foo
+
diff --git a/tests/manualtests/ms_vs_scrm-recomb-Tifs.sh b/tests/manualtests/ms_vs_scrm-recomb-Tifs.sh
new file mode 100755
index 0000000..9d2e5a9
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-recomb-Tifs.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+
+## compare times of genealogy changes
+mkdir test-recomb-Tifs
+cd test-recomb-Tifs
+rm *pdf
+
+msr=(10 20 10 50)
+msNsample=(2 3 7 10 20)
+
+rep=100000
+seqlen=100000
+
+compareRECOMB=compareRECOMB
+echo -e "compare number of recombination for ${rep} replicates 
+\t\t|\t\t\t|\tms \t\t|\t scrm\t\t|\tTest1\t\t\t|\tTest2\t\t\t
+Nsam\trho\t|\tmean\tstdv\t|\tmean\tstdv\t|\tmean\tstdv \t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" >${compareRECOMB}
+
+
+#for t in "${mst[@]}"
+#	do
+	for r in "${msr[@]}"
+		do
+		for nsam in "${msNsample[@]}"
+			do
+			prefix=${nsam}sample${r}recomb
+			#out=${prefix}out
+			recomb=${prefix}Recomb
+			ms ${nsam} ${rep} -r ${r} ${seqlen} -T | tail -n +4  |	gawk '/^\/\//{f="xx"++d} f{print > f} ' 
+			
+			for file in $(seq 1 1 ${rep})
+				do 
+				cat xx${file} | grep ";" | wc -l >> ms${recomb}
+				done
+				
+			find . -name "xx*" -print0 | xargs -0 rm
+				
+			scrm ${nsam} ${rep} -r ${r} ${seqlen} -Tifs | tail -n +4  | gawk '/^\/\//{f="xx"++d} f{print > f} ' 
+			
+			for file in $(seq 1 1 ${rep})
+				do 
+				cat xx${file} | grep ";" | wc -l >> scrm${recomb}
+				done
+			find . -name "xx*" -print0 | xargs -0 rm	
+				
+			echo "rm(list=ls());
+			source(\"../fun_src.r\");
+			msdata=read.table(\"ms${recomb}\")\$V1;
+			scrmdata=read.table(\"scrm${recomb}\")\$V1;
+			ee=ee_seg(${nsam},${r});
+			sdv=sd_recomb(${r},${nsam});
+datamax=max(msdata,scrmdata);
+		mstable=table(factor(msdata,levels=1:datamax))
+		scrmtable=table(factor(scrmdata,levels=1:datamax))
+pdf(\"${nsam}sample${r}recomb_NUM_RECOMB.pdf\");
+#plot(mstable,col=\"red\",ylab=\"Frequency\",xlab=\"Number of recombinations\");
+#lines(scrmtable,col=\"blue\");
+plot(as.numeric(names(mstable)), mstable/length(msdata),pch=16,col=\"red\",ylab=\"Frequency\",xlab=\"Number of recombinations\");
+points(as.numeric(names(scrmtable)), scrmtable/length(scrmdata),pch=16,col=\"blue\")
+ms_newtable=table(msdata);
+scrm_mstable=table(factor(scrmdata,levels=names(table(msdata))));
+combined_scrm_ms_test=chisq.test(cbind(scrm_mstable, ms_newtable));
+
+scrm_newtable=table(scrmdata);
+ms_scrmtable=table(factor(msdata,levels=names(table(scrmdata))));
+combined_ms_scrm_test=chisq.test(cbind(scrm_newtable, ms_scrmtable));
+legend(\"topright\",c(paste(\"Test 1 Statistics = \",combined_scrm_ms_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_scrm_ms_test\$p.value,digits=4),sep=\"\"),paste(\"Test 2 Statistics = \",combined_ms_scrm_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_ms_scrm_test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+
+cat(paste(${nsam},${r},\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",
+format(combined_scrm_ms_test\$statistic,digits=4),format(combined_scrm_ms_test\$p.value,scientific = TRUE),\"|\",
+format(combined_ms_scrm_test\$statistic,digits=4),format(combined_ms_scrm_test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareRECOMB}\",append=TRUE);cat(\"\n\",file=\"${compareRECOMB}\",append=TRUE);
+" > dummy.r
+			R CMD BATCH dummy.r
+			rm ms${recomb} scrm${recomb} 
+			done
+		done
+	#done
+
+	
+	
diff --git a/tests/manualtests/ms_vs_scrm-recomb.sh b/tests/manualtests/ms_vs_scrm-recomb.sh
new file mode 100755
index 0000000..630cf60
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-recomb.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+
+## compare times of genealogy changes
+mkdir test-recomb
+cd test-recomb
+rm *pdf
+
+msr=(10 20 10 50)
+msNsample=(2 3 7 10 20)
+
+rep=100000
+seqlen=100000
+
+compareRECOMB=compareRECOMB
+echo -e "compare number of recombination for ${rep} replicates 
+\t\t|\t\t\t|\tms \t\t|\t scrm\t\t|\tTest1\t\t\t|\tTest2\t\t\t
+Nsam\trho\t|\tmean\tstdv\t|\tmean\tstdv\t|\tmean\tstdv \t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" >${compareRECOMB}
+
+
+#for t in "${mst[@]}"
+#	do
+	for r in "${msr[@]}"
+		do
+		for nsam in "${msNsample[@]}"
+			do
+			prefix=${nsam}sample${r}recomb
+			#out=${prefix}out
+			recomb=${prefix}Recomb
+			ms ${nsam} ${rep} -r ${r} ${seqlen} -T | tail -n +4  |	gawk '/^\/\//{f="xx"++d} f{print > f} ' 
+			
+			for file in $(seq 1 1 ${rep})
+				do 
+				cat xx${file} | grep ";" | wc -l >> ms${recomb}
+				done
+				
+			find . -name "xx*" -print0 | xargs -0 rm
+				
+			scrm ${nsam} ${rep} -r ${r} ${seqlen} -T | tail -n +4  | gawk '/^\/\//{f="xx"++d} f{print > f} ' 
+			
+			for file in $(seq 1 1 ${rep})
+				do 
+				cat xx${file} | grep ";" | wc -l >> scrm${recomb}
+				done
+			find . -name "xx*" -print0 | xargs -0 rm	
+				
+			echo "rm(list=ls());
+			source(\"../fun_src.r\");
+			msdata=read.table(\"ms${recomb}\")\$V1;
+			scrmdata=read.table(\"scrm${recomb}\")\$V1;
+			ee=ee_seg(${nsam},${r});
+			sdv=sd_recomb(${r},${nsam});
+datamax=max(msdata,scrmdata);
+		mstable=table(factor(msdata,levels=1:datamax))
+		scrmtable=table(factor(scrmdata,levels=1:datamax))
+pdf(\"${nsam}sample${r}recomb_NUM_RECOMB.pdf\");
+#plot(mstable,col=\"red\",ylab=\"Frequency\",xlab=\"Number of recombinations\");
+#lines(scrmtable,col=\"blue\");
+plot(as.numeric(names(mstable)), mstable/length(msdata),pch=16,col=\"red\",ylab=\"Frequency\",xlab=\"Number of recombinations\");
+points(as.numeric(names(scrmtable)), scrmtable/length(scrmdata),pch=16,col=\"blue\")
+ms_newtable=table(msdata);
+scrm_mstable=table(factor(scrmdata,levels=names(table(msdata))));
+combined_scrm_ms_test=chisq.test(cbind(scrm_mstable, ms_newtable));
+
+scrm_newtable=table(scrmdata);
+ms_scrmtable=table(factor(msdata,levels=names(table(scrmdata))));
+combined_ms_scrm_test=chisq.test(cbind(scrm_newtable, ms_scrmtable));
+legend(\"topright\",c(paste(\"Test 1 Statistics = \",combined_scrm_ms_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_scrm_ms_test\$p.value,digits=4),sep=\"\"),paste(\"Test 2 Statistics = \",combined_ms_scrm_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_ms_scrm_test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+
+cat(paste(${nsam},${r},\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",
+format(combined_scrm_ms_test\$statistic,digits=4),format(combined_scrm_ms_test\$p.value,scientific = TRUE),\"|\",
+format(combined_ms_scrm_test\$statistic,digits=4),format(combined_ms_scrm_test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareRECOMB}\",append=TRUE);cat(\"\n\",file=\"${compareRECOMB}\",append=TRUE);
+" > dummy.r
+			R CMD BATCH dummy.r
+			rm ms${recomb} scrm${recomb} 
+			done
+		done
+	#done
+
+	
+	
diff --git a/tests/manualtests/ms_vs_scrm-seg.sh b/tests/manualtests/ms_vs_scrm-seg.sh
new file mode 100755
index 0000000..f809c2e
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-seg.sh
@@ -0,0 +1,84 @@
+#!/bin/bash
+
+###########################
+
+mkdir test-seg
+cd test-seg
+rm *pdf
+
+mst=(10 20 50 100)
+msNsample=(3 7 10)
+
+#mst=(10)
+#msNsample=(2)
+
+rep=10000
+#npop=20000
+
+## compare number of segregating sites
+compareSEG=compareSEG
+echo -e "compare number of mutations for ${rep} replicates \n\t\t|\t\t\t|\tms \t\t|\t scrm\t\t|\tTest1\t\t\t|\tTest2\t\t\t
+Nsam\ttheta\t|\tmean\tstdv\t|\tmean\tstdv\t|\tmean\tstdv \t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" >${compareSEG}
+
+for t in "${mst[@]}"
+	do
+	for nsam in "${msNsample[@]}"
+		do
+		prefix=${nsam}sample${t}mut
+		#out=${prefix}out
+		nseg=${prefix}NumOfSeg
+		ms ${nsam} ${rep} -t ${t} -T | tail -n +4 | grep -v "//" | grep "segsites" | sed -e "s/segsites: //" > ms${nseg}
+
+		scrm ${nsam} ${rep} -t ${t} | tail -n +4 | grep -v "//"  | grep "segsites" | sed -e "s/segsites: //" > scrm${nseg}
+
+		echo "rm(list=ls());
+		source(\"../fun_src.r\");
+		msdata=read.table(\"ms${nseg}\")\$V1;
+		scrmdata=read.table(\"scrm${nseg}\")\$V1;
+		ee=ee_seg(${nsam},${t});
+		sdv=sd_seg_norecomb(${nsam},${t});
+		datamax=max(msdata,scrmdata);
+		mstable=table(factor(msdata,levels=1:datamax))
+		scrmtable=table(factor(scrmdata,levels=1:datamax))
+pdf(\"${nsam}sample${t}mut_NUM_MUT.pdf\");
+plot(as.numeric(names(mstable)), mstable/length(msdata),pch=16,col=\"red\",ylab=\"Frequency\",xlab=\"Number of mutations\");
+points(as.numeric(names(scrmtable)), scrmtable/length(scrmdata),pch=16,col=\"blue\")
+
+ms_newtable=table(msdata);
+scrm_mstable=table(factor(scrmdata,levels=names(table(msdata))));
+combined_scrm_ms_test=chisq.test(cbind(scrm_mstable, ms_newtable));
+
+scrm_newtable=table(scrmdata);
+ms_scrmtable=table(factor(msdata,levels=names(table(scrmdata))));
+combined_ms_scrm_test=chisq.test(cbind(scrm_newtable, ms_scrmtable));
+
+legend(\"topright\",c(paste(\"Test 1 Statistics = \",combined_scrm_ms_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_scrm_ms_test\$p.value,digits=4),sep=\"\"),paste(\"Test 2 Statistics = \",combined_ms_scrm_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_ms_scrm_test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+
+dev.off();
+
+cat(paste(${nsam},${t},\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",
+format(combined_scrm_ms_test\$statistic,digits=4),format(combined_scrm_ms_test\$p.value,scientific = TRUE),\"|\",
+format(combined_ms_scrm_test\$statistic,digits=4),format(combined_ms_scrm_test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareSEG}\",append=TRUE);cat(\"\n\",file=\"${compareSEG}\",append=TRUE);
+" > dummy.r
+		R CMD BATCH dummy.r
+		rm ms${nseg}  scrm${nseg}
+		done
+	done
+
+
+
+
+
+#chistat=0
+#for (i in (1:dim(combinedtable)[1])){
+	#for (j in (1:dim(combinedtable)[2])){
+		#E=sum(combinedtable[i,])*sum(combinedtable[,j])/sum(combinedtable)
+#sum(combinedtable[i,])*sum(combinedtable[,j])/sum(combinedtable)
+		#chistat = chistat + (E-combinedtable[i,j])^2/E
+	#}
+
+#}
diff --git a/tests/manualtests/ms_vs_scrm-seg_wit_recomb.sh b/tests/manualtests/ms_vs_scrm-seg_wit_recomb.sh
new file mode 100755
index 0000000..b2ee76c
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-seg_wit_recomb.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+
+## compare number of mutations with recombinations
+# this pairwise_test.sh is a sub test of this 
+
+mkdir test-seg-recomb
+cd test-seg-recomb
+rm *pdf
+
+msr=(11 21 10 50 100)
+mst=(10 20 50 100 10)
+#msr=(100)
+#mst=(25)
+
+rep=100000
+seqlen=100000
+msNsample=(2 3 7 10)
+compareSEG=compareSEG-RECOMB
+echo -e "compare number of mutations with recombinations for ${rep} replicates 
+\t\t\t|\t\t\t|\t ms \t\t|\t scrm\t\t|\tTest1\t\t\t|\tTest2\t\t\t
+Nsam\ttheta\trho\t|\tmean\tstdv\t|\tmean\tstdv\t|\tmean\tstdv \t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" > ${compareSEG}
+
+
+for t in "${mst[@]}"
+	do
+	for r in "${msr[@]}"
+		do
+		for nsam in "${msNsample[@]}"
+			do
+			prefix=${nsam}sample${r}rho${t}theta
+			nseg=${prefix}NumOfSeg
+			ms ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} | tail -n +4 | grep -v "//" | grep "segsites" | sed -e "s/segsites: //" > ms${nseg}
+	
+			scrm ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} | tail -n +4 | grep -v "//"  | grep "segsites" | sed -e "s/segsites: //" > scrm${nseg}
+			
+			echo "rm(list=ls());
+		source(\"../fun_src.r\");
+		msdata=read.table(\"ms${nseg}\")\$V1;
+		scrmdata=read.table(\"scrm${nseg}\")\$V1;
+			ee=ee_seg(${nsam},${t});
+			sdv=sd_seg_recomb(${nsam},${t},${r});
+			datamax=max(msdata,scrmdata);
+		mstable=table(factor(msdata,levels=1:datamax))
+		scrmtable=table(factor(scrmdata,levels=1:datamax))
+pdf(\"${nsam}sample${t}mut${r}recomb_NUM_MUT.pdf\");
+#plot(mstable,col=\"red\",ylab=\"Frequency\",xlab=\"Number of mutations\");
+#lines(scrmtable,col=\"blue\");
+plot(as.numeric(names(mstable)), mstable/length(msdata),pch=16,col=\"red\",ylab=\"Frequency\",xlab=\"Number of mutations\");
+points(as.numeric(names(scrmtable)), scrmtable/length(scrmdata),pch=16,col=\"blue\")
+
+ms_newtable=table(msdata);
+scrm_mstable=table(factor(scrmdata,levels=names(table(msdata))));
+combined_scrm_ms_test=chisq.test(cbind(scrm_mstable, ms_newtable));
+
+scrm_newtable=table(scrmdata);
+ms_scrmtable=table(factor(msdata,levels=names(table(scrmdata))));
+combined_ms_scrm_test=chisq.test(cbind(scrm_newtable, ms_scrmtable));
+
+legend(\"topright\",c(paste(\"Test 1 Statistics = \",combined_scrm_ms_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_scrm_ms_test\$p.value,digits=4),sep=\"\"),paste(\"Test 2 Statistics = \",combined_ms_scrm_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_ms_scrm_test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+
+
+cat(paste(${nsam},${t},${r},\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",
+format(combined_scrm_ms_test\$statistic,digits=4),format(combined_scrm_ms_test\$p.value,scientific = TRUE),\"|\",
+format(combined_ms_scrm_test\$statistic,digits=4),format(combined_ms_scrm_test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareSEG}\",append=TRUE);cat(\"\n\",file=\"${compareSEG}\",append=TRUE);
+" > dummy.r
+			R CMD BATCH dummy.r
+			rm ms${nseg}  scrm${nseg}
+			done
+		done
+	done
+
+	
+	
diff --git a/tests/manualtests/ms_vs_scrm-seg_with_recomb_Tifs.sh b/tests/manualtests/ms_vs_scrm-seg_with_recomb_Tifs.sh
new file mode 100755
index 0000000..b2ee76c
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-seg_with_recomb_Tifs.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+
+## compare number of mutations with recombinations
+# this pairwise_test.sh is a sub test of this 
+
+mkdir test-seg-recomb
+cd test-seg-recomb
+rm *pdf
+
+msr=(11 21 10 50 100)
+mst=(10 20 50 100 10)
+#msr=(100)
+#mst=(25)
+
+rep=100000
+seqlen=100000
+msNsample=(2 3 7 10)
+compareSEG=compareSEG-RECOMB
+echo -e "compare number of mutations with recombinations for ${rep} replicates 
+\t\t\t|\t\t\t|\t ms \t\t|\t scrm\t\t|\tTest1\t\t\t|\tTest2\t\t\t
+Nsam\ttheta\trho\t|\tmean\tstdv\t|\tmean\tstdv\t|\tmean\tstdv \t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" > ${compareSEG}
+
+
+for t in "${mst[@]}"
+	do
+	for r in "${msr[@]}"
+		do
+		for nsam in "${msNsample[@]}"
+			do
+			prefix=${nsam}sample${r}rho${t}theta
+			nseg=${prefix}NumOfSeg
+			ms ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} | tail -n +4 | grep -v "//" | grep "segsites" | sed -e "s/segsites: //" > ms${nseg}
+	
+			scrm ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} | tail -n +4 | grep -v "//"  | grep "segsites" | sed -e "s/segsites: //" > scrm${nseg}
+			
+			echo "rm(list=ls());
+		source(\"../fun_src.r\");
+		msdata=read.table(\"ms${nseg}\")\$V1;
+		scrmdata=read.table(\"scrm${nseg}\")\$V1;
+			ee=ee_seg(${nsam},${t});
+			sdv=sd_seg_recomb(${nsam},${t},${r});
+			datamax=max(msdata,scrmdata);
+		mstable=table(factor(msdata,levels=1:datamax))
+		scrmtable=table(factor(scrmdata,levels=1:datamax))
+pdf(\"${nsam}sample${t}mut${r}recomb_NUM_MUT.pdf\");
+#plot(mstable,col=\"red\",ylab=\"Frequency\",xlab=\"Number of mutations\");
+#lines(scrmtable,col=\"blue\");
+plot(as.numeric(names(mstable)), mstable/length(msdata),pch=16,col=\"red\",ylab=\"Frequency\",xlab=\"Number of mutations\");
+points(as.numeric(names(scrmtable)), scrmtable/length(scrmdata),pch=16,col=\"blue\")
+
+ms_newtable=table(msdata);
+scrm_mstable=table(factor(scrmdata,levels=names(table(msdata))));
+combined_scrm_ms_test=chisq.test(cbind(scrm_mstable, ms_newtable));
+
+scrm_newtable=table(scrmdata);
+ms_scrmtable=table(factor(msdata,levels=names(table(scrmdata))));
+combined_ms_scrm_test=chisq.test(cbind(scrm_newtable, ms_scrmtable));
+
+legend(\"topright\",c(paste(\"Test 1 Statistics = \",combined_scrm_ms_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_scrm_ms_test\$p.value,digits=4),sep=\"\"),paste(\"Test 2 Statistics = \",combined_ms_scrm_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_ms_scrm_test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+
+
+cat(paste(${nsam},${t},${r},\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",
+format(combined_scrm_ms_test\$statistic,digits=4),format(combined_scrm_ms_test\$p.value,scientific = TRUE),\"|\",
+format(combined_ms_scrm_test\$statistic,digits=4),format(combined_ms_scrm_test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareSEG}\",append=TRUE);cat(\"\n\",file=\"${compareSEG}\",append=TRUE);
+" > dummy.r
+			R CMD BATCH dummy.r
+			rm ms${nseg}  scrm${nseg}
+			done
+		done
+	done
+
+	
+	
diff --git a/tests/manualtests/ms_vs_scrm-tmrca-wit-recomb.sh b/tests/manualtests/ms_vs_scrm-tmrca-wit-recomb.sh
new file mode 100755
index 0000000..df16b9f
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-tmrca-wit-recomb.sh
@@ -0,0 +1,176 @@
+#!/bin/bash
+
+#Compare summary statistics of ms and scrm for TMRCA with recombination events
+mkdir test-tmrca-recomb
+cd test-tmrca-recomb
+
+
+seqlen=100000
+
+rep=100000
+
+
+echo -e "rm(list=ls());
+for (i in (1:${rep})){
+	p=read.table(paste(\"xx\",i,\"Trees_freq\",sep=\"\"))\$V1/${seqlen}; 
+	T=read.table(paste(\"xx\",i,\"Trees_tmrca\",sep=\"\")); 
+	bl=read.table(paste(\"xx\",i,\"Trees_bl\",sep=\"\")); 
+	cat(paste(sum(T*p),sum(T^2*p),sum(T^3*p),sum(T^4*p),sep=\"\t\") ,file=\"tmrca_moments\",append=TRUE);
+	cat(\"\n\",file=\"tmrca_moments\",append=TRUE);
+	cat(paste(sum(bl*p),sum(bl^2*p),sum(bl^3*p),sum(bl^4*p),sep=\"\t\") ,file=\"bl_moments\",append=TRUE);
+	cat(\"\n\",file=\"bl_moments\",append=TRUE);
+	}" > compute_moments.r
+
+msNsample=(2 3 4 7 10 20)
+msr=(10 20 10 50 100)
+mst=(10 20 50 100 10)
+
+#msNsample=(3)
+#msr=(10)
+#mst=(10)
+
+
+## compare TMRCA
+compareTMRCA=compareTMRCA-RECOMB
+rm ${compareTMRCA}
+
+## compare total branch length
+compareBL=compareBL-RECOMB
+rm ${compareBL}
+
+rm *pdf
+#theta=10
+echo -e "compare TMRCA for ${rep} replicates \n\t\t\t|\t1st\t\t\t|\t2nd\t\t\t|\t3rd\t\t\t|\t4th\t\t\t
+\t\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" > ${compareTMRCA}
+
+echo -e "compare total branch length for ${rep} replicates \n\t\t\t|\t1st\t\t\t|\t2nd\t\t\t|\t3rd\t\t\t|\t4th\t\t\t
+\t\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" > ${compareBL}
+rm tmrca_moments
+rm bl_moments
+
+
+for t in "${mst[@]}"
+	do
+	for r in "${msr[@]}"
+		do
+		for nsam in "${msNsample[@]}"
+			do
+			rm ms_tmrca_moments
+			rm scrm_tmrca_moments
+			
+			rm ms_bl_moments
+			rm scrm_bl_moments
+			
+			prefix=${nsam}sample${r}rho${t}theta
+			out=${prefix}out
+			segrecomb=${prefix}segRecomb
+
+			ms ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} -T | tail -n +4 | gawk '/^\/\//{f="xx"++d} f{print > f} '
+			for file in $(seq 1 1 ${rep})
+				do 
+				grep ";" xx${file} | sed -e 's/\[.*\]//g' > xxTrees
+				hybrid-Lambda -gt xxTrees -tmrca xx${file}Trees_tmrca
+				hybrid-Lambda -gt xxTrees -bl xx${file}Trees_bl
+				grep ";" xx${file} | sed -e 's/\[//g' -e 's/\].*;//g' > xx${file}Trees_freq
+
+				done
+				R CMD BATCH compute_moments.r
+				find . -name "xx*" -print0 | xargs -0 rm
+				mv tmrca_moments ms_tmrca_moments
+				mv bl_moments ms_bl_moments
+				
+				
+			scrm ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} -T | tail -n +4 | gawk '/^\/\//{f="xx"++d} f{print > f} '
+			for file in $(seq 1 1 ${rep})
+				do 
+				grep ";" xx${file} | sed -e 's/\[.*\]//g' > xxTrees
+				hybrid-Lambda -gt xxTrees -tmrca xx${file}Trees_tmrca
+				hybrid-Lambda -gt xxTrees -bl xx${file}Trees_bl
+				grep ";" xx${file} | sed -e 's/\[//g' -e 's/\].*;//g' > xx${file}Trees_freq
+
+				done
+				R CMD BATCH compute_moments.r
+				find . -name "xx*" -print0 | xargs -0 rm
+				mv tmrca_moments scrm_tmrca_moments
+				mv bl_moments scrm_bl_moments
+
+				echo "rm(list=ls());
+msdata=read.table(\"ms_tmrca_moments\");
+scrmdata=read.table(\"scrm_tmrca_moments\");
+m1test=ks.test(msdata\$V1,scrmdata\$V1)
+m2test=ks.test(msdata\$V2,scrmdata\$V2)
+m3test=ks.test(msdata\$V3,scrmdata\$V3)
+m4test=ks.test(msdata\$V4,scrmdata\$V4)
+pdf(paste($nsam,\"sampleTMRCAmut\",${t},\"recomb\",${r},\"-KStest.pdf\",sep=\"\"));
+par(mfrow=c(2,2))
+plot(ecdf(msdata\$V1), xlim=range(c(msdata\$V1, scrmdata\$V1)),col=\"red\", main=\"1st Moment\")
+plot(ecdf(scrmdata\$V1), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m1test\$statistic,sep=\"\"), paste(\"p-value = \",format(m1test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V2), xlim=range(c(msdata\$V2, scrmdata\$V2)),col=\"red\", main=\"2nd Moment\")
+plot(ecdf(scrmdata\$V2), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m2test\$statistic,sep=\"\"), paste(\"p-value = \",format(m2test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V3), xlim=range(c(msdata\$V3, scrmdata\$V3)),col=\"red\", main=\"3rd Moment\")
+plot(ecdf(scrmdata\$V3), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m3test\$statistic,sep=\"\"), paste(\"p-value = \",format(m3test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V4), xlim=range(c(msdata\$V4, scrmdata\$V4)),col=\"red\", main=\"4th Moment\")
+plot(ecdf(scrmdata\$V4), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m4test\$statistic,sep=\"\"), paste(\"p-value = \",format(m4test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+dev.off();
+cat(paste(${nsam},${t},${r},\"|\",
+format(m1test\$statistic,digits=4),format(m1test\$p.value,scientific = TRUE),\"|\",
+format(m2test\$statistic,digits=4),format(m2test\$p.value,scientific = TRUE),\"|\",
+format(m3test\$statistic,digits=4),format(m3test\$p.value,scientific = TRUE),\"|\",
+format(m4test\$statistic,digits=4),format(m4test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareTMRCA}\",append=TRUE);cat(\"\n\",file=\"${compareTMRCA}\",append=TRUE);
+
+rm(list=ls());
+msdata=read.table(\"ms_bl_moments\");
+scrmdata=read.table(\"scrm_bl_moments\");
+m1test=ks.test(msdata\$V1,scrmdata\$V1)
+m2test=ks.test(msdata\$V2,scrmdata\$V2)
+m3test=ks.test(msdata\$V3,scrmdata\$V3)
+m4test=ks.test(msdata\$V4,scrmdata\$V4)
+pdf(paste($nsam,\"sampleBLmut\",${t},\"recomb\",${r},\"-KStest.pdf\",sep=\"\"));
+par(mfrow=c(2,2))
+plot(ecdf(msdata\$V1), xlim=range(c(msdata\$V1, scrmdata\$V1)),col=\"red\", main=\"1st Moment\")
+plot(ecdf(scrmdata\$V1), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m1test\$statistic,sep=\"\"), paste(\"p-value = \",format(m1test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V2), xlim=range(c(msdata\$V2, scrmdata\$V2)),col=\"red\", main=\"2nd Moment\")
+plot(ecdf(scrmdata\$V2), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m2test\$statistic,sep=\"\"), paste(\"p-value = \",format(m2test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V3), xlim=range(c(msdata\$V3, scrmdata\$V3)),col=\"red\", main=\"3rd Moment\")
+plot(ecdf(scrmdata\$V3), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m3test\$statistic,sep=\"\"), paste(\"p-value = \",format(m3test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V4), xlim=range(c(msdata\$V4, scrmdata\$V4)),col=\"red\", main=\"4th Moment\")
+plot(ecdf(scrmdata\$V4), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m4test\$statistic,sep=\"\"), paste(\"p-value = \",format(m4test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+dev.off();
+cat(paste(${nsam},${t},${r},\"|\",
+format(m1test\$statistic,digits=4),format(m1test\$p.value,scientific = TRUE),\"|\",
+format(m2test\$statistic,digits=4),format(m2test\$p.value,scientific = TRUE),\"|\",
+format(m3test\$statistic,digits=4),format(m3test\$p.value,scientific = TRUE),\"|\",
+format(m4test\$statistic,digits=4),format(m4test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareBL}\",append=TRUE);cat(\"\n\",file=\"${compareBL}\",append=TRUE);
+" > dummy.r
+			R CMD BATCH dummy.r
+			done
+		done
+	done
+	
+	
diff --git a/tests/manualtests/ms_vs_scrm-tmrca-wit-recomb_Tifs.sh b/tests/manualtests/ms_vs_scrm-tmrca-wit-recomb_Tifs.sh
new file mode 100755
index 0000000..4dcf62b
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-tmrca-wit-recomb_Tifs.sh
@@ -0,0 +1,176 @@
+#!/bin/bash
+
+#Compare summary statistics of ms and scrm for TMRCA with recombination events
+mkdir test-tmrca-recomb-Tifs
+cd test-tmrca-recomb-Tifs
+
+
+seqlen=100000
+
+rep=1000
+
+
+echo -e "rm(list=ls());
+for (i in (1:${rep})){
+	p=read.table(paste(\"xx\",i,\"Trees_freq\",sep=\"\"))\$V1/${seqlen}; 
+	T=read.table(paste(\"xx\",i,\"Trees_tmrca\",sep=\"\")); 
+	bl=read.table(paste(\"xx\",i,\"Trees_bl\",sep=\"\")); 
+	cat(paste(sum(T*p),sum(T^2*p),sum(T^3*p),sum(T^4*p),sep=\"\t\") ,file=\"tmrca_moments\",append=TRUE);
+	cat(\"\n\",file=\"tmrca_moments\",append=TRUE);
+	cat(paste(sum(bl*p),sum(bl^2*p),sum(bl^3*p),sum(bl^4*p),sep=\"\t\") ,file=\"bl_moments\",append=TRUE);
+	cat(\"\n\",file=\"bl_moments\",append=TRUE);
+	}" > compute_moments.r
+
+msNsample=(2 3 4 7 10 20)
+msr=(10 20 10 50 100)
+mst=(10 20 50 100 10)
+
+#msNsample=(3)
+#msr=(10)
+#mst=(10)
+
+
+## compare TMRCA
+compareTMRCA=compareTMRCA-RECOMB
+rm ${compareTMRCA}
+
+## compare total branch length
+compareBL=compareBL-RECOMB
+rm ${compareBL}
+
+rm *pdf
+#theta=10
+echo -e "compare TMRCA for ${rep} replicates \n\t\t\t|\t1st\t\t\t|\t2nd\t\t\t|\t3rd\t\t\t|\t4th\t\t\t
+\t\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" > ${compareTMRCA}
+
+echo -e "compare total branch length for ${rep} replicates \n\t\t\t|\t1st\t\t\t|\t2nd\t\t\t|\t3rd\t\t\t|\t4th\t\t\t
+\t\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" > ${compareBL}
+rm tmrca_moments
+rm bl_moments
+
+
+for t in "${mst[@]}"
+	do
+	for r in "${msr[@]}"
+		do
+		for nsam in "${msNsample[@]}"
+			do
+			rm ms_tmrca_moments
+			rm scrm_tmrca_moments
+			
+			rm ms_bl_moments
+			rm scrm_bl_moments
+			
+			prefix=${nsam}sample${r}rho${t}theta
+			out=${prefix}out
+			segrecomb=${prefix}segRecomb
+
+			ms ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} -T | tail -n +4 | gawk '/^\/\//{f="xx"++d} f{print > f} '
+			for file in $(seq 1 1 ${rep})
+				do 
+				grep ";" xx${file} | sed -e 's/\[.*\]//g' > xxTrees
+				hybrid-Lambda -gt xxTrees -tmrca xx${file}Trees_tmrca
+				hybrid-Lambda -gt xxTrees -bl xx${file}Trees_bl
+				grep ";" xx${file} | sed -e 's/\[//g' -e 's/\].*;//g' > xx${file}Trees_freq
+
+				done
+				R CMD BATCH compute_moments.r
+				find . -name "xx*" -print0 | xargs -0 rm
+				mv tmrca_moments ms_tmrca_moments
+				mv bl_moments ms_bl_moments
+				
+				
+			scrm ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} -Tifs | tail -n +4 | gawk '/^\/\//{f="xx"++d} f{print > f} '
+			for file in $(seq 1 1 ${rep})
+				do 
+				grep ";" xx${file} | sed -e 's/\[.*\]//g' > xxTrees
+				hybrid-Lambda -gt xxTrees -tmrca xx${file}Trees_tmrca
+				hybrid-Lambda -gt xxTrees -bl xx${file}Trees_bl
+				grep ";" xx${file} | sed -e 's/\[//g' -e 's/\].*;//g' > xx${file}Trees_freq
+
+				done
+				R CMD BATCH compute_moments.r
+				find . -name "xx*" -print0 | xargs -0 rm
+				mv tmrca_moments scrm_tmrca_moments
+				mv bl_moments scrm_bl_moments
+
+				echo "rm(list=ls());
+msdata=read.table(\"ms_tmrca_moments\");
+scrmdata=read.table(\"scrm_tmrca_moments\");
+m1test=ks.test(msdata\$V1,scrmdata\$V1)
+m2test=ks.test(msdata\$V2,scrmdata\$V2)
+m3test=ks.test(msdata\$V3,scrmdata\$V3)
+m4test=ks.test(msdata\$V4,scrmdata\$V4)
+pdf(paste($nsam,\"sampleTMRCAmut\",${t},\"recomb\",${r},\"-KStest.pdf\",sep=\"\"));
+par(mfrow=c(2,2))
+plot(ecdf(msdata\$V1), xlim=range(c(msdata\$V1, scrmdata\$V1)),col=\"red\", main=\"1st Moment\")
+plot(ecdf(scrmdata\$V1), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m1test\$statistic,sep=\"\"), paste(\"p-value = \",format(m1test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V2), xlim=range(c(msdata\$V2, scrmdata\$V2)),col=\"red\", main=\"2nd Moment\")
+plot(ecdf(scrmdata\$V2), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m2test\$statistic,sep=\"\"), paste(\"p-value = \",format(m2test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V3), xlim=range(c(msdata\$V3, scrmdata\$V3)),col=\"red\", main=\"3rd Moment\")
+plot(ecdf(scrmdata\$V3), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m3test\$statistic,sep=\"\"), paste(\"p-value = \",format(m3test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V4), xlim=range(c(msdata\$V4, scrmdata\$V4)),col=\"red\", main=\"4th Moment\")
+plot(ecdf(scrmdata\$V4), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m4test\$statistic,sep=\"\"), paste(\"p-value = \",format(m4test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+dev.off();
+cat(paste(${nsam},${t},${r},\"|\",
+format(m1test\$statistic,digits=4),format(m1test\$p.value,scientific = TRUE),\"|\",
+format(m2test\$statistic,digits=4),format(m2test\$p.value,scientific = TRUE),\"|\",
+format(m3test\$statistic,digits=4),format(m3test\$p.value,scientific = TRUE),\"|\",
+format(m4test\$statistic,digits=4),format(m4test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareTMRCA}\",append=TRUE);cat(\"\n\",file=\"${compareTMRCA}\",append=TRUE);
+
+rm(list=ls());
+msdata=read.table(\"ms_bl_moments\");
+scrmdata=read.table(\"scrm_bl_moments\");
+m1test=ks.test(msdata\$V1,scrmdata\$V1)
+m2test=ks.test(msdata\$V2,scrmdata\$V2)
+m3test=ks.test(msdata\$V3,scrmdata\$V3)
+m4test=ks.test(msdata\$V4,scrmdata\$V4)
+pdf(paste($nsam,\"sampleBLmut\",${t},\"recomb\",${r},\"-KStest.pdf\",sep=\"\"));
+par(mfrow=c(2,2))
+plot(ecdf(msdata\$V1), xlim=range(c(msdata\$V1, scrmdata\$V1)),col=\"red\", main=\"1st Moment\")
+plot(ecdf(scrmdata\$V1), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m1test\$statistic,sep=\"\"), paste(\"p-value = \",format(m1test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V2), xlim=range(c(msdata\$V2, scrmdata\$V2)),col=\"red\", main=\"2nd Moment\")
+plot(ecdf(scrmdata\$V2), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m2test\$statistic,sep=\"\"), paste(\"p-value = \",format(m2test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V3), xlim=range(c(msdata\$V3, scrmdata\$V3)),col=\"red\", main=\"3rd Moment\")
+plot(ecdf(scrmdata\$V3), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m3test\$statistic,sep=\"\"), paste(\"p-value = \",format(m3test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V4), xlim=range(c(msdata\$V4, scrmdata\$V4)),col=\"red\", main=\"4th Moment\")
+plot(ecdf(scrmdata\$V4), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m4test\$statistic,sep=\"\"), paste(\"p-value = \",format(m4test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+dev.off();
+cat(paste(${nsam},${t},${r},\"|\",
+format(m1test\$statistic,digits=4),format(m1test\$p.value,scientific = TRUE),\"|\",
+format(m2test\$statistic,digits=4),format(m2test\$p.value,scientific = TRUE),\"|\",
+format(m3test\$statistic,digits=4),format(m3test\$p.value,scientific = TRUE),\"|\",
+format(m4test\$statistic,digits=4),format(m4test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareBL}\",append=TRUE);cat(\"\n\",file=\"${compareBL}\",append=TRUE);
+" > dummy.r
+			R CMD BATCH dummy.r
+			done
+		done
+	done
+	
+	
diff --git a/tests/manualtests/ms_vs_scrm-tmrca.sh b/tests/manualtests/ms_vs_scrm-tmrca.sh
new file mode 100755
index 0000000..78c1d19
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-tmrca.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+#Compare summary statistics of ms and scrm for TMRCA
+
+mkdir test-tmrca
+cd test-tmrca
+rm *pdf
+
+msNsample=(2 3 4 7 10 20)
+
+rep=100000
+
+## compare TMRCA
+compareTMRCA=compareTMRCA
+rm ${compareTMRCA}
+echo -e "compare TMRCA for ${rep} replicates \n\t|Theoretical\t\t|\t ms \t\t|\t scrm\t\t|\tKS test\nNsam\t|\tmean\tstdv\t|\tmean\tstdv\t|\tmean\tstdv \t|\tstats\tp-value" >${compareTMRCA}
+#theta=10
+
+npop=1000000
+for nsam in "${msNsample[@]}"
+	do
+	prefix=${nsam}sample
+	out=${prefix}out
+	tmrca=${prefix}tmrca
+	Trees=${prefix}Trees
+	ms ${nsam} ${rep} -T | tail -n +4 | grep -v "//" > ms${out}
+	cat ms${out} | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+	hybrid-Lambda -gt ms${Trees} -tmrca ms${tmrca}
+	scrm ${nsam} ${rep} -T | tail -n +4 | grep -v "//" > scrm${out}
+	cat scrm${out} | grep ";" | sed -e 's/\[.*\]//g' > scrm${Trees}
+	hybrid-Lambda -gt scrm${Trees} -tmrca scrm${tmrca}
+	echo "rm(list=ls());
+source(\"../fun_src.r\");
+msdata=read.table(\"ms${tmrca}\")\$V1;
+scrmdata=read.table(\"scrm${tmrca}\")\$V1;
+ee=ee_tmrca(${nsam});
+sdv=sd_tmrca(${nsam});
+test=ks.test(msdata,scrmdata)
+pdf(paste($nsam,\"sampleTMRCA-KStest.pdf\",sep=\"\"));
+plot(ecdf(msdata), xlim=range(c(msdata, scrmdata)),col=\"red\", main=paste($nsam,\"sample TMRCA KS test\",sep=\"\"))
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+cat(paste(${nsam},\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",test\$statistic,format(test\$p.value,digits=4), 
+sep=\"\t\"),file=\"${compareTMRCA}\",append=TRUE);cat(\"\n\",file=\"${compareTMRCA}\",append=TRUE);" > dummy.r
+	R CMD BATCH dummy.r
+	rm ms${out} ms${Trees} ms${tmrca} scrm${out} scrm${Trees} scrm${tmrca} 
+	done
+
diff --git a/tests/manualtests/ms_vs_scrm-topofreq.sh b/tests/manualtests/ms_vs_scrm-topofreq.sh
new file mode 100755
index 0000000..1e49bf7
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm-topofreq.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+#Compare distribution of genealogies
+
+msNsample=(3 4 5)
+
+rep=20000
+
+## compare TMRCA
+compareTMRCA=compareTMRCA
+#rm ${compareTMRCA}
+#theta=10
+npop=1000000
+for nsam in "${msNsample[@]}"
+	do
+	prefix=${nsam}sample
+	out=${prefix}out
+	freq=${prefix}freq
+	Trees=${prefix}Trees
+	ms ${nsam} ${rep} -T | tail -n +4 | grep -v "//" > ms${out}
+	cat ms${out} | grep ";" | sed -e 's/\[.*\]//g' > ms${Trees}
+	hybrid-Lambda -gt ms${Trees} -fF ms${freq}
+	scrm ${nsam} ${rep} -T | tail -n +4 | grep -v "//" > scrm${out}
+	cat scrm${out} | grep ";" | sed -e 's/\[.*\]//g' > scrm${Trees}
+	hybrid-Lambda -gt scrm${Trees} -fF scrm${freq}
+	
+	#echo "rm(list=ls());msdata=read.table(\"ms${freq}\")\$V1;scrmdata=read.table(\"scrm${freq}\")\$V1;cat(paste(${nsam},mean(msdata),sd(msdata),sd(msdata)/sqrt(length(msdata)),mean(scrmdata),sd(scrmdata),sd(scrmdata)/sqrt(length(scrmdata)),sep=\"\t\"),file=\"${compareTMRCA}\",append=TRUE);cat(\"\n\",file=\"${compareTMRCA}\",append=TRUE);" > dummy.r
+	#R CMD BATCH dummy.r
+	#rm ms${out} ms${Trees} ms${freq} scrm${out} scrm${Trees} scrm${freq} 
+	done
+
diff --git a/tests/manualtests/ms_vs_scrm_1st_last_tmrca_2sample.sh b/tests/manualtests/ms_vs_scrm_1st_last_tmrca_2sample.sh
new file mode 100755
index 0000000..3752a86
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm_1st_last_tmrca_2sample.sh
@@ -0,0 +1,109 @@
+#!/bin/bash
+
+#Compare summary statistics of ms and scrm for TMRCA with recombination events
+mkdir test-first-last
+cd test-first-last
+
+
+seqlen=3
+
+rep=100000
+
+
+nsam=2 
+#msr=(10 20 50 100)
+#mst=(10 20 50 100)
+
+#msNsample=(3)
+msr=(10)
+mst=(1)
+
+
+## compare TMRCA
+compareTMRCA=compareTMRCA-LAST
+rm ${compareTMRCA}
+
+#compareBL=compareBL-LAST
+#rm ${compareBL}
+
+#rm *pdf
+
+echo -e "compare TMRCA for ${rep} replicates 
+\t\t\t|\t ms \t\t|\t scrm\t\t|\tKS test
+Nsam\ttheta\trho\t|\tmean\tstdv\t|\tmean\tstdv \t|\tstats\tp-value" >${compareTMRCA}
+
+
+#rm tmrca_moments
+#rm bl_moments
+
+
+for t in "${mst[@]}"
+	do
+	for r in "${msr[@]}"
+		do
+			prefix=${nsam}sample${r}rho${t}theta
+			echo ${prefix}
+			out=${prefix}out
+			#bl=${prefix}bl
+			tmrca=${prefix}tmrca
+			
+			rm first_ms${tmrca}_file
+			rm last_ms${tmrca}_file
+		
+			ms ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} -T | tail -n +4 | gawk '/^\/\//{f="xx"++d} f{print > f} '
+			for file in $(seq 1 1 ${rep})
+				do 
+				#grep ";" xx${file} | sed -e 's/\[.*\]//g' | tail -1 >> msTrees
+				grep ';' xx${file} | sed -e 's/\[.*://g' -e 's/);//g' | head -1 >> first_ms${tmrca}_file
+				grep ';' xx${file} | sed -e 's/\[.*://g' -e 's/);//g' | tail -1 >> last_ms${tmrca}_file
+				done
+				find . -name "xx*" -print0 | xargs -0 rm
+
+			rm first_scrm${tmrca}_file
+			rm last_scrm${tmrca}_file
+		
+			scrm ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} -T | tail -n +4 | gawk '/^\/\//{f="xx"++d} f{print > f} '
+			for file in $(seq 1 1 ${rep})
+				do 
+				#grep ";" xx${file} | sed -e 's/\[.*\]//g' | tail -1 >> scrmTrees
+				grep ';' xx${file} | sed -e 's/\[.*://g' -e 's/);//g' | head -1 >> first_scrm${tmrca}_file
+				grep ';' xx${file} | sed -e 's/\[.*://g' -e 's/);//g' | tail -1 >> last_scrm${tmrca}_file
+				done
+				find . -name "xx*" -print0 | xargs -0 rm
+				
+
+				echo "rm(list=ls());
+source(\"../fun_src.r\");
+msfirst = read.table(\"first_ms${tmrca}_file\")\$V1;
+mslast = read.table(\"last_ms${tmrca}_file\")\$V1;
+scrmfirst = read.table(\"first_scrm${tmrca}_file\")\$V1;
+scrmlast = read.table(\"last_scrm${tmrca}_file\")\$V1;
+#ee=ee_tmrca(${nsam});
+#sdv=sd_tmrca(${nsam});
+test=ks.test(mslast,scrmlast)
+pdf(paste($nsam,\"sample${t}mut${r}TMRCA-KStest.pdf\",sep=\"\"));
+plot(ecdf(msfirst), xlim=range(c(msfirst, mslast,scrmfirst,scrmlast)),col=\"red\", main=paste($nsam,\"sample TMRCA KS test\",sep=\"\"))
+plot(ecdf(mslast), add=TRUE, lty=\"dashed\", col=\"blue\")
+plot(ecdf(scrmfirst), add=TRUE, lty=\"dashed\", col=\"green\")
+plot(ecdf(scrmlast), add=TRUE, lty=\"dashed\", col=\"black\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"msfirst\",\"mslast\",\"scrmfirst\",\"scrmlast\"), col=c(\"red\",\"blue\",\"green\",\"black\"), pch=16)
+dev.off();
+pdf(paste($nsam,\"sample${t}mut${r}TMRCA-KStest_zoomin.pdf\",sep=\"\"));
+plot(ecdf(msfirst), xlim=c(1,2.5),ylim=c(0.8,1),col=\"red\", main=paste($nsam,\"sample TMRCA KS test\",sep=\"\"))
+plot(ecdf(mslast), add=TRUE, lty=\"dashed\", col=\"blue\")
+plot(ecdf(scrmfirst), add=TRUE, lty=\"dashed\", col=\"green\")
+plot(ecdf(scrmlast), add=TRUE, lty=\"dashed\", col=\"black\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"msfirst\",\"mslast\",\"scrmfirst\",\"scrmlast\"), col=c(\"red\",\"blue\",\"green\",\"black\"), pch=16)
+dev.off();
+#cat(paste(${nsam},${t},${r},\"|\",
+#format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+#format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",format(test\$statistic,digits=4),format(test\$p.value,scientific = TRUE), 
+#sep=\"\t\"),file=\"${compareTMRCA}\",append=TRUE);cat(\"\n\",file=\"${compareTMRCA}\",append=TRUE); " > dummy.r
+			R CMD BATCH dummy.r
+			#rm scrm${tmrca} scrm${bl} ms${tmrca} ms${bl}
+		done
+	done
+	
+	
diff --git a/tests/manualtests/ms_vs_scrm_SEG_samplestats.sh b/tests/manualtests/ms_vs_scrm_SEG_samplestats.sh
new file mode 100755
index 0000000..8640fb1
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm_SEG_samplestats.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+mkdir test-SEGsamplestats
+cd test-SEGsamplestats
+rm *pdf
+
+
+rep=100000
+
+## compare SEG data
+COMPAREFILE=compareSEG
+rm ${COMPAREFILE}
+
+theta=10
+
+source ../chisq_r.src
+
+source ../ks_r.src
+
+source ../process_sample_stats.src
+
+#case 1 
+echo "4_samples" > current_case
+ms 4 ${rep} -t ${theta} | sample_stats > ms_stats
+scrm 4 ${rep} -t ${theta} | sample_stats > scrm_stats
+foo
+
+
+#case 2
+echo "5_samples" > current_case
+ms 5 ${rep} -t ${theta} | sample_stats > ms_stats
+scrm 5 ${rep} -t ${theta} | sample_stats > scrm_stats
+foo
+
+#case 3
+#2 sub population, 6 samples from subpopulation 1, and 5 samples from subpopulation 2, with rate 10 from 1 to 2, and rate 5 from 2 to 1
+prefix="2groups6sam5sam_mig_x_10_5_x"
+echo ${prefix} > current_case
+ms 4 ${rep} -t ${theta} -I 2 2 2 -ma x 10.0 5.0 x | sample_stats > ms_stats
+scrm 4 ${rep} -t ${theta} -I 2 2 2 -ma x 10.0 5.0 x | sample_stats > scrm_stats
+foo
+
+#case 4
+#3 sub population, 10 samples from subpopulation 1, and 4 samples from subpopulation 2, and 1 sample from the third with rate matrix on manual page 5
+prefix="3groups10sam4sam1sam_mig_x123x456x"
+echo ${prefix} > current_case
+ms 15 ${rep} -t ${theta} -I 3 10 4 1 -ma x 1.0 2.0 3.0 x 4.0 5.0 6.0 x | sample_stats > ms_stats
+scrm 15 ${rep} -t ${theta} -I 3 10 4 1 -ma x 1.0 2.0 3.0 x 4.0 5.0 6.0 x | sample_stats > scrm_stats
+foo
diff --git a/tests/manualtests/ms_vs_scrm_growth-recomb.sh b/tests/manualtests/ms_vs_scrm_growth-recomb.sh
new file mode 100755
index 0000000..4b35900
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm_growth-recomb.sh
@@ -0,0 +1,137 @@
+#!/bin/bash
+dir=test-GROWTH-recomb
+mkdir ${dir}
+cd ${dir}
+rm *pdf
+
+
+rep=100000
+
+compareGrowth=compareGrowth
+rm ${compareGrowth}
+
+theta=100
+seqlen=100000
+r=10
+
+source ../chisq_r.src
+
+source ../ks_r.src
+
+source ../tmrca_r.src
+
+source ../bl_r.src
+
+source ../process_sample_stats.src	
+
+#case 1 
+echo "15_samples_case1" > current_case
+rm ms* scrm*
+
+ms 5 ${rep} -t ${theta} -r ${r} ${seqlen} -eG .3 7.0 -eN 0.3 0.5 -T > msout
+mstime
+
+scrm 5 ${rep} -t ${theta} -r ${r} ${seqlen} -eG .3 7.0 -eN 0.3 0.5 -T > scrmout
+scrmtime
+
+
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+#cat msout | sample_stats > ms_stats
+#cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+#hybrid-Lambda -gt msTrees -tmrca mstmrca
+#hybrid-Lambda -gt msTrees -bl msbl
+
+
+#cat scrmout | sample_stats > scrm_stats
+#cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+#hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+#hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+foo
+
+#case 2
+echo "5_samples_case2" > current_case
+rm ms* scrm*
+
+ms 5 ${rep} -t ${theta} -r ${r} ${seqlen} -G 6.93 -eG 0.2 0.0 -eN 0.3 0.5 -T > msout
+mstime
+
+scrm 5 ${rep} -t ${theta} -r ${r} ${seqlen} -G 6.93 -eG 0.2 0.0 -eN 0.3 0.5 -T > scrmout
+scrmtime
+
+#cat msout | sample_stats > ms_stats
+#cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+#hybrid-Lambda -gt msTrees -tmrca mstmrca
+#hybrid-Lambda -gt msTrees -bl msbl
+
+
+#cat scrmout | sample_stats > scrm_stats
+#cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+#hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+#hybrid-Lambda -gt scrmTrees -bl scrmbl
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+
+##case 3
+
+echo "15_samples_case_3" > current_case
+rm ms* scrm*
+
+ms 15 ${rep} -t ${theta} -r ${r} ${seqlen}  -I 2 3 12 -g 1 44.36 -n 2 0.125 -eg 0.03125 1 0.0 -en 0.0625 2 0.05 -ej 0.09375 2 1 -T > msout
+mstime
+
+scrm 15 ${rep} -t ${theta} -r ${r} ${seqlen} -I 2 3 12 -g 1 44.36 -n 2 0.125 -eg 0.03125 1 0.0 -en 0.0625 2 0.05 -ej 0.09375 2 1 -T > scrmout
+scrmtime
+
+#cat msout | sample_stats > ms_stats
+#cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+#hybrid-Lambda -gt msTrees -tmrca mstmrca
+#hybrid-Lambda -gt msTrees -bl msbl
+
+
+#cat scrmout | sample_stats > scrm_stats
+#cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+#hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+#hybrid-Lambda -gt scrmTrees -bl scrmbl
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+#case 4
+echo "15_samples_case_4" > current_case
+rm ms* scrm*
+
+ms 15 ${rep} -t ${theta} -r ${r} ${seqlen} -I 2 3 12 -g 1 11.09 -n 1 4.0 -n 2 0.5 -eg 0.125 1 0.0 -en 0.25 2 .2 -ej 0.375 2 1 -T > msout
+mstime
+scrm 15 ${rep} -t ${theta} -r ${r} ${seqlen} -I 2 3 12 -g 1 11.09 -n 1 4.0 -n 2 0.5 -eg 0.125 1 0.0 -en 0.25 2 .2 -ej 0.375 2 1 -T > scrmout
+scrmtime
+
+#cat msout | sample_stats > ms_stats
+#cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+#hybrid-Lambda -gt msTrees -tmrca mstmrca
+#hybrid-Lambda -gt msTrees -bl msbl
+
+
+#cat scrmout | sample_stats > scrm_stats
+#cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+#hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+#hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+cat msout | sample_stats > ms_stats
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+foo
+
diff --git a/tests/manualtests/ms_vs_scrm_growth.sh b/tests/manualtests/ms_vs_scrm_growth.sh
new file mode 100755
index 0000000..f423828
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm_growth.sh
@@ -0,0 +1,169 @@
+#!/bin/bash
+
+dir=test-GROWTH
+mkdir ${dir}
+cd ${dir}
+rm *pdf
+
+
+rep=100000
+
+COMPAREFILE=compareGrowth
+rm ${COMPAREFILE}
+
+theta=100
+
+source ../chisq_r.src
+
+source ../ks_r.src
+
+source ../tmrca_r.src
+
+source ../bl_r.src
+
+source ../process_sample_stats.src	
+
+
+#case 0
+echo "5_samples_case0" > current_case
+rm ms* scrm*
+
+ms 5 ${rep} -t ${theta} -G 7.0  -T > msout
+scrm 5 ${rep} -t ${theta} -G 7.0 -T > scrmout
+
+
+cat msout | sample_stats > ms_stats
+cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+hybrid-Lambda -gt msTrees -tmrca mstmrca -log
+hybrid-Lambda -gt msTrees -bl msbl -log
+
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+foo
+
+#case 1 
+echo "5_samples_case1" > current_case
+rm ms* scrm*
+
+ms 5 ${rep} -t ${theta} -eN 0.3 0.5 -eG .3 7.0  -T > msout
+scrm 5 ${rep} -t ${theta} -eN 0.3 0.5 -eG .3 7.0 -T > scrmout
+
+
+cat msout | sample_stats > ms_stats
+cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+hybrid-Lambda -gt msTrees -tmrca mstmrca
+hybrid-Lambda -gt msTrees -bl msbl
+
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+foo
+
+#case 2
+echo "5_samples_case2" > current_case
+rm ms* scrm*
+
+ms 5 ${rep} -t ${theta} -G 6.93 -eG 0.2 0.0 -eN 0.3 0.5 -T > msout
+scrm 5 ${rep} -t ${theta} -G 6.93 -eG 0.2 0.0 -eN 0.3 0.5 -T > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+hybrid-Lambda -gt msTrees -tmrca mstmrca
+hybrid-Lambda -gt msTrees -bl msbl
+
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+foo
+
+#case 2.1
+echo "5_samples_case2point1" > current_case
+rm ms* scrm*
+
+ms 5 ${rep} -t ${theta} -G 6.93 -eG 0.2 0.0  -T > msout
+scrm 5 ${rep} -t ${theta} -G 6.93 -eG 0.2 0.0  -T > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+hybrid-Lambda -gt msTrees -tmrca mstmrca
+hybrid-Lambda -gt msTrees -bl msbl
+
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+foo
+
+#case 2.2
+echo "5_samples_case2point2" > current_case
+rm ms* scrm*
+
+ms 5 ${rep} -t ${theta} -G 6.93 -eN 0.3 0.5 -T > msout
+scrm 5 ${rep} -t ${theta} -G 6.93 -eN 0.3 0.5 -T > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+hybrid-Lambda -gt msTrees -tmrca mstmrca
+hybrid-Lambda -gt msTrees -bl msbl
+
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+#foo
+
+##case 3
+
+echo "15_samples_case3" > current_case
+rm ms* scrm*
+
+ms 15 ${rep} -t ${theta} -I 2 3 12 -g 1 44.36 -n 2 0.125 -eg 0.03125 1 0.0 -en 0.0625 2 0.05 -ej 0.09375 2 1 -T > msout
+scrm 15 ${rep} -t ${theta} -I 2 3 12 -g 1 44.36 -n 2 0.125 -eg 0.03125 1 0.0 -en 0.0625 2 0.05 -ej 0.09375 2 1 -T > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+hybrid-Lambda -gt msTrees -tmrca mstmrca
+hybrid-Lambda -gt msTrees -bl msbl
+
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+foo
+
+#case 4
+echo "15_samples_case4" > current_case
+rm ms* scrm*
+
+ms 15 ${rep} -t ${theta} -I 2 3 12 -g 1 11.09 -n 1 4.0 -n 2 0.5 -eg 0.125 1 0.0 -en 0.25 2 .2 -ej 0.375 2 1 -T > msout
+scrm 15 ${rep} -t ${theta} -I 2 3 12 -g 1 11.09 -n 1 4.0 -n 2 0.5 -eg 0.125 1 0.0 -en 0.25 2 .2 -ej 0.375 2 1 -T > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+hybrid-Lambda -gt msTrees -tmrca mstmrca
+hybrid-Lambda -gt msTrees -bl msbl
+
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+foo
+
diff --git a/tests/manualtests/ms_vs_scrm_last_tmrca-wit-recomb.sh b/tests/manualtests/ms_vs_scrm_last_tmrca-wit-recomb.sh
new file mode 100755
index 0000000..5c58792
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm_last_tmrca-wit-recomb.sh
@@ -0,0 +1,140 @@
+#!/bin/bash
+
+#Compare summary statistics of ms and scrm for TMRCA with recombination events
+mkdir test-tmrca-last
+cd test-tmrca-last
+
+
+seqlen=100000
+
+rep=10000
+
+
+#echo -e "rm(list=ls());
+#for (i in (1:${rep})){
+	#p=read.table(paste(\"xx\",i,\"Trees_freq\",sep=\"\"))\$V1/${seqlen}; 
+	#T=read.table(paste(\"xx\",i,\"Trees_tmrca\",sep=\"\")); 
+	#bl=read.table(paste(\"xx\",i,\"Trees_bl\",sep=\"\")); 
+	#cat(paste(sum(T*p),sum(T^2*p),sum(T^3*p),sum(T^4*p),sep=\"\t\") ,file=\"tmrca_moments\",append=TRUE);
+	#cat(\"\n\",file=\"tmrca_moments\",append=TRUE);
+	#cat(paste(sum(bl*p),sum(bl^2*p),sum(bl^3*p),sum(bl^4*p),sep=\"\t\") ,file=\"bl_moments\",append=TRUE);
+	#cat(\"\n\",file=\"bl_moments\",append=TRUE);
+	#}" > compute_moments.r
+
+#msNsample=(2 3 4 7 10 20)
+#msNsample=(2 4)
+#msr=(10 20 50 100)
+#mst=(10 20 50 100)
+
+msNsample=(6)
+msr=(10)
+mst=(10)
+
+
+## compare TMRCA
+compareTMRCA=compareTMRCA-LAST
+rm ${compareTMRCA}
+
+compareBL=compareBL-LAST
+rm ${compareBL}
+
+rm *pdf
+#theta=10
+#echo -e "compare TMRCA for ${rep} replicates \n\t\t\t|\t1st\t\t\t|\t2nd\t\t\t|\t3rd\t\t\t|\t4th\t\t\t
+#\t\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" > ${compareTMRCA}
+
+#echo -e "compare total branch length for ${rep} replicates \n\t\t\t|\t1st\t\t\t|\t2nd\t\t\t|\t3rd\t\t\t|\t4th\t\t\t
+#\t\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" > ${compareBL}
+
+echo -e "compare TMRCA for ${rep} replicates 
+\t\t\t|\t ms \t\t|\t scrm\t\t|\tKS test
+Nsam\ttheta\trho\t|\tmean\tstdv\t|\tmean\tstdv \t|\tstats\tp-value" >${compareTMRCA}
+
+echo -e "compare BL for ${rep} replicates 
+\t\t\t|\t ms \t\t|\t scrm\t\t|\tKS test
+Nsam\ttheta\trho\t|\tmean\tstdv\t|\tmean\tstdv \t|\tstats\tp-value" >${compareBL}
+
+
+
+#rm tmrca_moments
+#rm bl_moments
+
+
+for t in "${mst[@]}"
+	do
+	for r in "${msr[@]}"
+		do
+		for nsam in "${msNsample[@]}"
+			do
+			#rm ms_tmrca_moments
+			#rm scrm_tmrca_moments
+			
+			#rm ms_bl_moments
+			#rm scrm_bl_moments
+			
+			prefix=${nsam}sample${r}rho${t}theta
+			out=${prefix}out
+			bl=${prefix}bl
+			tmrca=${prefix}tmrca
+			#segrecomb=${prefix}segRecomb
+			rm msTrees
+			ms ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} -T | tail -n +4 | gawk '/^\/\//{f="xx"++d} f{print > f} '
+			for file in $(seq 1 1 ${rep})
+				do 
+				grep ";" xx${file} | sed -e 's/\[.*\]//g' | tail -1 >> msTrees
+				done
+				hybrid-Lambda -gt msTrees -tmrca ms${tmrca}
+				hybrid-Lambda -gt msTrees -bl ms${bl}
+				find . -name "xx*" -print0 | xargs -0 rm
+				
+			rm 	scrmTrees
+			scrm ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} -T -l 100 | tail -n +4 | gawk '/^\/\//{f="xx"++d} f{print > f} '
+			for file in $(seq 1 1 ${rep})
+				do 
+				grep ";" xx${file} | sed -e 's/\[.*\]//g' | tail -1 >> scrmTrees
+				done
+				hybrid-Lambda -gt scrmTrees -tmrca scrm${tmrca}
+				hybrid-Lambda -gt scrmTrees -bl scrm${bl}
+				find . -name "xx*" -print0 | xargs -0 rm
+
+				echo "rm(list=ls());
+source(\"../fun_src.r\");
+msdata=read.table(\"ms${tmrca}\")\$V1;
+scrmdata=read.table(\"scrm${tmrca}\")\$V1;
+#ee=ee_tmrca(${nsam});
+#sdv=sd_tmrca(${nsam});
+test=ks.test(msdata,scrmdata)
+pdf(paste($nsam,\"sample${t}mut${r}TMRCA-KStest.pdf\",sep=\"\"));
+plot(ecdf(msdata), xlim=range(c(msdata, scrmdata)),col=\"red\", main=paste($nsam,\"sample TMRCA KS test\",sep=\"\"))
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+cat(paste(${nsam},${t},${r},\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",format(test\$statistic,digits=4),format(test\$p.value,scientific = TRUE), 
+sep=\"\t\"),file=\"${compareTMRCA}\",append=TRUE);cat(\"\n\",file=\"${compareTMRCA}\",append=TRUE);
+rm(list=ls());
+source(\"../fun_src.r\");
+msdata=read.table(\"ms${bl}\")\$V1;
+scrmdata=read.table(\"scrm${bl}\")\$V1;
+ee=ee_bl(${nsam});
+sdv=sd_bl(${nsam});
+test=ks.test(msdata,scrmdata)
+pdf(paste($nsam,\"sample${t}mut${r}BL-KStest.pdf\",sep=\"\"));
+plot(ecdf(msdata), xlim=range(c(msdata, scrmdata)),col=\"red\", main=paste($nsam,\"sample BL KS test\",sep=\"\"))
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+cat(paste(${nsam},${t},${r},\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",format(test\$statistic,digits=4),format(test\$p.value,scientific = TRUE), 
+sep=\"\t\"),file=\"${compareBL}\",append=TRUE);cat(\"\n\",file=\"${compareBL}\",append=TRUE);" > dummy.r
+			R CMD BATCH dummy.r
+			#rm scrm${tmrca} scrm${bl} ms${tmrca} ms${bl}
+			done
+		done
+	done
+	
+	
diff --git a/tests/manualtests/ms_vs_scrm_pop_struct.sh b/tests/manualtests/ms_vs_scrm_pop_struct.sh
new file mode 100755
index 0000000..f459d9d
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm_pop_struct.sh
@@ -0,0 +1,184 @@
+#!/bin/bash
+
+dir=test-POP
+mkdir ${dir}
+cd ${dir}
+rm *pdf
+
+
+rep=100000
+
+## compare population sturture for a single population data
+COMPAREFILE=comparePop
+rm ${COMPAREFILE}
+
+theta=10
+
+
+source ../chisq_r.src
+
+source ../ks_r.src
+
+source ../tmrca_r.src
+
+source ../bl_r.src
+
+source ../process_sample_stats.src	
+
+
+#case 1 
+echo "2_samples_case1" > current_case
+rm ms* scrm*
+ms 2 ${rep} -t ${theta} -eN 0.4 10.01 -eN 1 0.01 -T > msout
+scrm 2 ${rep} -t ${theta} -eN 0.4 10.01 -eN 1 0.01  -T > scrmout
+
+
+cat msout | sample_stats > ms_stats
+cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+hybrid-Lambda -gt msTrees -tmrca mstmrca
+hybrid-Lambda -gt msTrees -bl msbl
+
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+foo
+
+#case 1 
+echo "2_samples_case1.1" > current_case
+rm ms* scrm*
+ms 2 ${rep} -t ${theta} -eN 0 1 -eN 0.4 10.01 -eN 1 0.01 -T > msout
+scrm 2 ${rep} -t ${theta} -eN 0 1 -eN 0.4 10.01 -eN 1 0.01  -T > scrmout
+
+
+cat msout | sample_stats > ms_stats
+cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+hybrid-Lambda -gt msTrees -tmrca mstmrca
+hybrid-Lambda -gt msTrees -bl msbl
+
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+foo
+
+#case 2
+echo "2_samples_case1.2" > current_case
+rm ms* scrm*
+ms 2 ${rep} -t ${theta} -eN 0 10 -eN 0.4 10.01 -eN 1 0.01 -T > msout
+scrm 2 ${rep} -t ${theta} -eN 0 10 -eN 0.4 10.01 -eN 1 0.01  -T > scrmout
+
+
+cat msout | sample_stats > ms_stats
+cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+hybrid-Lambda -gt msTrees -tmrca mstmrca
+hybrid-Lambda -gt msTrees -bl msbl
+
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+foo
+
+#case 2
+echo "2_samples_case2" > current_case
+rm ms* scrm*
+ms 2 ${rep} -t ${theta} -eN .5 0.01 -T > msout
+scrm 2 ${rep} -t ${theta} -eN .5 0.01  -T > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+hybrid-Lambda -gt msTrees -tmrca mstmrca
+hybrid-Lambda -gt msTrees -bl msbl
+
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+foo
+
+
+##case 3
+
+echo "5_samples" > current_case
+rm ms* scrm*
+
+ms 5 ${rep} -t ${theta} -eN 0.5 10.0 -T > msout
+scrm 5 ${rep} -t ${theta} -eN 0.5 10.0 -T > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+hybrid-Lambda -gt msTrees -tmrca mstmrca
+hybrid-Lambda -gt msTrees -bl msbl
+
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+foo
+
+#case 4
+echo "4_samples" > current_case
+rm ms* scrm*
+
+ms 4 ${rep} -t ${theta} -eN 0.8 15  -T > msout
+scrm 4 ${rep} -t ${theta} -eN 0.8 15  -T > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+hybrid-Lambda -gt msTrees -tmrca mstmrca
+hybrid-Lambda -gt msTrees -bl msbl
+
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+foo
+
+#case 5
+echo "6_samples_case1" > current_case
+rm ms* scrm*
+ms 6 ${rep} -t ${theta} -eN 1 .1 -eN 3 10 -T > msout
+scrm 6 ${rep} -t ${theta} -eN 1 .1 -eN 3 10  -T > scrmout
+cat msout | sample_stats > ms_stats
+cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+hybrid-Lambda -gt msTrees -tmrca mstmrca
+hybrid-Lambda -gt msTrees -bl msbl
+
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+foo
+
+#case 6
+echo "6_samples_case2" > current_case
+rm ms* scrm*
+ms 6 ${rep} -t ${theta}  -eN .3 10 -T > msout
+scrm 6 ${rep} -t ${theta}  -eN .3 10  -T > scrmout
+cat msout | sample_stats > ms_stats
+cat msout | grep ";" | sed -e 's/\[.*\]//g' > msTrees
+hybrid-Lambda -gt msTrees -tmrca mstmrca
+hybrid-Lambda -gt msTrees -bl msbl
+
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep ";" | sed -e 's/\[.*\]//g' > scrmTrees
+hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+hybrid-Lambda -gt scrmTrees -bl scrmbl
+
+foo
diff --git a/tests/manualtests/ms_vs_scrm_subpop_struct.sh b/tests/manualtests/ms_vs_scrm_subpop_struct.sh
new file mode 100755
index 0000000..ed3b59c
--- /dev/null
+++ b/tests/manualtests/ms_vs_scrm_subpop_struct.sh
@@ -0,0 +1,79 @@
+#!/bin/bash
+
+dir=test-SUBPOP
+mkdir ${dir}
+cd ${dir}
+rm *pdf
+
+
+rep=100000
+
+## compare population sturture for a single population data
+COMPAREFILE=compareSubPop
+rm ${COMPAREFILE}
+
+theta=10
+
+source ../chisq_r.src
+
+source ../ks_r.src
+
+source ../tmrca_r.src
+
+source ../bl_r.src
+
+source ../process_sample_stats.src	
+
+
+#case 1 
+echo "10_samples_case1" > current_case
+rm ms* scrm*
+ms 10 ${rep} -t ${theta} -I 2 2 8 -eN 0.4 10.01 -eN 1 0.01 -en 0.25 2 0.2 -ej 3 2 1 -T -L > msout
+scrm 10 ${rep} -t ${theta} -I 2 2 8 -eN 0.4 10.01 -eN 1 0.01 -en 0.25 2 0.2 -ej 3 2 1 -T -L > scrmout
+
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+#case 4
+#3 sub population, 10 samples from subpopulation 1, and 4 samples from subpopulation 2, and 1 sample from the third with rate 5
+
+echo "3groups10sam4sam1sam_mig_offdiag5" > current_case
+rm ms* scrm*
+
+	
+ms 15 ${rep} -t ${theta} -I 3 10 4 1 -ma x 5.0 5.0 5.0 x 5.0 5.0 5.0 x -eN 0.8 15 -ej .7 2 1 -ej 1 3 1 -T -L > msout
+scrm 15 ${rep} -t ${theta} -I 3 10 4 1 -ma x 5.0 5.0 5.0 x 5.0 5.0 5.0 x -eN 0.8 15 -ej .7 2 1 -ej 1 3 1 -T -L > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
+
+
+
+#case 5
+#3 sub population, 10 samples from subpopulation 1, and 4 samples from subpopulation 2, and 1 sample from the third with rate matrix on manual page 5
+
+echo "3groups10sam4sam1sam_mig_x123x456x" > current_case
+
+rm ms* scrm*
+	
+ms 15 ${rep} -t ${theta} -I 3 10 4 1 -ma x 1.0 2.0 3.0 x 4.0 5.0 6.0 x -eN 1 .1 -eN 3 10 -ej .7 2 1 -ej 4 3 1 -T -L > msout
+scrm 15 ${rep} -t ${theta} -I 3 10 4 1 -ma x 1.0 2.0 3.0 x 4.0 5.0 6.0 x -eN 1 .1 -eN 3 10 -ej .7 2 1 -ej 4 3 1 -T -L > scrmout
+
+cat msout | sample_stats > ms_stats
+cat msout | grep "time:" > mstime
+
+cat scrmout | sample_stats > scrm_stats
+cat scrmout | grep "time:" >  scrmtime
+
+foo
diff --git a/tests/manualtests/mysample_stats.c b/tests/manualtests/mysample_stats.c
new file mode 100644
index 0000000..b5de3c9
--- /dev/null
+++ b/tests/manualtests/mysample_stats.c
@@ -0,0 +1,200 @@
+//this program is from ms (Hudson 2002), and made simple modifications
+//gcc -o sample_stats mysample_stats.c tajd.c -lm
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+	double nucdiv(int, int, char **);
+	double tajd(int, int, double) ;
+	double hfay(int, int, char **);
+	double thetah(int, int, char **);
+
+int maxsites = 1000 ;
+
+main(argc,argv)
+	int argc;
+	char *argv[];
+{
+	int nsam, j ,nsites, i,  howmany  ;
+	char **list, **cmatrix(), allele,na, line[1001], slashline[1001]  ;
+	FILE *pf, *fopen(), *pfin ;
+	double *posit   ;
+	int   segsites, count  , nadv, probflag  ;
+	double pi , h, th  ,prob ;
+	char dum[20], astr[100] ;
+	int  nsegsub, segsub( int nsam, int segsites, char **list ) ;
+
+/* read in first two lines of output  (parameters and seed) */
+  pfin = stdin ;
+  fgets( line, 1000, pfin);
+  sscanf(line," %s  %d %d", dum,  &nsam, &howmany);
+
+/* printf( " dum = %s nsam = %d howmany = %d \n", dum,  nsam, howmany); */
+
+  fgets( line, 1000, pfin);
+
+	if( argc > 1 ) { 
+	   nadv = atoi( argv[1] ) ; 
+	}
+
+  list = cmatrix(nsam,maxsites+1);
+  posit = (double *)malloc( maxsites*sizeof( double ) ) ;
+
+  count=0;
+	probflag = 0 ;
+while( howmany-count++ ) {
+
+/* read in a sample */
+  do {
+     if( fgets( line, 1000, pfin) == NULL ){
+	   exit(0);
+	 }
+	 if( line[0] == '/' )  strcpy(slashline,line+2);
+  }while ( (line[0] != 's') && (line[0] != 'p' ) ) ;
+ 
+  if( line[0] == 'p'){
+      sscanf( line, "  prob: %lf", &prob );
+	  probflag = 1 ;
+	  if( fgets( line, 1000, pfin) == NULL ){
+	    exit(0);
+	  }
+  }
+  sscanf( line, "  segsites: %d", &segsites );
+  if( segsites >= maxsites){
+	maxsites = segsites + 10 ;
+	posit = (double *)realloc( posit, maxsites*sizeof( double) ) ;
+        biggerlist(nsam,maxsites, list) ;
+        }
+   if( segsites > 0) {
+	fscanf(pfin," %s", astr);
+	for( i=0; i<segsites ; i++) fscanf(pfin," %lf",posit+i) ;
+	for( i=0; i<nsam;i++) fscanf(pfin," %s", list[i] );
+	}
+/* analyse sample ( do stuff with segsites and list) */
+	if( argc > 1 ) nsegsub = segsub( nadv, segsites, list) ;
+	pi = nucdiv(nsam, segsites, list) ;
+	h = hfay(nsam, segsites, list) ;
+	th = thetah(nsam, segsites, list) ;
+	if( argc > 1 )
+	printf("pi: %lf ss: %d  D: %lf H: %lf thetah: %lf segsub: %d \n", pi,segsites, tajd(nsam,segsites,pi) , h , th, nsegsub ) ;
+	else if( probflag == 1 ) 
+	  printf("pi:\t%lf\tss:\t%d\tD:\t%lf\tthetaH:\t%lf\tH:\t%lf\tprob:\t%g%s",
+	          pi,segsites, tajd(nsam,segsites,pi) , th , h, prob , slashline ) ;
+	else 
+	  printf("pi:\t%lf\tss:\t%d\tD:\t%lf\tthetaH:\t%lf\tH:\t%lf%s", pi,segsites, tajd(nsam,segsites,pi) , th , h,slashline  ) ;
+	
+
+  }
+}
+
+	
+
+/* allocates space for gametes (character strings) */
+	char **
+cmatrix(nsam,len)
+	int nsam, len;
+{
+	int i;
+	char **m;
+
+	if( ! ( m = (char **) malloc( (unsigned)( nsam*sizeof( char* )) ) ) )
+	   perror("alloc error in cmatrix") ;
+	for( i=0; i<nsam; i++) {
+		if( ! ( m[i] = (char *) malloc( (unsigned) (len*sizeof( char )) )))
+			perror("alloc error in cmatric. 2");
+		}
+	return( m );
+}
+
+        int
+biggerlist(nsam, nmax, list )
+        int nsam ;
+        unsigned nmax ;
+        char ** list ;
+{
+        int i;
+
+        maxsites = nmax  ;
+        for( i=0; i<nsam; i++){
+           list[i] = (char *)realloc( list[i],maxsites*sizeof(char) ) ;
+           if( list[i] == NULL ) perror( "realloc error. bigger");
+           }
+}                        
+
+
+	double
+nucdiv( int nsam, int segsites, char **list)
+{
+	int s, frequency( char, int, int, char**);
+	double pi, p1, nd, nnm1  ;
+
+	pi = 0.0 ;
+
+	nd = nsam;
+	nnm1 = nd/(nd-1.0) ;
+   	for( s = 0; s <segsites; s++){
+		p1 = frequency('1', s,nsam,list)/nd ;
+		pi += 2.0*p1*(1.0 -p1)*nnm1 ;
+		}
+	return( pi ) ;
+}
+
+/*   thetah - pi   */
+	double
+hfay( int nsam, int segsites, char **list)
+{
+	int s, frequency( char, int, int, char**);
+	double pi, p1, nd, nnm1  ;
+
+	pi = 0.0 ;
+
+	nd = nsam;
+	nnm1 = nd/(nd-1.0) ;
+   	for( s = 0; s <segsites; s++){
+		p1 = frequency('1', s,nsam,list)/nd ;
+		pi += 2.0*p1*(2.*p1 - 1.0 )*nnm1 ;
+		}
+	return( -pi ) ;
+}
+
+/* Fay's theta_H  */
+        double
+thetah( int nsam, int segsites, char **list)
+{
+        int s, frequency( char, int, int, char**);
+        double pi, p1, nd, nnm1  ;
+
+        pi = 0.0 ;
+
+        nd = nsam;
+        nnm1 = nd/(nd-1.0) ;
+        for( s = 0; s <segsites; s++){
+                p1 = frequency('1', s,nsam,list) ;
+                pi += p1*p1 ; 
+                }
+        return( pi*2.0/( nd*(nd-1.0) )  ) ;
+}
+
+
+        int
+frequency( char allele,int site,int nsam,  char **list)
+{
+        int i, count=0;
+        for( i=0; i<nsam; i++) count += ( list[i][site] == allele ? 1: 0 ) ;
+        return( count);
+}        
+
+	int
+segsub( int nsub, int segsites, char **list )
+{
+	int i, count = 0 , c1 ;
+	int frequency( char, int, int, char**) ;
+
+	for(i=0; i < segsites ; i++){
+	  c1 = frequency('1',i,nsub, list);
+	  if( ( c1 > 0 ) && ( c1 <nsub )  ) count++;
+	  }
+	return( count ) ;
+}
+	
diff --git a/tests/manualtests/pairwise_test.sh b/tests/manualtests/pairwise_test.sh
new file mode 100755
index 0000000..fc3dca6
--- /dev/null
+++ b/tests/manualtests/pairwise_test.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+## Need to review this again... is PSk the probability of observing k number of mutations? (Hein 2005 2.30, Wakeley 2008 4.3) when there is no recombination???
+msr=(0 10 100)
+msr=(0)
+rep=100000
+seqlen=100000
+nsam=2
+compareRECOMB=compareSEG-RECOMB
+
+t=10
+
+echo "rm(list=ls());
+pdf(\"pairwise_diff.pdf\");
+plot(c(0,50),c(0,0.1),type=\"n\")
+for (r in c(0,10,100)){
+	ms=read.table(paste(\"ms${nsam}sample\",r,\"rho${t}thetasegRecomb\",sep=\"\"));
+	scrm=read.table(paste(\"scrm${nsam}sample\",r,\"rho${t}thetasegRecomb\",sep=\"\"));
+	mstable=table(ms)
+	scrmtable=table(scrm)
+	points(as.numeric(names(mstable)), mstable/dim(ms)[1],pch=\".\",col=\"red\")
+	points(as.numeric(names(scrmtable)), scrmtable/dim(scrm)[1],pch=\".\",col=\"blue\")
+	}
+dev.off()
+" > dummy.r
+
+
+for r in "${msr[@]}"
+	do
+		prefix=${nsam}sample${r}rho${t}theta
+		out=${prefix}out
+		segrecomb=${prefix}segRecomb
+
+		ms ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} -T | tail -n +4 | grep -v "//" | grep "segsites" | sed -e "s/segsites: //" > ms${segrecomb}
+
+		scrm ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} | tail -n +4 | grep -v "//"  | grep "segsites" | sed -e "s/segsites: //" > scrm${segrecomb}
+
+	done
+	
+
+R CMD BATCH dummy.r
+
+	
+	
diff --git a/tests/manualtests/process_sample_stats.src b/tests/manualtests/process_sample_stats.src
new file mode 100644
index 0000000..b23238e
--- /dev/null
+++ b/tests/manualtests/process_sample_stats.src
@@ -0,0 +1,54 @@
+foo(){
+    #cut -f 2 mstime > mstmrca
+	#cut -f 2 scrmtime > scrmtmrca
+	echo "TMRCA" > figuretitle
+	R CMD BATCH tmrca.r
+
+    #cut -f 3 mstime > msbl
+	#cut -f 3 scrmtime > scrmbl
+	echo "BL" > figuretitle
+	R CMD BATCH bl.r
+
+	cut -f 6 ms_stats > msdata
+	cut -f 6 scrm_stats > scrmdata
+	echo "Tajima_D" > figuretitle
+	R CMD BATCH ks.r
+
+	cut -f 2 ms_stats > msdata
+	cut -f 2 scrm_stats > scrmdata
+	echo "Pairewise_difference" > figuretitle
+	R CMD BATCH ks.r
+
+	cut -f 8 ms_stats > msdata
+	cut -f 8 scrm_stats > scrmdata
+	echo "theta_H" > figuretitle
+	R CMD BATCH ks.r
+
+	cut -f 10 ms_stats > msdata
+	cut -f 10 scrm_stats > scrmdata
+	echo "H" > figuretitle
+	R CMD BATCH ks.r
+	}
+
+mstime(){
+    cat msout | gawk '/^\/\//{f="xx"++d} f{print > f} '
+    for file in $(seq 1 1 ${rep})
+        do 
+        grep ";" xx${file} | sed -e 's/\[.*\]//g' | tail -1 >> msTrees
+        done
+        hybrid-Lambda -gt msTrees -tmrca mstmrca
+        hybrid-Lambda -gt msTrees -bl msbl
+        find . -name "xx*" -print0 | xargs -0 rm    
+    }	
+	
+scrmtime(){
+    cat scrmout | gawk '/^\/\//{f="xx"++d} f{print > f} '
+    for file in $(seq 1 1 ${rep})
+        do 
+        grep ";" xx${file} | sed -e 's/\[.*\]//g' | tail -1 >> scrmTrees
+        done
+        hybrid-Lambda -gt scrmTrees -tmrca scrmtmrca
+        hybrid-Lambda -gt scrmTrees -bl scrmbl
+        find . -name "xx*" -print0 | xargs -0 rm    
+    }	
+		
diff --git a/tests/manualtests/pruning_test/compute_moment.py b/tests/manualtests/pruning_test/compute_moment.py
new file mode 100755
index 0000000..2809403
--- /dev/null
+++ b/tests/manualtests/pruning_test/compute_moment.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+import sys
+
+def extract_tmrca ( file_name ):
+    tmrca_file = open( file_name, "r")
+    tmrca = [ float(x) for x in tmrca_file.read().split() ]
+    tmrca_file.close()
+    return tmrca
+
+
+def compute_tmrca_moment( prefix , out ):
+    tmrca = extract_tmrca ( prefix+"Tmrca" )
+    duration = extract_tmrca ( prefix+"TreeFreq" )
+    seqlen = sum(duration)
+    
+    moment = []
+    for power in range (1, 5):
+        ith_moment = 0
+        for i, tmrca_i in enumerate( tmrca ):
+            ith_moment += tmrca_i**power * duration[i] / seqlen
+            
+        moment.append ( ith_moment )
+    outfile = open(out, "aw" )
+    outfile.write ( `moment`.strip("[").strip("]") + '\n' )
+    outfile.close()
+    
+    
+if __name__ == "__main__":
+    _in =  sys.argv[1] 
+    _out = sys.argv[2] 
+    compute_tmrca_moment( _in, _out)
+
diff --git a/tests/manualtests/pruning_test/grep_stats.sh b/tests/manualtests/pruning_test/grep_stats.sh
new file mode 100755
index 0000000..88e9946
--- /dev/null
+++ b/tests/manualtests/pruning_test/grep_stats.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N grep_stats
+#$ -j y
+source parameters
+
+echo ${replicate}
+#replicate=100
+#top_dir="./prune_test"
+
+
+foo(){
+    statfile=${job}_stat
+    rm ${statfile}
+    tmrca_momentFile=${job}_moment
+    rm ${tmrca_momentFile}
+    for i in $(seq 1 1 ${replicate})
+        do
+        prefix=${job}_${i}
+        dir=${top_dir}"/"${prefix}
+        if [ -d ${dir} ]
+            then
+            cat ${dir}"/"${prefix}stat >> ${statfile}
+            ./compute_moment.py ${dir}"/"${prefix} ${tmrca_momentFile}
+        fi
+        done
+
+}
+
+
+#job=ms
+#foo
+
+#job=scrm
+#foo
+
+#job=scrmprune50000
+#foo
+
+#job=scrmprune10000
+#foo
+
+job=scrmprune0
+foo
diff --git a/tests/manualtests/pruning_test/ms_sim.sh b/tests/manualtests/pruning_test/ms_sim.sh
new file mode 100755
index 0000000..d75ee9b
--- /dev/null
+++ b/tests/manualtests/pruning_test/ms_sim.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N ms 
+#$ -t 10001-20000
+#$ -j y
+
+source parameters
+
+#######################
+program=ms
+cmd=${cmd}
+#######################
+
+job=${program}_
+
+prefix=${job}${rep}
+mkdir ${top_dir}"/"${prefix}
+
+fileprefix=${top_dir}"/"${prefix}"/"${prefix}
+
+{ time -p ${program} ${cmd} > ${fileprefix} -seed ${rep} ${rep} ${rep} ;} 2> ${fileprefix}time.text
+
+tree_file_name=${fileprefix}"Trees"
+tree_freq_name=${fileprefix}"TreeFreq"
+tmrca_name=${fileprefix}"Tmrca"
+stat_file_name=${fileprefix}"stat"
+
+grep ';' ${fileprefix} | sed -e "s/\\[.*\\]//g" > ${tree_file_name}
+grep ";" ${fileprefix} | sed -e "s/\\[//g" | sed -e "s/\\].*;//g" > ${tree_freq_name}
+hybrid-Lambda -gt ${tree_file_name} -tmrca ${tmrca_name}
+
+cat ${fileprefix} | sample_stats > ${stat_file_name}
+rm ${fileprefix} ${tree_file_name}
+
diff --git a/tests/manualtests/pruning_test/parameters b/tests/manualtests/pruning_test/parameters
new file mode 100644
index 0000000..8ff5807
--- /dev/null
+++ b/tests/manualtests/pruning_test/parameters
@@ -0,0 +1,21 @@
+nsam=6
+rep=20000
+seqlen=10000001
+rho=4000
+mut=8000
+replicate=20000
+
+#toy trial...
+#rep=100
+#seqlen=1000001
+#rho=400
+#mut=800
+
+top_dir="/well/bsg/joezhu/prune_test"
+
+
+cmd="${nsam} 1 -T -t ${mut} -r ${rho} ${seqlen}"
+rep=$(expr $SGE_TASK_ID )
+
+#rep=10
+
diff --git a/tests/manualtests/pruning_test/printing_table.r b/tests/manualtests/pruning_test/printing_table.r
new file mode 100644
index 0000000..3b845ba
--- /dev/null
+++ b/tests/manualtests/pruning_test/printing_table.r
@@ -0,0 +1,41 @@
+rm(list=ls())
+library(matrixStats)
+
+ms_     = read.table( "ms_moment" ,         sep = ",") 
+scrm_   = read.table( "scrm_moment" ,       sep = ",") 
+scrm_p_ = read.table( "scrmprune_moment" , sep = ",") 
+
+meanMat = matrix(0,4,3)
+meanMat[,1]=colMeans(ms_)
+meanMat[,2]=colMeans(scrm_)
+meanMat[,3]=colMeans(scrm_p_)
+
+sdMat = matrix(0,4,3)
+sdMat[,1]=colSds(ms_)
+sdMat[,2]=colSds(scrm_)
+sdMat[,3]=colSds(scrm_p_)
+
+
+printmat = matrix(0,4,6)
+printmat[,1]=colMeans(ms_)
+printmat[,2]=colSds(ms_)
+printmat[,3]=colMeans(scrm_)
+printmat[,4]=colSds(scrm_)
+printmat[,5]=colMeans(scrm_p_)
+printmat[,6]=colSds(scrm_p_)
+print(format(printmat,digits=2))
+
+
+ms     = read.table( "ms_stat"   ) 
+scrm   = read.table( "scrm_stat" ) 
+scrm_p = read.table( "scrmprune_stat") 
+
+printmat2 = matrix(0, 5, 6)
+printmat2[,1]=colMeans(ms[,c(2,4,6,8,10)])
+printmat2[,2]=colSds(ms[,c(2,4,6,8,10)])
+printmat2[,3]=colMeans(scrm[,c(2,4,6,8,10)])
+printmat2[,4]=colSds(scrm[,c(2,4,6,8,10)])
+printmat2[,5]=colMeans(scrm_p[,c(2,4,6,8,10)])
+printmat2[,6]=colSds(scrm_p[,c(2,4,6,8,10)])
+
+print(format(printmat2,digits=3))
diff --git a/tests/manualtests/pruning_test/prune_test_top_script.sh b/tests/manualtests/pruning_test/prune_test_top_script.sh
new file mode 100755
index 0000000..116d464
--- /dev/null
+++ b/tests/manualtests/pruning_test/prune_test_top_script.sh
@@ -0,0 +1,270 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N ms 
+#$ -t 1-1000
+#$ -j y
+
+
+
+foo(){
+    #cut -f 2 mstime > mstmrca
+	#cut -f 2 scrmtime > scrmtmrca
+	echo "TMRCA" > figuretitle
+	R CMD BATCH tmrca.r
+
+    #cut -f 3 mstime > msbl
+	#cut -f 3 scrmtime > scrmbl
+	echo "BL" > figuretitle
+	R CMD BATCH bl.r
+
+	cut -f 6 ms_stats > msdata
+	cut -f 6 scrm_stats > scrmdata
+	echo "Tajima_D" > figuretitle
+	R CMD BATCH ks.r
+
+	cut -f 2 ms_stats > msdata
+	cut -f 2 scrm_stats > scrmdata
+	echo "Pairewise_difference" > figuretitle
+	R CMD BATCH chisq.r
+
+	cut -f 8 ms_stats > msdata
+	cut -f 8 scrm_stats > scrmdata
+	echo "theta_H" > figuretitle
+	R CMD BATCH chisq.r
+
+	cut -f 10 ms_stats > msdata
+	cut -f 10 scrm_stats > scrmdata
+	echo "H" > figuretitle
+	R CMD BATCH chisq.r
+	}
+
+#Compare summary statistics of ms and scrm for TMRCA with recombination events
+mkdir test-tmrca-prune-recomb
+cd test-tmrca-prune-recomb
+
+
+		echo "rm(list=ls());
+		#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+msdata=read.table(paste(\"ms\",\"data\",sep=\"\"))\$V1;
+scrmdata=read.table(paste(\"scrm\",\"data\",sep=\"\"))\$V1;
+		#ee=ee_seg(${nsam},${t});
+		#sdv=sd_seg_norecomb(${nsam},${t});
+		datamax=max(msdata,scrmdata);
+		mstable=table(factor(msdata,levels=1:datamax))
+		scrmtable=table(factor(scrmdata,levels=1:datamax))
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(as.numeric(names(mstable)), mstable/length(msdata),pch=16,col=\"red\",ylab=\"Frequency\",xlab=figuretitle);
+points(as.numeric(names(scrmtable)), scrmtable/length(scrmdata),pch=16,col=\"blue\")
+
+ms_newtable=table(msdata);
+scrm_mstable=table(factor(scrmdata,levels=names(table(msdata))));
+combined_scrm_ms_test=chisq.test(cbind(scrm_mstable, ms_newtable));
+
+scrm_newtable=table(scrmdata);
+ms_scrmtable=table(factor(msdata,levels=names(table(scrmdata))));
+combined_ms_scrm_test=chisq.test(cbind(scrm_newtable, ms_scrmtable));
+
+legend(\"topright\",c(paste(\"Test 1 Statistics = \",combined_scrm_ms_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_scrm_ms_test\$p.value,digits=4),sep=\"\"),paste(\"Test 2 Statistics = \",combined_ms_scrm_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_ms_scrm_test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+
+dev.off();
+
+#cat(paste(${nsam},${t},\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+cat(paste(currentcase, figuretitle , \"\n\",\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"||\",
+format(combined_scrm_ms_test\$statistic,digits=4),format(combined_scrm_ms_test\$p.value,scientific = TRUE),\"||\",
+format(combined_ms_scrm_test\$statistic,digits=4),format(combined_ms_scrm_test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareMIG}\",append=TRUE);cat(\"\n\",file=\"${compareMIG}\",append=TRUE);
+" > chisq.r
+
+echo "rm(list=ls());
+#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+msdata=read.table(paste(\"ms\",\"data\",sep=\"\"))\$V1;
+scrmdata=read.table(paste(\"scrm\",\"data\",sep=\"\"))\$V1;
+#ee=1#ee_tmrca(${nsam});
+#sdv=1#sd_tmrca(${nsam});
+test=ks.test(msdata,scrmdata)
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(ecdf(msdata), xlim=range(c(msdata, scrmdata)),col=\"red\", main=currentcase)
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+#cat(paste(currentcase,\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+cat(paste(currentcase, figuretitle , \"\n\",\"|\",
+format(mean(msdata),scientific = TRUE),format(sd(msdata),scientific = TRUE),\"||\",
+format(mean(scrmdata),scientific = TRUE),format(sd(scrmdata),scientific = TRUE),\"|\",format(test\$statistic,scientific = TRUE),format(test\$p.value,scientific = TRUE), 
+sep=\"\t\"),file=\"${compareMIG}\",append=TRUE);cat(\"\n\",file=\"${compareMIG}\",append=TRUE);" > ks.r
+
+
+
+echo -e "rm(list=ls());
+for (i in (1:${rep})){
+	p=read.table(paste(\"xx\",i,\"Trees_freq\",sep=\"\"))\$V1/${seqlen}; 
+	T=read.table(paste(\"xx\",i,\"Trees_tmrca\",sep=\"\")); 
+	bl=read.table(paste(\"xx\",i,\"Trees_bl\",sep=\"\")); 
+	cat(paste(sum(T*p),sum(T^2*p),sum(T^3*p),sum(T^4*p),sep=\"\t\") ,file=\"tmrca_moments\",append=TRUE);
+	cat(\"\n\",file=\"tmrca_moments\",append=TRUE);
+	cat(paste(sum(bl*p),sum(bl^2*p),sum(bl^3*p),sum(bl^4*p),sep=\"\t\") ,file=\"bl_moments\",append=TRUE);
+	cat(\"\n\",file=\"bl_moments\",append=TRUE);
+	}" > compute_moments.r
+
+msNsample=(7 10 20)
+msr=(10 20 50 100)
+#mst=(10 20 50 100 10)
+
+#msNsample=(3)
+#msr=(10)
+#mst=(10)
+
+
+## compare TMRCA
+compareTMRCA=compareTMRCA-RECOMB
+rm ${compareTMRCA}
+
+## compare total branch length
+compareBL=compareBL-RECOMB
+rm ${compareBL}
+
+rm *pdf
+#theta=10
+echo -e "compare TMRCA for ${rep} replicates \n\t\t|\t1st\t\t\t|\t2nd\t\t\t|\t3rd\t\t\t|\t4th\t\t\t
+\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" > ${compareTMRCA}
+
+echo -e "compare total branch length for ${rep} replicates \n\t\t|\t1st\t\t\t|\t2nd\t\t\t|\t3rd\t\t\t|\t4th\t\t\t
+\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" > ${compareBL}
+rm tmrca_moments
+rm bl_moments
+
+
+for r in "${msr[@]}"
+    do
+    for nsam in "${msNsample[@]}"
+        do
+        rm ms_tmrca_moments
+        rm scrm_tmrca_moments
+        
+        rm ms_bl_moments
+        rm scrm_bl_moments
+        
+        prefix=${nsam}sample${r}rho
+        out=${prefix}out
+        segrecomb=${prefix}segRecomb
+
+        ms ${nsam} ${rep} -r ${r} ${seqlen} -T | tail -n +4 | gawk '/^\/\//{f="xx"++d} f{print > f} '
+        for file in $(seq 1 1 ${rep})
+            do 
+            grep ";" xx${file} | sed -e 's/\[.*\]//g' > xxTrees
+            hybrid-Lambda -gt xxTrees -tmrca xx${file}Trees_tmrca
+            hybrid-Lambda -gt xxTrees -bl xx${file}Trees_bl
+            grep ";" xx${file} | sed -e 's/\[//g' -e 's/\].*;//g' > xx${file}Trees_freq
+
+            done
+            R CMD BATCH compute_moments.r
+            find . -name "xx*" -print0 | xargs -0 rm
+            mv tmrca_moments ms_tmrca_moments
+            mv bl_moments ms_bl_moments
+            
+            
+        scrm ${nsam} ${rep} -r ${r} ${seqlen} -T -l 10000 | tail -n +4 | gawk '/^\/\//{f="xx"++d} f{print > f} '
+        for file in $(seq 1 1 ${rep})
+            do 
+            grep ";" xx${file} | sed -e 's/\[.*\]//g' > xxTrees
+            hybrid-Lambda -gt xxTrees -tmrca xx${file}Trees_tmrca
+            hybrid-Lambda -gt xxTrees -bl xx${file}Trees_bl
+            grep ";" xx${file} | sed -e 's/\[//g' -e 's/\].*;//g' > xx${file}Trees_freq
+
+            done
+            R CMD BATCH compute_moments.r
+            find . -name "xx*" -print0 | xargs -0 rm
+            mv tmrca_moments scrm_tmrca_moments
+            mv bl_moments scrm_bl_moments
+
+            echo "rm(list=ls());
+msdata=read.table(\"ms_tmrca_moments\");
+scrmdata=read.table(\"scrm_tmrca_moments\");
+m1test=ks.test(msdata\$V1,scrmdata\$V1)
+m2test=ks.test(msdata\$V2,scrmdata\$V2)
+m3test=ks.test(msdata\$V3,scrmdata\$V3)
+m4test=ks.test(msdata\$V4,scrmdata\$V4)
+pdf(paste($nsam,\"sampleTMRCA\",\"recomb\",${r},\"-KStest.pdf\",sep=\"\"));
+par(mfrow=c(2,2))
+plot(ecdf(msdata\$V1), xlim=range(c(msdata\$V1, scrmdata\$V1)),col=\"red\", main=\"1st Moment\")
+plot(ecdf(scrmdata\$V1), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m1test\$statistic,sep=\"\"), paste(\"p-value = \",format(m1test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V2), xlim=range(c(msdata\$V2, scrmdata\$V2)),col=\"red\", main=\"2nd Moment\")
+plot(ecdf(scrmdata\$V2), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m2test\$statistic,sep=\"\"), paste(\"p-value = \",format(m2test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V3), xlim=range(c(msdata\$V3, scrmdata\$V3)),col=\"red\", main=\"3rd Moment\")
+plot(ecdf(scrmdata\$V3), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m3test\$statistic,sep=\"\"), paste(\"p-value = \",format(m3test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V4), xlim=range(c(msdata\$V4, scrmdata\$V4)),col=\"red\", main=\"4th Moment\")
+plot(ecdf(scrmdata\$V4), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m4test\$statistic,sep=\"\"), paste(\"p-value = \",format(m4test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+dev.off();
+cat(paste(${nsam},${r},\"|\",
+format(m1test\$statistic,digits=4),format(m1test\$p.value,scientific = TRUE),\"|\",
+format(m2test\$statistic,digits=4),format(m2test\$p.value,scientific = TRUE),\"|\",
+format(m3test\$statistic,digits=4),format(m3test\$p.value,scientific = TRUE),\"|\",
+format(m4test\$statistic,digits=4),format(m4test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareTMRCA}\",append=TRUE);cat(\"\n\",file=\"${compareTMRCA}\",append=TRUE);
+
+rm(list=ls());
+msdata=read.table(\"ms_bl_moments\");
+scrmdata=read.table(\"scrm_bl_moments\");
+m1test=ks.test(msdata\$V1,scrmdata\$V1)
+m2test=ks.test(msdata\$V2,scrmdata\$V2)
+m3test=ks.test(msdata\$V3,scrmdata\$V3)
+m4test=ks.test(msdata\$V4,scrmdata\$V4)
+pdf(paste($nsam,\"sampleBLmut\",\"recomb\",${r},\"-KStest.pdf\",sep=\"\"));
+par(mfrow=c(2,2))
+plot(ecdf(msdata\$V1), xlim=range(c(msdata\$V1, scrmdata\$V1)),col=\"red\", main=\"1st Moment\")
+plot(ecdf(scrmdata\$V1), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m1test\$statistic,sep=\"\"), paste(\"p-value = \",format(m1test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V2), xlim=range(c(msdata\$V2, scrmdata\$V2)),col=\"red\", main=\"2nd Moment\")
+plot(ecdf(scrmdata\$V2), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m2test\$statistic,sep=\"\"), paste(\"p-value = \",format(m2test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V3), xlim=range(c(msdata\$V3, scrmdata\$V3)),col=\"red\", main=\"3rd Moment\")
+plot(ecdf(scrmdata\$V3), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m3test\$statistic,sep=\"\"), paste(\"p-value = \",format(m3test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V4), xlim=range(c(msdata\$V4, scrmdata\$V4)),col=\"red\", main=\"4th Moment\")
+plot(ecdf(scrmdata\$V4), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m4test\$statistic,sep=\"\"), paste(\"p-value = \",format(m4test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+dev.off();
+cat(paste(${nsam},${r},\"|\",
+format(m1test\$statistic,digits=4),format(m1test\$p.value,scientific = TRUE),\"|\",
+format(m2test\$statistic,digits=4),format(m2test\$p.value,scientific = TRUE),\"|\",
+format(m3test\$statistic,digits=4),format(m3test\$p.value,scientific = TRUE),\"|\",
+format(m4test\$statistic,digits=4),format(m4test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareBL}\",append=TRUE);cat(\"\n\",file=\"${compareBL}\",append=TRUE);
+" > dummy.r
+    R CMD BATCH dummy.r
+        done
+    done
+	
+	
diff --git a/tests/manualtests/pruning_test/r_tests.r b/tests/manualtests/pruning_test/r_tests.r
new file mode 100644
index 0000000..1125bf4
--- /dev/null
+++ b/tests/manualtests/pruning_test/r_tests.r
@@ -0,0 +1,118 @@
+rm(list=ls())
+library(dgof) # overwrite ks.test() function, allow discrete case. However, it does not make any difference in our case.
+tmrca_moment <- function ( ms, scrm, s10000, s50000){
+    ms_scrm_test = list ( ks.test( ms$V1, scrm$V1 ),
+                          ks.test( ms$V2, scrm$V2 ),
+                          ks.test( ms$V3, scrm$V3 ),
+                          ks.test( ms$V4, scrm$V4 ) )
+    
+    ms_s10000_test = list ( ks.test( ms$V1, s10000$V1 ),
+                           ks.test( ms$V2, s10000$V2 ),
+                           ks.test( ms$V3, s10000$V3 ),
+                           ks.test( ms$V4, s10000$V4 ) )    
+    
+    ms_s50000_test = list (ks.test( ms$V1, s50000$V1 ),
+                           ks.test( ms$V2, s50000$V2 ),
+                           ks.test( ms$V3, s50000$V3 ),
+                           ks.test( ms$V4, s50000$V4 ) )
+
+    titles = c("1st", "2nd", "3rd", "4th")
+    
+    pdf ( "TMRCA_moment_KStest.pdf" )
+    par(mfrow=c(2,2))
+    for ( i in c(1:4) ) {
+        ms_i    = ms[,i]
+        scrm_i  = scrm[,i]
+        scrm_p1 = s10000[,i]
+        scrm_p5 = s50000[,i]
+
+        xrange = range ( c(ms_i, scrm_i, scrm_p1, scrm_p5) )
+
+        plot( ecdf(ms_i), xlim = xrange, col="red", main = paste( titles[i], "Moment" ) )
+        plot( ecdf(scrm_i), add=TRUE, lty="dashed", col="blue")
+        plot( ecdf(scrm_p1), add=TRUE, lty="dashed", col="green")
+        plot( ecdf(scrm_p5), add=TRUE, lty="dashed", col="black")
+
+	legend( "bottomright", c( paste( "p-value = ",      format(ms_scrm_test[[i]]$p.value,   digits = 2), sep = ""),
+				  paste( "p-value = ",      format(ms_s50000_test[[i]]$p.value, digits = 2), sep = ""),
+                                  paste( "p-value = ",      format(ms_s10000_test[[i]]$p.value, digits = 2), sep = "") ) , 
+				col=c("blue", "black", "green"), pch = 16)
+        legend( "topleft" , c( "window 10000 ", "window 50000",  "scrm exact", "ms"), col=c( "green", "black", "blue", "red" ), pch=16)
+    }
+    dev.off()
+}
+
+ms_     = read.table( "ms_moment" ,  colClasses = "numeric",    sep = ",") 
+scrm_   = read.table( "scrm_moment" , colClasses = "numeric",   sep = ",") 
+#scrm_p0   = read.table( "scrmprune0_moment" , colClasses = "numeric",   sep = ",") 
+scrm_p10000_ = read.table( "scrmprune10000_moment" ,colClasses = "numeric",  sep = ",") 
+scrm_p50000_ = read.table( "scrmprune50000_moment" ,colClasses = "numeric",  sep = ",")
+
+tmrca_moment ( ms_, scrm_, scrm_p10000_, scrm_p50000_)
+
+#cat(paste(${nsam},${r},\"|\",
+#format(m1test\$statistic,digits=4),format(m1test\$p.value,scientific = TRUE),\"|\",
+#format(m2test\$statistic,digits=4),format(m2test\$p.value,scientific = TRUE),\"|\",
+#format(m3test\$statistic,digits=4),format(m3test\$p.value,scientific = TRUE),\"|\",
+#format(m4test\$statistic,digits=4),format(m4test\$p.value,scientific = TRUE),
+#sep=\"\t\"),file=\"${compareTMRCA}\",append=TRUE);cat(\"\n\",file=\"${compareTMRCA}\",append=TRUE);
+
+rm( list=ls() )
+
+continuous <- function (ms, scrm, scrm_p10000, scrm_p50000, title_i){
+    test1 = ks.test( ms, scrm )
+    test2 = ks.test( ms, scrm_p50000)
+    test3 = ks.test( ms, scrm_p10000)
+    xrange = range ( c(ms, scrm, scrm_p10000, scrm_p50000) )
+    pdf ( paste( title_i,".pdf", sep = "" ) )
+    plot( ecdf(ms), xlim = xrange, col="red", main = paste( title_i ) , xlab = title_i)
+    plot( ecdf(scrm), add=TRUE, lty="dashed", col="blue")
+    plot( ecdf(scrm_p10000), add=TRUE, lty="dashed", col="green")
+    plot( ecdf(scrm_p50000), add=TRUE, lty="dashed", col="black")
+    legend( "topleft" , c( "window 10000", "window 50000", "scrm", "ms"), col=c( "green", "black",  "blue", "red" ), pch=16)
+    legend( "bottomright", c( paste( "p-value = ",      format(test1$p.value,   digits = 2), sep = ""),
+                              paste( "p-value = ",      format(test2$p.value,   digits = 2), sep = ""),
+			      paste( "p-value = ",      format(test3$p.value,   digits = 2), sep = "")  ),
+				col=c("blue", "black", "green"), pch=16 )
+
+    dev.off()
+}
+
+discrete <- function (ms, scrm, scrm_p10000, scrm_p50000, title_i){
+    test1 = ks.test( ms, scrm )
+    test2 = ks.test( ms, scrm_p50000)
+    test3 = ks.test( ms, scrm_p10000)
+    xrange = range ( c(ms, scrm, scrm_p10000, scrm_p50000) )
+    pdf ( paste( title_i,".pdf", sep = "" ) )
+    plot( ecdf(ms), xlim = xrange, col="red", main = paste( title_i ) , xlab = title_i)
+    plot( ecdf(scrm), add=TRUE, lty="dashed", col="blue")
+    plot( ecdf(scrm_p10000), add=TRUE, lty="dashed", col="green")
+    plot( ecdf(scrm_p50000), add=TRUE, lty="dashed", col="black")
+    legend( "topleft" , c( "window 10000", "window 50000", "scrm", "ms"), col=c( "green", "black",  "blue", "red" ), pch=16)
+    legend( "bottomright", c( paste( "p-value = ",      format(test1$p.value,   digits = 2), sep = ""),
+                              paste( "p-value = ",      format(test2$p.value,   digits = 2), sep = ""),
+			      paste( "p-value = ",      format(test3$p.value,   digits = 2), sep = "")  ),
+				col=c("blue", "black", "green"), pch=16 )
+
+    dev.off()
+}
+
+#ms     = read.table( "ms_stat"   ) 
+#scrm   = read.table( "scrm_stat" ) 
+#scrm_p = read.table( "scrmprune_stat") 
+
+ms_     = read.table( "ms_stat")
+scrm_   = read.table( "scrm_stat")
+scrm_p0_ = read.table( "scrmprune0_stat")
+#scrm_=scrm_p0_
+scrm_p10000_ = read.table( "scrmprune10000_stat")
+scrm_p50000_ = read.table( "scrmprune50000_stat")
+
+discrete ( ms_$V2, scrm_$V2, scrm_p10000_$V2, scrm_p50000_$V2, "Pairwise_difference")
+discrete ( ms_$V4, scrm_$V4, scrm_p10000_$V4, scrm_p50000_$V4, "ss")
+
+#continuous ( ms_$V2, scrm_$V2, scrm_p10000_$V2, scrm_p50000_$V2, "Pairwise_difference")
+#continuous ( ms_$V4, scrm_$V4, scrm_p10000_$V4, scrm_p50000_$V4, "ss")
+continuous ( ms_$V6, scrm_$V6, scrm_p10000_$V6, scrm_p50000_$V6, "TajimaD")
+continuous ( ms_$V8, scrm_$V8, scrm_p10000_$V8, scrm_p50000_$V8, "ThetaH")
+continuous ( ms_$V10, scrm_$V10, scrm_p10000_$V10, scrm_p50000_$V10, "H")
diff --git a/tests/manualtests/pruning_test/scrm_sim.sh b/tests/manualtests/pruning_test/scrm_sim.sh
new file mode 100755
index 0000000..81df2f8
--- /dev/null
+++ b/tests/manualtests/pruning_test/scrm_sim.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrm 
+#$ -t 10001-20000
+#$ -j y
+
+source parameters
+
+#######################
+program=scrm
+cmd=${cmd}
+#######################
+
+job=${program}_
+
+prefix=${job}${rep}
+mkdir ${top_dir}"/"${prefix}
+
+fileprefix=${top_dir}"/"${prefix}"/"${prefix}
+
+{ time -p ${program} ${cmd} > ${fileprefix} -seed ${rep} ;} 2> ${fileprefix}time.text
+
+tree_file_name=${fileprefix}"Trees"
+tree_freq_name=${fileprefix}"TreeFreq"
+tmrca_name=${fileprefix}"Tmrca"
+stat_file_name=${fileprefix}"stat"
+
+grep ';' ${fileprefix} | sed -e "s/\\[.*\\]//g" > ${tree_file_name}
+grep ";" ${fileprefix} | sed -e "s/\\[//g" | sed -e "s/\\].*;//g" > ${tree_freq_name}
+hybrid-Lambda -gt ${tree_file_name} -tmrca ${tmrca_name}
+
+cat ${fileprefix} | sample_stats > ${stat_file_name}
+rm ${fileprefix} ${tree_file_name}
+
diff --git a/tests/manualtests/pruning_test/scrmfull_prune_sim.sh b/tests/manualtests/pruning_test/scrmfull_prune_sim.sh
new file mode 100755
index 0000000..33a314c
--- /dev/null
+++ b/tests/manualtests/pruning_test/scrmfull_prune_sim.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrmfullprune
+#$ -t 1-20000
+#$ -j y
+
+source parameters
+
+#######################
+program=scrm
+cmd="${cmd} -l 0"
+#######################
+
+job=${program}prune0_
+
+prefix=${job}${rep}
+mkdir ${top_dir}"/"${prefix}
+
+fileprefix=${top_dir}"/"${prefix}"/"${prefix}
+
+{ time -p ${program} ${cmd} > ${fileprefix} -seed ${rep} ;} 2> ${fileprefix}time.text
+
+tree_file_name=${fileprefix}"Trees"
+tree_freq_name=${fileprefix}"TreeFreq"
+tmrca_name=${fileprefix}"Tmrca"
+stat_file_name=${fileprefix}"stat"
+
+grep ';' ${fileprefix} | sed -e "s/\\[.*\\]//g" > ${tree_file_name}
+grep ";" ${fileprefix} | sed -e "s/\\[//g" | sed -e "s/\\].*;//g" > ${tree_freq_name}
+hybrid-Lambda -gt ${tree_file_name} -tmrca ${tmrca_name}
+
+cat ${fileprefix} | sample_stats > ${stat_file_name}
+rm ${fileprefix} ${tree_file_name}
+
diff --git a/tests/manualtests/pruning_test/scrmprune10000_sim.sh b/tests/manualtests/pruning_test/scrmprune10000_sim.sh
new file mode 100755
index 0000000..77bd88f
--- /dev/null
+++ b/tests/manualtests/pruning_test/scrmprune10000_sim.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrmprune10000 
+#$ -t 1-20000
+#$ -j y
+
+source parameters
+
+#######################
+program=scrm
+cmd="${cmd} -l 10000"
+#######################
+
+job=${program}prune10000_
+
+prefix=${job}${rep}
+mkdir ${top_dir}"/"${prefix}
+
+fileprefix=${top_dir}"/"${prefix}"/"${prefix}
+
+{ time -p ${program} ${cmd} > ${fileprefix} -seed ${rep} ;} 2> ${fileprefix}time.text
+
+tree_file_name=${fileprefix}"Trees"
+tree_freq_name=${fileprefix}"TreeFreq"
+tmrca_name=${fileprefix}"Tmrca"
+stat_file_name=${fileprefix}"stat"
+
+grep ';' ${fileprefix} | sed -e "s/\\[.*\\]//g" > ${tree_file_name}
+grep ";" ${fileprefix} | sed -e "s/\\[//g" | sed -e "s/\\].*;//g" > ${tree_freq_name}
+hybrid-Lambda -gt ${tree_file_name} -tmrca ${tmrca_name}
+
+cat ${fileprefix} | sample_stats > ${stat_file_name}
+rm ${fileprefix} ${tree_file_name}
+
diff --git a/tests/manualtests/pruning_test/scrmprune50000_sim.sh b/tests/manualtests/pruning_test/scrmprune50000_sim.sh
new file mode 100755
index 0000000..e742b55
--- /dev/null
+++ b/tests/manualtests/pruning_test/scrmprune50000_sim.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+#$ -cwd
+#$ -V
+#$ -P bsg.prjb -q short.qb
+#$ -e ErrFiles
+#$ -o OutFiles
+#$ -N scrmprune50000 
+#$ -t 1-20000
+#$ -j y
+
+source parameters
+
+#######################
+program=scrm
+cmd="${cmd} -l 50000"
+#######################
+
+job=${program}prune50000_
+
+prefix=${job}${rep}
+mkdir ${top_dir}"/"${prefix}
+
+fileprefix=${top_dir}"/"${prefix}"/"${prefix}
+
+{ time -p ${program} ${cmd} > ${fileprefix} -seed ${rep} ;} 2> ${fileprefix}time.text
+
+tree_file_name=${fileprefix}"Trees"
+tree_freq_name=${fileprefix}"TreeFreq"
+tmrca_name=${fileprefix}"Tmrca"
+stat_file_name=${fileprefix}"stat"
+
+grep ';' ${fileprefix} | sed -e "s/\\[.*\\]//g" > ${tree_file_name}
+grep ";" ${fileprefix} | sed -e "s/\\[//g" | sed -e "s/\\].*;//g" > ${tree_freq_name}
+hybrid-Lambda -gt ${tree_file_name} -tmrca ${tmrca_name}
+
+cat ${fileprefix} | sample_stats > ${stat_file_name}
+rm ${fileprefix} ${tree_file_name}
+
diff --git a/tests/manualtests/pruning_test/test.sh b/tests/manualtests/pruning_test/test.sh
new file mode 100755
index 0000000..e25ece6
--- /dev/null
+++ b/tests/manualtests/pruning_test/test.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+source test_param
+echo "rho is ${rho}"
diff --git a/tests/manualtests/scrm_first_vs_last.sh b/tests/manualtests/scrm_first_vs_last.sh
new file mode 100755
index 0000000..52e15eb
--- /dev/null
+++ b/tests/manualtests/scrm_first_vs_last.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+#Compare summary statistics of scrm simulation for the initial genealogy and the final genealogy for TMRCA with recombination events
+
+mkdir test-scrm-first_vs_last
+cd test-scrm-first_vs_last
+rm *pdf
+
+compareFirstLast=compareFirstLast
+rm ${compareFirstLast}
+
+
+echo "rm(list=ls());
+currentcase=scan(\"current_case\",what=\"\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+
+firstdata=read.table(\"scrmfirsttmrca\")\$V1;
+lastdata=read.table(\"scrmlasttmrca\")\$V1;
+test=ks.test(firstdata,lastdata)
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(ecdf(firstdata), xlim=range(c(firstdata, lastdata)),col=\"red\", main=currentcase)
+plot(ecdf(lastdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"first\",\"last\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+cat(paste(currentcase,figuretitle,\"|\",
+format(mean(firstdata),digits=4),format(sd(firstdata),digits=4),\"|\",
+format(mean(lastdata),digits=4),format(sd(lastdata),digits=4),\"|\",test\$statistic,format(test\$p.value,digits=4), 
+sep=\"\t\"),file=\"${compareFirstLast}\",append=TRUE);cat(\"\n\",file=\"${compareFirstLast}\",append=TRUE);" > tmrca.r
+
+seqlen=100000
+
+rep=100000
+
+scrmNsample=(2 4 6)
+scrmr=(10 20)
+scrmt=(10 5)
+
+rm current_case scrm* figuretitle
+for t in "${scrmt[@]}"
+	do
+	for r in "${scrmr[@]}"
+		do
+		for nsam in "${scrmNsample[@]}"
+			do
+			rm current_case scrm*Trees scrm*tmrca figuretitle
+			prefix=scrm${nsam}sample${r}rho${t}theta
+			echo ${prefix} > current_case
+			cat current_case
+
+			scrm ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} -T | tail -n +4 | gawk '/^\/\//{f="xx"++d} f{print > f} '
+			for file in $(seq 1 1 ${rep})
+				do 
+				grep ";" xx${file} | sed -e 's/\[.*\]//g' | head -1 >> scrmfirstTrees
+				grep ";" xx${file} | sed -e 's/\[.*\]//g' | tail -1 >> scrmlastTrees
+				done
+			find . -name "xx*" -print0 | xargs -0 rm
+
+			hybrid-Lambda -gt scrmfirstTrees -tmrca scrmfirsttmrca
+			hybrid-Lambda -gt scrmlastTrees -tmrca scrmlasttmrca
+			echo "TMRCA" > figuretitle
+			R CMD BATCH tmrca.r
+			rm scrm*tmrca
+			hybrid-Lambda -gt scrmfirstTrees -bl scrmfirsttmrca
+			hybrid-Lambda -gt scrmlastTrees -bl scrmlasttmrca
+			echo "BL" > figuretitle
+			R CMD BATCH tmrca.r
+			
+			done
+		done
+	done
diff --git a/tests/manualtests/scrm_prune_vs_ms.sh b/tests/manualtests/scrm_prune_vs_ms.sh
new file mode 100755
index 0000000..905aa49
--- /dev/null
+++ b/tests/manualtests/scrm_prune_vs_ms.sh
@@ -0,0 +1,173 @@
+#!/bin/bash
+
+#Compare summary statistics of ms and scrm for TMRCA with recombination events
+mkdir newtest-tmrca-prune-recomb
+cd newtest-tmrca-prune-recomb
+
+
+seqlen=10000001
+
+rep=10000
+
+
+echo -e "rm(list=ls());
+for (i in (1:${rep})){
+	p=read.table(paste(\"xx\",i,\"Trees_freq\",sep=\"\"))\$V1/${seqlen}; 
+	T=read.table(paste(\"xx\",i,\"Trees_tmrca\",sep=\"\")); 
+	bl=read.table(paste(\"xx\",i,\"Trees_bl\",sep=\"\")); 
+	cat(paste(sum(T*p),sum(T^2*p),sum(T^3*p),sum(T^4*p),sep=\"\t\") ,file=\"tmrca_moments\",append=TRUE);
+	cat(\"\n\",file=\"tmrca_moments\",append=TRUE);
+	cat(paste(sum(bl*p),sum(bl^2*p),sum(bl^3*p),sum(bl^4*p),sep=\"\t\") ,file=\"bl_moments\",append=TRUE);
+	cat(\"\n\",file=\"bl_moments\",append=TRUE);
+	}" > compute_moments.r
+
+msNsample=(6)
+msr=(4000)
+#mst=(10 20 50 100 10)
+
+#msNsample=(3)
+#msr=(10)
+#mst=(10)
+
+
+## compare TMRCA
+compareTMRCA=compareTMRCA-RECOMB
+rm ${compareTMRCA}
+
+## compare total branch length
+compareBL=compareBL-RECOMB
+rm ${compareBL}
+
+rm *pdf
+#theta=10
+echo -e "compare TMRCA for ${rep} replicates \n\t\t|\t1st\t\t\t|\t2nd\t\t\t|\t3rd\t\t\t|\t4th\t\t\t
+\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" > ${compareTMRCA}
+
+echo -e "compare total branch length for ${rep} replicates \n\t\t|\t1st\t\t\t|\t2nd\t\t\t|\t3rd\t\t\t|\t4th\t\t\t
+\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t|\tstats\tp-value\t\t" > ${compareBL}
+rm tmrca_moments
+rm bl_moments
+
+
+for r in "${msr[@]}"
+    do
+    for nsam in "${msNsample[@]}"
+        do
+        rm ms_tmrca_moments
+        rm scrm_tmrca_moments
+        
+        rm ms_bl_moments
+        rm scrm_bl_moments
+        
+        prefix=${nsam}sample${r}rho
+        out=${prefix}out
+        segrecomb=${prefix}segRecomb
+
+        ms ${nsam} ${rep} -r ${r} ${seqlen} -T | tail -n +4 | gawk '/^\/\//{f="xx"++d} f{print > f} '
+        for file in $(seq 1 1 ${rep})
+            do 
+            grep ";" xx${file} | sed -e 's/\[.*\]//g' > xxTrees
+            hybrid-Lambda -gt xxTrees -tmrca xx${file}Trees_tmrca
+            hybrid-Lambda -gt xxTrees -bl xx${file}Trees_bl
+            grep ";" xx${file} | sed -e 's/\[//g' -e 's/\].*;//g' > xx${file}Trees_freq
+
+            done
+            R CMD BATCH compute_moments.r
+            find . -name "xx*" -print0 | xargs -0 rm
+            mv tmrca_moments ms_tmrca_moments
+            mv bl_moments ms_bl_moments
+            
+            
+        scrm ${nsam} ${rep} -r ${r} ${seqlen} -T -l 100000 | tail -n +4 | gawk '/^\/\//{f="xx"++d} f{print > f} '
+        for file in $(seq 1 1 ${rep})
+            do 
+            grep ";" xx${file} | sed -e 's/\[.*\]//g' > xxTrees
+            hybrid-Lambda -gt xxTrees -tmrca xx${file}Trees_tmrca
+            hybrid-Lambda -gt xxTrees -bl xx${file}Trees_bl
+            grep ";" xx${file} | sed -e 's/\[//g' -e 's/\].*;//g' > xx${file}Trees_freq
+
+            done
+            R CMD BATCH compute_moments.r
+            find . -name "xx*" -print0 | xargs -0 rm
+            mv tmrca_moments scrm_tmrca_moments
+            mv bl_moments scrm_bl_moments
+
+            echo "rm(list=ls());
+msdata=read.table(\"ms_tmrca_moments\");
+scrmdata=read.table(\"scrm_tmrca_moments\");
+m1test=ks.test(msdata\$V1,scrmdata\$V1)
+m2test=ks.test(msdata\$V2,scrmdata\$V2)
+m3test=ks.test(msdata\$V3,scrmdata\$V3)
+m4test=ks.test(msdata\$V4,scrmdata\$V4)
+pdf(paste($nsam,\"sampleTMRCA\",\"recomb\",${r},\"-KStest.pdf\",sep=\"\"));
+par(mfrow=c(2,2))
+plot(ecdf(msdata\$V1), xlim=range(c(msdata\$V1, scrmdata\$V1)),col=\"red\", main=\"1st Moment\")
+plot(ecdf(scrmdata\$V1), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m1test\$statistic,sep=\"\"), paste(\"p-value = \",format(m1test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V2), xlim=range(c(msdata\$V2, scrmdata\$V2)),col=\"red\", main=\"2nd Moment\")
+plot(ecdf(scrmdata\$V2), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m2test\$statistic,sep=\"\"), paste(\"p-value = \",format(m2test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V3), xlim=range(c(msdata\$V3, scrmdata\$V3)),col=\"red\", main=\"3rd Moment\")
+plot(ecdf(scrmdata\$V3), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m3test\$statistic,sep=\"\"), paste(\"p-value = \",format(m3test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V4), xlim=range(c(msdata\$V4, scrmdata\$V4)),col=\"red\", main=\"4th Moment\")
+plot(ecdf(scrmdata\$V4), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m4test\$statistic,sep=\"\"), paste(\"p-value = \",format(m4test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+dev.off();
+cat(paste(${nsam},${r},\"|\",
+format(m1test\$statistic,digits=4),format(m1test\$p.value,scientific = TRUE),\"|\",
+format(m2test\$statistic,digits=4),format(m2test\$p.value,scientific = TRUE),\"|\",
+format(m3test\$statistic,digits=4),format(m3test\$p.value,scientific = TRUE),\"|\",
+format(m4test\$statistic,digits=4),format(m4test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareTMRCA}\",append=TRUE);cat(\"\n\",file=\"${compareTMRCA}\",append=TRUE);
+
+rm(list=ls());
+msdata=read.table(\"ms_bl_moments\");
+scrmdata=read.table(\"scrm_bl_moments\");
+m1test=ks.test(msdata\$V1,scrmdata\$V1)
+m2test=ks.test(msdata\$V2,scrmdata\$V2)
+m3test=ks.test(msdata\$V3,scrmdata\$V3)
+m4test=ks.test(msdata\$V4,scrmdata\$V4)
+pdf(paste($nsam,\"sampleBLmut\",\"recomb\",${r},\"-KStest.pdf\",sep=\"\"));
+par(mfrow=c(2,2))
+plot(ecdf(msdata\$V1), xlim=range(c(msdata\$V1, scrmdata\$V1)),col=\"red\", main=\"1st Moment\")
+plot(ecdf(scrmdata\$V1), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m1test\$statistic,sep=\"\"), paste(\"p-value = \",format(m1test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V2), xlim=range(c(msdata\$V2, scrmdata\$V2)),col=\"red\", main=\"2nd Moment\")
+plot(ecdf(scrmdata\$V2), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m2test\$statistic,sep=\"\"), paste(\"p-value = \",format(m2test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V3), xlim=range(c(msdata\$V3, scrmdata\$V3)),col=\"red\", main=\"3rd Moment\")
+plot(ecdf(scrmdata\$V3), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m3test\$statistic,sep=\"\"), paste(\"p-value = \",format(m3test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+plot(ecdf(msdata\$V4), xlim=range(c(msdata\$V4, scrmdata\$V4)),col=\"red\", main=\"4th Moment\")
+plot(ecdf(scrmdata\$V4), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",m4test\$statistic,sep=\"\"), paste(\"p-value = \",format(m4test\$p.value,scientific = TRUE),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+####
+dev.off();
+cat(paste(${nsam},${r},\"|\",
+format(m1test\$statistic,digits=4),format(m1test\$p.value,scientific = TRUE),\"|\",
+format(m2test\$statistic,digits=4),format(m2test\$p.value,scientific = TRUE),\"|\",
+format(m3test\$statistic,digits=4),format(m3test\$p.value,scientific = TRUE),\"|\",
+format(m4test\$statistic,digits=4),format(m4test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${compareBL}\",append=TRUE);cat(\"\n\",file=\"${compareBL}\",append=TRUE);
+" > dummy.r
+    R CMD BATCH dummy.r
+        done
+    done
+	
+	
diff --git a/tests/manualtests/spectrum-wit-recomb.sh b/tests/manualtests/spectrum-wit-recomb.sh
new file mode 100755
index 0000000..ef8d8fc
--- /dev/null
+++ b/tests/manualtests/spectrum-wit-recomb.sh
@@ -0,0 +1,104 @@
+#!/bin/bash
+## compare the Spectrum of the segregating sites, frequencies of observing a k mutation...
+
+###########################
+#!!!!! need to check is there a formula for the theoretical probability????
+
+mkdir test-spectrum-recomb
+cd test-spectrum-recomb
+
+msr=(11 21 10 50 100)
+mst=(10 20 50 100 10)
+
+msNsample=(3 7 10)
+
+rep=10000
+seqlen=100000
+
+compareSPEC=compareSPEC
+
+rm ${compareSPEC}
+#echo -e "compare number of mutations for ${rep} replicates \n\t\t|\t\t\t|\t\t ms \t\t|\t\t scrm\nNsam\ttheta\t|\tmean\tstdv\t|\tmean\tstdv\tstd err\t|\tmean\tstdv \tstd err" >${compareSEG}
+
+for r in "${msr[@]}"
+	do
+
+	for t in "${mst[@]}"
+		do
+		for nsam in "${msNsample[@]}"
+			do
+			prefix=${nsam}sample${t}mut
+			out=${prefix}out
+			nseg=${prefix}Seg
+			
+			
+			ms ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} | tail -n +4 | sed '/segsites/d' | sed '/positions/d' | gawk '/^\/\//{f="xx"++d} f{print > f} '
+			
+			for file in $(seq 1 1 ${rep})
+					do 
+					sed '/\/\//d' xx${file} | sed 's/.\{1\}/& /g' | awk '
+		{ for(i=1;i<=NF;++i) t[i]+=$i
+		if(n<NF)n=NF
+		} 
+		END {
+		printf t[1]
+		for(i=2;i<=n;++i) printf ","t[i]
+		printf "\n"
+		}
+		' >> mscolsumsOld
+					done
+			cat mscolsumsOld | tr '\n' ',' > mscolsums
+		rm mscolsumsOld  
+			find . -name "xx*" -print0 | xargs -0 rm
+			
+			
+		
+			scrm ${nsam} ${rep} -t ${t} -r ${r} ${seqlen} | tail -n +4  | sed '/segsites/d' | sed '/positions/d' | gawk '/^\/\//{f="xx"++d} f{print > f} '
+			for file in $(seq 1 1 ${rep})
+					do 
+					sed '/\/\//d' xx${file} | sed 's/.\{1\}/& /g' | awk '
+		{ for(i=1;i<=NF;++i) t[i]+=$i
+		if(n<NF)n=NF
+		} 
+		END {
+		printf t[1]
+		for(i=2;i<=n;++i) printf ","t[i]
+		printf "\n"
+		}
+		' >> scrmcolsumsOld
+					done
+			cat scrmcolsumsOld | tr '\n' ',' > scrmcolsums
+		rm scrmcolsumsOld  
+			find . -name "xx*" -print0 | xargs -0 rm
+		
+		#echo  -e "Sample size = ${nsam}, theta = ${t}" >> ${compareSPEC}
+		
+			
+			echo "rm(list=ls());
+			#source(\"fun_src.r\");
+			msdata=as.numeric(read.table(\"mscolsums\",sep=\",\"));
+			msnum=length(msdata)-1
+			mstable=table(msdata)
+			
+			a=as.numeric(read.table(\"scrmcolsums\",sep=\",\"));
+			scrmdata=a[!is.na(a)]
+			scrmdata=a[a>0]
+			scrmnum=length(scrmdata)-1
+			scrmtable=table(scrmdata)
+			test=chisq.test(cbind(mstable, scrmtable));
+			cat(paste(\"Sample size = ${nsam}, theta = ${t}, rho = ${r}, test statistics = \",
+		format(test\$statistic,digits=4),\", p-value = \",format(test\$p.value,scientific = TRUE),
+		sep=\"\"),file=\"${compareSPEC}\",append=TRUE);cat(\"\n\",file=\"${compareSPEC}\",append=TRUE);
+		
+			for (i in (1:(${nsam}-1))){
+			cat(paste( paste(\"P(S=\",i,\")  \",sep=\"\") , \"|\", format(mstable[i]/msnum,scientific = TRUE), \"|\", format(scrmtable[i]/scrmnum,scientific = TRUE),
+		sep=\"\t\"),file=\"${compareSPEC}\",append=TRUE);
+		cat(\"\n\",file=\"${compareSPEC}\",append=TRUE);						
+			}
+			" > dummy.r
+			R CMD BATCH dummy.r
+			#rm ms${out} ms${nseg} scrm${out} scrm${nseg}
+			done
+		done
+	done
+
diff --git a/tests/manualtests/spectrum.sh b/tests/manualtests/spectrum.sh
new file mode 100755
index 0000000..f40eff8
--- /dev/null
+++ b/tests/manualtests/spectrum.sh
@@ -0,0 +1,123 @@
+#!/bin/bash
+## compare the Spectrum of the segregating sites, frequencies of observing a k mutation...
+
+###########################
+#!!!!! need to check is there a formula for the theoretical probability????
+
+mkdir test-spectrum
+cd test-spectrum
+
+mst=(10 20 50 100 10)
+
+msNsample=(3 7 10)
+
+msNsample=(3)
+
+rep=1000
+#npop=20000
+
+compareSPEC=compareSPEC
+
+rm ${compareSPEC}
+#echo -e "compare number of mutations for ${rep} replicates \n\t\t|\t\t\t|\t\t ms \t\t|\t\t scrm\nNsam\ttheta\t|\tmean\tstdv\t|\tmean\tstdv\tstd err\t|\tmean\tstdv \tstd err" >${compareSEG}
+
+for t in "${mst[@]}"
+	do
+	for nsam in "${msNsample[@]}"
+		do
+		prefix=${nsam}sample${t}mut
+		out=${prefix}out
+		nseg=${prefix}Seg
+		rm mscolsum*  
+		find . -name "xx*" -print0 | xargs -0 rm
+		
+		ms ${nsam} ${rep} -t ${t} | tail -n +4 | sed '/segsites/d' | sed '/positions/d' | gawk '/^\/\//{f="xx"++d} f{print > f} '
+		
+		for file in $(seq 1 1 ${rep})
+				do 
+				sed '/\/\//d' xx${file} | sed 's/.\{1\}/& /g' | awk '
+{ for(i=1;i<=NF;++i) t[i]+=$i
+  if(n<NF)n=NF
+} 
+END {
+  printf t[1]
+  for(i=2;i<=n;++i) printf ","t[i]
+  printf "\n"
+}
+' >> mscolsumsOld
+				done
+		cat mscolsumsOld | tr '\n' ',' > mscolsums
+	
+		rm scrmcolsum*  
+		find . -name "yy*" -print0 | xargs -0 rm
+	
+		scrm ${nsam} ${rep} -t ${t} | tail -n +4 | sed '/segsites/d' | sed '/positions/d' | gawk '/^\/\//{f="yy"++d} f{print > f} '
+		
+        for file in $(seq 1 1 ${rep})
+				do 
+				sed '/\/\//d' yy${file} | sed 's/.\{1\}/& /g' | awk '
+{ for(i=1;i<=NF;++i) t[i]+=$i
+  if(n<NF)n=NF
+} 
+END {
+  printf t[1]
+  for(i=2;i<=n;++i) printf ","t[i]
+  printf "\n"
+}
+' >> scrmcolsumsOld
+				done
+		cat scrmcolsumsOld | tr '\n' ',' > scrmcolsums
+
+
+#echo  -e "Sample size = ${nsam}, theta = ${t}" >> ${compareSPEC}
+
+		
+		echo "rm(list=ls());
+		#source(\"fun_src.r\");
+		msdata=as.numeric(read.table(\"mscolsums\",sep=\",\"));
+		msnum=length(msdata)-1
+		mstable=table(msdata)
+		
+		a=as.numeric(read.table(\"scrmcolsums\",sep=\",\"));
+		scrmdata=a[!is.na(a)]
+		scrmdata=a[a>0]
+		scrmnum=length(scrmdata)-1
+		scrmtable=table(scrmdata)
+		test=chisq.test(cbind(mstable, scrmtable));
+		cat(paste(\"Sample size = ${nsam}, theta = ${t}, test statistics = \",
+format(test\$statistic,digits=4),\", p-value = \",format(test\$p.value,scientific = TRUE),
+sep=\"\"),file=\"${compareSPEC}\",append=TRUE);cat(\"\n\",file=\"${compareSPEC}\",append=TRUE);
+
+		for (i in (1:(${nsam}-1))){
+		cat(paste( paste(\"P(S=\",i,\")  \",sep=\"\") , \"|\", format(mstable[i]/msnum,scientific = TRUE), \"|\", format(scrmtable[i]/scrmnum,scientific = TRUE),
+sep=\"\t\"),file=\"${compareSPEC}\",append=TRUE);
+cat(\"\n\",file=\"${compareSPEC}\",append=TRUE);						
+		}
+		" > dummy.r
+		R CMD BATCH dummy.r
+        find . -name "xx*" -print0 | xargs -0 rm
+        find . -name "yy*" -print0 | xargs -0 rm
+		#rm ms${out} ms${nseg} scrm${out} scrm${nseg}
+		done
+	done
+
+
+
+
+# make the transpose?
+#awk '
+#{ 
+    #for (i=1; i<=NF; i++)  {
+        #a[NR,i] = $i
+    #}
+#}
+#NF>p { p = NF }
+#END {    
+    #for(j=1; j<=p; j++) {
+        #str=a[1,j]
+        #for(i=2; i<=NR; i++){
+            #str=str" "a[i,j];
+        #}
+        #print str
+    #}
+#}' > xx${file}transpose
diff --git a/tests/manualtests/tajd.c b/tests/manualtests/tajd.c
new file mode 100644
index 0000000..e12ec9b
--- /dev/null
+++ b/tests/manualtests/tajd.c
@@ -0,0 +1,120 @@
+/************************* tajima.c *************************************************************
+ This program calculates Tajima's D when number of sequences, number of segregating sites,
+   and average pairwise differences (pi) are known.  It also reports all the coefficients for Tajima's
+   D (a1, a2, b1, b2, c1, c2, e1, e2). 
+**************************************************************************************************/
+
+
+#include <stdio.h>
+#include <math.h>
+
+
+
+double a1f(int);
+double a2f(int);
+double b1f(int);
+double b2f(int);
+double c1f(double, double);
+double c2f(int, double, double, double);
+double e1f(double, double);
+double e2f(double, double, double);
+
+
+	double
+tajd(int nsam, int segsites, double sumk)
+{
+
+double  a1, a2, b1, b2, c1, c2, e1, e2; 
+ 
+if( segsites == 0 ) return( 0.0) ;
+
+a1 = a1f(nsam);
+a2 = a2f(nsam);
+b1 = b1f(nsam);
+b2 = b2f(nsam);
+c1 = c1f(a1, b1);
+c2 = c2f(nsam, a1, a2, b2);
+e1 = e1f(a1, c1);
+e2 = e2f(a1, a2, c2);
+
+return( (sumk - (segsites/a1))/sqrt((e1*segsites) + ((e2*segsites)*(segsites
+-1))) ) ;
+
+}
+
+double a1f(int nsam)
+{
+double a1;
+int i;
+a1 = 0.0;
+for (i=1; i<=nsam-1; i++) a1 += 1.0/i;
+return (a1);
+}
+
+
+double a2f(int nsam) 
+{
+double a2;
+int i;
+a2 = 0.0;
+for (i=1; i<=nsam-1; i++) a2 += 1.0/(i*i);
+return (a2);
+}
+
+
+double b1f(int nsam)
+{
+double b1;
+b1 = (nsam + 1.0)/(3.0*(nsam-1.0));
+return (b1);
+}
+
+
+double b2f(int nsam)
+{
+double b2;
+b2 = (2*(nsam*nsam + nsam + 3.0))/(9*nsam*(nsam - 1));
+return (b2);
+}
+
+
+double e1f(double a1, double c1) 
+{
+double e1;
+e1 = c1/a1;
+return (e1);
+}
+
+double e2f(double a1, double a2, double c2)
+{ 
+double e2;
+e2 = c2/((a1*a1)+a2);
+return (e2);
+}
+
+
+double c1f(double a1, double b1)
+{
+double c1;
+c1 = b1 - (1/a1);
+return (c1);
+}
+
+
+double c2f(int nsam, double a1, double a2, double b2)
+{
+double c2;
+c2 = b2 - ((nsam+2)/(a1*nsam)) + (a2/(a1 * a1));
+return (c2);
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/manualtests/tmrca_r.src b/tests/manualtests/tmrca_r.src
new file mode 100644
index 0000000..e58a79a
--- /dev/null
+++ b/tests/manualtests/tmrca_r.src
@@ -0,0 +1,19 @@
+echo "rm(list=ls());
+#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+msdata=read.table(\"mstmrca\")\$V1;
+scrmdata=read.table(\"scrmtmrca\")\$V1;
+#ee=ee_tmrca(${nsam});
+#sdv=sd_tmrca(${nsam});
+test=ks.test(msdata,scrmdata)
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(ecdf(msdata), xlim=range(c(msdata, scrmdata)),col=\"red\", main=currentcase)
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"ms\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+cat(paste(currentcase,figuretitle , \"\n\",\"|\",
+format(mean(msdata),digits=4),format(sd(msdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",test\$statistic,format(test\$p.value,digits=4), 
+sep=\"\t\"),file=\"${COMPAREFILE}\",append=TRUE);cat(\"\n\",file=\"${COMPAREFILE}\",append=TRUE);" > tmrca.r
diff --git a/tests/test_binaries.sh b/tests/test_binaries.sh
new file mode 100755
index 0000000..e44c40c
--- /dev/null
+++ b/tests/test_binaries.sh
@@ -0,0 +1,92 @@
+#!/bin/bash
+#
+# Test the binaries using scrms build in debug checks 
+# 
+# Author:   Paul R. Staab 
+# Email:    staab (at) bio.lmu.de
+# Licence:  GPLv3 or later
+#
+
+function test_scrm {
+  echo -n " scrm $@ "
+  for i in `seq 1 10`; do
+    echo -n "."
+
+    # Test using scrm self-checks
+    ./scrm_dbg $@ -seed $i > /dev/null 
+    if [ $? -ne 0 ]; then
+      echo ""
+      echo "Executing \"./scrm_dbg $@ -seed $i\" failed."
+      echo "Debug Call: make -mj2 scrm_dbg && ./scrm_dbg $@ -seed $i 2>&1 | less"
+      exit 1
+    fi
+
+    # Test for memory leaks
+    valgrind --error-exitcode=1 --leak-check=full -q ./scrm $@ -seed $i > /dev/null
+    if [ $? -ne 0 ]; then
+      echo ""
+      echo "Valgrind check of \"./scrm $@ -seed $i\" failed."
+      exit 1
+    fi
+
+  done
+  echo " done."
+}
+
+
+echo "Testing Initial Tree"
+ test_scrm 5 1000 -t 5 || exit 1
+ test_scrm 3 1000 -t 5 -L -oSFS || exit 1
+ test_scrm 100 20 -O || exit 1
+ test_scrm 250 1 -T || exit 1
+echo ""
+
+echo "Testing Recombinations"
+ test_scrm 4 500 -r 5 100 || exit 1
+ test_scrm 6 500 -r 1 100 -t 5 -L -T || exit 1
+ test_scrm 8 500 -r 1 100 -t 5 -oSFS -O || exit 1
+echo ""
+
+echo "Testing Pruning"
+ test_scrm 10 200 -r 10 500 -l 10 -t 5 -oSFS || exit 1
+ test_scrm 3 500 -r 10 500 -l 0 -t 1 -oSFS || exit 1
+ test_scrm 10 200 -r 10 500 -l 2r -L || exit 1
+ test_scrm 10 200 -r 1 500 -l -1 -T || exit 1
+echo ""
+
+echo "Testing Migration"
+ test_scrm 5 50 -r 5 100 -I 2 3 2 1.2 || exit 1
+ test_scrm 10 1 -r 20 200 -I 5 2 2 2 2 2 0.75 -l 5 || exit 1
+ test_scrm 10 1 -r 10 100 -I 2 7 3 0.5 -eM 0.3 1.1 --print-model || exit 1
+ test_scrm 10 1 -r 10 100 -I 2 7 3 -m 1 2 0.3 -em 0.5 2 1 0.6 -eM 2.0 1 || exit 1
+ test_scrm 20 100 -I 3 2 2 2 1.0 -eI 1.0 2 2 2 -eI 2.0 2 3 3 || exit 1
+echo ""
+
+echo "Testing Size Change"
+  test_scrm 10 2 -r 1 100 -I 3 3 3 4 0.5 -eN 0.1 0.05 -eN 0.2 0.5 --print-model || exit 1 
+  test_scrm 10 2 -r 10 100 -I 3 3 3 4 0.5 -eN 0.1 0.05 -eN 0.2 0.5 -l 10 || exit 1 
+echo ""
+
+echo "Testing Splits & Merges"
+ test_scrm 5 30 -r 20 200 -I 2 3 2 0.4 -ej 1.1 2 1 -l 25  || exit 1
+ test_scrm 6 30 -r 20 200 -I 3 2 2 2 -ej 0.2 2 1 -ej 0.25 3 1 -l 25 || exit 1
+ test_scrm 20 2 -r 5 200 -I 2 10 10 1.5 -es 1.6 2 0.5 -eM 2.0 1 -l 25 || exit 1
+ test_scrm 20 2 -r 5 200 -I 2 10 10 1.5 -es 0.9 1 0.8 -es 1.6 2 0.5 -eM 2.0 1 -l 50 || exit 1
+ test_scrm 20 2 -r 5 200 -I 2 10 10 -eps 1.0 2 1 0.0 || exit 1
+echo ""
+
+echo "Testing Growth"
+ test_scrm 5 100 -r 20 200 -G 1.5 -l 25 || exit 1
+ test_scrm 5 60 -r 2 200 -G -2.5 -eG 1 0.0 -l 25 || exit 1
+ test_scrm 4 30 -r 2 200 -G -2.5 -eN 1 0.25 -eG 2 0.0 -eN 2.5 0.25 -l 25 || exit 1
+echo ""
+
+echo "Testing Variable Rates"
+ test_scrm 3 200 -r 2 100 -t 5 -st 10 10 -sr 20 5 -st 30 1 -sr 40 0 -st 50 20 -T || exit 1
+echo ""
+
+echo "Various Edge Cases"
+ test_scrm 6 1 -I 2 3 3 0.5 -r 1 100 -es 0 2 0.5 -ej 1 3 1 -t 1  || exit 1
+ test_scrm 10 10 -es 1.0 1 0.5 -ej 1.0 2 1 || exit 1
+echo ""
+
diff --git a/tests/test_read_init/3tax_gt b/tests/test_read_init/3tax_gt
new file mode 100644
index 0000000..85e5dff
--- /dev/null
+++ b/tests/test_read_init/3tax_gt
@@ -0,0 +1 @@
+((1:1,2:1):3,3:4);
diff --git a/tests/test_read_init/4tax_gt b/tests/test_read_init/4tax_gt
new file mode 100644
index 0000000..1c04b4d
--- /dev/null
+++ b/tests/test_read_init/4tax_gt
@@ -0,0 +1 @@
+((1:1.1,2:1.1):6,(3:3.3,4:3.3):3.8);
diff --git a/tests/test_read_init/bl_r.src b/tests/test_read_init/bl_r.src
new file mode 100644
index 0000000..5150640
--- /dev/null
+++ b/tests/test_read_init/bl_r.src
@@ -0,0 +1,17 @@
+echo "rm(list=ls());
+#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+scrmInitdata=read.table(\"scrmInitbl\")\$V1;
+scrmdata=read.table(\"scrmbl\")\$V1;
+test=ks.test(scrmInitdata,scrmdata)
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(ecdf(scrmInitdata), xlim=range(c(scrmInitdata, scrmdata)),col=\"red\", main=currentcase)
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"scrmInit\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+cat(paste(currentcase,figuretitle , \"\n\",\"|\",
+format(mean(scrmInitdata),digits=4),format(sd(scrmInitdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",test\$statistic,format(test\$p.value,digits=4), 
+sep=\"\t\"),file=\"${COMPAREFILE}\",append=TRUE);cat(\"\n\",file=\"${COMPAREFILE}\",append=TRUE);" > bl.r
diff --git a/tests/test_read_init/chisq_r.src b/tests/test_read_init/chisq_r.src
new file mode 100644
index 0000000..e94f36b
--- /dev/null
+++ b/tests/test_read_init/chisq_r.src
@@ -0,0 +1,36 @@
+		echo "rm(list=ls());
+		#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+scrmInitdata=read.table(paste(\"scrmInit\",\"data\",sep=\"\"))\$V1;
+scrmdata=read.table(paste(\"scrm\",\"data\",sep=\"\"))\$V1;
+		#ee=ee_seg(${nsam},${t});
+		#sdv=sd_seg_norecomb(${nsam},${t});
+		datamax=max(scrmInitdata,scrmdata);
+		scrmInittable=table(factor(scrmInitdata,levels=1:datamax))
+		scrmtable=table(factor(scrmdata,levels=1:datamax))
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(as.numeric(names(scrmInittable)), scrmInittable/length(scrmInitdata),pch=16,col=\"red\",ylab=\"Frequency\",xlab=figuretitle);
+points(as.numeric(names(scrmtable)), scrmtable/length(scrmdata),pch=16,col=\"blue\")
+
+scrmInit_newtable=table(scrmInitdata);
+scrm_scrmInittable=table(factor(scrmdata,levels=names(table(scrmInitdata))));
+combined_scrm_scrmInit_test=chisq.test(cbind(scrm_scrmInittable, scrmInit_newtable));
+
+scrm_newtable=table(scrmdata);
+scrmInit_scrmtable=table(factor(scrmInitdata,levels=names(table(scrmdata))));
+combined_scrmInit_scrm_test=chisq.test(cbind(scrm_newtable, scrmInit_scrmtable));
+
+legend(\"topright\",c(paste(\"Test 1 Statistics = \",combined_scrm_scrmInit_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_scrm_scrmInit_test\$p.value,digits=4),sep=\"\"),paste(\"Test 2 Statistics = \",combined_scrmInit_scrm_test\$statistic,sep=\"\"), paste(\"p-value = \",format(combined_scrmInit_scrm_test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"scrmInit\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+
+dev.off();
+
+#cat(paste(${nsam},${t},\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+cat(paste(currentcase, figuretitle , \"\n\",\"|\",
+format(mean(scrmInitdata),digits=4),format(sd(scrmInitdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"||\",
+format(combined_scrm_scrmInit_test\$statistic,digits=4),format(combined_scrm_scrmInit_test\$p.value,scientific = TRUE),\"||\",
+format(combined_scrmInit_scrm_test\$statistic,digits=4),format(combined_scrmInit_scrm_test\$p.value,scientific = TRUE),
+sep=\"\t\"),file=\"${COMPAREFILE}\",append=TRUE);cat(\"\n\",file=\"${COMPAREFILE}\",append=TRUE);
+" > chisq.r
diff --git a/tests/test_read_init/ks_r.src b/tests/test_read_init/ks_r.src
new file mode 100644
index 0000000..dfb594f
--- /dev/null
+++ b/tests/test_read_init/ks_r.src
@@ -0,0 +1,20 @@
+echo "rm(list=ls());
+#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+scrmInitdata=read.table(paste(\"scrmInit\",\"data\",sep=\"\"))\$V1;
+scrmdata=read.table(paste(\"scrm\",\"data\",sep=\"\"))\$V1;
+#ee=1#ee_tmrca(${nsam});
+#sdv=1#sd_tmrca(${nsam});
+test=ks.test(scrmInitdata,scrmdata)
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(ecdf(scrmInitdata), xlim=range(c(scrmInitdata, scrmdata)),col=\"red\", main=currentcase)
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"scrmInit\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+#cat(paste(currentcase,\"|\",format(ee,digits=4),format(sdv,digits=4),\"|\",
+cat(paste(currentcase, figuretitle , \"\n\",\"|\",
+format(mean(scrmInitdata),scientific = TRUE),format(sd(scrmInitdata),scientific = TRUE),\"||\",
+format(mean(scrmdata),scientific = TRUE),format(sd(scrmdata),scientific = TRUE),\"|\",format(test\$statistic,scientific = TRUE),format(test\$p.value,scientific = TRUE), 
+sep=\"\t\"),file=\"${COMPAREFILE}\",append=TRUE);cat(\"\n\",file=\"${COMPAREFILE}\",append=TRUE);" > ks.r
diff --git a/tests/test_read_init/process_sample_stats.src b/tests/test_read_init/process_sample_stats.src
new file mode 100644
index 0000000..a45935d
--- /dev/null
+++ b/tests/test_read_init/process_sample_stats.src
@@ -0,0 +1,56 @@
+foo(){
+    #cut -f 2 scrmInittime > scrmInittmrca
+	#cut -f 2 scrmtime > scrmtmrca
+	echo "TMRCA" > figuretitle
+	R CMD BATCH tmrca.r
+
+    #cut -f 3 scrmInittime > scrmInitbl
+	#cut -f 3 scrmtime > scrmbl
+	echo "BL" > figuretitle
+	R CMD BATCH bl.r
+
+	cut -f 6 scrmInit_stats > scrmInitdata
+	cut -f 6 scrm_stats > scrmdata
+	echo "Tajima_D" > figuretitle
+	R CMD BATCH ks.r
+
+	cut -f 2 scrmInit_stats > scrmInitdata
+	cut -f 2 scrm_stats > scrmdata
+	echo "Pairewise_difference" > figuretitle
+	R CMD BATCH ks.r
+
+	cut -f 8 scrmInit_stats > scrmInitdata
+	cut -f 8 scrm_stats > scrmdata
+	echo "theta_H" > figuretitle
+	R CMD BATCH ks.r
+
+	cut -f 10 scrmInit_stats > scrmInitdata
+	cut -f 10 scrm_stats > scrmdata
+	echo "H" > figuretitle
+	R CMD BATCH ks.r
+	}
+
+scrmInittime(){
+    cat scrmInitout | gawk '/^\/\//{f="xx"++d} f{print > f} '
+    for file in $(seq 1 1 ${rep})
+        do 
+        grep ";" xx${file} | sed -e 's/\[.*\]//g' | tail -1 >> scrmInitTrees
+        done
+        hybrid-Lambda -gt scrmInitTrees -tmrca -o scrmInit
+        hybrid-Lambda -gt scrmInitTrees -bl -o scrmInit
+        find . -name "xx*" -print0 | xargs -0 rm    
+    }	
+	
+scrmtime(){
+    rm scrmReadTrees
+    cat scrmout | gawk '/^\/\//{f="xx"++d} f{print > f} '
+    for file in $(seq 1 1 ${rep})
+        do 
+        grep ";" xx${file} | sed -e 's/\[.*\]//g' | tail -1 >> scrmTrees
+        grep ";" xx${file} | sed -e 's/\[.*\]//g' | head -1 >> scrmReadTrees
+        done
+        hybrid-Lambda -gt scrmTrees -tmrca -o scrm
+        hybrid-Lambda -gt scrmTrees -bl -o scrm
+        #find . -name "xx*" -print0 | xargs -0 rm    
+    }	
+		
diff --git a/tests/test_read_init/scrm_vs_scrmInitialtree.sh b/tests/test_read_init/scrm_vs_scrmInitialtree.sh
new file mode 100755
index 0000000..bc9702d
--- /dev/null
+++ b/tests/test_read_init/scrm_vs_scrmInitialtree.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+dir=test-demo
+mkdir ${dir}
+cd ${dir}
+rm *pdf
+
+
+rep=1000
+seqlen=100000
+
+## compare population sturture for a single population data
+COMPAREFILE=compareDemo
+rm ${COMPAREFILE}
+
+theta=10
+r=10
+
+
+source ../chisq_r.src
+
+source ../ks_r.src
+
+source ../tmrca_r.src
+
+source ../bl_r.src
+
+source ../process_sample_stats.src	
+
+
+#case 1
+echo "case_1" > current_case
+rm scrm* scrmInit*
+scrm 10 ${rep} -t ${theta} -r ${r} ${seqlen} -eN 0.4 10.01 -eN 1 0.01  -T -L > scrmout
+scrmtime
+cat scrmout | sample_stats > scrm_stats
+
+scrm 10 ${rep} -t ${theta} -r ${r} ${seqlen} -eN 0.4 10.01 -eN 1 0.01  -T -L -init scrmReadTrees > scrmInitout
+scrmInittime
+cat scrmInitout | sample_stats > scrmInit_stats
+
+foo
+
+#case 2
+echo "case_2" > current_case
+rm scrm* scrmInit*
+scrm 16 ${rep} -t ${theta} -r ${r} ${seqlen} -G 5.4 -eG 0.4 1 -eN 0.8 15  -T -L > scrmout
+scrmtime
+cat scrmout | sample_stats > scrm_stats
+
+scrm 16 ${rep} -t ${theta} -r ${r} ${seqlen} -G 5.4 -eG 0.4 1 -eN 0.8 15 -T -L -init scrmReadTrees > scrmInitout
+scrmInittime
+cat scrmInitout | sample_stats > scrmInit_stats
+
+foo
diff --git a/tests/test_read_init/tmrca_r.src b/tests/test_read_init/tmrca_r.src
new file mode 100644
index 0000000..6ddba58
--- /dev/null
+++ b/tests/test_read_init/tmrca_r.src
@@ -0,0 +1,19 @@
+echo "rm(list=ls());
+#source(\"../fun_src.r\");
+figuretitle=scan(\"figuretitle\",what=\"\");
+currentcase=scan(\"current_case\",what=\"\");
+scrmInitdata=read.table(\"scrmInittmrca\")\$V1;
+scrmdata=read.table(\"scrmtmrca\")\$V1;
+#ee=ee_tmrca(${nsam});
+#sdv=sd_tmrca(${nsam});
+test=ks.test(scrmInitdata,scrmdata)
+pdf(paste(currentcase,figuretitle,\".pdf\",sep=\"\"));
+plot(ecdf(scrmInitdata), xlim=range(c(scrmInitdata, scrmdata)),col=\"red\", main=currentcase)
+plot(ecdf(scrmdata), add=TRUE, lty=\"dashed\", col=\"blue\")
+legend(\"bottomright\",c(paste(\"Tests Statistics = \",test\$statistic,sep=\"\"), paste(\"p-value = \",format(test\$p.value,digits=4),sep=\"\")))
+legend(\"topleft\",c(\"scrmInit\",\"scrm\"), col=c(\"red\",\"blue\"), pch=16)
+dev.off();
+cat(paste(currentcase,figuretitle , \"\n\",\"|\",
+format(mean(scrmInitdata),digits=4),format(sd(scrmInitdata),digits=4),\"|\",
+format(mean(scrmdata),digits=4),format(sd(scrmdata),digits=4),\"|\",test\$statistic,format(test\$p.value,digits=4), 
+sep=\"\t\"),file=\"${COMPAREFILE}\",append=TRUE);cat(\"\n\",file=\"${COMPAREFILE}\",append=TRUE);" > tmrca.r
diff --git a/tests/unittests/test_contemporaries_container.cc b/tests/unittests/test_contemporaries_container.cc
new file mode 100644
index 0000000..d41ec0c
--- /dev/null
+++ b/tests/unittests/test_contemporaries_container.cc
@@ -0,0 +1,404 @@
+#include <cppunit/TestCase.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "../../src/contemporaries_container.h"
+#include "../../src/node_container.h"
+#include "../../src/random/mersenne_twister.h"
+
+class TestContemporariesContainer : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE( TestContemporariesContainer );
+
+  CPPUNIT_TEST( add );
+  CPPUNIT_TEST( remove );
+  CPPUNIT_TEST( clear );
+  CPPUNIT_TEST( iterator );
+  CPPUNIT_TEST( sample );
+  CPPUNIT_TEST( buffer );
+  CPPUNIT_TEST( empty );
+
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  MersenneTwister *rg;
+  NodeContainer *nc;
+  Node *node1, *node2, *node3, *node4;
+
+ public:
+  void setUp() {
+    rg = new MersenneTwister(5);
+    nc = new NodeContainer();
+    node1 = nc->createNode(5);
+    node2 = nc->createNode(10);
+    node2->set_population(1);
+    node3 = nc->createNode(10);
+    node3->set_population(2);
+    node4 = nc->createNode(15);
+    node4->set_population(2);
+  }
+
+  void tearDown() {
+    delete rg, nc;
+  }
+
+  void add() { 
+    // Vector
+    ContemporariesContainer cc = ContemporariesContainer(3, 10, rg);
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(2) );
+
+    cc.add(node1);
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(2) );
+
+    cc.add(node2);
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(2) );
+
+    cc.add(node3);
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(2) );
+
+    cc.add(node4);
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, cc.size(2) );
+
+    // Set
+    cc = ContemporariesContainer(3, 1000, rg);
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(2) );
+
+    cc.add(node1);
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(2) );
+
+    cc.add(node2);
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(2) );
+
+    cc.add(node3);
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(2) );
+
+    cc.add(node4);
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, cc.size(2) );
+  }
+
+  void remove() {
+    // Vector
+    ContemporariesContainer cc = ContemporariesContainer(3, 10, rg);
+    cc.add(node1);
+    cc.add(node2);
+    cc.add(node3);
+    cc.add(node4);
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, cc.size(2) );
+
+    cc.remove(node1);
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, cc.size(2) );
+
+    cc.remove(node3);
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(2) );
+
+    cc.remove(node4);
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(2) );
+
+    cc.remove(node2);
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(2) );
+
+    // Set
+    cc = ContemporariesContainer(3, 1000, rg);
+    cc.add(node1);
+    cc.add(node2);
+    cc.add(node3);
+    cc.add(node4);
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, cc.size(2) );
+
+    cc.remove(node1);
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, cc.size(2) );
+
+    cc.remove(node3);
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(2) );
+
+    cc.remove(node4);
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(2) );
+
+    cc.remove(node2);
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(2) );
+  }
+
+  void clear() {
+    ContemporariesContainer cc = ContemporariesContainer(3, 10, rg);
+    cc.add(node1);
+    cc.add(node2);
+    cc.add(node3);
+    cc.add(node4);
+
+    cc.clear();
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(2) );
+    
+    cc = ContemporariesContainer(3, 1000, rg);
+    cc.add(node1);
+    cc.add(node2);
+    cc.add(node3);
+    cc.add(node4);
+
+    cc.clear();
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(2) );
+  }
+
+  void iterator() {
+    // Vector
+    ContemporariesContainer cc = ContemporariesContainer(3, 10, rg);
+    cc.add(node1);
+    cc.add(node2);
+    cc.add(node3);
+    cc.add(node4);
+
+    size_t count = 0;
+    for (auto it = cc.begin(0); it != cc.end(0); ++it) {
+      CPPUNIT_ASSERT( *it == node1 );
+      ++count;
+    }
+    CPPUNIT_ASSERT_EQUAL((size_t)1, count);
+
+    for (auto it = cc.begin(2); it != cc.end(2); ++it) {
+      CPPUNIT_ASSERT( *it == node4 || *it == node3 );
+      ++count;
+    }
+    CPPUNIT_ASSERT_EQUAL((size_t)3, count);
+
+    for (auto it = cc.begin(1); it != cc.end(1); ++it) {
+      CPPUNIT_ASSERT( *it == node2 );
+      ++count;
+    }
+    CPPUNIT_ASSERT_EQUAL((size_t)4, count);
+
+    // Set
+    cc = ContemporariesContainer(3, 1000, rg);
+    cc.add(node1);
+    cc.add(node2);
+    cc.add(node3);
+    cc.add(node4);
+
+    count = 0;
+    for (auto it = cc.begin(0); it != cc.end(0); ++it) {
+      CPPUNIT_ASSERT( *it == node1 );
+      ++count;
+    }
+    CPPUNIT_ASSERT_EQUAL((size_t)1, count);
+
+    for (auto it = cc.begin(2); it != cc.end(2); ++it) {
+      CPPUNIT_ASSERT( *it == node4 || *it == node3 );
+      ++count;
+    }
+    CPPUNIT_ASSERT_EQUAL((size_t)3, count);
+
+    for (auto it = cc.begin(1); it != cc.end(1); ++it) {
+      CPPUNIT_ASSERT( *it == node2 );
+      ++count;
+    }
+    CPPUNIT_ASSERT_EQUAL((size_t)4, count);
+  }
+
+  void sample() {
+    // Vector
+    ContemporariesContainer cc = ContemporariesContainer(3, 10, rg);
+    cc.add(node1);
+    cc.add(node2);
+    cc.add(node3);
+    cc.add(node4);
+
+    for (size_t i = 0; i < 1000; ++i) {
+      CPPUNIT_ASSERT_EQUAL(node1, cc.sample(0));
+      CPPUNIT_ASSERT_EQUAL(node2, cc.sample(1));
+    } 
+
+    double count = 0;
+    for (size_t i = 0; i < 10000; ++i) {
+      Node* node = cc.sample(2);
+      CPPUNIT_ASSERT( node == node3 || node == node4 );
+      if (node == node3) ++count;
+    } 
+    count /= 10000;
+    CPPUNIT_ASSERT( 0.49 < count && count < 0.51 ); 
+
+    // Set
+    cc = ContemporariesContainer(3, 1000, rg);
+    cc.add(node1);
+    cc.add(node2);
+    cc.add(node3);
+    cc.add(node4);
+
+    for (size_t i = 0; i < 1000; ++i) {
+      CPPUNIT_ASSERT_EQUAL(node1, cc.sample(0));
+      CPPUNIT_ASSERT_EQUAL(node2, cc.sample(1));
+    } 
+
+    count = 0;
+    for (size_t i = 0; i < 10000; ++i) {
+      Node* node = cc.sample(2);
+      CPPUNIT_ASSERT( node == node3 || node == node4 );
+      if (node == node3) ++count;
+    } 
+    count /= 10000;
+    CPPUNIT_ASSERT( 0.49 < count && count < 0.51 ); 
+  }
+
+  void buffer() {
+    // Vector
+    ContemporariesContainer cc = ContemporariesContainer(3, 10, rg);
+    cc.add(node1);
+    cc.add(node2);
+    cc.add(node3);
+    cc.add(node4);
+
+    cc.buffer(17.5);
+    CPPUNIT_ASSERT_EQUAL( 17.5, cc.buffer_time() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(2) );
+
+    size_t count = 0;
+    for (auto it = cc.buffer_begin(0); it != cc.buffer_end(0); ++it) {
+      CPPUNIT_ASSERT( *it == node1 );
+      ++count;
+    }
+    CPPUNIT_ASSERT_EQUAL((size_t)1, count);
+
+    for (auto it = cc.buffer_begin(2); it != cc.buffer_end(2); ++it) {
+      CPPUNIT_ASSERT( *it == node4 || *it == node3 );
+      ++count;
+    }
+    CPPUNIT_ASSERT_EQUAL((size_t)3, count);
+
+    for (auto it = cc.buffer_begin(1); it != cc.buffer_end(1); ++it) {
+      CPPUNIT_ASSERT( *it == node2 );
+      ++count;
+    }
+    CPPUNIT_ASSERT_EQUAL((size_t)4, count);
+
+    cc.buffer(20.2);
+    CPPUNIT_ASSERT_EQUAL( 20.2, cc.buffer_time() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(2) );
+    count = 0;
+    for (auto it = cc.buffer_begin(0); it != cc.buffer_end(0); ++it) ++count;
+    for (auto it = cc.buffer_begin(1); it != cc.buffer_end(1); ++it) ++count;
+    for (auto it = cc.buffer_begin(2); it != cc.buffer_end(2); ++it) ++count;
+    CPPUNIT_ASSERT_EQUAL((size_t)0, count);
+
+    // Set
+    cc = ContemporariesContainer(3, 1000, rg);
+    cc.add(node1);
+    cc.add(node2);
+    cc.add(node3);
+    cc.add(node4);
+
+    cc.buffer(17.5);
+    CPPUNIT_ASSERT_EQUAL( 17.5, cc.buffer_time() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(2) );
+
+    count = 0;
+    for (auto it = cc.buffer_begin(0); it != cc.buffer_end(0); ++it) {
+      CPPUNIT_ASSERT( *it == node1 );
+      ++count;
+    }
+    CPPUNIT_ASSERT_EQUAL((size_t)1, count);
+
+    for (auto it = cc.buffer_begin(2); it != cc.buffer_end(2); ++it) {
+      CPPUNIT_ASSERT( *it == node4 || *it == node3 );
+      ++count;
+    }
+    CPPUNIT_ASSERT_EQUAL((size_t)3, count);
+
+    for (auto it = cc.buffer_begin(1); it != cc.buffer_end(1); ++it) {
+      CPPUNIT_ASSERT( *it == node2 );
+      ++count;
+    }
+    CPPUNIT_ASSERT_EQUAL((size_t)4, count);
+
+    cc.buffer(20.2);
+    CPPUNIT_ASSERT_EQUAL( 20.2, cc.buffer_time() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cc.size(2) );
+    count = 0;
+    for (auto it = cc.buffer_begin(0); it != cc.buffer_end(0); ++it) ++count;
+    for (auto it = cc.buffer_begin(1); it != cc.buffer_end(1); ++it) ++count;
+    for (auto it = cc.buffer_begin(2); it != cc.buffer_end(2); ++it) ++count;
+    CPPUNIT_ASSERT_EQUAL((size_t)0, count);
+  }
+
+  void empty() {
+    // Vector 
+    ContemporariesContainer cc = ContemporariesContainer(3, 10, rg);
+    CPPUNIT_ASSERT( cc.empty() );
+    cc.add(node1);
+    CPPUNIT_ASSERT( !cc.empty() );
+
+    cc.clear();
+    CPPUNIT_ASSERT( cc.empty() );
+    cc.add(node2);
+    CPPUNIT_ASSERT( !cc.empty() );
+
+    cc.clear();
+    CPPUNIT_ASSERT( cc.empty() );
+    cc.add(node3);
+    CPPUNIT_ASSERT( !cc.empty() );
+
+    // Set
+    cc = ContemporariesContainer(3, 1000, rg);
+    CPPUNIT_ASSERT( cc.empty() );
+    cc.add(node1);
+    CPPUNIT_ASSERT( !cc.empty() );
+
+    cc.clear();
+    CPPUNIT_ASSERT( cc.empty() );
+    cc.add(node2);
+    CPPUNIT_ASSERT( !cc.empty() );
+
+    cc.clear();
+    CPPUNIT_ASSERT( cc.empty() );
+    cc.add(node3);
+    CPPUNIT_ASSERT( !cc.empty() );
+  }
+};
+CPPUNIT_TEST_SUITE_REGISTRATION( TestContemporariesContainer );
diff --git a/tests/unittests/test_fastfunc.cc b/tests/unittests/test_fastfunc.cc
new file mode 100644
index 0000000..faa1080
--- /dev/null
+++ b/tests/unittests/test_fastfunc.cc
@@ -0,0 +1,60 @@
+#include <cppunit/TestCase.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "../../src/random/fastfunc.h"
+#include "../../src/random/mersenne_twister.h"
+
+class TestFastFunc : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE( TestFastFunc );
+
+  CPPUNIT_TEST( testlog );
+  CPPUNIT_TEST( testexp );
+
+  CPPUNIT_TEST_SUITE_END();
+
+ public:
+  void testlog() {
+    MersenneTwister rg(5);
+    class FastFunc ff;
+    double d = 1e-6;
+    double maxdiff = 0.0;
+
+    // Check difference to log
+    double logd, truelogd;
+    while (d < 1) {
+      logd = ff.fastlog( d );
+      CPPUNIT_ASSERT( logd != 0.0 );
+      truelogd = log( d );
+      maxdiff = std::max( maxdiff, std::abs( logd-truelogd ) );
+      d += 1e-6;
+    }
+    CPPUNIT_ASSERT( maxdiff < 1.5e-7 );
+
+    // Check that the random generator does not produce exactly 0
+    for (int i=0; i<1e6; ++i) CPPUNIT_ASSERT( -ff.fastlog(rg.sample()) != 0.0 );
+  }
+
+  void testexp() {
+    class MersenneTwister rg;
+    class FastFunc ff;
+    int i;
+
+    double x, true_exp, lower_bound, upper_bound;
+
+    for (i=0; i<10000; ++i) {
+      x = (rg.sample()-0.5) * 1400.0;
+      true_exp = exp(x);
+      lower_bound = ff.fastexp_lo(x);
+      upper_bound = ff.fastexp_up(x);
+      //std::cout << x << " " << true_exp << " " << lower_bound << " " << upper_bound << std::endl;
+      CPPUNIT_ASSERT(lower_bound <= true_exp);
+      CPPUNIT_ASSERT(lower_bound > true_exp * (1.0 - 0.05792));
+      CPPUNIT_ASSERT(upper_bound >= true_exp);
+      CPPUNIT_ASSERT(upper_bound < true_exp * (1.0 + 0.06148));
+    }
+  }
+};
+
+//Uncomment this to activate the test
+CPPUNIT_TEST_SUITE_REGISTRATION( TestFastFunc );
diff --git a/tests/unittests/test_forest.cc b/tests/unittests/test_forest.cc
new file mode 100644
index 0000000..dad9c2c
--- /dev/null
+++ b/tests/unittests/test_forest.cc
@@ -0,0 +1,859 @@
+#include <cppunit/TestCase.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "../../src/forest.h"
+#include "../../src/random/constant_generator.h"
+#include "../../src/random/mersenne_twister.h"
+#include "../../src/event.h"
+#include "../../src/summary_statistics/tmrca.h"
+
+class TestForest : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE( TestForest );
+
+  CPPUNIT_TEST( testInitialization );
+  CPPUNIT_TEST( testGettersAndSetters );
+  CPPUNIT_TEST( testCreateExampleTree );
+  CPPUNIT_TEST( testCheckTreeLength );
+  CPPUNIT_TEST( testGetFirstNode );
+  CPPUNIT_TEST( testSamplePoint );
+  CPPUNIT_TEST( testCalcRecombinationRate );
+  CPPUNIT_TEST( testCalcRate );
+  CPPUNIT_TEST( testNodeIsOld );
+  CPPUNIT_TEST( testPrune );
+  CPPUNIT_TEST( testSelectFirstTime );
+  CPPUNIT_TEST( testSampleEventType );
+  CPPUNIT_TEST( testSampleEvent );
+  CPPUNIT_TEST( testGetNodeState ); 
+  CPPUNIT_TEST( testCut );
+  CPPUNIT_TEST( testImplementCoalescence );
+  CPPUNIT_TEST( testBuildInitialTree ); 
+  CPPUNIT_TEST( testImplementRecombination ); 
+  CPPUNIT_TEST( testImplementFixTimeEvent ); 
+  CPPUNIT_TEST( testPrintTree );
+  CPPUNIT_TEST( testCopyConstructor );
+  CPPUNIT_TEST( testCheckForNodeAtHeight );
+  CPPUNIT_TEST( testPrintLocusSumStats );
+  CPPUNIT_TEST( testSampleNextPosition ); 
+  CPPUNIT_TEST( testClear ); 
+
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  Model *model, *model_2pop;
+  Forest *forest, *forest_2pop;
+  MersenneTwister *rg;
+
+ public:
+  void setUp() {
+    rg = new MersenneTwister(1234);
+    model = new Model(5);
+    model_2pop = new Model(5);
+    model_2pop->set_population_number(2);
+    forest = new Forest(model, rg);
+    forest->createExampleTree();
+    forest_2pop = new Forest(model_2pop, rg);
+    forest_2pop->createExampleTree();
+  }
+
+  void tearDown() {
+    delete forest, forest_2pop;
+    delete model, model_2pop;
+    delete rg;
+  }
+
+  void testInitialization() {
+    Forest test_forest = Forest(new Model(4), rg);
+    CPPUNIT_ASSERT( test_forest.model().sample_size() == 4 );
+    CPPUNIT_ASSERT( test_forest.random_generator() == rg );
+    delete test_forest.writable_model();
+  }
+
+  void testGettersAndSetters() {
+    CPPUNIT_ASSERT( forest->model().sample_size() == 4 );
+  }
+
+  void testGetFirstNode() {
+    CPPUNIT_ASSERT( forest->nodes()->get(0)->height() == 0 );
+  }
+
+  void testCreateExampleTree() {
+    CPPUNIT_ASSERT_EQUAL((size_t)2, forest_2pop->model().population_number() );
+    CPPUNIT_ASSERT_EQUAL((size_t)9, forest->nodes()->size());
+    CPPUNIT_ASSERT( forest->local_root() == forest->nodes()->get(8) );
+    CPPUNIT_ASSERT( forest->primary_root() == forest->nodes()->get(8) );
+    CPPUNIT_ASSERT( forest->getLocalTreeLength() == 24 );
+    CPPUNIT_ASSERT( forest->checkTree() );
+    
+    forest->createExampleTree();
+    CPPUNIT_ASSERT_EQUAL((size_t)9, forest->nodes()->size());
+    CPPUNIT_ASSERT( forest->local_root() == forest->nodes()->get(8) );
+    CPPUNIT_ASSERT( forest->primary_root() == forest->nodes()->get(8) );
+    CPPUNIT_ASSERT( forest->getLocalTreeLength() == 24 );
+    CPPUNIT_ASSERT( forest->checkTree() );
+  }
+
+  void testCheckTreeLength() {
+    CPPUNIT_ASSERT( forest->checkTreeLength() );
+  }
+
+
+  void testCalcRate() {
+    TimeIntervalIterator tii(forest, forest->nodes()->at(0));
+    size_t pop_size = 2*forest->model().population_size(0);
+    Node *node1 = new Node(0.1);
+    Node *node2 = new Node(0.2);
+
+    forest->set_active_node(0, node1);
+    forest->set_active_node(1, node2);
+    forest->states_[0] = 0;
+    forest->states_[1] = 0;
+    CPPUNIT_ASSERT_NO_THROW( forest->calcRates(*tii) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, forest->rates_[0] );   
+    CPPUNIT_ASSERT_EQUAL( 0.0, forest->rates_[1] );   
+    CPPUNIT_ASSERT_EQUAL( 0.0, forest->rates_[2] );   
+
+    forest->states_[0] = 1;
+    CPPUNIT_ASSERT_NO_THROW( forest->calcRates(*tii) );
+    CPPUNIT_ASSERT_EQUAL( 4.0/pop_size, forest->rates_[0] );   
+    CPPUNIT_ASSERT_EQUAL( 0.0, forest->rates_[1] );   
+    CPPUNIT_ASSERT_EQUAL( 0.0, forest->rates_[2] );   
+
+    forest->states_[1] = 1;
+    CPPUNIT_ASSERT_NO_THROW( forest->calcRates(*tii) );
+    CPPUNIT_ASSERT( areSame(9.0/pop_size, forest->rates_[0]) );   
+    CPPUNIT_ASSERT_EQUAL( 0.0, forest->rates_[1] );   
+    CPPUNIT_ASSERT_EQUAL( 0.0, forest->rates_[2] );   
+
+    // Coalescence with structure 
+    forest_2pop->set_active_node(0, node1);
+    forest_2pop->set_active_node(1, node2);
+    forest_2pop->states_[0] = 1;
+    forest_2pop->states_[1] = 1;
+
+    node1->set_population(1);
+    forest_2pop->nodes()->at(1)->set_population(1);
+
+    TimeIntervalIterator tii2(forest_2pop, forest_2pop->nodes()->at(0));
+    CPPUNIT_ASSERT_NO_THROW( forest_2pop->calcRates(*tii2) );
+    // Only node2 can coalescence
+    CPPUNIT_ASSERT( areSame(4.0/pop_size, forest_2pop->rates_[0]) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, forest_2pop->rates_[1] );
+    CPPUNIT_ASSERT_EQUAL( 0.0, forest_2pop->rates_[2] );
+
+    std::vector<double> growth(2, 0.0);
+    growth.at(1) = 1.0;
+    forest_2pop->writable_model()->addGrowthRates(0, growth);
+    growth.at(0) = 2.0;
+    forest_2pop->writable_model()->addGrowthRates(1, growth);
+    TimeIntervalIterator tii3(forest_2pop, forest_2pop->nodes()->at(0));
+
+    CPPUNIT_ASSERT_NO_THROW( forest_2pop->calcRates(*tii3) );
+    CPPUNIT_ASSERT( areSame(3.0/pop_size, forest_2pop->rates_[0]) );   
+    CPPUNIT_ASSERT( areSame(1.0/pop_size, forest_2pop->rates_[1]) );   
+    CPPUNIT_ASSERT( areSame(0.0/pop_size, forest_2pop->rates_[2]) );   
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, forest_2pop->active_nodes_timelines_[0] );   
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, forest_2pop->active_nodes_timelines_[1] );   
+
+    forest_2pop->writable_model()->increaseTime();
+    CPPUNIT_ASSERT_NO_THROW( forest_2pop->calcRates(*tii3) );
+    //CPPUNIT_ASSERT_EQUAL( 0.0/pop_size, forest_2pop->rates_[0] );   
+    //CPPUNIT_ASSERT_EQUAL( 1.0/pop_size, forest_2pop->rates_[1] );   
+    //CPPUNIT_ASSERT_EQUAL( 3.0/pop_size, forest_2pop->rates_[2] );   
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, forest_2pop->active_nodes_timelines_[0] );   
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, forest_2pop->active_nodes_timelines_[1] );   
+
+    node2->set_population(1);
+    CPPUNIT_ASSERT_NO_THROW( forest_2pop->calcRates(*tii3) );
+    //CPPUNIT_ASSERT_EQUAL( 0.0/pop_size, forest_2pop->rates_[0] );   
+    //CPPUNIT_ASSERT( areSame(3.0/pop_size, forest_2pop->rates_[1]) );   
+    //CPPUNIT_ASSERT_EQUAL( 0.0/pop_size, forest_2pop->rates_[2] );   
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, forest_2pop->active_nodes_timelines_[0] );   
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, forest_2pop->active_nodes_timelines_[1] );   
+
+    delete node1;
+    delete node2;
+  }
+
+  void testGetNodeState() { 
+    CPPUNIT_ASSERT( forest->getNodeState(forest->getNodes()->get(8), 11) == 1 );
+    CPPUNIT_ASSERT( forest->getNodeState(forest->getNodes()->get(6), 11) == 2 );
+    CPPUNIT_ASSERT( forest->getNodeState(forest->getNodes()->get(7), 11) == 1 );
+  }
+
+  void testPrintTree() {
+    //CPPUNIT_ASSERT_NO_THROW( forest->printTree() );
+  }
+
+  void testSelectFirstTime() {
+    double current_time = -1.0;
+    size_t time_line = -1;
+
+    forest->selectFirstTime(-1, 1, current_time, time_line);
+    CPPUNIT_ASSERT_EQUAL( -1.0, current_time );
+
+    forest->selectFirstTime(5.0, 1, current_time, time_line);
+    CPPUNIT_ASSERT_EQUAL( 5.0, current_time );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, time_line );
+
+    forest->selectFirstTime(7.0, 2, current_time, time_line);
+    CPPUNIT_ASSERT_EQUAL( 5.0, current_time );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, time_line );
+
+    forest->selectFirstTime(-1, 2, current_time, time_line);
+    CPPUNIT_ASSERT_EQUAL( 5.0, current_time );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, time_line );
+
+    forest->selectFirstTime(4.0, 2, current_time, time_line);
+    CPPUNIT_ASSERT_EQUAL( 4.0, current_time );
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, time_line );
+  }
+
+  void testSampleEventType() {
+    Event event;
+    Forest *forest2 = forest_2pop; 
+
+    forest2->nodes()->at(0)->set_population(1);
+    forest2->nodes()->at(1)->set_population(1);
+    forest2->writable_model()->addMigrationRates(1, std::vector<double>(4, 5.0), false, true);
+    forest2->writable_model()->addGrowthRates(0.2, std::vector<double>(2, 0.000125));
+    forest2->writable_model()->addGrowthRates(1, std::vector<double>(2, 0.0));
+    forest2->writable_model()->addGrowthRates(2, std::vector<double>(2, 2));
+    forest2->writable_model()->finalize();
+    forest2->writable_model()->resetTime();
+
+    TimeIntervalIterator tii(forest2, forest2->nodes()->at(0));
+
+    forest2->set_active_node(0, forest2->nodes()->at(0));
+    forest2->set_active_node(1, forest2->nodes()->at(2));
+    forest2->states_[0] = 1;
+    forest2->states_[1] = 0;
+    forest2->calcRates(*tii);
+    forest2->active_nodes_timelines_[0] = 0;
+    forest2->active_nodes_timelines_[1] = 0;
+
+    forest2->sampleEventType(-1, 0, *tii, event);
+    CPPUNIT_ASSERT( event.isNoEvent() );
+
+    forest2->sampleEventType(0.5, 0, *tii, event);
+    CPPUNIT_ASSERT_EQUAL( 0.5, event.time() );
+    CPPUNIT_ASSERT( event.isCoalescence() );
+
+    // Only coalescence possible
+    for (size_t i = 0; i < 1000; ++i) {
+      forest2->sampleEventType(0.5, 0, *tii, event);
+      CPPUNIT_ASSERT( event.isCoalescence() );
+      CPPUNIT_ASSERT( event.node() == forest2->active_node(0) );
+    };
+
+    // Coalescence of two nodes
+    // active_node 0: Pop 1, 2 Contemporaries 
+    // active_node 1: Pop 0, 2 Contemporaries
+    // => 50% each 
+    forest2->states_[1] = 1;
+    forest2->calcRates(*tii);
+    size_t count = 0, count2 = 0;
+    for (size_t i = 0; i < 10000; ++i) {
+      forest2->sampleEventType(0.5, 0, *tii, event);
+      CPPUNIT_ASSERT( event.isCoalescence() );
+      count += (event.node() == forest2->active_node(0));
+    };
+    CPPUNIT_ASSERT( 4900 < count && count < 5100 ); // ~5000
+
+    // Test with Pw Coalescence
+    // active_node 0: Pop 1, 2 Contemporaries 
+    // active_node 1: Pop 1, 2 Contemporaries
+    // 4/5 Prob of Coalescence, 1/5 of Pw coalescence
+    forest2->writable_model()->resetTime();
+    forest2->set_active_node(1, forest2->nodes()->at(1));
+    forest2->calcRates(*tii);
+    count = 0;
+    for (size_t i = 0; i < 10000; ++i) {
+      forest2->sampleEventType(0.5, 0, *tii, event);
+      CPPUNIT_ASSERT( event.isCoalescence() || event.isPwCoalescence() );
+      count += event.isCoalescence();
+    };
+    CPPUNIT_ASSERT( 7900 < count && count < 8100 ); 
+
+    // Test with migration
+    // active_node 0: Pop 1, 2 Contemporaries 
+    // active_node 1: Pop 1, 2 Contemporaries
+    // => Coal: 4/2Ne, Pw Coal: 1/2Ne
+    //    Migration: 2 * 5/4Ne
+    // => 40% Coal, 10% Pw Coal, 50% Mig 
+    forest2->writable_model()->increaseTime();
+    forest2->writable_model()->increaseTime();
+    forest2->calcRates(*tii);
+
+    count = 0;
+    for (size_t i = 0; i < 10000; ++i) {
+      forest2->sampleEventType(0.5, 0, *tii, event);
+      CPPUNIT_ASSERT( event.isCoalescence() || event.isPwCoalescence() || event.isMigration() );
+      count += event.isMigration();
+      count2 += event.isCoalescence();
+    };
+    CPPUNIT_ASSERT( 4900 < count && count < 5100 );
+    CPPUNIT_ASSERT( 3900 < count2 && count2 < 4100 );
+
+
+    // Coalescence and Recombination 
+    // active_node 0: Pop 1, 2 Contemporaries => Coal rate: 2 / 2 * Ne = 1/Ne 
+    // active_node 1: Pop 1, Recombination    => Rec rate: 10 Bases * 0.4 / 4Ne = 1/Ne    
+    // => 50% Recombination, 50% Coalescence 
+    forest2->writable_model()->setLocusLength(101);
+    forest2->writable_model()->setRecombinationRate(0.4, false, true);
+    forest2->set_current_base(10);
+    forest2->active_node(1)->make_nonlocal(forest2->current_rec_);
+    forest2->set_next_base(20);
+    forest2->current_rec_++;
+    forest2->states_[0] = 1;
+    forest2->states_[1] = 2;
+    forest2->writable_model()->resetTime(); // set migration to 0
+    forest2->calcRates(*tii);
+
+    count = 0;
+    for (size_t i = 0; i < 100000; ++i) {
+      forest2->sampleEventType(0.5, 0, *tii, event);
+      CPPUNIT_ASSERT( event.isCoalescence() || event.isRecombination() );
+      count += event.isRecombination();
+    };
+    CPPUNIT_ASSERT( 49500 < count && count < 50500 );
+
+    // Other way round
+    Node* tmp = forest2->active_node(1);
+    forest2->set_active_node(1, forest2->active_node(0));
+    forest2->set_active_node(0, tmp);
+    forest2->states_[0] = 2;
+    forest2->states_[1] = 1;
+    forest2->calcRates(*tii);
+
+    count = 0;
+    for (size_t i = 0; i < 100000; ++i) {
+      forest2->sampleEventType(0.5, 0, *tii, event);
+      CPPUNIT_ASSERT( event.isCoalescence() || event.isRecombination() );
+      count += event.isRecombination();
+    };
+    CPPUNIT_ASSERT( 49500 < count && count < 50500 ); // True with >95%
+
+
+    // Double recombination
+    // => 1/3 active_node 0
+    //    2/3 active_node 1
+    forest2->states_[0] = 2;
+    forest2->states_[1] = 2;
+
+    forest2->set_current_base(10.0);
+    forest2->set_next_base(15.0);
+    forest2->set_next_base(20.0);
+    
+    forest2->current_rec_ += 2;
+    forest2->active_node(0)->make_nonlocal(forest2->current_rec_ - 1);
+    forest2->active_node(1)->make_nonlocal(forest2->current_rec_ - 2);
+    forest2->calcRates(*tii);
+
+    count = 0;
+    for (size_t i = 0; i < 15000; ++i) {
+      forest2->sampleEventType(0.5, 0, *tii, event);
+      CPPUNIT_ASSERT( event.isRecombination() );
+      count += (event.node() == forest2->active_node(0));
+    };
+    CPPUNIT_ASSERT( 4880 < count && count < 5120 ); // True with >96%
+
+
+    // Recombination with Rate 0
+    // active_node 1: Up to date = rec rate = 0;
+    // => always coalescence
+    forest2->states_[0] = 1;
+    forest2->active_node(0)->make_local();
+    forest2->active_node(1)->set_last_update(forest2->current_rec_);
+    forest2->calcRates(*tii);
+    for (size_t i = 0; i < 1000; ++i) {
+      forest2->sampleEventType(0.5, 0, *tii, event);
+      CPPUNIT_ASSERT( event.isCoalescence() );
+    };
+
+    // Combinations With Growth
+    forest2->writable_model()->resetTime(); 
+    forest2->writable_model()->increaseTime();
+    forest2->writable_model()->increaseTime();
+    forest2->writable_model()->increaseTime();
+    forest2->states_[0] = 1;
+    forest2->states_[1] = 1;
+    forest2->active_node(0)->set_population(0);
+    forest2->active_node(1)->set_population(1);
+    forest2->calcRates(*tii);
+
+    for (size_t i = 0; i < 100; ++i) {
+      CPPUNIT_ASSERT_NO_THROW( forest2->sampleEventType(0.5, 0, *tii, event) );
+      CPPUNIT_ASSERT( event.isMigration() );
+      CPPUNIT_ASSERT_NO_THROW( forest2->sampleEventType(0.5, 1, *tii, event) );
+      CPPUNIT_ASSERT( event.isCoalescence() );
+      CPPUNIT_ASSERT( event.node() == forest2->active_node(0) );
+      CPPUNIT_ASSERT_NO_THROW( forest2->sampleEventType(0.5, 2, *tii, event) );
+      CPPUNIT_ASSERT( event.isCoalescence() );
+      CPPUNIT_ASSERT( event.node() == forest2->active_node(1) );
+    };
+
+    forest2->active_node(0)->set_population(0);
+    forest2->active_node(1)->set_population(0);
+    forest2->calcRates(*tii);
+    for (size_t i = 0; i < 100; ++i) {
+      CPPUNIT_ASSERT_NO_THROW( forest2->sampleEventType(0.5, 0, *tii, event) );
+      CPPUNIT_ASSERT( event.isMigration() );
+      CPPUNIT_ASSERT_NO_THROW( forest2->sampleEventType(0.5, 1, *tii, event) );
+      CPPUNIT_ASSERT( event.isCoalescence() || event.isPwCoalescence() );
+    };
+
+    delete forest2->writable_model();
+    delete forest2;
+  }
+
+  void testCalcRecombinationRate() {
+    forest->writable_model()->setRecombinationRate(1, false, false, 0);
+    forest->writable_model()->setRecombinationRate(2, false, false, 10);
+    forest->writable_model()->setRecombinationRate(3, false, false, 15);
+    forest->writable_model()->setRecombinationRate(4, false, false, 20);
+    forest->writable_model()->resetSequencePosition();
+
+    Node* node = forest->nodes()->at(6);
+
+    forest->set_next_base(7.0);
+    forest->current_rec_++;
+    CPPUNIT_ASSERT_EQUAL( 2.0, forest->calcRecombinationRate(node) );
+
+    forest->writable_model()->increaseSequencePosition();
+    forest->set_current_base(12);
+    CPPUNIT_ASSERT_EQUAL( 5.0+2*2, forest->calcRecombinationRate(node) );
+
+    forest->writable_model()->increaseSequencePosition();
+    forest->set_current_base(17);
+    CPPUNIT_ASSERT_EQUAL( 5.0+10.0+6.0, forest->calcRecombinationRate(node) );
+
+    forest->writable_model()->increaseSequencePosition();
+    forest->set_current_base(22);
+    CPPUNIT_ASSERT_EQUAL( 5.0+10.0+15.0+8.0, forest->calcRecombinationRate(node) );
+  }
+
+  void testSampleEvent() {
+    Model model = Model(5);
+    Forest forest2 = Forest(&model, rg);
+    forest2.createScaledExampleTree();
+    forest2.writable_model()->finalize();
+    forest2.writable_model()->resetTime();
+
+    TimeIntervalIterator tii(&forest2, forest2.nodes()->at(0));
+
+    forest2.set_active_node(0, forest2.nodes()->at(0));
+    forest2.set_active_node(1, forest2.nodes()->at(8));
+    forest2.states_[0] = 1;
+    forest2.states_[1] = 0;
+    forest2.calcRates(*tii);
+    forest2.active_nodes_timelines_[0] = 0;
+    forest2.active_nodes_timelines_[1] = 0;
+
+    Event event;
+    double tmp_event_time = 0.0;
+    for (size_t i = 0; i < 1000; ++i) {
+      forest2.sampleEvent(*tii, tmp_event_time, event); 
+      CPPUNIT_ASSERT( event.isNoEvent() || ( 0 <= event.time() && event.time() < forest2.nodes()->at(4)->height() ) );
+      CPPUNIT_ASSERT( event.isNoEvent() || event.isCoalescence() );
+    }
+
+    ++tii;
+    forest2.calcRates(*tii);
+    for (size_t i = 0; i < 1000; ++i) {
+      forest2.sampleEvent(*tii, tmp_event_time, event); 
+      CPPUNIT_ASSERT( event.isNoEvent() || ( forest2.nodes()->at(4)->height() <= event.time() && event.time() < forest2.nodes()->at(5)->height() ) );
+      CPPUNIT_ASSERT( event.isNoEvent() || event.isCoalescence() );
+    }
+  }
+
+  void testNodeIsOld() {
+    forest->set_current_base(5.0);
+    forest->set_next_base(15);
+    forest->current_rec_++;
+
+    forest->writable_model()->disable_approximation();
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(0)) );
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(5)) );
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(6)) );
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(7)) );
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(8)) );
+
+    forest->writable_model()->set_window_length_seq(5);
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(0)) );
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(5)) );
+    CPPUNIT_ASSERT(  forest->nodeIsOld(forest->nodes()->at(6)) );
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(7)) );
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(8)) );
+
+    forest->writable_model()->set_window_length_seq(9.5);
+    CPPUNIT_ASSERT( forest->nodeIsOld(forest->nodes()->at(6)) );
+    forest->writable_model()->set_window_length_seq(10.5);
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(6)) );
+
+    forest->createExampleTree();
+    forest->writable_model()->set_window_length_rec(2);
+    forest->set_next_base(15);
+    forest->current_rec_++;
+    forest->set_next_base(20);
+    forest->current_rec_++;
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(0)) );
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(5)) );
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(6)) );
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(7)) );
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(8)) );
+
+    forest->set_next_base(25);
+    forest->current_rec_++;
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(0)) );
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(5)) );
+    CPPUNIT_ASSERT(  forest->nodeIsOld(forest->nodes()->at(6)) );
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(7)) );
+    CPPUNIT_ASSERT(! forest->nodeIsOld(forest->nodes()->at(8)) );
+  }
+
+  void testPrune() {
+    // Old node
+    forest->set_current_base(5.0);
+    forest->set_next_base(15);
+    forest->current_rec_++;
+
+    forest->writable_model()->disable_approximation();
+    forest->writable_model()->set_window_length_seq(5);
+    CPPUNIT_ASSERT( forest->model().has_approximation() );
+    CPPUNIT_ASSERT( forest->model().has_window_seq() );
+    CPPUNIT_ASSERT( !forest->model().has_window_rec() );
+
+    CPPUNIT_ASSERT(! forest->pruneNodeIfNeeded(forest->nodes()->at(0)) );
+    CPPUNIT_ASSERT(! forest->pruneNodeIfNeeded(forest->nodes()->at(1)) );
+    CPPUNIT_ASSERT(! forest->pruneNodeIfNeeded(forest->nodes()->at(2)) );
+    CPPUNIT_ASSERT(! forest->pruneNodeIfNeeded(forest->nodes()->at(3)) );
+    CPPUNIT_ASSERT(! forest->pruneNodeIfNeeded(forest->nodes()->at(4)) );
+    CPPUNIT_ASSERT(! forest->pruneNodeIfNeeded(forest->nodes()->at(5)) );
+    CPPUNIT_ASSERT(! forest->pruneNodeIfNeeded(forest->nodes()->at(7)) );
+    CPPUNIT_ASSERT(! forest->pruneNodeIfNeeded(forest->nodes()->at(8)) );
+
+    CPPUNIT_ASSERT( forest->pruneNodeIfNeeded(forest->nodes()->at(6)) );
+    CPPUNIT_ASSERT( forest->nodes()->size() == 8);
+    CPPUNIT_ASSERT( forest->checkTree() );
+
+    // Orphaned node
+    CPPUNIT_ASSERT( forest->pruneNodeIfNeeded(forest->nodes()->at(6)) );
+    CPPUNIT_ASSERT( forest->nodes()->size() == 7);
+    CPPUNIT_ASSERT( forest->checkTree() == 1 );
+
+    // In-Between Nodes should be pruned, iff they are of same age
+    Node *parent = new Node(20), 
+         *inbetween1 = new Node(19), 
+         *inbetween2 = new Node(18), 
+         *child = new Node(17);
+
+    forest->set_current_base(13);
+    inbetween2->make_nonlocal(forest->current_rec_);
+    child->make_nonlocal(forest->current_rec_);
+
+    forest->set_next_base(15);
+    forest->current_rec_++;
+    parent->make_nonlocal(forest->current_rec_);
+    inbetween1->make_nonlocal(forest->current_rec_);
+    forest->nodes()->add(parent);
+    forest->nodes()->add(inbetween1);
+    forest->nodes()->add(inbetween2);
+    forest->nodes()->add(child);
+
+    parent->set_first_child(inbetween1);
+    inbetween1->set_first_child(inbetween2);
+    inbetween2->set_first_child(child);
+    child->set_parent(inbetween2);
+    inbetween2->set_parent(inbetween1);
+    inbetween1->set_parent(parent);
+
+    CPPUNIT_ASSERT( !forest->nodeIsOld(inbetween2) );
+    CPPUNIT_ASSERT( forest->pruneNodeIfNeeded(inbetween2) );
+    CPPUNIT_ASSERT_EQUAL(inbetween1, child->parent());
+    CPPUNIT_ASSERT( inbetween1->parent() == parent );
+    CPPUNIT_ASSERT( parent->is_root() );
+    CPPUNIT_ASSERT( parent->first_child() == inbetween1 );
+    CPPUNIT_ASSERT( inbetween1->first_child() == child );
+    CPPUNIT_ASSERT( child->countChildren() == 0 );
+
+    forest->nodes()->at(0)->set_parent(NULL);
+    CPPUNIT_ASSERT(! forest->pruneNodeIfNeeded(forest->nodes()->at(0)) );
+  }
+
+  void testBuildInitialTree() {
+    Model model = Model(5);
+
+    for (size_t i = 0; i < 100; ++i) {
+      Forest frst = Forest(&model, rg);
+      frst.buildInitialTree();
+      CPPUNIT_ASSERT_EQUAL(true, frst.checkTree());
+      CPPUNIT_ASSERT( frst.current_base() == 0.0 );
+      CPPUNIT_ASSERT( frst.next_base() > 0.0 );
+    }
+
+    model = Model(2);
+    model.set_population_number(2);
+    model.addSampleSizes(0.0, std::vector<size_t>(2, 1)); 
+    model.addSymmetricMigration(0.0, 5.0, true, true);
+    model.finalize();
+    Forest frst = Forest(&model, rg);
+    CPPUNIT_ASSERT_NO_THROW( frst.buildInitialTree() );
+    CPPUNIT_ASSERT_EQUAL( true, frst.checkTree() );
+    size_t i = 0;
+    for (size_t j = 0; j < 4; ++j) {
+      CPPUNIT_ASSERT( frst.nodes()->at(j)->population() == 0 || 
+                      frst.nodes()->at(j)->population() == 1 );
+      i += frst.nodes()->at(j)->population();
+    }
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, i );
+
+    model = Model(0);
+    model.set_population_number(2);
+    std::vector<size_t> sample_size(2, 1);
+    sample_size.at(1) = 0;
+    model.addSampleSizes(0.0, sample_size); 
+    sample_size.at(0) = 0;
+    sample_size.at(1) = 1;
+    model.addSampleSizes(1.0, sample_size); 
+    model.addSymmetricMigration(0.0, 5.0, true, true);
+    model.finalize();
+    frst = Forest(&model, rg);
+    CPPUNIT_ASSERT_NO_THROW( frst.buildInitialTree() );
+    CPPUNIT_ASSERT_EQUAL( true, frst.checkTree() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, frst.nodes()->at(0)->population() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, frst.nodes()->at(1)->population() );
+    CPPUNIT_ASSERT_EQUAL( 0.0, frst.nodes()->at(0)->height() );
+    CPPUNIT_ASSERT_EQUAL( 1.0, frst.nodes()->at(1)->height() );
+  }
+
+  void testCut() {
+    Node* base_node = forest->nodes()->at(4);
+    Node* new_root = forest->cut(TreePoint(base_node, 3.5, false));
+
+    CPPUNIT_ASSERT_EQUAL((size_t)11, forest->nodes()->size());
+    CPPUNIT_ASSERT( new_root->local() );
+    CPPUNIT_ASSERT( new_root->is_root() );
+    CPPUNIT_ASSERT_EQUAL((size_t)1, new_root->countChildren() );
+    CPPUNIT_ASSERT_EQUAL(3.5, new_root->height() );
+
+    CPPUNIT_ASSERT( base_node->parent() == new_root );
+    CPPUNIT_ASSERT( base_node->local() );
+
+    Node* single_branch = forest->local_root()->first_child();
+    CPPUNIT_ASSERT( !single_branch->local() );
+    CPPUNIT_ASSERT_EQUAL( forest->segment_count(), single_branch->last_update() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, single_branch->countChildren() );
+    CPPUNIT_ASSERT_EQUAL( 3.5, single_branch->height() );
+  }
+
+  void testImplementRecombination() {
+    Node* new_root = forest->cut(TreePoint(forest->nodes()->at(4), 3.5, false));
+    TimeIntervalIterator tii(forest, new_root);
+    forest->set_active_node(0, new_root);
+    forest->set_active_node(1, forest->local_root());
+
+    forest->states_[0] = 2;
+    forest->states_[1] = 0;
+
+    Event event = Event(3.7);
+    event.setToCoalescence(new_root, 0);
+    forest->tmp_event_ = event;
+
+    forest->implementCoalescence(event, tii);
+    ++tii;
+
+    forest->set_current_base(100);
+    event.set_time(4.5);
+    event.setToRecombination(forest->active_node(0), 0);
+    CPPUNIT_ASSERT_NO_THROW( forest->implementRecombination(event, tii) );
+
+    CPPUNIT_ASSERT( forest->nodes()->at(9) == forest->active_node(0) || 
+                   forest->nodes()->at(10) == forest->active_node(0) );
+
+    CPPUNIT_ASSERT( forest->active_node(0)->local() );
+    CPPUNIT_ASSERT( forest->active_node(0)->is_root() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, forest->active_node(0)->countChildren() );
+
+    Node* single_branch = forest->nodes()->at(9);
+    if( forest->nodes()->at(9) == forest->active_node(0) ) 
+      single_branch = forest->nodes()->at(10);
+
+    CPPUNIT_ASSERT( !single_branch->local() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, single_branch->countChildren() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, single_branch->last_update() );
+  }
+
+  void testImplementCoalescence() {
+    for (size_t i=0; i<100; ++i) {
+      forest->createExampleTree(); 
+
+      Node* new_root = forest->cut(TreePoint(forest->nodes()->at(1), 1.5, false));
+      TimeIntervalIterator tii(forest, new_root);
+      CPPUNIT_ASSERT_EQUAL( (size_t)3, forest->contemporaries_.size(0) );
+      forest->set_active_node(0, new_root);
+      forest->set_active_node(1, forest->local_root());
+
+      forest->states_[0] = 1;
+      forest->states_[1] = 0;
+
+      forest->tmp_event_ = Event(2.0);
+      forest->tmp_event_.setToCoalescence(new_root, 0);
+
+      forest->implementCoalescence(forest->tmp_event_, tii);
+
+      CPPUNIT_ASSERT( forest->active_node(0) == new_root );
+      CPPUNIT_ASSERT( new_root->parent_height() == 3 ||
+                     new_root->parent_height() == 10 );
+
+      if ( !new_root->local() ) {
+        CPPUNIT_ASSERT( new_root->countChildren() == 2 );
+        CPPUNIT_ASSERT( !(new_root->first_child()->local() && new_root->second_child()->local()) ); 
+        Node* child = new_root->first_child();
+        if (!new_root->second_child()->local()) child = new_root->second_child();
+        CPPUNIT_ASSERT( child->last_update() == 1 );
+        CPPUNIT_ASSERT( child->length_below() == 0 );
+
+        CPPUNIT_ASSERT( new_root->last_update() == 1 );
+      }
+    }
+  }
+
+  void testImplementFixTimeEvent() {
+    Model* model2 = new Model(5);
+    model2->set_population_number(3);
+    model2->addSingleMigrationEvent(0.5, 0, 1, 1.0);
+    Forest* forest2 = new Forest(model2, rg);
+    forest2->createExampleTree();
+    Node* new_root = forest2->cut(TreePoint(forest2->nodes()->at(1), 0.5, false));
+    forest2->set_active_node(0, new_root);
+    forest2->set_active_node(1, forest2->local_root());
+    forest2->states_[0] = 1;
+    forest2->states_[1] = 0;
+    TimeIntervalIterator tii(forest2, new_root);
+
+    CPPUNIT_ASSERT( new_root->population() == 0 );
+    forest2->implementFixedTimeEvent(tii);
+    forest2->printTree();
+    CPPUNIT_ASSERT( new_root->is_root() );
+    CPPUNIT_ASSERT( new_root->population() == 1 );
+
+    // Chained events
+    new_root->set_population(0);
+    model2->addSingleMigrationEvent(0.5, 1, 2, 1.0);
+    forest2->implementFixedTimeEvent(tii);
+    forest2->printTree();
+    CPPUNIT_ASSERT( new_root->is_root() );
+    CPPUNIT_ASSERT( new_root->population() == 2 );
+
+    // Circe detection
+    model2->addSingleMigrationEvent(0.5, 2, 0, 1.0);
+    CPPUNIT_ASSERT_THROW( forest2->implementFixedTimeEvent(tii), 
+                          std::logic_error );
+
+    delete forest2, model2;
+  }
+
+  void testSamplePoint() {
+    rg->set_seed(1234);
+    forest->createScaledExampleTree();
+
+    TreePoint point;
+    int n0 = 0, n1 = 0, n2 = 0, n3 = 0, 
+        n4 = 0, n5 = 0;
+    for (int i = 0; i < 240000; ++i) {
+      point = forest->samplePoint();
+      CPPUNIT_ASSERT( point.base_node() != NULL );
+      CPPUNIT_ASSERT( point.base_node()->local() );
+      if (point.base_node() == forest->nodes()->at(0)) ++n0;
+      if (point.base_node() == forest->nodes()->at(1)) ++n1;
+      if (point.base_node() == forest->nodes()->at(2)) ++n2;
+      if (point.base_node() == forest->nodes()->at(3)) ++n3;
+      if (point.base_node() == forest->nodes()->at(4)) ++n4;
+      if (point.base_node() == forest->nodes()->at(5)) ++n5;
+    }
+
+    //std::cout << n0 << " " << n1 << " " << n2 << " "
+    //          << n3 << " " << n4 << " " << n5 << std::endl;
+    CPPUNIT_ASSERT( 29500 <= n0 && n0 <= 30500 ); // expected 30000 
+    CPPUNIT_ASSERT( 29500 <= n1 && n1 <= 30500 ); // expected 30000 
+    CPPUNIT_ASSERT(  9800 <= n2 && n2 <= 10200 ); // expected 10000 
+    CPPUNIT_ASSERT(  9800 <= n3 && n3 <= 10200 ); // expected 10000 
+    CPPUNIT_ASSERT( 89000 <= n4 && n4 <= 91000 ); // expected 90000 
+    CPPUNIT_ASSERT( 69000 <= n5 && n5 <= 71000 ); // expected 70000 
+  }
+
+  void testCopyConstructor() {
+    forest->createScaledExampleTree();
+    CPPUNIT_ASSERT( forest->coalescence_finished_ == true );
+    Forest forest2 = Forest(*forest);
+
+    CPPUNIT_ASSERT_EQUAL( forest->nodes()->size(), forest2.nodes()->size() );
+    CPPUNIT_ASSERT( forest2.model_ == forest->model_ );
+
+    for (auto it = forest2.nodes()->iterator(); it.good(); ++it) {
+      CPPUNIT_ASSERT( (*it)->label() <= 4 );
+      CPPUNIT_ASSERT( (*it)->parent() != NULL || (*it)->first_child() != NULL );
+    }
+
+    CPPUNIT_ASSERT( forest2.checkTree() );
+  }
+
+  void testCheckForNodeAtHeight() {
+    CPPUNIT_ASSERT( forest->checkForNodeAtHeight( 0.0 ) );
+    CPPUNIT_ASSERT( forest->checkForNodeAtHeight( 1.0 ) );
+    CPPUNIT_ASSERT( forest->checkForNodeAtHeight( 3.0 ) );
+    CPPUNIT_ASSERT( forest->checkForNodeAtHeight( 4.0 ) );
+    CPPUNIT_ASSERT( forest->checkForNodeAtHeight( 6.0 ) );
+    CPPUNIT_ASSERT( forest->checkForNodeAtHeight( 10.0 ) );
+
+    CPPUNIT_ASSERT( !forest->checkForNodeAtHeight( 0.5 ) );
+    CPPUNIT_ASSERT( !forest->checkForNodeAtHeight( 1.5 ) );
+    CPPUNIT_ASSERT( !forest->checkForNodeAtHeight( 2.0 ) );
+    CPPUNIT_ASSERT( !forest->checkForNodeAtHeight( 9.0 ) );
+    CPPUNIT_ASSERT( !forest->checkForNodeAtHeight( 20.0 ) );
+  }
+
+  void testPrintLocusSumStats() {
+    ostringstream output;
+    forest->printLocusSumStats(output);
+
+    forest->writable_model()->addSummaryStatistic(std::make_shared<TMRCA>());
+    forest->calcSegmentSumStats();
+    forest->printLocusSumStats(output);
+    CPPUNIT_ASSERT( output.str() != "" );
+  }
+
+  void testSampleNextPosition() {
+    forest->createScaledExampleTree();
+    forest->writable_model()->setRecombinationRate(0.0);
+    forest->writable_model()->setRecombinationRate(1.0, false, false, 3);
+    forest->sampleNextBase();
+    CPPUNIT_ASSERT_EQUAL(3.0, forest->next_base());
+    CPPUNIT_ASSERT_EQUAL(1.0, forest->model().recombination_rate());
+  }
+
+  void testClear() {
+    forest->createScaledExampleTree();
+    forest->writable_model()->setRecombinationRate(0.0);
+    forest->writable_model()->setRecombinationRate(1.0, false, false, 3);
+    forest->writable_model()->addSymmetricMigration(1.0, 0.5);
+    forest->writable_model()->increaseSequencePosition();
+    forest->writable_model()->increaseTime();
+    CPPUNIT_ASSERT_EQUAL(3.0, forest->model().getCurrentSequencePosition());
+    CPPUNIT_ASSERT_EQUAL(1.0, forest->model().getCurrentTime());
+
+    forest->clear();
+    CPPUNIT_ASSERT_EQUAL((size_t)0, forest->nodes()->size());
+    CPPUNIT_ASSERT_EQUAL((size_t)1, forest->rec_bases_.size());
+    CPPUNIT_ASSERT_EQUAL((size_t)0, forest->segment_count());
+    CPPUNIT_ASSERT_EQUAL(-1.0, forest->current_base());
+    CPPUNIT_ASSERT_EQUAL(0.0, forest->model().getCurrentSequencePosition());
+    CPPUNIT_ASSERT_EQUAL(0.0, forest->model().getCurrentTime());
+  }
+};
+
+
+//Uncomment this to activate the test
+CPPUNIT_TEST_SUITE_REGISTRATION( TestForest );
diff --git a/tests/unittests/test_model.cc b/tests/unittests/test_model.cc
new file mode 100644
index 0000000..dca3442
--- /dev/null
+++ b/tests/unittests/test_model.cc
@@ -0,0 +1,667 @@
+/*
+ * A sample test case which can be used as a template.
+ */
+#include <iostream>
+#include <cmath>
+#include <cppunit/TestCase.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <stdexcept>
+
+#include "../../src/model.h"
+#include "../../src/forest.h"
+#include "../../src/summary_statistics/tmrca.h"
+
+class TestModel : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE( TestModel );
+
+  CPPUNIT_TEST( testSetGetMutationRate );
+  CPPUNIT_TEST( testAddChangePositions );
+  CPPUNIT_TEST( testSetGetRecombinationRate );
+  CPPUNIT_TEST( testGetPopulationSize );
+  CPPUNIT_TEST( testAddChangeTime );
+  CPPUNIT_TEST( testAddSampleSizes );
+  CPPUNIT_TEST( testAddPopulationSizes );
+  CPPUNIT_TEST( testAddRelativePopulationSizes );
+  CPPUNIT_TEST( testAddGrowthRates );
+  CPPUNIT_TEST( testAddMigRates );
+  CPPUNIT_TEST( testAddMigRate );
+  CPPUNIT_TEST( testDebugConstructor );
+  CPPUNIT_TEST( testIncreaseTime );
+  CPPUNIT_TEST( testGetNextTime );
+  CPPUNIT_TEST( testGetters );
+  CPPUNIT_TEST( testHasFixedTimeEvent );
+  CPPUNIT_TEST( testCheck );
+  CPPUNIT_TEST( testPopSizeAfterGrowth );
+  CPPUNIT_TEST( testAddSummaryStatistic );
+  CPPUNIT_TEST( testSetLocusLength );
+  CPPUNIT_TEST( testAddPopToVectorList );
+  CPPUNIT_TEST( testAddPopToMatrixList );
+
+  CPPUNIT_TEST_SUITE_END();
+
+ public:
+  void testAddChangeTime() {
+    Model model = Model();
+    std::vector<double> v1 = std::vector<double>(1, 1), 
+                        v2 = std::vector<double>(1, 2), 
+                        v3 = std::vector<double>(1, 3); 
+
+    // Check basic adding first time;
+    CPPUNIT_ASSERT( model.addChangeTime(0) == 0 );
+    CPPUNIT_ASSERT( model.change_times_.size() == 1 );
+    CPPUNIT_ASSERT( model.change_times_.at(0) == 0 ); 
+    CPPUNIT_ASSERT( model.pop_sizes_list_.size() == 1 );
+    model.pop_sizes_list_[0] = v1;
+
+    // Check adding a time at the end;
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, model.addChangeTime(3) );
+    CPPUNIT_ASSERT( model.change_times_.size() == 2 );
+    CPPUNIT_ASSERT( model.change_times_.at(1) == 3 ); 
+    CPPUNIT_ASSERT( model.pop_sizes_list_[0] == v1 ); 
+    CPPUNIT_ASSERT( model.pop_sizes_list_[1].empty() ); 
+    model.pop_sizes_list_[1] = v3;
+
+    // Check adding a time in the middle;
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, model.addChangeTime(2) );
+    CPPUNIT_ASSERT( model.change_times_.size() == 3 );
+    CPPUNIT_ASSERT( model.change_times_.at(0) == 0 ); 
+    CPPUNIT_ASSERT( model.change_times_.at(1) == 2 ); 
+    CPPUNIT_ASSERT( model.change_times_.at(2) == 3 ); 
+    CPPUNIT_ASSERT( model.pop_sizes_list_[0] == v1 ); 
+    CPPUNIT_ASSERT( model.pop_sizes_list_[1].empty() ); 
+    CPPUNIT_ASSERT( model.pop_sizes_list_[2] == v3 ); 
+    model.pop_sizes_list_[1] = v2;
+
+    CPPUNIT_ASSERT( model.pop_sizes_list_[0] == v1 ); 
+    CPPUNIT_ASSERT( model.pop_sizes_list_[1] == v2 ); 
+    CPPUNIT_ASSERT( model.pop_sizes_list_[2] == v3 ); 
+
+    // Check that we don't add a time twice 
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, model.addChangeTime(0) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, model.addChangeTime(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, model.addChangeTime(2) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)3, model.addChangeTime(3) );
+    CPPUNIT_ASSERT( model.change_times_.size() == 4 );
+    CPPUNIT_ASSERT( model.pop_sizes_list_.size() == 4 );
+  }
+
+  void testAddSampleSizes() {
+    Model model = Model();
+    model.addSampleSizes(0.0, std::vector<size_t>(1,3));
+    CPPUNIT_ASSERT_EQUAL( model.sample_size(), (size_t)3 ); 
+    CPPUNIT_ASSERT_EQUAL( model.sample_population(2), (size_t)0 ); 
+    CPPUNIT_ASSERT_EQUAL( model.sample_time(1), (double)0.0 ); 
+
+    model = Model(0);
+    model.set_population_number(3);
+    model.addSampleSizes(0.0, std::vector<size_t>(3,1));
+    CPPUNIT_ASSERT_EQUAL( model.sample_size(), (size_t)3 ); 
+    CPPUNIT_ASSERT_EQUAL( model.sample_population(0), (size_t)0 ); 
+    CPPUNIT_ASSERT_EQUAL( model.sample_population(1), (size_t)1 ); 
+    CPPUNIT_ASSERT_EQUAL( model.sample_population(2), (size_t)2 ); 
+    CPPUNIT_ASSERT_EQUAL( model.sample_time(0), (double)0.0 ); 
+    CPPUNIT_ASSERT_EQUAL( model.sample_time(1), (double)0.0 ); 
+    CPPUNIT_ASSERT_EQUAL( model.sample_time(2), (double)0.0 ); 
+
+    std::vector<size_t> sample_size;
+    sample_size.push_back(0);
+    sample_size.push_back(0);
+    sample_size.push_back(2);
+    model.addSampleSizes(1.0, sample_size);
+    CPPUNIT_ASSERT_EQUAL( (size_t)5, model.sample_size() ); 
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, model.sample_population(3) ); 
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, model.sample_population(4) ); 
+    CPPUNIT_ASSERT_EQUAL( 1.0, model.sample_time(3) ); 
+    CPPUNIT_ASSERT_EQUAL( 1.0, model.sample_time(4) ); 
+
+    Model model2 = Model();
+    std::vector<size_t> sample_sizes;
+    sample_sizes.push_back(5);
+    sample_sizes.push_back(2);
+    model2.addSampleSizes(0.0, sample_sizes);
+    CPPUNIT_ASSERT_EQUAL( model2.sample_size(), (size_t)7 ); 
+    CPPUNIT_ASSERT_EQUAL( model2.sample_population(0), (size_t)0 ); 
+    CPPUNIT_ASSERT_EQUAL( model2.sample_population(4), (size_t)0 ); 
+    CPPUNIT_ASSERT_EQUAL( model2.sample_population(5), (size_t)1 ); 
+    CPPUNIT_ASSERT_EQUAL( model2.sample_population(6), (size_t)1 ); 
+    CPPUNIT_ASSERT_EQUAL( model2.sample_time(0), (double)0.0 ); 
+    CPPUNIT_ASSERT_EQUAL( model2.sample_time(4), (double)0.0 ); 
+    CPPUNIT_ASSERT_EQUAL( model2.sample_time(6), (double)0.0 ); 
+    sample_sizes.clear();
+    sample_sizes.push_back(2);
+    sample_sizes.push_back(1);
+    model2.addSampleSizes(7.4, sample_sizes);
+    CPPUNIT_ASSERT_EQUAL( model2.sample_size(), (size_t)10 ); 
+    CPPUNIT_ASSERT_EQUAL( model2.sample_population(7), (size_t)0 ); 
+    CPPUNIT_ASSERT_EQUAL( model2.sample_population(8), (size_t)0 ); 
+    CPPUNIT_ASSERT_EQUAL( model2.sample_population(9), (size_t)1 ); 
+    CPPUNIT_ASSERT_EQUAL( model2.sample_time(0), (double)0.0 ); 
+    CPPUNIT_ASSERT_EQUAL( model2.sample_time(6), (double)0.0 ); 
+    CPPUNIT_ASSERT_EQUAL( model2.sample_time(8), (double)7.4 ); 
+  }
+
+  void testAddPopulationSizes() {
+    Model model = Model();
+    model.set_population_number(2);
+    model.addPopulationSizes(1, std::vector<double>(2, 4));
+    model.resetTime();
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 1.0, model.getCurrentTime() );
+    CPPUNIT_ASSERT( model.population_size(0) == 4 );
+
+    model.addPopulationSizes(1, std::vector<double>(2, 5), true, false);
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 1.0 * 4 * model.default_pop_size, model.getCurrentTime() );
+    CPPUNIT_ASSERT( model.population_size(0) == 5 );
+
+    model.addPopulationSizes(2, 10, true, false);
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 2.0 * 4 * model.default_pop_size, model.getCurrentTime() );
+    CPPUNIT_ASSERT( model.population_size(0) == 10 );
+
+    auto pop_sizes2 = std::vector<double>();
+    pop_sizes2.push_back(7);
+    pop_sizes2.push_back(6);
+    model.addPopulationSizes(0.0, pop_sizes2);
+    model.resetTime();
+    CPPUNIT_ASSERT( model.population_size(0) == 7 );
+    CPPUNIT_ASSERT( model.population_size(1) == 6 );
+    
+    CPPUNIT_ASSERT_THROW( model.addPopulationSizes(1, std::vector<double>(1, 5)), std::logic_error );
+    CPPUNIT_ASSERT_THROW( model.addPopulationSizes(1, std::vector<double>(3, 5)), std::logic_error );
+  }
+  
+  void testAddRelativePopulationSizes() {
+    Model model = Model();
+    model.set_population_number(2);
+    model.addPopulationSizes(1, std::vector<double>(2, .5), false, true);
+    model.resetTime();
+    model.increaseTime();
+
+    CPPUNIT_ASSERT_EQUAL( 1.0, model.getCurrentTime() );
+    CPPUNIT_ASSERT_EQUAL( 0.5 * model.default_pop_size, model.population_size(0) );
+
+    model.addPopulationSizes(1, std::vector<double>(2, .4), true, true);
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 1.0 * 4 * model.default_pop_size, model.getCurrentTime() );
+    CPPUNIT_ASSERT_EQUAL( 0.4 * model.default_pop_size, model.population_size(0) );
+
+    model.addPopulationSizes(2, 10, true, true);
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 2.0 * 4 * model.default_pop_size, model.getCurrentTime() );
+    CPPUNIT_ASSERT( areSame(10.0 * model.default_pop_size, model.population_size(0)) );
+
+    CPPUNIT_ASSERT_THROW( model.addPopulationSizes(3, 0, true, true), std::invalid_argument);
+  }
+
+  void testAddGrowthRates() {
+    Model model = Model();
+    model.set_population_number(2);
+
+    model.addGrowthRates(1, std::vector<double>(2, 1.5));
+    CPPUNIT_ASSERT( model.growth_rates_list_.at(1).at(0) == 1.5 );
+
+    std::vector<double> growth_rates2 = std::vector<double>();
+    growth_rates2.push_back(2.5);
+    growth_rates2.push_back(3.5);
+    model.addGrowthRates(0, growth_rates2);
+    CPPUNIT_ASSERT( model.growth_rates_list_.at(0).at(0) == 2.5 );
+    CPPUNIT_ASSERT( model.growth_rates_list_.at(0).at(1) == 3.5 );
+
+    CPPUNIT_ASSERT_THROW( model.addGrowthRates(1, std::vector<double>(1, 5)), std::logic_error );
+    CPPUNIT_ASSERT_THROW( model.addGrowthRates(1, std::vector<double>(3, 5)), std::logic_error );
+  }
+
+  void testGetPopulationSize() {
+    Model model = Model(2);
+    model.set_population_number(2);
+    model.addSymmetricMigration(0.0, 1);
+    model.addGrowthRates(1.0, std::vector<double>(2, 1.5));
+    model.finalize();
+    model.resetTime();
+
+    CPPUNIT_ASSERT( areSame( model.default_pop_size,  model.population_size() ) );
+    CPPUNIT_ASSERT( areSame( model.default_pop_size,  model.population_size(0) ) );
+    CPPUNIT_ASSERT( areSame( model.default_pop_size,  model.population_size(1) ) );
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 1.0, model.getCurrentTime() );
+    CPPUNIT_ASSERT( areSame( model.default_pop_size,  model.population_size(0) ) );
+    CPPUNIT_ASSERT( areSame( model.default_pop_size * std::exp( -1.5 ),  model.population_size(0, 2.0) ) );
+  }
+
+  void testAddMigRates() {
+    Model model = Model(2);
+    model.set_population_number(3);
+
+    std::vector<double> rates;
+    for (size_t i = 1; i < 9; ++i) {
+      rates.push_back(i);
+    }
+    CPPUNIT_ASSERT_THROW( model.addMigrationRates(1, rates), std::logic_error );
+    rates.push_back(9);
+    model.addMigrationRates(1, rates);
+    
+    model.resetTime();
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 2.0, model.migration_rate(0,1) );
+    CPPUNIT_ASSERT_EQUAL( 3.0, model.migration_rate(0,2) );
+    CPPUNIT_ASSERT_EQUAL( 4.0, model.migration_rate(1,0) );
+    CPPUNIT_ASSERT_EQUAL( 7.0, model.migration_rate(2,0) );
+    CPPUNIT_ASSERT_EQUAL( 6.0, model.migration_rate(1,2) );
+  }
+
+  void testAddMigRate() {
+    Model model = Model(2);
+    model.set_population_number(2);
+    model.addMigrationRate(0.0, 0, 1, 0.5);
+    model.resetTime();
+    CPPUNIT_ASSERT_EQUAL( 0.5, model.migration_rate(0,1) );
+    CPPUNIT_ASSERT( std::isnan(model.migration_rate(1,0)) );
+
+    model.addMigrationRate(0.0, 0, 1, 0.7);
+    CPPUNIT_ASSERT_EQUAL( 0.7, model.migration_rate(0,1) );
+    CPPUNIT_ASSERT( std::isnan(model.migration_rate(1,0)) );
+
+    model.addMigrationRate(0.0, 1, 0, 0.9);
+    CPPUNIT_ASSERT_EQUAL( 0.7, model.migration_rate(0,1) );
+    CPPUNIT_ASSERT_EQUAL( 0.9, model.migration_rate(1,0) );
+  }
+
+  void testDebugConstructor() {
+    Model model = Model(7);
+    CPPUNIT_ASSERT_EQUAL( (size_t)7, model.sample_size() );
+    CPPUNIT_ASSERT( model.growth_rate(0) == 0 );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, model.current_time_idx_ );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, model.current_seq_idx_ );
+  }
+
+  void testAddChangePositions() {
+    Model model = Model(7);
+    CPPUNIT_ASSERT_EQUAL((size_t)1, model.change_position_.size());
+    CPPUNIT_ASSERT_EQUAL(0.0, model.change_position_[0]);
+    CPPUNIT_ASSERT_EQUAL((size_t)1, model.mutation_rates_.size());
+    CPPUNIT_ASSERT_EQUAL((size_t)1, model.recombination_rates_.size());
+
+    // 0.0 is already in => no change
+    CPPUNIT_ASSERT_EQUAL((size_t)0, model.addChangePosition(0.0));
+    CPPUNIT_ASSERT_EQUAL((size_t)1, model.change_position_.size());
+    CPPUNIT_ASSERT_EQUAL(0.0, model.change_position_[0]);
+    CPPUNIT_ASSERT_EQUAL((size_t)1, model.mutation_rates_.size());
+    CPPUNIT_ASSERT_EQUAL((size_t)1, model.recombination_rates_.size());
+
+    // Really add 1.0 ad the end
+    CPPUNIT_ASSERT_EQUAL((size_t)1, model.addChangePosition(1.0));
+    CPPUNIT_ASSERT_EQUAL((size_t)2, model.change_position_.size());
+    CPPUNIT_ASSERT_EQUAL(0.0, model.change_position_[0]);
+    CPPUNIT_ASSERT_EQUAL(1.0, model.change_position_[1]);
+    CPPUNIT_ASSERT_EQUAL((size_t)2, model.mutation_rates_.size());
+    CPPUNIT_ASSERT_EQUAL((size_t)2, model.recombination_rates_.size());
+
+    // Really add 1.0 again => nothing changes
+    CPPUNIT_ASSERT_EQUAL((size_t)1, model.addChangePosition(1.0));
+    CPPUNIT_ASSERT_EQUAL((size_t)2, model.change_position_.size());
+    CPPUNIT_ASSERT_EQUAL(0.0, model.change_position_[0]);
+    CPPUNIT_ASSERT_EQUAL(1.0, model.change_position_[1]);
+    CPPUNIT_ASSERT_EQUAL((size_t)2, model.mutation_rates_.size());
+    CPPUNIT_ASSERT_EQUAL((size_t)2, model.recombination_rates_.size());
+
+    // Add 0.5 in the middle
+    CPPUNIT_ASSERT_EQUAL((size_t)1, model.addChangePosition(0.5));
+    CPPUNIT_ASSERT_EQUAL((size_t)3, model.change_position_.size());
+    CPPUNIT_ASSERT_EQUAL(0.0, model.change_position_[0]);
+    CPPUNIT_ASSERT_EQUAL(0.5, model.change_position_[1]);
+    CPPUNIT_ASSERT_EQUAL(1.0, model.change_position_[2]);
+    CPPUNIT_ASSERT_EQUAL((size_t)3, model.mutation_rates_.size());
+    CPPUNIT_ASSERT_EQUAL((size_t)3, model.recombination_rates_.size());
+  }
+
+  void testIncreaseTime() {
+    Model model = Model(7);
+    model.addGrowthRates(1.0, std::vector<double>(1, 1.5));
+    model.addGrowthRates(2.0, std::vector<double>(1, 1));
+    
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, model.current_time_idx_ );
+    CPPUNIT_ASSERT_NO_THROW( model.increaseTime() );
+
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, model.current_time_idx_ );
+    CPPUNIT_ASSERT_NO_THROW( model.increaseTime() );
+
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, model.current_time_idx_ );
+
+    CPPUNIT_ASSERT_THROW( model.increaseTime(), std::out_of_range );
+  }
+
+  void testGetNextTime() {
+    Model model = Model(7);
+    CPPUNIT_ASSERT( model.getNextTime() == DBL_MAX );
+
+    model.addGrowthRates(1.0, std::vector<double>(1, 1.5));
+    model.addGrowthRates(2.0, std::vector<double>(1, 1));
+
+    CPPUNIT_ASSERT_EQUAL( 1.0, model.getNextTime() );
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 2.0, model.getNextTime() );
+    model.increaseTime();
+    CPPUNIT_ASSERT( model.getNextTime() == DBL_MAX );
+  }
+
+  void testGetters() {
+    Model model = Model(7);
+    model.addGrowthRates(1.0, std::vector<double>(1, 1.5));
+    model.addPopulationSizes(2.0, std::vector<double>(1, 5000));
+    model.addGrowthRates(3.0, std::vector<double>(1, 1));
+    model.addPopulationSizes(4.0, std::vector<double>(1, 10000));
+
+    CPPUNIT_ASSERT_EQUAL( (size_t)7, model.sample_size() );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.growth_rate(0) );
+    CPPUNIT_ASSERT_EQUAL( model.default_pop_size, model.population_size(0) );
+
+    CPPUNIT_ASSERT_NO_THROW( model.increaseTime() ); // 1.0
+    CPPUNIT_ASSERT_EQUAL( 1.5, model.growth_rate(0) );
+    CPPUNIT_ASSERT_EQUAL( model.default_pop_size, model.population_size(0) );
+
+    CPPUNIT_ASSERT_NO_THROW( model.increaseTime() ); // 2.0
+    CPPUNIT_ASSERT_EQUAL( 1.5, model.growth_rate(0) );
+    CPPUNIT_ASSERT_EQUAL( 5000.0, model.population_size(0) );
+
+    CPPUNIT_ASSERT_NO_THROW( model.increaseTime() ); // 3.0
+    CPPUNIT_ASSERT_EQUAL( 1.0, model.growth_rate(0) );
+    CPPUNIT_ASSERT_EQUAL( 5000.0, model.population_size(0) );
+
+    CPPUNIT_ASSERT_NO_THROW( model.increaseTime() ); // 4.0
+    CPPUNIT_ASSERT_EQUAL( 1.0, model.growth_rate(0) );
+    CPPUNIT_ASSERT_EQUAL( 10000.0, model.population_size(0) );
+  }
+
+  void testHasFixedTimeEvent() {
+    Model model = Model();
+    model.set_population_number(3);
+
+    model.addSingleMigrationEvent(10, 1, 0, .5);
+    model.resetTime();
+    CPPUNIT_ASSERT( ! model.hasFixedTimeEvent(1) );
+    CPPUNIT_ASSERT( ! model.hasFixedTimeEvent(10) );
+    model.increaseTime();
+    CPPUNIT_ASSERT( model.hasFixedTimeEvent(10) );
+    CPPUNIT_ASSERT( ! model.hasFixedTimeEvent(1) );
+    CPPUNIT_ASSERT( ! model.hasFixedTimeEvent(20) );
+  }
+
+  void testSetGetMutationRate() {
+    Model model = Model(5);
+    model.setMutationRate(0.001);
+    CPPUNIT_ASSERT_EQUAL( 0.001, model.mutation_rate() );
+    
+    model.setMutationRate(10, false, false);
+    CPPUNIT_ASSERT_EQUAL( 10.0, model.mutation_rate() );
+
+    model.setMutationRate(10, true, false);
+    CPPUNIT_ASSERT_EQUAL( 10.0/model.default_loci_length, model.mutation_rate() );
+
+    model.setMutationRate(10, false, true);
+    CPPUNIT_ASSERT_EQUAL( 10.0/(4*model.default_pop_size), model.mutation_rate() );
+
+    model.setMutationRate(10, true, true);
+    CPPUNIT_ASSERT_EQUAL(10.0/(4*model.default_pop_size*model.default_loci_length), 
+                         model.mutation_rate() );
+
+    // Test setting multiple rates
+    model.setMutationRate(10, false, false, 0.0);
+    model.setMutationRate(5, false, false, 2.0);
+    CPPUNIT_ASSERT_EQUAL(10.0, model.mutation_rate());
+    model.increaseSequencePosition();
+    CPPUNIT_ASSERT_EQUAL(5.0, model.mutation_rate());
+
+    model.setMutationRate(7.5, false, false, 1.0);
+    model.resetSequencePosition();
+    CPPUNIT_ASSERT_EQUAL(10.0, model.mutation_rate());
+    model.increaseSequencePosition();
+    CPPUNIT_ASSERT_EQUAL(7.5, model.mutation_rate());
+    model.increaseSequencePosition();
+    CPPUNIT_ASSERT_EQUAL(5.0, model.mutation_rate());
+
+    // Test if the vector are filled during finalization
+    model.resetSequencePosition();
+    model.setRecombinationRate(2.5, false, false, 0.5);
+    model.finalize();
+    CPPUNIT_ASSERT_EQUAL(10.0, model.mutation_rate());
+    model.increaseSequencePosition();
+    CPPUNIT_ASSERT_EQUAL(10.0, model.mutation_rate());
+    model.increaseSequencePosition();
+    CPPUNIT_ASSERT_EQUAL(7.5, model.mutation_rate());
+    model.increaseSequencePosition();
+    CPPUNIT_ASSERT_EQUAL(5.0, model.mutation_rate());
+  }
+
+  void testSetGetRecombinationRate() {
+    Model model = Model();
+    CPPUNIT_ASSERT( !model.has_recombination() );
+
+    model.setLocusLength(101);
+    model.setRecombinationRate(0.001);
+    CPPUNIT_ASSERT_EQUAL( 0.001, model.recombination_rate() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)101, model.loci_length() );
+    CPPUNIT_ASSERT( model.has_recombination() );
+
+    model.setRecombinationRate(0.001, false, false);
+    CPPUNIT_ASSERT_EQUAL( 0.001, model.recombination_rate() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)101, model.loci_length() );
+    CPPUNIT_ASSERT( model.has_recombination() );
+
+    model.setRecombinationRate(0.001, true, false);
+    CPPUNIT_ASSERT_EQUAL( 0.00001, model.recombination_rate() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)101, model.loci_length() );
+    CPPUNIT_ASSERT( model.has_recombination() );
+
+    model.setRecombinationRate(0.001, false, true);
+    CPPUNIT_ASSERT_EQUAL( 0.001/(4*model.default_pop_size), model.recombination_rate() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)101, model.loci_length() );
+
+    model.setRecombinationRate(0.001, true, true);
+    CPPUNIT_ASSERT( areSame(0.00001/(4*model.default_pop_size), model.recombination_rate()) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)101, model.loci_length() );
+
+    CPPUNIT_ASSERT_THROW( model.setRecombinationRate(-0.001, 100), std::invalid_argument );
+
+    // Test setting multiple rates
+    model.setRecombinationRate(10, false, false, 0.0);
+    model.setRecombinationRate(5, false, false, 2.0);
+    CPPUNIT_ASSERT_EQUAL(10.0, model.recombination_rate());
+    model.increaseSequencePosition();
+    CPPUNIT_ASSERT_EQUAL(5.0, model.recombination_rate());
+
+    model.setRecombinationRate(7.5, false, false, 1.0);
+    model.resetSequencePosition();
+    CPPUNIT_ASSERT_EQUAL(10.0, model.recombination_rate());
+    model.increaseSequencePosition();
+    CPPUNIT_ASSERT_EQUAL(7.5, model.recombination_rate());
+    model.increaseSequencePosition();
+    CPPUNIT_ASSERT_EQUAL(5.0, model.recombination_rate());
+  }
+
+  void testCheck() {
+    Model model = Model(1);
+    CPPUNIT_ASSERT_THROW( model.check(), std::invalid_argument );
+
+    model = Model(2);
+    model.set_population_number(2);
+    CPPUNIT_ASSERT_THROW( model.check(), std::invalid_argument );
+    model.addMigrationRate(20, 0, 1, 0.0);
+    CPPUNIT_ASSERT_THROW( model.finalize(), std::invalid_argument );
+    model.addMigrationRate(10, 0, 1, 5.0);
+    CPPUNIT_ASSERT_NO_THROW( model.finalize() );
+
+    model = Model(3);
+    model.set_population_number(2);
+    model.addSingleMigrationEvent(1, 0, 1, 1);
+    CPPUNIT_ASSERT_NO_THROW( model.check() );
+  } 
+
+  void testPopSizeAfterGrowth() {
+    // Growth only
+    Model model = Model(5); 
+    model.set_population_number(2);
+    model.addSymmetricMigration(0, 1.0);
+    model.addPopulationSizes(0, 1000);
+    std::vector<double> growth_rates;
+    growth_rates.push_back(-0.5);
+    growth_rates.push_back(0.5);
+    model.addGrowthRates(1.0, growth_rates);
+    model.addGrowthRates(2.5, 2);
+    model.addSingleMigrationEvent(3.5, 1, 0, 0.5);
+    model.finalize();
+
+    model.increaseTime();
+    model.increaseTime();
+    double n_1 = 1000*std::exp(0.5*1.5),
+           n_2 = 1000*std::exp(-0.5*1.5);
+    CPPUNIT_ASSERT( areSame( n_1, model.population_size(0) ) );
+    CPPUNIT_ASSERT( areSame( n_2, model.population_size(1) ) );
+    model.increaseTime();
+    CPPUNIT_ASSERT( areSame( n_1*std::exp(-2), model.population_size(0) ) );
+    CPPUNIT_ASSERT( areSame( n_2*std::exp(-2), model.population_size(1) ) );
+    CPPUNIT_ASSERT( areSame( n_1*std::exp(-2*2), model.population_size(0, 4.5) ) );
+    CPPUNIT_ASSERT( areSame( n_2*std::exp(-2*2), model.population_size(1, 4.5) ) );
+    
+    // Growth with a pop size change in between
+    model = Model(5); 
+    model.set_population_number(2);
+    model.addSymmetricMigration(0, 1.0);
+    growth_rates.clear();
+    growth_rates.push_back(-0.5);
+    growth_rates.push_back(0.5);
+    model.addGrowthRates(1.0, growth_rates);
+    model.addSymmetricMigration(1.25, 2.0);
+    model.addPopulationSize(1.5, 0, 500);
+    model.addGrowthRate(2.5, 1, 2.0);
+    model.addPopulationSize(3.0, 0, 500);
+    model.addGrowthRate(3.5, 0, 2.0);
+    model.finalize();
+    //std::cout << model << std::endl;
+    
+
+    model.resetTime();
+    double size0 = model.default_pop_size;
+    double size1 = model.default_pop_size;
+    CPPUNIT_ASSERT( areSame( size0, model.population_size(0) ) );
+    CPPUNIT_ASSERT( areSame( size1, model.population_size(1) ) );
+
+    model.increaseTime(); 
+    CPPUNIT_ASSERT_EQUAL( 1.0, model.getCurrentTime() );
+    CPPUNIT_ASSERT( areSame( size0, model.population_size(0) ) );
+    CPPUNIT_ASSERT( areSame( size1, model.population_size(1) ) );
+
+    model.increaseTime(); 
+    CPPUNIT_ASSERT_EQUAL( 1.25, model.getCurrentTime() );
+    CPPUNIT_ASSERT( areSame( size0*std::exp(0.5*0.25), model.population_size(0) ) );
+    CPPUNIT_ASSERT( areSame( size0*std::exp(-0.5*0.25), model.population_size(1) ) );
+
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 1.5, model.getCurrentTime() );
+    CPPUNIT_ASSERT( areSame( 500, model.population_size(0) ) );
+    CPPUNIT_ASSERT( areSame( model.default_pop_size*std::exp(-0.5*0.5), model.population_size(1) ) );
+
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 2.5, model.getCurrentTime() );
+    size0 = 500*std::exp(0.5*1.0);
+    size1 = model.default_pop_size*std::exp(-0.5*1.5);
+    CPPUNIT_ASSERT( areSame( size0, model.population_size(0) ) );
+    CPPUNIT_ASSERT( areSame( size1, model.population_size(1) ) );
+
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 3.0, model.getCurrentTime() );
+    size0  = 500; 
+    size1 *= exp(-2*0.5);
+    CPPUNIT_ASSERT( areSame( size0, model.population_size(0) ) );
+    CPPUNIT_ASSERT( areSame( size1, model.population_size(1) ) );
+
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 3.5, model.getCurrentTime() );
+    size0 *= exp(0.5*0.5);
+    size1 *= exp(-2*0.5);
+    CPPUNIT_ASSERT( areSame( size0, model.population_size(0) ) );
+    CPPUNIT_ASSERT( areSame( size1, model.population_size(1) ) );
+
+    model = Model(5); 
+    model.set_population_number(2);
+    model.addSymmetricMigration(0, 1.0);
+    model.addPopulationSize(0, 1, 500);
+    model.finalize();
+    //std::cout << model << std::endl;
+    model.resetTime();
+    CPPUNIT_ASSERT( areSame( model.default_pop_size, model.population_size(0) ) );
+    CPPUNIT_ASSERT( areSame( 500.0, model.population_size(1) ) );
+  }
+
+  void testAddSummaryStatistic() {
+    Model model = Model(5);
+    CPPUNIT_ASSERT(model.countSummaryStatistics() == 0); 
+    model.addSummaryStatistic(std::make_shared<TMRCA>());
+    CPPUNIT_ASSERT(model.countSummaryStatistics() == 1); 
+  }
+
+  void testSetLocusLength() {
+    Model model = Model(5);
+    CPPUNIT_ASSERT_EQUAL(model.default_loci_length, model.loci_length() );
+    model.setMutationRate(5.0, true, false);
+    CPPUNIT_ASSERT_EQUAL(5.0/model.default_loci_length, model.mutation_rate());
+
+    model.setLocusLength(2000);
+    CPPUNIT_ASSERT_EQUAL((size_t)2000, model.loci_length() );
+    CPPUNIT_ASSERT_EQUAL(0.0025, model.mutation_rate());
+
+    model.setLocusLength(5000);
+    CPPUNIT_ASSERT_EQUAL((size_t)5000, model.loci_length() );
+    CPPUNIT_ASSERT_EQUAL(0.001, model.mutation_rate());
+  }
+
+  void testAddPopToVectorList() {
+    Model model = Model(5);
+    std::vector<std::vector<double> > vector_list;
+    vector_list.push_back(std::vector<double>(2, 1.0));    
+    vector_list.push_back(std::vector<double>());    
+    vector_list.push_back(std::vector<double>(2, 0.5));    
+
+    model.addPopToVectorList(vector_list);
+    CPPUNIT_ASSERT_EQUAL( (size_t)3, vector_list.at(0).size() );
+    CPPUNIT_ASSERT_EQUAL( 1.0, vector_list.at(0).at(0) );
+    CPPUNIT_ASSERT_EQUAL( 1.0, vector_list.at(0).at(1) );
+    CPPUNIT_ASSERT( std::isnan(vector_list.at(0).at(2)));
+
+    CPPUNIT_ASSERT_EQUAL( (size_t)3, vector_list.at(2).size() );
+    CPPUNIT_ASSERT_EQUAL( 0.5, vector_list.at(2).at(0) );
+    CPPUNIT_ASSERT_EQUAL( 0.5, vector_list.at(2).at(1) );
+    CPPUNIT_ASSERT( std::isnan(vector_list.at(2).at(2)));
+  }
+
+  void testAddPopToMatrixList() {
+    Model model = Model(5);
+    std::vector<std::vector<double> > vector_list;
+    vector_list.push_back(std::vector<double>(2, 1.0));    
+    vector_list.push_back(std::vector<double>());    
+    vector_list.push_back(std::vector<double>(2, 0.5));    
+
+    model.set_population_number(3);
+    model.addPopToMatrixList(vector_list, 2);
+
+    CPPUNIT_ASSERT_EQUAL( (size_t)6, vector_list.at(0).size() );
+    CPPUNIT_ASSERT_EQUAL( 1.0, vector_list.at(0).at(0) );
+    CPPUNIT_ASSERT_EQUAL( 1.0, vector_list.at(0).at(2) );
+    CPPUNIT_ASSERT( std::isnan(vector_list.at(0).at(1)));
+    CPPUNIT_ASSERT( std::isnan(vector_list.at(0).at(3)));
+    CPPUNIT_ASSERT( std::isnan(vector_list.at(0).at(4)));
+    CPPUNIT_ASSERT( std::isnan(vector_list.at(0).at(5)));
+
+    CPPUNIT_ASSERT_EQUAL( (size_t)6, vector_list.at(2).size() );
+    CPPUNIT_ASSERT_EQUAL( 0.5, vector_list.at(2).at(0) );
+    CPPUNIT_ASSERT_EQUAL( 0.5, vector_list.at(2).at(2) );
+    CPPUNIT_ASSERT( std::isnan(vector_list.at(0).at(1)));
+    CPPUNIT_ASSERT( std::isnan(vector_list.at(0).at(3)));
+    CPPUNIT_ASSERT( std::isnan(vector_list.at(0).at(4)));
+    CPPUNIT_ASSERT( std::isnan(vector_list.at(0).at(5)));
+  }
+};
+
+//Uncomment this to activate the test
+CPPUNIT_TEST_SUITE_REGISTRATION( TestModel );
diff --git a/tests/unittests/test_node.cc b/tests/unittests/test_node.cc
new file mode 100644
index 0000000..1e6f501
--- /dev/null
+++ b/tests/unittests/test_node.cc
@@ -0,0 +1,175 @@
+/*
+ * A sample test case which can be used as a template.
+ */
+#include <cppunit/TestCase.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "../../src/node.h"
+#include "../../src/forest.h"
+#include "../../src/random/constant_generator.h"
+
+class TestNode : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE( TestNode );
+
+  CPPUNIT_TEST( testGettersAndSetters );
+  CPPUNIT_TEST( testIsRoot );
+  CPPUNIT_TEST( testInSample );
+  CPPUNIT_TEST( testSamplesBelow );
+  CPPUNIT_TEST( testLengthBelow );
+  CPPUNIT_TEST( testCountChildren );
+  CPPUNIT_TEST( testLocalNavigation );
+
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  Forest *forest;
+  ConstantGenerator *rg;
+  Model *model;
+
+ public:
+  void setUp() {
+    rg = new ConstantGenerator();
+    model = new Model(0);
+    forest = new Forest(model, rg);
+    forest->createExampleTree();
+  }
+
+  void tearDown() {
+    delete forest;
+    delete rg;
+    delete model;
+  }
+
+  void testGettersAndSetters() {
+    Node node1, node2;
+
+    //height
+    node1.set_height(1);
+    CPPUNIT_ASSERT( node1.height() == 1 );
+
+    //parent
+    node2.set_parent(&node1);
+    CPPUNIT_ASSERT( node2.parent()->height() == 1 );
+
+    //Children
+    node2.set_second_child(&node1);
+    CPPUNIT_ASSERT( node2.second_child()->height() == 1 );
+    node2.set_first_child(&node1);
+    CPPUNIT_ASSERT( node2.first_child()->height() == 1 );
+
+    //local
+    node1.make_local();
+    node2.make_nonlocal(1);
+    CPPUNIT_ASSERT( node1.local() && !node2.local() );
+    node1.make_nonlocal(1);
+    node2.make_local();
+    CPPUNIT_ASSERT( (!node1.local()) && node2.local() );
+
+    //population
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, node1.population() );
+    node1.set_population(1);
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, node1.population() );
+  }
+
+  void testIsRoot(){
+    CPPUNIT_ASSERT( !forest->nodes()->get(0)->is_root() );
+    CPPUNIT_ASSERT( !forest->nodes()->get(1)->is_root() );
+    CPPUNIT_ASSERT( !forest->nodes()->get(2)->is_root() );
+    CPPUNIT_ASSERT( !forest->nodes()->get(3)->is_root() );
+    CPPUNIT_ASSERT( !forest->nodes()->get(4)->is_root() );
+    CPPUNIT_ASSERT( !forest->nodes()->get(5)->is_root() );
+    CPPUNIT_ASSERT( !forest->nodes()->get(6)->is_root() );
+    CPPUNIT_ASSERT( forest->nodes()->get(7)->is_root() );
+    CPPUNIT_ASSERT( forest->nodes()->get(8)->is_root() );
+  }
+
+  void testInSample(){
+    CPPUNIT_ASSERT( forest->nodes()->get(0)->in_sample() );
+    CPPUNIT_ASSERT( forest->nodes()->get(1)->in_sample() );
+    CPPUNIT_ASSERT( forest->nodes()->get(2)->in_sample() );
+    CPPUNIT_ASSERT( forest->nodes()->get(3)->in_sample() );
+    CPPUNIT_ASSERT( !forest->nodes()->get(4)->in_sample() );
+    CPPUNIT_ASSERT( !forest->nodes()->get(5)->in_sample() );
+    CPPUNIT_ASSERT( !forest->nodes()->get(6)->in_sample() );
+    CPPUNIT_ASSERT( !forest->nodes()->get(7)->in_sample() );
+    CPPUNIT_ASSERT( !forest->nodes()->get(8)->in_sample() );
+  }
+
+  void testSamplesBelow(){
+    CPPUNIT_ASSERT( forest->nodes()->get(0)->samples_below() == 1 );
+    CPPUNIT_ASSERT( forest->nodes()->get(1)->samples_below() == 1 );
+    CPPUNIT_ASSERT( forest->nodes()->get(2)->samples_below() == 1 );
+    CPPUNIT_ASSERT( forest->nodes()->get(3)->samples_below() == 1 );
+    CPPUNIT_ASSERT( forest->nodes()->get(4)->samples_below() == 2 );
+    CPPUNIT_ASSERT( forest->nodes()->get(5)->samples_below() == 2 );
+    CPPUNIT_ASSERT( forest->nodes()->get(6)->samples_below() == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(7)->samples_below() == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(8)->samples_below() == 4 );
+  }
+
+  void testLengthBelow(){
+    CPPUNIT_ASSERT( forest->nodes()->get(0)->length_below() == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(1)->length_below() == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(2)->length_below() == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(3)->length_below() == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(4)->length_below() == 2 );
+    CPPUNIT_ASSERT( forest->nodes()->get(5)->length_below() == 6 );
+    CPPUNIT_ASSERT( forest->nodes()->get(6)->length_below() == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(7)->length_below() == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(8)->length_below() == 24 );
+  }
+
+  void testCountChildren(){
+    CPPUNIT_ASSERT( forest->nodes()->get(0)->countChildren() == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(1)->countChildren() == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(2)->countChildren() == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(3)->countChildren() == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(4)->countChildren() == 2 );
+    CPPUNIT_ASSERT( forest->nodes()->get(5)->countChildren() == 2 );
+    CPPUNIT_ASSERT( forest->nodes()->get(6)->countChildren() == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(7)->countChildren() == 1 );
+    CPPUNIT_ASSERT( forest->nodes()->get(8)->countChildren() == 2 );
+
+    CPPUNIT_ASSERT( forest->nodes()->get(0)->countChildren(true) == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(1)->countChildren(true) == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(2)->countChildren(true) == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(3)->countChildren(true) == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(4)->countChildren(true) == 2 );
+    CPPUNIT_ASSERT( forest->nodes()->get(5)->countChildren(true) == 2 );
+    CPPUNIT_ASSERT( forest->nodes()->get(6)->countChildren(true) == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(7)->countChildren(true) == 0 );
+    CPPUNIT_ASSERT( forest->nodes()->get(8)->countChildren(true) == 2 );
+
+    forest->nodes()->at(4)->make_nonlocal(1.0);
+    CPPUNIT_ASSERT( forest->nodes()->get(8)->countChildren(true) == 1 );
+  }
+
+  void testLocalNavigation() {
+    Node* n1 = new Node(7.5);
+    n1->make_local();
+    Node* n2 = new Node(6.5);
+    n2->make_nonlocal(1.0);
+
+    Node *n3 = forest->nodes()->at(4), 
+         *root = forest->local_root(),
+         *n4 = forest->nodes()->at(5);
+
+    root->remove_child(n3);
+    forest->addNodeToTree(n1, root, n3, NULL);
+    forest->addNodeToTree(n2, n1, NULL, NULL);
+
+    CPPUNIT_ASSERT(n1->countChildren() == 2);
+    CPPUNIT_ASSERT(n1->countChildren(true) == 1);
+    CPPUNIT_ASSERT(n1->getLocalParent() == root);
+    CPPUNIT_ASSERT(n3->getLocalParent() == root);
+
+    CPPUNIT_ASSERT( (root->getLocalChild1() == n3 && root->getLocalChild2() == n4) || 
+                    (root->getLocalChild1() == n4 && root->getLocalChild2() == n3) );
+
+    CPPUNIT_ASSERT(forest->nodes()->at(0)->getLocalChild1() == NULL);
+    CPPUNIT_ASSERT(forest->nodes()->at(1)->getLocalChild1() == NULL);
+    CPPUNIT_ASSERT(n4->getLocalParent() == root);
+  }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TestNode );
diff --git a/tests/unittests/test_node_container.cc b/tests/unittests/test_node_container.cc
new file mode 100644
index 0000000..fc082cd
--- /dev/null
+++ b/tests/unittests/test_node_container.cc
@@ -0,0 +1,248 @@
+/*
+ * Unit tests for NodeContainer
+ * If the container passes this tests, it should also do for the remaining code
+ * */
+#include <cppunit/TestCase.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "../../src/forest.h"
+
+
+class TestNodeContainer : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE( TestNodeContainer );
+
+  CPPUNIT_TEST( testGet );
+  CPPUNIT_TEST( testAdd );
+  CPPUNIT_TEST( testNodeIterator );
+  CPPUNIT_TEST( testNodeIteratorHeight );
+  CPPUNIT_TEST( testReverseIterator );
+  CPPUNIT_TEST( testRemove );
+  CPPUNIT_TEST( testMove );
+  CPPUNIT_TEST( testCopyConstructor );
+  CPPUNIT_TEST( testClear );
+  CPPUNIT_TEST( testMemoryAllocation );
+
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+    Node *node1;
+    Node *node2;
+    Node *node3;
+    NodeContainer nc;
+
+ public:
+  void setUp() {
+    node1 = new Node(1, 1);
+    node2 = new Node(2, 2);
+    node3 = new Node(3, 0);
+    nc = NodeContainer();
+    nc.add(node1);
+    nc.add(node2);
+    nc.add(node3);
+  }
+
+  void tearDown() {
+    nc.clear();
+  }
+
+  void testGet() {
+    CPPUNIT_ASSERT( nc.get(0) == node1 );
+    CPPUNIT_ASSERT( nc.get(1) == node2 );
+    CPPUNIT_ASSERT( nc.get(2) == node3 );
+  }
+
+  void testAdd() {
+    CPPUNIT_ASSERT( nc.get(0) == node1 );
+    CPPUNIT_ASSERT( nc.get(1) == node2 );
+    CPPUNIT_ASSERT( nc.get(2) == node3 );
+    CPPUNIT_ASSERT( nc.first() == node1 );
+    CPPUNIT_ASSERT( nc.last() == node3 );
+    CPPUNIT_ASSERT_EQUAL( (size_t)3, nc.size() );
+
+    // Add new first node
+    Node* node = new Node(0);
+    nc.add(node);
+    CPPUNIT_ASSERT_EQUAL( (size_t)4, nc.size() );
+    CPPUNIT_ASSERT( nc.get(0) == node );
+    CPPUNIT_ASSERT( nc.first() == node );
+
+    // Add new last node
+    node = new Node(10);
+    nc.add(node);
+    CPPUNIT_ASSERT_EQUAL( (size_t)5, nc.size() );
+    CPPUNIT_ASSERT( nc.get(4) == node );
+    CPPUNIT_ASSERT( nc.last() == node );
+
+    // Add something in between 
+    node = new Node(3);
+    nc.add(node);
+    CPPUNIT_ASSERT_EQUAL( (size_t)6, nc.size() );
+    CPPUNIT_ASSERT( nc.get(4) == node );
+  }
+
+  void testRemove() {
+    Node *node = new Node(2.5);
+    nc.add(node);
+    nc.remove(node);
+    CPPUNIT_ASSERT( nc.size() == 3 );
+    CPPUNIT_ASSERT( nc.get(0) == node1 );
+    CPPUNIT_ASSERT( nc.get(1) == node2 );
+    CPPUNIT_ASSERT( nc.get(2) == node3 );
+
+    nc.remove(node3);
+    CPPUNIT_ASSERT( nc.size() == 2 );
+    CPPUNIT_ASSERT( nc.last() == node2 );
+
+    nc.remove(node1);
+    CPPUNIT_ASSERT( nc.size() == 1 );
+    CPPUNIT_ASSERT( nc.first() == node2 );
+
+    nc.remove(node2);
+    CPPUNIT_ASSERT( nc.size() == 0 );
+    CPPUNIT_ASSERT( nc.first() == NULL );
+    CPPUNIT_ASSERT( nc.last() == NULL );
+  }
+
+
+  void testMove() {
+    Node* node4 = new Node(4);
+    nc.add(node4);
+
+    // Middle -> Middle (forwards)
+    nc.move(node2, 3.5);
+    CPPUNIT_ASSERT( nc.get(0) == node1 );
+    CPPUNIT_ASSERT( nc.get(1) == node3 );
+    CPPUNIT_ASSERT( nc.get(2) == node2 );
+    CPPUNIT_ASSERT( nc.get(3) == node4 );
+    CPPUNIT_ASSERT( node2->height() == 3.5 );
+
+    // Middle -> Middle (backwards)
+    nc.move(node2, 2);
+    CPPUNIT_ASSERT( nc.get(0) == node1 );
+    CPPUNIT_ASSERT( nc.get(1) == node2 );
+    CPPUNIT_ASSERT( nc.get(2) == node3 );
+    CPPUNIT_ASSERT( nc.get(3) == node4 );
+    CPPUNIT_ASSERT( node2->height() == 2 );
+
+    // start -> end
+    nc.move(node1, 10);
+    CPPUNIT_ASSERT( nc.get(0) == node2 );
+    CPPUNIT_ASSERT( nc.get(1) == node3 );
+    CPPUNIT_ASSERT( nc.get(2) == node4 );
+    CPPUNIT_ASSERT( nc.get(3) == node1 );
+    CPPUNIT_ASSERT( nc.first() == node2 );
+    CPPUNIT_ASSERT( nc.last() == node1 );
+    CPPUNIT_ASSERT( node1->height() == 10 );
+        
+    // end -> start
+    nc.move(node1, 1);
+    CPPUNIT_ASSERT( nc.get(0) == node1 );
+    CPPUNIT_ASSERT( nc.get(1) == node2 );
+    CPPUNIT_ASSERT( nc.get(2) == node3 );
+    CPPUNIT_ASSERT( nc.get(3) == node4 );
+    CPPUNIT_ASSERT( nc.first() == node1 );
+    CPPUNIT_ASSERT( nc.last() == node4 );
+    CPPUNIT_ASSERT( node1->height() == 1 );
+
+    // start -> start
+    nc.move(node1, 0.5);
+    CPPUNIT_ASSERT( nc.get(0) == node1 );
+    CPPUNIT_ASSERT( nc.get(1) == node2 );
+    CPPUNIT_ASSERT( nc.get(2) == node3 );
+    CPPUNIT_ASSERT( nc.get(3) == node4 );
+    CPPUNIT_ASSERT( nc.first() == node1 );
+    CPPUNIT_ASSERT( nc.last() == node4 );
+    CPPUNIT_ASSERT( node1->height() == 0.5 );
+
+    // end -> end
+    nc.move(node4, 11);
+    CPPUNIT_ASSERT( nc.get(0) == node1 );
+    CPPUNIT_ASSERT( nc.get(1) == node2 );
+    CPPUNIT_ASSERT( nc.get(2) == node3 );
+    CPPUNIT_ASSERT( nc.get(3) == node4 );
+    CPPUNIT_ASSERT( nc.first() == node1 );
+    CPPUNIT_ASSERT( nc.last() == node4 );
+    CPPUNIT_ASSERT( node4->height() == 11 );
+  }
+
+
+  void testNodeIterator() {
+    NodeIterator it = nc.iterator();
+    CPPUNIT_ASSERT( *it == node1 );
+    CPPUNIT_ASSERT( it.good() );
+    CPPUNIT_ASSERT( it.good() && it++ == node1 );
+    CPPUNIT_ASSERT( it.good() && it++ == node2 );
+    CPPUNIT_ASSERT( it.good() && it++ == node3 );
+    CPPUNIT_ASSERT( !it.good() );
+    CPPUNIT_ASSERT_THROW( ++it, std::out_of_range );
+
+    it = nc.iterator();
+    int i = 0;
+    for (it = nc.iterator(); it.good(); ++it) {
+      (*it)->make_local();
+      ++i;
+    }
+    CPPUNIT_ASSERT( i == 3 );
+
+    it = nc.iterator();
+    ++it; --it;
+    CPPUNIT_ASSERT( it.good() && *it == node1 );
+    ++it; ++it; --it;
+    CPPUNIT_ASSERT( it.good() && *it == node2 );
+    --it; --it;
+    CPPUNIT_ASSERT_THROW( --it, std::out_of_range );
+  }
+  
+
+  void testReverseIterator() {
+    ReverseConstNodeIterator it = nc.reverse_iterator();
+    CPPUNIT_ASSERT( *it == node3 );
+    CPPUNIT_ASSERT( it.good() );
+    CPPUNIT_ASSERT( it.good() && it++ == node3 );
+    CPPUNIT_ASSERT( it.good() && it++ == node2 );
+    CPPUNIT_ASSERT( it.good() && it++ == node1 );
+    CPPUNIT_ASSERT( !it.good() );
+    CPPUNIT_ASSERT_THROW( ++it, std::out_of_range );
+  }
+  
+
+  void testNodeIteratorHeight() {
+    NodeIterator it = nc.iterator();
+    CPPUNIT_ASSERT( it.height() == 1 );
+    ++it; CPPUNIT_ASSERT( it.height() == 2 );
+    ++it; CPPUNIT_ASSERT( it.height() == 3 );
+    ++it; CPPUNIT_ASSERT( it.height() == DBL_MAX );
+  }
+
+  void testCopyConstructor() {
+    NodeContainer nc2 = NodeContainer(nc);
+    CPPUNIT_ASSERT_EQUAL( (size_t)3, nc2.size() );
+    CPPUNIT_ASSERT( nc2.sorted() );
+    CPPUNIT_ASSERT( nc2.unsorted_node_ == NULL );
+    for (auto it = nc.iterator(); it.good(); ++it) {
+      CPPUNIT_ASSERT( (*it)->label() <= 2 );
+    }
+  }
+
+  void testClear() {
+    nc.clear();
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, nc.size() );
+    CPPUNIT_ASSERT( nc.first() == NULL );
+    CPPUNIT_ASSERT( nc.last() == NULL );
+  }
+
+  void testMemoryAllocation() {
+    nc.clear();
+    for (size_t i = 0; i < 20005; ++i) {
+      nc.createNode(5);
+    }
+    nc.clear();
+    for (size_t i = 0; i < 20005; ++i) {
+      nc.createNode(10);
+    }
+  }
+};
+
+//Uncomment this to make_local the test
+CPPUNIT_TEST_SUITE_REGISTRATION( TestNodeContainer );
diff --git a/tests/unittests/test_param.cc b/tests/unittests/test_param.cc
new file mode 100644
index 0000000..4c27f52
--- /dev/null
+++ b/tests/unittests/test_param.cc
@@ -0,0 +1,516 @@
+#include <cppunit/TestCase.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "../../src/param.h"
+#include "../../src/model.h"
+#include "../../src/forest.h"
+
+#pragma GCC diagnostic ignored "-Wwrite-strings"
+
+class TestParam : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE( TestParam );
+
+  CPPUNIT_TEST( testMainConstructor );
+  CPPUNIT_TEST( testStringConstructor );
+  CPPUNIT_TEST( testParseBasicCmdStructure );
+  CPPUNIT_TEST( testParseSeeds );
+  CPPUNIT_TEST( testParseCommonOptions );
+  CPPUNIT_TEST( testParseMigrationOptions );
+  CPPUNIT_TEST( testParseMergeOptions );
+  CPPUNIT_TEST( testParseSplitOptions );
+  CPPUNIT_TEST( testParseOutputOptions );
+  CPPUNIT_TEST( testParseGrowthOptions );
+  CPPUNIT_TEST( testParseVariableRates );
+  CPPUNIT_TEST( testParseUnsupportedMsArguments );
+  CPPUNIT_TEST( testParseSequenceScaling );
+  CPPUNIT_TEST( testErrorOnInfintieRecRate );
+  CPPUNIT_TEST( testScientificNotation );
+  CPPUNIT_TEST( testApproximation );
+
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  Model model;
+
+ public:
+  void testMainConstructor() {
+    char *argv[] = { "scrm", "arg1", "arg2", "arg3" };
+    Param pars(4, argv);
+    CPPUNIT_ASSERT_EQUAL((size_t)3, pars.argv_.size());
+    CPPUNIT_ASSERT_EQUAL(std::string("arg1"), pars.argv_[0]);
+    CPPUNIT_ASSERT_EQUAL(std::string("arg2"), pars.argv_[1]);
+    CPPUNIT_ASSERT_EQUAL(std::string("arg3"), pars.argv_[2]);
+  }
+
+  void testStringConstructor() {
+    Param pars("arg1 arg2 arg3");
+    CPPUNIT_ASSERT_EQUAL((size_t)3, pars.argv_.size());
+    CPPUNIT_ASSERT_EQUAL(std::string("arg1"), pars.argv_[0]);
+    CPPUNIT_ASSERT_EQUAL(std::string("arg2"), pars.argv_[1]);
+    CPPUNIT_ASSERT_EQUAL(std::string("arg3"), pars.argv_[2]);
+  }
+
+  void testParseBasicCmdStructure() {
+    Model model;
+    CPPUNIT_ASSERT_THROW(Param("scrm").parse(), std::invalid_argument); 
+
+    Param pars = Param("-h");
+    model = pars.parse();
+    CPPUNIT_ASSERT( pars.help() ); 
+
+    pars = Param("--help");
+    model = pars.parse();
+    CPPUNIT_ASSERT( pars.help() ); 
+
+    pars = Param("2 1 -h");
+    model = pars.parse();
+    CPPUNIT_ASSERT(pars.help()); 
+
+    CPPUNIT_ASSERT_THROW( Param("1").parse(), std::invalid_argument ); 
+    CPPUNIT_ASSERT_THROW( Param("1 -t 5").parse(), std::invalid_argument ); 
+    CPPUNIT_ASSERT_THROW( Param("-t 5").parse(), std::invalid_argument ); 
+
+    pars = Param("2 1");
+    model = pars.parse();
+    CPPUNIT_ASSERT( !pars.help() ); 
+    CPPUNIT_ASSERT( !pars.version() ); 
+
+    pars = Param("-v");
+    model = pars.parse();
+    CPPUNIT_ASSERT( pars.version() ); 
+
+    pars = Param("--version");
+    model = pars.parse();
+    CPPUNIT_ASSERT( pars.version() ); 
+
+    pars = Param("2 1 -v");
+    model = pars.parse();
+    CPPUNIT_ASSERT( pars.version() ); 
+  }
+
+  void testParseSeeds() {
+    Model model;
+    Param pars = Param("4 7 -seed 123 -t 5");
+    model = pars.parse();
+    CPPUNIT_ASSERT_EQUAL( (size_t)123, pars.random_seed() );
+
+    pars = Param("4 7 -seed 1 2 3 -t 5");
+    model = pars.parse();
+    size_t seed = pars.random_seed();
+    pars = Param("4 7 -seed 1 2 3 -t 5");
+    model = pars.parse();
+    CPPUNIT_ASSERT_EQUAL(seed, pars.random_seed());
+
+    CPPUNIT_ASSERT_THROW(Param("20 10 -seed 1 2 3 4").parse(), std::invalid_argument); 
+    CPPUNIT_ASSERT_THROW(Param("20 10 -seed -t 2").parse(), std::invalid_argument); 
+  }
+
+  void testParseCommonOptions() {
+    Model model = Param("4 7 -t 40.04 -r 1.24 1001 -l 1000").parse();
+    CPPUNIT_ASSERT_EQUAL( (size_t)4, model.sample_size() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)7, model.loci_number() );
+    CPPUNIT_ASSERT( areSame(40.04/(4*model.default_pop_size*1001), model.mutation_rate()) );
+    CPPUNIT_ASSERT( areSame(1.24/(4*model.default_pop_size*1000), model.recombination_rate()) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)1001, model.loci_length() );
+    CPPUNIT_ASSERT( model.has_approximation() );
+    CPPUNIT_ASSERT( model.has_window_seq() );
+    CPPUNIT_ASSERT_EQUAL( 1000.0, model.window_length_seq() );
+
+    CPPUNIT_ASSERT_THROW( Param("15 10 -I 3 7 8 5").parse(), std::invalid_argument ); 
+    CPPUNIT_ASSERT_THROW( Param("15 10 -tv").parse(), std::invalid_argument ); 
+    CPPUNIT_ASSERT_THROW( Param("15 10 -t 17 1").parse(), std::invalid_argument ); 
+
+    model = Param("20 10 -t 3.74 -I 3 7 8 5 -T -M 5.0").parse();
+    CPPUNIT_ASSERT_EQUAL( (size_t)3, model.population_number() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)20, model.sample_size() );
+    CPPUNIT_ASSERT_EQUAL( model.sample_population(4), (size_t)0 );
+    CPPUNIT_ASSERT_EQUAL( model.sample_population(10), (size_t)1 );
+    CPPUNIT_ASSERT_EQUAL( model.sample_population(17), (size_t)2 );
+    CPPUNIT_ASSERT_EQUAL( model.sample_time(4), (double)0.0 );
+    CPPUNIT_ASSERT_EQUAL( model.sample_time(17), (double)0.0 );
+
+    model = Param("20 10 -t 3.74 -I 3 7 8 5 5.0 -T").parse();
+    CPPUNIT_ASSERT_EQUAL( (size_t)3, model.population_number() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)20, model.sample_size() );
+    CPPUNIT_ASSERT_EQUAL( model.sample_population(4), (size_t)0 );
+    CPPUNIT_ASSERT_EQUAL( model.sample_population(10), (size_t)1 );
+    CPPUNIT_ASSERT_EQUAL( model.sample_population(17), (size_t)2 );
+    CPPUNIT_ASSERT_EQUAL( model.sample_time(4), (double)0.0 );
+    CPPUNIT_ASSERT_EQUAL( model.sample_time(17), (double)0.0 );
+    //std::cout << model << std::endl;
+    model.finalize();
+    CPPUNIT_ASSERT( areSame(2.5/(4*model.default_pop_size), model.migration_rate(1, 0)) );
+    CPPUNIT_ASSERT( areSame(2.5/(4*model.default_pop_size), model.migration_rate(0, 1)) );
+    CPPUNIT_ASSERT( areSame(2.5/(4*model.default_pop_size), model.migration_rate(0, 2)) );
+
+    model = Param("2 1 -t 3.74 -I 2 1 1 5.0").parse();
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, model.population_number() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, model.sample_size() );
+    CPPUNIT_ASSERT_EQUAL( model.sample_population(0), (size_t)0 );
+    CPPUNIT_ASSERT_EQUAL( model.sample_population(1), (size_t)1 );
+
+    model = Param("23 10 -t 3.74 -I 3 7 8 5 -eI 12.3 2 0 1 -M 5.0").parse();
+    CPPUNIT_ASSERT_EQUAL( model.sample_population(20), (size_t)0 );
+    CPPUNIT_ASSERT_EQUAL( model.sample_population(22), (size_t)2 );
+    CPPUNIT_ASSERT_EQUAL( 12.3 * 4 * model.default_pop_size, model.sample_time(20) );
+    CPPUNIT_ASSERT_EQUAL( 12.3 * 4 * model.default_pop_size, model.sample_time(22) );
+
+    // -N & -eN 
+    model = Param("20 10 -t 3.74 -I 3 7 8 5 -N 0.3 -eN 8.2 0.75 -G 1.5 -M 5.0").parse();
+    model.resetTime();
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.getCurrentTime() );
+    CPPUNIT_ASSERT( areSame(0.3*model.default_pop_size, model.population_size(0)) );
+    CPPUNIT_ASSERT( areSame(0.3*model.default_pop_size, model.population_size(1)) );
+    CPPUNIT_ASSERT( areSame(0.3*model.default_pop_size, model.population_size(2)) );
+    model.increaseTime();
+    CPPUNIT_ASSERT( areSame(8.2 * 4 * model.default_pop_size, model.getCurrentTime()) );
+    CPPUNIT_ASSERT( areSame(0.75*model.default_pop_size, model.population_size(0)) );
+    CPPUNIT_ASSERT( areSame(0.75*model.default_pop_size, model.population_size(1)) );
+    CPPUNIT_ASSERT( areSame(0.75*model.default_pop_size, model.population_size(2)) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.growth_rate(0) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.growth_rate(1) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.growth_rate(2) );
+
+    // -n & -en 
+    model = Param("20 10 -t 3.74 -I 3 7 8 5 -G 1.5 -n 2 0.3 -eN 1.1 0.75 -en 2 3 0.1 -eG 1.5 2 -M 5.0").parse();
+    model.finalize();
+    model.resetTime();
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.getCurrentTime() );
+    CPPUNIT_ASSERT( areSame(model.default_pop_size, model.population_size(0)) );
+    CPPUNIT_ASSERT( areSame(0.3*model.default_pop_size, model.population_size(1)) );
+    CPPUNIT_ASSERT( areSame(model.default_pop_size, (size_t)model.population_size(2)) );
+    CPPUNIT_ASSERT( areSame(1.5 / 4 / model.default_pop_size, model.growth_rate(0)) );
+    CPPUNIT_ASSERT( areSame(1.5 / 4 / model.default_pop_size, model.growth_rate(1)) );
+    CPPUNIT_ASSERT( areSame(1.5 / 4 / model.default_pop_size, model.growth_rate(2)) );
+    model.increaseTime();
+    CPPUNIT_ASSERT( areSame(1.1 * 4 * model.default_pop_size, model.getCurrentTime()) );
+    model.increaseTime();
+    CPPUNIT_ASSERT( areSame(1.5 * 4 * model.default_pop_size, model.getCurrentTime()) );
+    model.increaseTime();
+    CPPUNIT_ASSERT( areSame(2.0 * 4 * model.default_pop_size, model.getCurrentTime()) );
+    CPPUNIT_ASSERT( 0.75*model.default_pop_size > model.population_size(0) );
+    CPPUNIT_ASSERT( 0.75*model.default_pop_size > model.population_size(1) );
+    CPPUNIT_ASSERT_EQUAL( (size_t)(0.10*model.default_pop_size), (size_t)model.population_size(2) );
+    CPPUNIT_ASSERT_EQUAL( 2.0 / 4 / model.default_pop_size  , model.growth_rate(0) );
+    CPPUNIT_ASSERT_EQUAL( 2.0 / 4 / model.default_pop_size, model.growth_rate(1) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.growth_rate(2) );
+  }
+
+  void testParseMigrationOptions() {
+    // -ma
+    Model model = Param("20 10 -I 2 10 10 -ma x 5 7 x").parse();
+    model.resetTime();
+    CPPUNIT_ASSERT( areSame(5.0/(4*model.default_pop_size), model.migration_rate(0, 1)) );
+    CPPUNIT_ASSERT( areSame(7.0/(4*model.default_pop_size), model.migration_rate(1, 0)) );
+
+    // -ema
+    model = Param("20 10 -I 2 10 10 -ema 1.6 x 5 7 x").parse();
+    model.resetTime();
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 1.6 * 4 * model.default_pop_size, model.getCurrentTime() );
+    CPPUNIT_ASSERT( areSame(5.0/(4*model.default_pop_size), model.migration_rate(0, 1)) );
+    CPPUNIT_ASSERT( areSame(7.0/(4*model.default_pop_size), model.migration_rate(1, 0)) );
+
+    // -M
+    model = Param("30 10 -I 3 10 10 10 0 -M 5").parse();
+    model.resetTime();
+    CPPUNIT_ASSERT( areSame(2.5/(4*model.default_pop_size), model.migration_rate(1, 0)) );
+    CPPUNIT_ASSERT( areSame(2.5/(4*model.default_pop_size), model.migration_rate(0, 1)) );
+    CPPUNIT_ASSERT( areSame(2.5/(4*model.default_pop_size), model.migration_rate(0, 2)) );
+
+    // -eM
+    model = Param("30 10 -I 3 10 10 10 0 -eM 1.6 5").parse();
+    model.resetTime();
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 1.6 * 4 * model.default_pop_size,  model.getCurrentTime() );
+    CPPUNIT_ASSERT( areSame(2.5/(4*model.default_pop_size), model.migration_rate(1, 0)) );
+    CPPUNIT_ASSERT( areSame(2.5/(4*model.default_pop_size), model.migration_rate(0, 1)) );
+    CPPUNIT_ASSERT( areSame(2.5/(4*model.default_pop_size), model.migration_rate(0, 2)) );
+
+    model = Param("20 1 -I 2 13 7 -m 1 2 1.5").parse();
+    //std::cout << model << std::endl;
+    CPPUNIT_ASSERT( areSame(0.0, model.migration_rate(1, 0)) );
+    CPPUNIT_ASSERT( areSame(1.5/(4*model.default_pop_size), model.migration_rate(0, 1)) );
+
+    model = Param("20 1 -I 2 13 7 -m 1 2 1.5 -m 2 1 0.5").parse();
+    //std::cout << model << std::endl;
+    CPPUNIT_ASSERT( areSame(1.5/(4*model.default_pop_size), model.migration_rate(0, 1)) );
+    CPPUNIT_ASSERT( areSame(0.5/(4*model.default_pop_size), model.migration_rate(1, 0)) );
+
+    model = Param("20 1 -I 2 13 7 -em 1.0 2 1 0.5 -em 2.0 2 1 0.6").parse();
+    CPPUNIT_ASSERT( areSame(0.0/(4*model.default_pop_size), model.migration_rate(1, 0)) );
+    CPPUNIT_ASSERT( areSame(0.0/(4*model.default_pop_size), model.migration_rate(0, 1)) );
+    model.increaseTime();
+    CPPUNIT_ASSERT( areSame(0.5/(4*model.default_pop_size), model.migration_rate(1, 0)) );
+    CPPUNIT_ASSERT( areSame(0.0/(4*model.default_pop_size), model.migration_rate(0, 1)) );
+    model.increaseTime();
+    CPPUNIT_ASSERT( areSame(0.6/(4*model.default_pop_size), model.migration_rate(1, 0)) );
+    CPPUNIT_ASSERT( areSame(0.0/(4*model.default_pop_size), model.migration_rate(0, 1)) );
+  }
+
+  void testParseMergeOptions() {
+    // -es
+    Model model;
+    CPPUNIT_ASSERT_NO_THROW(model = Param("20 10 -I 2 10 10 1.5 -es 1.6 2 0.5").parse());
+    model.resetTime();
+    CPPUNIT_ASSERT_EQUAL( (size_t)3, model.population_number() );
+    CPPUNIT_ASSERT( areSame(1.5/(4*model.default_pop_size), model.migration_rate(0,1)) );
+    CPPUNIT_ASSERT( areSame(1.5/(4*model.default_pop_size), model.migration_rate(1,0)) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.migration_rate(0,2) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.migration_rate(2,0) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.migration_rate(0,2) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.migration_rate(2,1) );
+    CPPUNIT_ASSERT_EQUAL( model.default_pop_size, model.population_size(2) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.growth_rate(2) );
+
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 1.6 * 4 * model.default_pop_size, model.getCurrentTime() );
+    CPPUNIT_ASSERT_EQUAL( 0.5, model.single_mig_pop(1, 2) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.single_mig_pop(2, 1) );
+    CPPUNIT_ASSERT( areSame(1.5/(4*model.default_pop_size), model.migration_rate(0,1)) );
+    CPPUNIT_ASSERT( areSame(1.5/(4*model.default_pop_size), model.migration_rate(1,0)) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.migration_rate(0,2) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.migration_rate(2,0) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.migration_rate(1,2) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.migration_rate(2,1) );
+    CPPUNIT_ASSERT_EQUAL( model.default_pop_size, model.population_size(1) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.growth_rate() );
+
+    CPPUNIT_ASSERT_THROW(Param("20 10 -I 2 10 10 1.5 -es 1.6 2 0.5 -eM 0.9 5.0").parse(), 
+                         std::invalid_argument );
+    CPPUNIT_ASSERT_THROW(Param("20 10 -I 2 10 10 1.5 -es 1.6 2 0.5 -eG 0.9 5.0").parse(), 
+                         std::invalid_argument );
+    CPPUNIT_ASSERT_THROW(Param("20 10 -I 2 10 10 1.5 -es 1.6 2 0.5 -eN 0.9 5.0").parse(), 
+                         std::invalid_argument );
+    CPPUNIT_ASSERT_THROW(Param("20 10 -I 2 10 10 1.5 -es 1.6 2 0.5 -es 0.9 3 1").parse(), 
+                         std::invalid_argument );
+  }
+
+  void testParseSplitOptions() {
+    // -ej
+    Model model;
+    CPPUNIT_ASSERT_NO_THROW(model = Param("20 10 -I 2 10 10 -ej 1.6 2 1 -M 1.3").parse());
+    model.resetTime();
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 1.6 * 4 * model.default_pop_size, model.getCurrentTime() );
+    CPPUNIT_ASSERT_EQUAL( 1.0, model.single_mig_pop(1, 0) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.single_mig_pop(0, 1) );
+
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.migration_rate(0, 1) );
+    CPPUNIT_ASSERT_EQUAL( 1.3/(4*model.default_pop_size), model.migration_rate(1, 0) );
+  }
+
+  void testParseOutputOptions() {
+    Model model;
+    CPPUNIT_ASSERT_NO_THROW(model = Param("20 10 -T").parse(); );
+    CPPUNIT_ASSERT( model.summary_statistics_.size() == 1 );
+
+    CPPUNIT_ASSERT_NO_THROW(model = Param("20 10 -O").parse(); );
+    CPPUNIT_ASSERT( model.summary_statistics_.size() == 1 );
+
+    CPPUNIT_ASSERT_NO_THROW(model = Param("20 10 -t 5").parse(); );
+    CPPUNIT_ASSERT( model.summary_statistics_.size() == 1 );
+
+    CPPUNIT_ASSERT_NO_THROW(model = Param("20 10 -L").parse());
+    CPPUNIT_ASSERT( model.summary_statistics_.size() == 1 );
+
+    CPPUNIT_ASSERT_THROW(Param("20 10 -oSFS").parse(), std::invalid_argument ); 
+
+    CPPUNIT_ASSERT_NO_THROW(model = Param("20 10 -oSFS -t 5").parse());
+    CPPUNIT_ASSERT( model.summary_statistics_.size() == 2 );
+
+    CPPUNIT_ASSERT_NO_THROW(model = Param("20 10 -oSFS -t 5 -L").parse());
+    CPPUNIT_ASSERT( model.summary_statistics_.size() == 3 );
+
+    CPPUNIT_ASSERT_NO_THROW(model = Param("20 10 -oSFS -t 5 -L -T").parse());
+    CPPUNIT_ASSERT( model.summary_statistics_.size() == 4 );
+  }
+
+  void testParseGrowthOptions() {
+    // -G && -eG
+    Model model;
+    char *argv[] = { "scrm", "20", "10", "-t", "3.74", "-I", "2", "10", "10", 
+      "-G", "2", "-eG", "1", "3", "-M", "5.0" };
+    CPPUNIT_ASSERT_NO_THROW( model = Param(16, argv).parse(); );
+    model.resetTime();
+    CPPUNIT_ASSERT( areSame(2.0 / 4 / model.default_pop_size, model.growth_rate(0)) );
+    CPPUNIT_ASSERT( areSame(2.0 / 4 / model.default_pop_size, model.growth_rate(1)) );
+    model.increaseTime();
+    CPPUNIT_ASSERT( areSame(1.0 * 4 * model.default_pop_size, model.getCurrentTime()) );
+    CPPUNIT_ASSERT( areSame(3.0 / 4 / model.default_pop_size, model.growth_rate(0)) );
+    CPPUNIT_ASSERT( areSame(3.0 / 4 / model.default_pop_size, model.growth_rate(1)) );
+
+    // -g && -eg
+    char *argv2[] = { 
+      "scrm", "20", "10", "-t", "3.74", "-I", "2", "10", "10", 
+      "-g", "2", "0.1", "-eG", "1", "3", "-eg", "2", "1", "2.4", "-M", "5.0"};
+    CPPUNIT_ASSERT_NO_THROW( model = Param(21, argv2).parse(); );
+    model.resetTime();
+    CPPUNIT_ASSERT_EQUAL( model.default_growth_rate, model.growth_rate(0) );
+    CPPUNIT_ASSERT_EQUAL( 0.1 / 4 / model.default_pop_size, model.growth_rate(1) );
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 1.0 * 4 * model.default_pop_size, model.getCurrentTime() );
+    model.increaseTime();
+    CPPUNIT_ASSERT_EQUAL( 2.0 * 4 * model.default_pop_size, model.getCurrentTime() );
+    CPPUNIT_ASSERT( areSame(2.4 / 4 / model.default_pop_size, model.growth_rate(0)) );
+    CPPUNIT_ASSERT( areSame(3.0 / 4 / model.default_pop_size, model.growth_rate(1)) );
+  }
+
+  void testParseVariableRates() {
+    // -st
+    Model model;
+    char *argv[] = { "scrm", "20", "10", "-t", "3.74", "-st", "10", "5.1", "-st", "4.5", "3.2"};
+    CPPUNIT_ASSERT_NO_THROW( model = Param(11, argv).parse(); );
+    double scale = 1 / ( 4 * model.default_pop_size * model.default_loci_length );
+    CPPUNIT_ASSERT( areSame(3.74 * scale, model.mutation_rate()) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.getCurrentSequencePosition() );
+    CPPUNIT_ASSERT_EQUAL( 4.5, model.getNextSequencePosition() );
+
+    model.increaseSequencePosition();
+    CPPUNIT_ASSERT( areSame(3.2 * scale, model.mutation_rate()) );
+    CPPUNIT_ASSERT_EQUAL( 4.5, model.getCurrentSequencePosition() );
+    CPPUNIT_ASSERT_EQUAL( 10.0, model.getNextSequencePosition() );
+
+    model.increaseSequencePosition();
+    CPPUNIT_ASSERT( areSame(5.1 * scale, model.mutation_rate()) );
+    CPPUNIT_ASSERT_EQUAL( 10.0, model.getCurrentSequencePosition() );
+
+    // -sr
+    char *argv2[] = { "scrm", "20", "10", "-r", "3.74", "100", "-sr", "10", "5.1", "-sr", "4.5", "3.2"};
+    CPPUNIT_ASSERT_NO_THROW( model = Param(12, argv2).parse(); );
+    model.resetSequencePosition();
+    scale = 1 / ( 4 * model.default_pop_size * 99 );
+    CPPUNIT_ASSERT( areSame(3.74 * scale, model.recombination_rate()) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.getCurrentSequencePosition() );
+    CPPUNIT_ASSERT_EQUAL( 4.5, model.getNextSequencePosition() );
+
+    model.increaseSequencePosition();
+    CPPUNIT_ASSERT( areSame(3.2 * scale, model.recombination_rate()) );
+    CPPUNIT_ASSERT_EQUAL( 4.5, model.getCurrentSequencePosition() );
+    CPPUNIT_ASSERT_EQUAL( 10.0, model.getNextSequencePosition() );
+
+    model.increaseSequencePosition();
+    CPPUNIT_ASSERT( areSame(5.1 * scale, model.recombination_rate()) );
+    CPPUNIT_ASSERT_EQUAL( 10.0, model.getCurrentSequencePosition() );
+
+    // both
+    char *argv3[] = { "scrm", "20", "10", "-r", "3.74", "100", "-sr", "10", "5.1", "-st", "4.5", "3.2"};
+    CPPUNIT_ASSERT_NO_THROW( model = Param(12, argv3).parse(); );
+    model.resetSequencePosition();
+    model.resetTime();
+    scale = 1 / ( 4 * model.default_pop_size * 99 );
+    double scale2 = 1 / ( 4 * model.default_pop_size * 100 );
+
+    CPPUNIT_ASSERT( areSame(3.74 * scale, model.recombination_rate()) );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.mutation_rate() );
+    CPPUNIT_ASSERT_EQUAL( 0.0, model.getCurrentSequencePosition() );
+    CPPUNIT_ASSERT_EQUAL( 4.5, model.getNextSequencePosition() );
+
+    model.increaseSequencePosition();
+    CPPUNIT_ASSERT_EQUAL( 4.5, model.getCurrentSequencePosition() );
+    CPPUNIT_ASSERT_EQUAL( 10.0, model.getNextSequencePosition() );
+    CPPUNIT_ASSERT( areSame(3.74 * scale, model.recombination_rate()) );
+    CPPUNIT_ASSERT( areSame(3.2 * scale2, model.mutation_rate()) );
+
+    model.increaseSequencePosition();
+    CPPUNIT_ASSERT( areSame(5.1 * scale, model.recombination_rate()) );
+    CPPUNIT_ASSERT( areSame(3.2 * scale2, model.mutation_rate()) );
+    CPPUNIT_ASSERT_EQUAL( 10.0, model.getCurrentSequencePosition() );
+  }
+
+  void testParseUnsupportedMsArguments() {
+    char *argv[] = { "scrm", "20", "10", "-t", "3.74", "-c", "10", "5.1", "-st", "4.5", "3.2"};
+    CPPUNIT_ASSERT_THROW( Param(11, argv).parse(), std::invalid_argument ); 
+
+    char *argv2[] = { "scrm", "20", "10", "-s", "5"};
+    CPPUNIT_ASSERT_THROW( Param(5, argv2).parse(), std::invalid_argument ); 
+  }
+
+
+
+  void testParseSequenceScaling() {
+    Model model;
+    char *argv1[] = { "scrm", "4", "7", "-SC", "ms"};
+    Param pars = Param(5, argv1);
+    CPPUNIT_ASSERT_NO_THROW( model = pars.parse() );
+    CPPUNIT_ASSERT( model.getSequenceScaling() == ms );
+
+    char *argv2[] = { "scrm", "4", "7", "-SC", "rel"};
+    pars = Param(5, argv2);
+    CPPUNIT_ASSERT_NO_THROW( model = pars.parse() );
+    CPPUNIT_ASSERT( model.getSequenceScaling() == relative );
+
+    char *argv3[] = { "scrm", "4", "7", "-SC", "abs"};
+    pars = Param(5, argv3);
+    CPPUNIT_ASSERT_NO_THROW( model = pars.parse() );
+    CPPUNIT_ASSERT( model.getSequenceScaling() == absolute );
+
+    char *argv4[] = { "scrm", "4", "7", "-SC", "blub"};
+    CPPUNIT_ASSERT_THROW( Param(5, argv4).parse(), std::invalid_argument );
+    char *argv5[] = { "scrm", "4", "7", "-SC"};
+    CPPUNIT_ASSERT_THROW( Param(4, argv5).parse(), std::invalid_argument );
+  }
+
+
+  void testErrorOnInfintieRecRate() {
+    Param pars = Param("4 7 -r 0.5 1");
+    CPPUNIT_ASSERT_THROW(model = pars.parse(), std::invalid_argument);
+
+    pars = Param("4 7 -r 0.5 0");
+    CPPUNIT_ASSERT_THROW(model = pars.parse(), std::invalid_argument);
+  }
+
+
+  void testScientificNotation() {
+    Param pars;
+    pars = Param("4 7 -r 1e3 1001");
+    CPPUNIT_ASSERT_NO_THROW(model = pars.parse());
+    CPPUNIT_ASSERT_EQUAL(1.0/(4*model.default_pop_size), model.recombination_rate());
+
+    pars = Param("4 7 -r 0.5 2e3");
+    CPPUNIT_ASSERT_NO_THROW(model = pars.parse());
+    CPPUNIT_ASSERT_EQUAL((size_t)2000, model.loci_length());
+
+    pars = Param("4 1e3 -r 0.5 2");
+    CPPUNIT_ASSERT_NO_THROW(model = pars.parse());
+    CPPUNIT_ASSERT_EQUAL((size_t)1000, model.loci_number());
+  }
+
+  void testPrintModel() {
+    Param pars;
+    pars = Param("4 7 -r 1 1001");
+    CPPUNIT_ASSERT_NO_THROW(model = pars.parse());
+    CPPUNIT_ASSERT_EQUAL(false, pars.print_model());
+
+    pars = Param("4 7 -r 1 1001 -print-model");
+    CPPUNIT_ASSERT_NO_THROW(model = pars.parse());
+    CPPUNIT_ASSERT_EQUAL(true, pars.print_model());
+
+    pars = Param("4 7 --print-model");
+    CPPUNIT_ASSERT_NO_THROW(model = pars.parse());
+    CPPUNIT_ASSERT_EQUAL(true, pars.print_model());
+  }
+
+  void testApproximation() {
+    Model model = Param("2 2 -r 10 100 -l -1").parse();
+    CPPUNIT_ASSERT( !model.has_approximation() );
+    CPPUNIT_ASSERT( !model.has_window_rec() );
+    CPPUNIT_ASSERT( !model.has_window_seq() );
+
+    model = Param("2 2 -r 10 100 -l 10").parse();
+    CPPUNIT_ASSERT(  model.has_approximation() );
+    CPPUNIT_ASSERT( !model.has_window_rec() );
+    CPPUNIT_ASSERT(  model.has_window_seq() );
+    CPPUNIT_ASSERT_EQUAL( 10.0, model.window_length_seq() );
+
+    model = Param("2 2 -r 10 100 -l 10r").parse();
+    CPPUNIT_ASSERT(  model.has_approximation() );
+    CPPUNIT_ASSERT(  model.has_window_rec() );
+    CPPUNIT_ASSERT( !model.has_window_seq() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)10, model.window_length_rec() );
+  }
+};
+
+//Uncomment this to activate the test
+CPPUNIT_TEST_SUITE_REGISTRATION( TestParam );
diff --git a/tests/unittests/test_random_generator.cc b/tests/unittests/test_random_generator.cc
new file mode 100644
index 0000000..1d65ab3
--- /dev/null
+++ b/tests/unittests/test_random_generator.cc
@@ -0,0 +1,141 @@
+/*
+ * A sample test case which can be used as a template.
+ */
+#include <cppunit/TestCase.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "../../src/random/mersenne_twister.h"
+#include "../../src/random/random_generator.h"
+
+class TestRandomGenerator : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE( TestRandomGenerator );
+
+  CPPUNIT_TEST( testConstructor );
+  CPPUNIT_TEST( testSampleExpoLimit );
+  CPPUNIT_TEST( testSampleUnitExpo );
+  CPPUNIT_TEST( testSampleExpo );
+  CPPUNIT_TEST( testSampleExpoExpoLimit );
+  CPPUNIT_TEST( testSampleInt );
+  CPPUNIT_TEST( testSeeding );
+
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  RandomGenerator *rg;
+
+ public:
+  void setUp() {
+    rg = new MersenneTwister(5);
+  }
+
+  void tearDown() {
+    delete rg;
+  }
+
+  void testConstructor() {
+    CPPUNIT_ASSERT_EQUAL( (size_t)5, rg->seed() );
+    CPPUNIT_ASSERT( rg->unit_exponential_ > 0 );
+  }
+
+  void testSampleExpoLimit() {
+    double expo;
+    for (size_t i = 0; i < 1000; ++i) {
+      expo = rg->sampleExpoLimit(1, 2);
+      CPPUNIT_ASSERT( expo == -1 || expo > 0 );
+      CPPUNIT_ASSERT( expo <= 2 ); 
+    }
+  }
+
+  void testSampleUnitExpo() {
+    size_t n = 10000;
+    double expo = 0.0;
+    for (size_t i = 0; i < n; ++i) {
+      expo += rg->sampleUnitExponential();
+    }
+    expo /= n;
+    CPPUNIT_ASSERT( 0.99 <= expo && expo <= 1.01 );
+  }
+
+  void testSampleExpo() {
+    size_t n = 100000;
+    double expo = 0;
+    for (size_t i = 0; i < n; ++i) {
+      expo += rg->sampleExpo(5);
+    }
+    expo /= n;
+    //std::cout << expo << std::endl;
+    CPPUNIT_ASSERT( 0.199 <= expo && expo <= 0.201 );
+  }
+  
+  void testSampleExpoExpoLimit() {
+    size_t n = 10000;
+    double expo = 0, sample = 0;
+    size_t sample_number = 0;
+    
+    // c = 0;
+    for (size_t i = 0; i < n; ++i) {
+      sample = rg->sampleExpoExpoLimit(2,0,1);
+      if (sample >= 0) {
+        expo += sample;
+        ++sample_number;
+      }
+    }
+    expo /= sample_number;
+    // Expected: 0.34 
+    CPPUNIT_ASSERT( 0.32 < expo && expo < 0.36 );
+
+    expo = 0;
+    sample_number = 0;
+    for (size_t i = 0; i < n; ++i) {
+      sample = rg->sampleExpoExpoLimit(2,0,2);
+      if (sample >= 0) {
+        expo += sample;
+        ++sample_number;
+      }
+    }
+    expo /= sample_number;
+    // Expected: 0.46 
+    CPPUNIT_ASSERT( 0.44 < expo && expo < 0.48 );
+
+    expo = 0;
+    sample_number = 0;
+    for (size_t i = 0; i < n; ++i) {
+      sample = rg->sampleExpoExpoLimit(2,0,4);
+      if (sample >= 0) {
+        expo += sample;
+        ++sample_number;
+      }
+    }
+    expo /= sample_number;
+    // Expected: 0.50 
+    CPPUNIT_ASSERT( 0.48 < expo && expo < 0.52 );
+  }
+
+  void testSampleInt() {
+    size_t n = 50000;
+    int sample;
+    int result[5] = { 0 };
+
+    for (size_t i = 0; i < n; ++i) {
+      sample = rg->sampleInt(5);
+      ++result[sample]; 
+    }
+
+    for (size_t i = 0; i < 5; ++i) {
+      //std::cout << i << " : " << result[i] << std::endl;
+      CPPUNIT_ASSERT( 9750 < result[i] && result[i] < 10250 ); 
+    }
+  }
+
+  void testSeeding() {
+    rg->set_seed(5);
+    int sample = rg->sampleInt(10000);
+    rg->set_seed(5);
+    CPPUNIT_ASSERT_EQUAL( sample, rg->sampleInt(10000) );
+
+    MersenneTwister rg2 = MersenneTwister(5);
+    CPPUNIT_ASSERT_EQUAL( sample, rg2.sampleInt(10000) );
+  }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TestRandomGenerator );
diff --git a/tests/unittests/test_seg.cc b/tests/unittests/test_seg.cc
new file mode 100644
index 0000000..2b60f96
--- /dev/null
+++ b/tests/unittests/test_seg.cc
@@ -0,0 +1,56 @@
+/*
+ * A sample test case which can be used as a template.
+ */
+#include <cppunit/TestCase.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <valarray>
+
+#include "../../src/seg.h"
+#include "../../src/forest.h"
+
+class TestSeg : public CppUnit::TestCase {
+
+	CPPUNIT_TEST_SUITE( TestSeg );
+
+	CPPUNIT_TEST( testTraversal );
+
+	CPPUNIT_TEST_SUITE_END();
+
+ private:
+  Forest *forest;
+  ConstantGenerator *rg;
+
+ public:
+  void setUp() {
+    rg = new ConstantGenerator;
+    forest = new Forest(new Model(5), rg);
+    forest->createExampleTree();
+  }
+
+  void tearDown() {
+    delete forest->writable_model();
+    delete forest;
+    delete rg;
+  }
+
+  void testTraversal() {
+    std::valarray <int>haplotype(4);
+    //traversal(forest->nodes()->at(4), haplotype);
+    forest->traversal(forest->nodes()->at(4), haplotype);
+    CPPUNIT_ASSERT_EQUAL( 1, haplotype[0] );
+    CPPUNIT_ASSERT_EQUAL( 1, haplotype[1] );
+    CPPUNIT_ASSERT_EQUAL( 0, haplotype[2] );
+    CPPUNIT_ASSERT_EQUAL( 0, haplotype[3] );
+
+    haplotype *= 0;
+    //traversal(forest->nodes()->at(5), haplotype);
+    forest->traversal(forest->nodes()->at(5), haplotype);
+    CPPUNIT_ASSERT_EQUAL( 0, haplotype[0] );
+    CPPUNIT_ASSERT_EQUAL( 0, haplotype[1] );
+    CPPUNIT_ASSERT_EQUAL( 1, haplotype[2] );
+    CPPUNIT_ASSERT_EQUAL( 1, haplotype[3] );
+  }
+};
+
+//Uncomment this to activate the test
+CPPUNIT_TEST_SUITE_REGISTRATION( TestSeg );
diff --git a/tests/unittests/test_summary_statistics.cc b/tests/unittests/test_summary_statistics.cc
new file mode 100644
index 0000000..bb9547e
--- /dev/null
+++ b/tests/unittests/test_summary_statistics.cc
@@ -0,0 +1,322 @@
+/*
+ * A sample test case which can be used as a template.
+ */
+#include <cppunit/TestCase.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <valarray>
+#include <memory>
+
+#include "../../src/forest.h"
+#include "../../src/tree_point.h"
+#include "../../src/random/mersenne_twister.h"
+#include "../../src/summary_statistics/tmrca.h"
+#include "../../src/summary_statistics/seg_sites.h"
+#include "../../src/summary_statistics/summary_statistic.h"
+#include "../../src/summary_statistics/frequency_spectrum.h"
+#include "../../src/summary_statistics/oriented_forest.h"
+#include "../../src/summary_statistics/newick_tree.h"
+
+class TestSummaryStatistics : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE( TestSummaryStatistics );
+
+  CPPUNIT_TEST( testTMRCA );
+  CPPUNIT_TEST( testSegSitesTraversal );
+  CPPUNIT_TEST( testSegSitesGetHaplotypes );
+  CPPUNIT_TEST( testSegSitesCalculate );
+  CPPUNIT_TEST( testSiteFrequencies );
+  CPPUNIT_TEST( testOrientedForestGenerateTreeData );
+  CPPUNIT_TEST( testOrientedForest );
+  CPPUNIT_TEST( testNewickTree );
+
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  Forest *forest;
+  MersenneTwister *rg;
+
+ public:
+  void setUp() {
+    rg = new MersenneTwister(1234);
+    forest = new Forest(new Model(5), rg);
+    forest->createExampleTree();
+  }
+
+  void tearDown() {
+    delete forest->writable_model();
+    delete forest;
+    delete rg;
+  }
+
+  void testTMRCA() {
+    forest->createScaledExampleTree();
+    TMRCA tmrca = TMRCA();
+    tmrca.calculate(*forest);
+    CPPUNIT_ASSERT_EQUAL( 10.0, tmrca.tmrca().at(0) );
+    CPPUNIT_ASSERT_EQUAL( 24.0, tmrca.tree_length().at(0) );
+
+    tmrca.calculate(*forest);
+    CPPUNIT_ASSERT_EQUAL( 10.0, tmrca.tmrca().at(1) );
+    CPPUNIT_ASSERT_EQUAL( 24.0, tmrca.tree_length().at(1) );
+    
+    tmrca.clear();
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, tmrca.tmrca().size() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, tmrca.tree_length().size() );
+  }
+
+  void testSegSitesTraversal() {
+    SegSites seg_sites = SegSites();
+
+    std::valarray <bool>haplotype(4);
+    seg_sites.traversal(forest->nodes()->at(4), haplotype);
+    CPPUNIT_ASSERT_EQUAL( true,  haplotype[0] );
+    CPPUNIT_ASSERT_EQUAL( true,  haplotype[1] );
+    CPPUNIT_ASSERT_EQUAL( false, haplotype[2] );
+    CPPUNIT_ASSERT_EQUAL( false, haplotype[3] );
+
+    haplotype *= 0;
+    seg_sites.traversal(forest->nodes()->at(5), haplotype);
+    CPPUNIT_ASSERT_EQUAL( false, haplotype[0] );
+    CPPUNIT_ASSERT_EQUAL( false, haplotype[1] );
+    CPPUNIT_ASSERT_EQUAL( true,  haplotype[2] );
+    CPPUNIT_ASSERT_EQUAL( true,  haplotype[3] );
+
+    haplotype *= 0;
+    seg_sites.traversal(forest->nodes()->at(8), haplotype);
+    CPPUNIT_ASSERT_EQUAL( true, haplotype[0] );
+    CPPUNIT_ASSERT_EQUAL( true, haplotype[1] );
+    CPPUNIT_ASSERT_EQUAL( true, haplotype[2] );
+    CPPUNIT_ASSERT_EQUAL( true, haplotype[3] );
+
+    haplotype *= 0;
+    seg_sites.traversal(forest->nodes()->at(0), haplotype);
+    CPPUNIT_ASSERT_EQUAL( false, haplotype[0] );
+    CPPUNIT_ASSERT_EQUAL( false, haplotype[1] );
+    CPPUNIT_ASSERT_EQUAL( false, haplotype[2] );
+    CPPUNIT_ASSERT_EQUAL( true,  haplotype[3] );
+
+    haplotype *= 0;
+    seg_sites.traversal(forest->nodes()->at(1), haplotype);
+    CPPUNIT_ASSERT_EQUAL( false, haplotype[0] );
+    CPPUNIT_ASSERT_EQUAL( false, haplotype[1] );
+    CPPUNIT_ASSERT_EQUAL( true,  haplotype[2] );
+    CPPUNIT_ASSERT_EQUAL( false, haplotype[3] );
+  }
+
+  void testSegSitesGetHaplotypes() {
+    SegSites seg_sites = SegSites();
+
+    TreePoint mutation = TreePoint(forest->nodes()->at(4), 1, true);
+    std::valarray<bool> haplotype = seg_sites.getHaplotypes(mutation, *forest);
+    CPPUNIT_ASSERT_EQUAL( (size_t)4, haplotype.size() );
+    CPPUNIT_ASSERT_EQUAL( true, haplotype[0] );
+    CPPUNIT_ASSERT_EQUAL( true, haplotype[1] );
+    CPPUNIT_ASSERT_EQUAL( false, haplotype[2] );
+    CPPUNIT_ASSERT_EQUAL( false, haplotype[3] );
+
+    mutation = TreePoint(forest->nodes()->at(5), 0.5, true);
+    haplotype = seg_sites.getHaplotypes(mutation, *forest);
+    CPPUNIT_ASSERT_EQUAL( (size_t)4, haplotype.size() );
+    CPPUNIT_ASSERT_EQUAL( false, haplotype[0] );
+    CPPUNIT_ASSERT_EQUAL( false, haplotype[1] );
+    CPPUNIT_ASSERT_EQUAL( true, haplotype[2] );
+    CPPUNIT_ASSERT_EQUAL( true, haplotype[3] );
+
+    mutation = TreePoint(forest->nodes()->at(8), 0.5, true);
+    haplotype = seg_sites.getHaplotypes(mutation, *forest);
+    CPPUNIT_ASSERT_EQUAL( (size_t)4, haplotype.size() );
+    CPPUNIT_ASSERT_EQUAL( true, haplotype[0] );
+    CPPUNIT_ASSERT_EQUAL( true, haplotype[1] );
+    CPPUNIT_ASSERT_EQUAL( true, haplotype[2] );
+    CPPUNIT_ASSERT_EQUAL( true, haplotype[3] );
+  }
+
+  void testSegSitesCalculate() {
+    forest->createScaledExampleTree();
+    forest->writable_model()->setMutationRate(0.0001);
+    forest->set_current_base(0.0);
+    forest->set_next_base(15.0);
+    SegSites seg_sites = SegSites();
+    CPPUNIT_ASSERT_EQUAL( 0.0, seg_sites.position() );
+
+    // Create an example state
+    seg_sites.positions_.push_back(0.5);
+    seg_sites.positions_.push_back(0.7);
+    seg_sites.positions_.push_back(0.8);
+
+    std::valarray<bool> ht = {1, 0, 0, 0};
+    seg_sites.haplotypes_.push_back(ht);
+    ht[1] = 1;
+    seg_sites.haplotypes_.push_back(ht);
+    ht = 0;
+    ht[1] = 1;
+    seg_sites.haplotypes_.push_back(ht);
+
+    // Check status
+    CPPUNIT_ASSERT_EQUAL( (size_t)3, seg_sites.countMutations() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)4, seg_sites.getHaplotype(0)->size() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)4, seg_sites.getHaplotype(1)->size() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)4, seg_sites.getHaplotype(2)->size() );
+
+    // Check clear
+    seg_sites.clear();
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, seg_sites.countMutations() );
+
+    // Check distribution
+    seg_sites.calculate(*forest);
+    CPPUNIT_ASSERT( seg_sites.countMutations() > 0 ); 
+    int freqs[4] = { 0 };
+    int types[2] = { 0 };
+    int sum = 0;
+    for (auto it = seg_sites.haplotypes_.begin(); it != seg_sites.haplotypes_.end(); ++it) {
+      for (size_t i = 0; i < 4; ++i) {
+        if ((*it)[i]) ++freqs[i]; 
+        sum += (*it)[i];
+      }
+      CPPUNIT_ASSERT( sum == 1 || sum == 2 );
+      ++types[sum-1];
+      sum = 0;
+    }
+
+    for (size_t i = 0; i < 4; ++i) {
+      CPPUNIT_ASSERT( 0.4 < (double)freqs[i] / seg_sites.countMutations() );
+      CPPUNIT_ASSERT( (double)freqs[i] / seg_sites.countMutations() < 0.43 );
+    }
+
+    CPPUNIT_ASSERT( (double)types[0] / types[1] > 0.45 );
+    CPPUNIT_ASSERT( (double)types[0] / types[1] < 0.55 );
+
+    CPPUNIT_ASSERT_EQUAL( forest->next_base(), seg_sites.position() );
+
+    // Test if the seg_sites clears itself after each locus automatically
+    size_t mutation_count = seg_sites.countMutations();
+    rg->set_seed(1234);
+    seg_sites.calculate(*forest);
+    CPPUNIT_ASSERT_EQUAL( mutation_count, seg_sites.countMutations() );
+  }
+
+  void testSiteFrequencies() {
+    forest->createScaledExampleTree();
+    forest->writable_model()->setMutationRate(0.0001);
+    forest->set_current_base(0.0);
+    forest->set_next_base(10.0);
+    
+    std::shared_ptr<SegSites> seg_sites = std::make_shared<SegSites>();
+    seg_sites->positions_.push_back(0.5);
+    seg_sites->positions_.push_back(0.7);
+    seg_sites->positions_.push_back(0.8);
+
+    std::valarray<bool> ht = {1, 0, 0, 0};
+    seg_sites->haplotypes_.push_back(ht); // singleton
+    ht[1] = 1;
+    seg_sites->haplotypes_.push_back(ht); // doubleton
+    ht = 0;
+    ht[1] = 1;
+    seg_sites->haplotypes_.push_back(ht); // singletion
+    seg_sites->set_position(forest->next_base());
+
+    FrequencySpectrum sfs(seg_sites, forest->model());
+    std::ostringstream output;
+
+    // Check values for example segment
+    sfs.calculate(*forest);
+    sfs.printLocusOutput(output);
+    CPPUNIT_ASSERT( output.str().compare("SFS: 2 1 0 \n") == 0 );
+
+    // Add another segment
+    seg_sites->positions_.push_back(0.9);
+    seg_sites->haplotypes_.push_back(ht);
+    sfs.calculate(*forest);
+    CPPUNIT_ASSERT_EQUAL((size_t)3, sfs.sfs().at(0));
+    CPPUNIT_ASSERT_EQUAL((size_t)1, sfs.sfs().at(1));
+    CPPUNIT_ASSERT_EQUAL((size_t)0, sfs.sfs().at(2));
+
+    // Check that it is reset at a new locus
+    output.str("");
+    output.clear();
+
+    sfs.clear();
+    forest->createScaledExampleTree();
+    forest->set_current_base(0.0);
+    forest->set_next_base(0.000001);
+    sfs.calculate(*forest);
+    sfs.printLocusOutput(output);
+    CPPUNIT_ASSERT( output.str().compare("SFS: 0 0 0 \n") == 0 );
+  }
+
+  void testOrientedForestGenerateTreeData() {
+    OrientedForest of(4);
+    size_t pos = 2*forest->sample_size()-2;
+    double sf = forest->model().scaling_factor();
+    of.generateTreeData(forest->local_root(), pos, 0, sf); 
+    CPPUNIT_ASSERT( of.heights_.at(0) == 0.0 );
+    CPPUNIT_ASSERT( of.heights_.at(1) == 0.0 );
+    CPPUNIT_ASSERT( of.heights_.at(2) == 0.0 );
+    CPPUNIT_ASSERT( of.heights_.at(3) == 0.0 );
+    CPPUNIT_ASSERT( of.parents_.at(4) == 7 );
+    CPPUNIT_ASSERT( of.parents_.at(5) == 7 );
+    CPPUNIT_ASSERT( of.heights_.at(6) == 10.0 * sf && of.parents_.at(6) == 0 );
+
+    CPPUNIT_ASSERT( of.heights_.at(4) == 1.0 * sf || of.heights_.at(4) == 3.0 * sf );
+    if ( of.heights_.at(4) == 1.0 ) {
+      CPPUNIT_ASSERT( of.parents_.at(0) == 5 );
+      CPPUNIT_ASSERT( of.parents_.at(1) == 5 );
+      CPPUNIT_ASSERT( of.parents_.at(2) == 6 );
+      CPPUNIT_ASSERT( of.parents_.at(3) == 6 );
+      CPPUNIT_ASSERT( of.heights_.at(5) == 3.0 * sf);
+    } else {
+      CPPUNIT_ASSERT( of.parents_.at(0) == 6 );
+      CPPUNIT_ASSERT( of.parents_.at(1) == 6 ); CPPUNIT_ASSERT( of.parents_.at(2) == 5 );
+      CPPUNIT_ASSERT( of.parents_.at(3) == 5 );
+      CPPUNIT_ASSERT( of.heights_.at(5) == 1.0 * sf );
+    }
+  }
+
+  void testOrientedForest() {
+    forest->createScaledExampleTree();
+    forest->set_current_base(0.0);
+    forest->set_next_base(10.0);
+    
+    OrientedForest of(4);
+    std::ostringstream output;
+    of.calculate(*forest);
+    of.printSegmentOutput(output);
+    //std::cout << output.str() << std::endl;
+    CPPUNIT_ASSERT( output.str().compare("{\"parents\":[5,5,6,6,7,7,0], \"node_times\":[0,0,0,0,1,3,10]}\n") == 0 ||
+                    output.str().compare("{\"parents\":[6,6,5,5,7,7,0], \"node_times\":[0,0,0,0,3,1,10]}\n") == 0 );
+
+    output.str("");
+    output.clear();
+    forest->writable_model()->setRecombinationRate(0.0001);
+    of.clear();
+    of.calculate(*forest);
+    of.printSegmentOutput(output);
+    //std::cout << output.str() << std::endl;
+    CPPUNIT_ASSERT( output.str().compare("{\"length\":10, \"parents\":[5,5,6,6,7,7,0], \"node_times\":[0,0,0,0,1,3,10]}\n") == 0 ||
+                    output.str().compare("{\"length\":10, \"parents\":[6,6,5,5,7,7,0], \"node_times\":[0,0,0,0,3,1,10]}\n") == 0 );
+  }
+
+  void testNewickTree() {
+    forest->createScaledExampleTree();
+    forest->set_current_base(0.0);
+    forest->set_next_base(10.0);
+    
+    NewickTree of(4, forest->model().has_recombination());
+    std::ostringstream output;
+    of.calculate(*forest);
+    of.printSegmentOutput(output);
+    //std::cout << output.str() << std::endl;
+    CPPUNIT_ASSERT( output.str().compare("((1:1,2:1):9,(3:3,4:3):7);\n") == 0 );
+    
+    output.str("");
+    output.clear();
+    forest->writable_model()->setRecombinationRate(0.0001);
+    of = NewickTree(4, forest->model().has_recombination());
+    of.calculate(*forest);
+    of.printSegmentOutput(output);
+    //std::cout << output.str() << std::endl;
+    CPPUNIT_ASSERT( output.str().compare("[10]((1:1,2:1):9,(3:3,4:3):7);\n") == 0 );
+  }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TestSummaryStatistics );
diff --git a/tests/unittests/test_time_interval.cc b/tests/unittests/test_time_interval.cc
new file mode 100644
index 0000000..016ec19
--- /dev/null
+++ b/tests/unittests/test_time_interval.cc
@@ -0,0 +1,264 @@
+/*
+ * A sample test case which can be used as a template.
+ */
+#include <cppunit/TestCase.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "../../src/forest.h"
+#include "../../src/random/mersenne_twister.h"
+
+
+class TestTimeInterval : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE( TestTimeInterval );
+
+  CPPUNIT_TEST( testIteratorCreation );
+  CPPUNIT_TEST( testIteratorNext );
+  CPPUNIT_TEST( testIteratorCreationWithTimeFrames );
+  CPPUNIT_TEST( testIteratorNextWithTimeFrames );
+  CPPUNIT_TEST( testSplitIntervall );
+  CPPUNIT_TEST( testRecalculateTI );
+  CPPUNIT_TEST( testFindContemporaries );
+
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  Forest *forest, *forest2;
+  Model *model, *model2;
+  MersenneTwister *rg;
+
+ public:
+  void setUp() {
+    rg = new MersenneTwister(5);
+    model = new Model(5);
+    model2 = new Model(5);
+    model2->set_population_number(3);
+
+    forest = new Forest(model, rg);
+    forest->createExampleTree();
+
+    forest2 = new Forest(model2, rg);
+    forest2->createExampleTree();
+  }
+
+  void tearDown() {
+    delete forest, forest2;
+    delete model, model2; 
+    delete rg;
+  }
+
+  void testIteratorCreation() {
+    TimeIntervalIterator it(forest, forest->nodes()->at(0));
+    CPPUNIT_ASSERT( (*it).start_height() == 0 );
+    CPPUNIT_ASSERT( (*it).end_height() == 1 );
+    CPPUNIT_ASSERT_EQUAL( (size_t)4, it.contemporaries()->size(0) );
+    
+    TimeIntervalIterator it2(forest, forest->nodes()->at(4));
+    CPPUNIT_ASSERT( (*it2).start_height() == 1 );
+    CPPUNIT_ASSERT( (*it2).end_height() == 3 );
+    CPPUNIT_ASSERT_EQUAL( (size_t)3, it2.contemporaries()->size(0) );
+    
+    TimeIntervalIterator it3(forest, forest->nodes()->at(5));
+    CPPUNIT_ASSERT( (*it3).start_height() == 3 );
+    CPPUNIT_ASSERT( (*it3).end_height() == 4 );
+    CPPUNIT_ASSERT( it3.contemporaries()->size(0) == 2 );
+ 
+    TimeIntervalIterator it4(forest, forest->nodes()->at(6));
+    CPPUNIT_ASSERT( (*it4).start_height() == 4 );
+    CPPUNIT_ASSERT( (*it4).end_height() == 6 );
+    CPPUNIT_ASSERT( it4.contemporaries()->size(0) == 3 );
+ 
+    TimeIntervalIterator it5(forest, forest->nodes()->at(7));
+    CPPUNIT_ASSERT( (*it5).start_height() == 6 );
+    CPPUNIT_ASSERT( (*it5).end_height() == 10 );
+    CPPUNIT_ASSERT( it5.contemporaries()->size(0) == 2 );
+    
+    TimeIntervalIterator it6(forest, forest->nodes()->at(8));
+    CPPUNIT_ASSERT( (*it6).start_height() == 10 );
+    CPPUNIT_ASSERT( (*it6).end_height() == DBL_MAX );
+    CPPUNIT_ASSERT( it6.contemporaries()->size(0) == 0 );
+  }
+
+  void testIteratorNext() {
+    TimeIntervalIterator it(forest, forest->nodes()->at(0));
+    CPPUNIT_ASSERT( (*it).start_height() == 0 );
+    CPPUNIT_ASSERT( (*it).end_height() == 1 );
+    CPPUNIT_ASSERT( it.contemporaries()->size(0) == 4);
+    CPPUNIT_ASSERT( it.good() );
+    
+    ++it;
+    CPPUNIT_ASSERT( (*it).start_height() == 1 );
+    CPPUNIT_ASSERT( (*it).end_height() == 3 );
+    CPPUNIT_ASSERT( it.contemporaries()->size(0) == 3);
+    CPPUNIT_ASSERT( it.good() );
+  
+    ++it;
+    CPPUNIT_ASSERT( (*it).start_height() == 3 );
+    CPPUNIT_ASSERT( (*it).end_height() == 4 );
+    CPPUNIT_ASSERT( it.contemporaries()->size(0) == 2 );
+    CPPUNIT_ASSERT( it.good() );
+ 
+    ++it;
+    CPPUNIT_ASSERT( (*it).start_height() == 4 );
+    CPPUNIT_ASSERT( (*it).end_height() == 6 );
+    CPPUNIT_ASSERT( it.contemporaries()->size(0) == 3 );
+    CPPUNIT_ASSERT( it.good() );
+ 
+    ++it;
+    CPPUNIT_ASSERT( (*it).start_height() == 6 );
+    CPPUNIT_ASSERT( (*it).end_height() == 10 );
+    CPPUNIT_ASSERT( it.contemporaries()->size(0) == 2 );
+    CPPUNIT_ASSERT( it.good() );
+    
+    ++it;
+    CPPUNIT_ASSERT( (*it).start_height() == 10 );
+    CPPUNIT_ASSERT( (*it).end_height() == DBL_MAX );
+    CPPUNIT_ASSERT( it.contemporaries()->size(0) == 0 );
+    CPPUNIT_ASSERT( it.good() );
+  
+    ++it;
+    CPPUNIT_ASSERT( !it.good() );
+
+    int i = 0;
+    for (TimeIntervalIterator events(forest, forest->nodes()->at(0));
+         events.good(); ++events) { 
+      ++i;
+    }
+    CPPUNIT_ASSERT( i == 6 );
+  }
+
+  void testIteratorCreationWithTimeFrames() {
+    forest->writable_model()->addGrowthRates(0.0, std::vector<double>(1, 1.5));
+    forest->writable_model()->addGrowthRates(0.5, std::vector<double>(1, 1.5));
+    forest->writable_model()->addGrowthRates(1.5, std::vector<double>(1, 1.5));
+
+    TimeIntervalIterator it(forest, forest->nodes()->at(0));
+    CPPUNIT_ASSERT( (*it).start_height() == 0 );
+    CPPUNIT_ASSERT( (*it).end_height() == 0.5 );
+    CPPUNIT_ASSERT( it.contemporaries()->size(0) == 4 );
+
+    TimeIntervalIterator it2(forest, forest->nodes()->at(4));
+    CPPUNIT_ASSERT( (*it2).start_height() == 1 );
+    CPPUNIT_ASSERT( (*it2).end_height() == 1.5 );
+    CPPUNIT_ASSERT_EQUAL( (size_t)3, it2.contemporaries()->size(0) );
+  }
+
+  void testIteratorNextWithTimeFrames() {
+    forest->writable_model()->addGrowthRates(0.0, std::vector<double>(1, 1.5));
+    forest->writable_model()->addGrowthRates(0.5, std::vector<double>(1, 1.5));
+    forest->writable_model()->addGrowthRates(1, std::vector<double>(1, 1.5));
+    forest->writable_model()->addGrowthRates(1.5, std::vector<double>(1, 1.5));
+
+    TimeIntervalIterator it(forest, forest->nodes()->at(0));
+    CPPUNIT_ASSERT( (*it).start_height() == 0 );
+    CPPUNIT_ASSERT( (*it).end_height() == 0.5 );
+    CPPUNIT_ASSERT( it.contemporaries()->size(0) == 4 );
+
+    CPPUNIT_ASSERT_NO_THROW( it.next() );
+    CPPUNIT_ASSERT( (*it).start_height() == 0.5 );
+    CPPUNIT_ASSERT( (*it).end_height() == 1 );
+    CPPUNIT_ASSERT( it.contemporaries()->size(0) == 4 );
+
+    CPPUNIT_ASSERT_NO_THROW( it.next() );
+    CPPUNIT_ASSERT( (*it).start_height() == 1 );
+    CPPUNIT_ASSERT( (*it).end_height() == 1.5 );
+    CPPUNIT_ASSERT( it.contemporaries()->size(0) == 3 );
+    
+    CPPUNIT_ASSERT_NO_THROW( it.next() );
+    CPPUNIT_ASSERT( (*it).start_height() == 1.5 );
+    CPPUNIT_ASSERT( (*it).end_height() == 3 );
+    CPPUNIT_ASSERT( it.contemporaries()->size(0) == 3 );
+  }
+
+  void testSplitIntervall() {
+    TimeIntervalIterator it(forest, forest->nodes()->at(0));
+    Node* split_node = forest->nodes()->createNode(0.5);
+    it.splitCurrentInterval(split_node);
+    ++it;
+
+    // Check split interval
+    CPPUNIT_ASSERT( (*it).start_height() == 0.5 );
+    CPPUNIT_ASSERT( (*it).end_height() == 1 );
+    CPPUNIT_ASSERT( it.contemporaries()->size(0) == 4);
+    CPPUNIT_ASSERT( it.good() );
+
+    // Check that next interval is unchanged
+    ++it;
+    CPPUNIT_ASSERT( (*it).start_height() == 1 );
+    CPPUNIT_ASSERT( (*it).end_height() == 3 );
+    CPPUNIT_ASSERT( it.contemporaries()->size(0) == 3);
+    CPPUNIT_ASSERT( it.good() );
+  }
+
+  void testRecalculateTI() {
+    TimeIntervalIterator it(forest, forest->nodes()->at(0));
+    ++it;
+
+    // Check that is does not change anything if the underlying tree is
+    // unchanged
+    it.recalculateInterval();
+    CPPUNIT_ASSERT( (*it).start_height() == 1 );
+    CPPUNIT_ASSERT( (*it).end_height() == 3 );
+    CPPUNIT_ASSERT( it.contemporaries()->size(0) == 3);
+    CPPUNIT_ASSERT( it.good() );
+
+    // Now change the current interval
+    forest->nodes()->add(forest->nodes()->createNode(2));
+    CPPUNIT_ASSERT( (*it).start_height() == 1 );
+    CPPUNIT_ASSERT( (*it).end_height() == 3 );
+    it.recalculateInterval();
+    CPPUNIT_ASSERT( (*it).start_height() == 1 );
+    CPPUNIT_ASSERT( (*it).end_height() == 2 );
+    CPPUNIT_ASSERT( it.contemporaries()->size(0) == 3);
+    CPPUNIT_ASSERT( it.good() );
+
+    // Also test the next interval
+    ++it;
+    CPPUNIT_ASSERT( (*it).start_height() == 2 );
+    CPPUNIT_ASSERT( (*it).end_height() == 3 );
+    CPPUNIT_ASSERT( it.contemporaries()->size(0) == 3);
+    CPPUNIT_ASSERT( it.good() );
+
+    // Test if we can change the final interval
+    while ( (*it).end_height() < 1000 ) ++it;
+    forest->nodes()->add(forest->nodes()->createNode(1000));
+    it.recalculateInterval();
+    CPPUNIT_ASSERT( (*it).end_height() == 1000 ); 
+    CPPUNIT_ASSERT_NO_THROW( ++it );
+    CPPUNIT_ASSERT( (*it).start_height() == 1000 ); 
+    CPPUNIT_ASSERT( (*it).end_height() == DBL_MAX ); 
+  }
+
+  void testFindContemporaries() {
+    TimeIntervalIterator tii(forest, forest->nodes()->at(0));
+    tii.contemporaries()->clear();
+
+    tii.searchContemporariesBottomUp(forest->nodes()->at(4));
+    CPPUNIT_ASSERT_EQUAL((size_t)2, tii.contemporaries()->size(0)); 
+    tii.contemporaries()->buffer(forest->nodes()->at(4)->height());
+
+    tii.searchContemporariesBottomUp(forest->nodes()->at(5));
+    CPPUNIT_ASSERT_EQUAL((size_t)1, tii.contemporaries()->size(0)); 
+    tii.searchContemporariesBottomUp(forest->nodes()->at(5), true);
+    CPPUNIT_ASSERT_EQUAL((size_t)1, tii.contemporaries()->size(0)); 
+    tii.contemporaries()->buffer(forest->nodes()->at(4)->height());
+
+    tii.searchContemporariesBottomUp(forest->nodes()->at(6));
+    CPPUNIT_ASSERT_EQUAL((size_t)2, tii.contemporaries()->size(0)); 
+    tii.searchContemporariesBottomUp(forest->nodes()->at(6), true);
+    CPPUNIT_ASSERT_EQUAL((size_t)2, tii.contemporaries()->size(0)); 
+
+    tii.searchContemporariesBottomUp(forest->nodes()->at(7));
+    CPPUNIT_ASSERT_EQUAL((size_t)2, tii.contemporaries()->size(0)); 
+    tii.searchContemporariesBottomUp(forest->nodes()->at(7), true);
+    CPPUNIT_ASSERT_EQUAL((size_t)2, tii.contemporaries()->size(0)); 
+
+    tii.searchContemporariesBottomUp(forest->nodes()->at(8));
+    CPPUNIT_ASSERT_EQUAL((size_t)0, tii.contemporaries()->size(0)); 
+    tii.searchContemporariesBottomUp(forest->nodes()->at(8), true);
+    CPPUNIT_ASSERT_EQUAL((size_t)0, tii.contemporaries()->size(0)); 
+  }
+};
+
+//Uncomment this to activate the test
+CPPUNIT_TEST_SUITE_REGISTRATION( TestTimeInterval );
diff --git a/tools/build_win_binaries.sh b/tools/build_win_binaries.sh
new file mode 100755
index 0000000..49d2422
--- /dev/null
+++ b/tools/build_win_binaries.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# ---------------------------------------------------------------------------
+# build_win_binaries.sh
+# Cross-compiles scrm for Windows. Requires that mingw-w64 is installed.
+# 
+# usage ./build_win_binaries.sh vx.y.z
+# ---------------------------------------------------------------------------
+
+
+if [ "${1:0:1}" != "v" ]; then
+  echo "Wrong argument; usage $0 vx.y.z"
+  exit 1
+fi
+
+version=${1:1}
+tempdir=$(mktemp -d)
+cd $tempdir
+
+echo "Getting scrm $1"
+git clone -q https://github.com/scrm/scrm.git || exit 1
+cd scrm || exit 1
+git checkout -q "$1" || exit 1
+
+
+./bootstrap
+
+# Build the 64bit version
+CXX=i686-w64-mingw32-g++ CXXFLAGS='-O3' LDFLAGS='-static-libgcc -static -lpthread' \
+  ./configure --host=i686-w64-mingw32 || exit 1
+make && zip ../scrm-$version-win64.zip scrm.exe
+
+# Build the 32bit version
+CXX=i686-w64-mingw32-g++ CXXFLAGS='-O3 -m32' LDFLAGS='-static-libgcc -static -lpthread' \
+  ./configure --host=i686-w64-mingw32 || exit 1
+make clean && make && zip ../scrm-$version-win32.zip scrm.exe
+
+cd ..
+rm -rf scrm
+echo "Binaries in $tempdir"
diff --git a/tools/compare_versions.sh b/tools/compare_versions.sh
new file mode 100755
index 0000000..7a717b4
--- /dev/null
+++ b/tools/compare_versions.sh
@@ -0,0 +1,71 @@
+#!/bin/bash
+#
+# This script compares two version of scrm.
+# Usage: ./tools/compare_versions.sh <ref1> <ref2> 
+# Where ref1 and 2 are valid git reverences 
+# (e.g. branches or commits)
+# 
+# Author:   Paul R. Staab 
+# Email:    staab (at) bio.lmu.de
+# Date:     2014-07-21
+# Licence:  GPLv3 or later
+#
+
+function test_scrm {
+  time_file_stable=$(mktemp)
+  time_file_new=$(mktemp)
+  for i in `seq 1 100`; do
+
+    equal_results='Yes'
+    hash_stable=$(/usr/bin/time -f "%e %M" $bin1 $@ -seed $i 2>> $time_file_stable | sha512sum)
+    hash_new=$(/usr/bin/time -f "%e %M" $bin2 $@ -seed $i 2>> $time_file_new | sha512sum)
+
+    if [ "$hash_stable" != "$hash_new" ]; then
+      equal_results='No'
+    fi
+  done
+  time_stable=`Rscript -e "options(digits=2); cat(mean(read.table(\"$time_file_stable\")[,1]), 's\n', sep='')"`
+  ram_stable=`Rscript -e "cat(round(mean(read.table(\"$time_file_stable\")[,2])), 'kb\n', sep='')"`
+  time_new=`Rscript -e "options(digits=2); cat(mean(read.table(\"$time_file_new\")[,1]), 's\n', sep='')"`
+  ram_new=`Rscript -e "cat(round(mean(read.table(\"$time_file_new\")[,2])), 'kb\n', sep='')"`
+  rm "$time_file_stable" "$time_file_new"
+
+  echo "scrm $@ | $equal_results | $time_stable | $time_new | $ram_stable | $ram_new"
+}
+
+function build_scrm {
+  git clone -q https://github.com/scrm/scrm.git > /dev/null || exit 1
+  cd scrm || exit 1
+  git checkout -q $1 > /dev/null || exit 1
+  ./bootstrap 2> /dev/null > /dev/null || exit 1
+  make -j4 scrm 2> /dev/null > /dev/null || exit 1
+  mv scrm ../scrm-"$2"
+  cd ..; rm -rf scrm
+}
+
+tempdir=$(mktemp -d)
+cd $tempdir
+echo "Build scrm..."
+build_scrm $1 "old" 
+bin1="./scrm-old"
+echo " $1: $($bin1 --version)"
+
+build_scrm $2 "new"
+bin2="./scrm-new"
+echo " $2: $($bin2 --version)"
+echo ""
+
+echo "Command | Equal results | time $1 | time $2 | memory $1 | memory $2"
+echo "------- | ------------- | ----------- | -------- | ------------- | ---------"
+test_scrm 100 100 -t 5 -T
+test_scrm 20 100 -r 10 100 -t 3 -T -L
+test_scrm 4 10000 -r 10 100 -t 5
+test_scrm 20 2 -r 500 100 -L
+test_scrm 2000 1 -r 10 100 -l 50 -L
+test_scrm 20 1 -r 4000 10000000 -l 300000 -T
+test_scrm 10 100 -r 10 100 -I 3 3 3 4 0.5 -eN 0.1 0.05 -eN 0.2 0.5 -L
+test_scrm 50 100 -r 20 200 -G 1.5 -l 100 -L
+
+cd /
+rm -r "$tempdir"
+
diff --git a/tools/runTillError.sh b/tools/runTillError.sh
new file mode 100755
index 0000000..237b549
--- /dev/null
+++ b/tools/runTillError.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+#
+# runTillError.sh
+# Systematically calls the debug version of scrm for different seeds until an
+# error occurs. Passes command line parameters to scrm. 
+#
+# Author:   Paul R. Staab 
+# Email:    staab (at) bio.lmu.de
+# Date:     2013-04-19
+# Licence:  GPLv3 or later
+#
+
+pars=$@
+[ $# == 0 ] && pars='5 10 -r 100 1000 -l 50'
+make -j2 scrm scrm_dbg
+
+i=0
+while [ 1 ]; do
+  ((i++))
+  echo "Seed: $i"
+  ./scrm_dbg $pars -seed $i > /dev/null 
+  [ $? -eq 0 ] || { echo "Failed: ./scrm_dbg $pars -seed $i"; exit 1; }
+  valgrind --error-exitcode=1 --leak-check=full -q ./scrm $pars -seed $i > /dev/null  
+  [ $? -eq 0 ] || { echo "valgrind failed: ./scrm_dbg $pars -seed $i"; exit 1; }
+done
diff --git a/tools/try_seeds.sh b/tools/try_seeds.sh
new file mode 100755
index 0000000..e1f3bd8
--- /dev/null
+++ b/tools/try_seeds.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+#
+
+pars=$@
+[ $# == 0 ] && pars='5 10 -r 100 1000 -l 50'
+make -j2 scrm
+
+i=0
+while [ 1 ]; do
+  ((i++))
+  echo "Seed: $i"
+  ./scrm $pars -seed $i > /dev/null 
+  [ $? -eq 0 ] || { echo "Failed: ./scrm $pars -seed $i"; exit 1; }
+done

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/scrm.git



More information about the debian-med-commit mailing list