Merge branch 'master' into rotation
authorCarsten Kutzner <ckutzne@gwdg.de>
Thu, 4 Nov 2010 09:42:45 +0000 (10:42 +0100)
committerCarsten Kutzner <ckutzne@gwdg.de>
Thu, 4 Nov 2010 09:42:45 +0000 (10:42 +0100)
Conflicts:
src/kernel/runner.c

79 files changed:
CMakeLists.txt
Makefile.am
README
acinclude.m4
configure.ac
include/copyrite.h
include/gstat.h
include/index.h
include/mdrun.h
include/membed.h [moved from include/gmx_membed.h with 100% similarity]
include/pme.h
scripts/GMXRC.bash.cmakein
scripts/GMXRC.bash.in
scripts/GMXRC.csh.cmakein
scripts/GMXRC.csh.in
scripts/GMXRC.zsh.cmakein
scripts/GMXRC.zsh.in
share/html/online/mdp_opt.html
share/template/Makefile.am
share/top/charmm27.ff/Makefile.am
share/top/charmm27.ff/dna.arn [new file with mode: 0644]
share/top/charmm27.ff/dna.c.tdb [new file with mode: 0644]
share/top/charmm27.ff/dna.hdb [new file with mode: 0644]
share/top/charmm27.ff/dna.n.tdb [new file with mode: 0644]
share/top/charmm27.ff/dna.r2b [deleted file]
share/top/charmm27.ff/dna.rtp
share/top/charmm27.ff/ffnonbonded.itp
share/top/charmm27.ff/rna.arn [new file with mode: 0644]
share/top/charmm27.ff/rna.c.tdb [new file with mode: 0644]
share/top/charmm27.ff/rna.hdb [new file with mode: 0644]
share/top/charmm27.ff/rna.n.tdb [new file with mode: 0644]
share/top/charmm27.ff/rna.r2b
share/top/charmm27.ff/rna.rtp
share/top/gurgle.dat
share/top/ions.itp
src/gmxlib/CMakeLists.txt
src/gmxlib/Makefile.am
src/gmxlib/checkpoint.c
src/gmxlib/copyrite.c
src/gmxlib/ftocstr.c [deleted file]
src/gmxlib/gmxfio.c
src/gmxlib/index.c
src/gmxlib/names.c
src/gmxlib/selection/compiler.c
src/gmxlib/selection/evaluate.c
src/gmxlib/selection/parser.c
src/gmxlib/selection/parser.h
src/gmxlib/selection/parser.y
src/gmxlib/selection/scanner.c
src/gmxlib/selection/scanner.l
src/gmxlib/selection/selhelp.c
src/gmxlib/vmdio.c
src/kernel/CMakeLists.txt
src/kernel/Makefile.am
src/kernel/gmx_gpu_utils/CMakeLists.txt
src/kernel/grompp.c
src/kernel/md.c
src/kernel/md_openmm.c
src/kernel/membed.c [moved from src/kernel/gmx_membed.c with 99% similarity]
src/kernel/readir.c
src/kernel/runner.c
src/mdlib/force.c
src/mdlib/forcerec.c
src/mdlib/gmx_fft_fftw3.c
src/mdlib/mdebin.c
src/mdlib/minimize.c
src/mdlib/pme.c
src/tools/CMakeLists.txt
src/tools/Makefile.am
src/tools/dlist.c
src/tools/gmx_chi.c
src/tools/gmx_density.c
src/tools/gmx_genbox.c
src/tools/gmx_membed.c
src/tools/gmx_saltbr.c
src/tools/gmx_tune_pme.c
src/tools/gmx_velacc.c
src/tools/gmx_wham.c
src/tools/pp2shift.h

index efde6dba111c0e4c4da6da36de5a04d6962bddfd..bee6e3f585233e682d5c263a6f2ea5e8f4bb1094 100644 (file)
@@ -85,7 +85,7 @@ option(GMX_FAHCORE "Build a library with mdrun functionality" OFF)
 mark_as_advanced(GMX_FAHCORE)
 option(GMX_OPENMM "Accelerated execution on GPUs through the OpenMM library (rerun cmake after changing to see relevant options)" OFF)
 set(GMX_ACCELERATION "auto" 
-    CACHE STRING "Accelerated kernels. Pick one of: auto, none, SSE, BlueGene, Power6, ia64, altivec")
+    CACHE STRING "Accelerated kernels. Pick one of: auto, none, SSE, BlueGene, Power6, ia64, altivec, fortran")
 
 set(GMX_FFT_LIBRARY "fftw3" 
     CACHE STRING "FFT library choices: fftw3,fftw2,mkl,fftpack[built-in]")
@@ -112,6 +112,10 @@ option(USE_VERSION_H "Generate development version string/information" ON)
 mark_as_advanced(USE_VERSION_H)
 
 option(GMX_DEFAULT_SUFFIX "Use default suffixes for GROMACS binaries and libs (_d for double, _mpi for MPI; rerun cmake after changing to see relevant options)" ON)
+
+########################################################################
+# Set up binary and library suffixing 
+########################################################################
 set(GMX_BINARY_SUFFIX "" CACHE STRING "Suffix for GROMACS binaries (default: _d for double, _mpi for MPI, _mpi_d for MPI and double).")
 set(GMX_LIBS_SUFFIX "" 
   CACHE STRING "Suffix for GROMACS libs (default: _d for double, _mpi for MPI, _mpi_d for MPI and double).")
@@ -126,6 +130,10 @@ if (GMX_DEFAULT_SUFFIX)
     set (GMX_BINARY_SUFFIX "${GMX_BINARY_SUFFIX}_d")
     set (GMX_LIBS_SUFFIX "${GMX_LIBS_SUFFIX}_d")
   endif(GMX_DOUBLE)
+  if (GMX_OPENMM)
+    set (GMX_BINARY_SUFFIX "-gpu")
+    set (GMX_LIBS_SUFFIX "_gpu")
+  endif(GMX_OPENMM)
   mark_as_advanced(FORCE GMX_BINARY_SUFFIX GMX_LIBS_SUFFIX)
   message(STATUS "Using default binary suffix: \"${GMX_BINARY_SUFFIX}\"")    
   message(STATUS "Using default library suffix: \"${GMX_LIBS_SUFFIX}\"") 
@@ -137,7 +145,7 @@ endif(GMX_DEFAULT_SUFFIX)
 
 set(PKG_CFLAGS "")
 if(GMX_DOUBLE)
-  set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_DOUBLE")
+    set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_DOUBLE")
 endif(GMX_DOUBLE)
 if(GMX_SOFTWARE_INVSQRT)
   set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_SOFTWARE_INVSQRT")
@@ -189,30 +197,36 @@ endif(GMX_MPI)
 if(GMX_OPENMM)
     cmake_minimum_required(VERSION 2.6.4)
     # we'll use the built-in fft to avoid unnecessary dependencies
-    message(STATUS "No external FFT libraries needed for the OpenMM build, using fftpack!")
-    set (GMX_FFT_LIBRARY "fftpack" CACHE STRING 
-               "No external FFT libraries needed for the OpenMM build, using fftpack!" FORCE)
+    string(TOUPPER ${GMX_FFT_LIBRARY} GMX_FFT_LIBRARY)
+    if(NOT ${GMX_FFT_LIBRARY} STREQUAL "FFTPACK")
+        message(STATUS "No external FFT libraries needed for the OpenMM build, switching to fftpack!")
+        set(GMX_FFT_LIBRARY "fftpack" CACHE STRING 
+               "No external FFT libraries needed for the OpenMM build, switching to  fftpack!" FORCE)
+    endif()
     if(GMX_MPI)
         message(FATAL_ERROR "The OpenMM build is not compatible with MPI!")
     endif(GMX_MPI)
     if(GMX_THREADS)
-        message(STATUS "Threads not compatible with OpenMM build, disabled!")
+        message(STATUS "Threads are  not compatible with OpenMM build, disabled!")
         set(GMX_THREADS OFF CACHE BOOL 
-               "Threads not compatible with OpenMM build, disabled!" FORCE)
+               "Threads are not compatible with OpenMM build, disabled!" FORCE)
     endif(GMX_THREADS)
     if(GMX_SOFTWARE_INVSQRT)
-        set(GMX_SOFTWARE_INVSQRT OFF FORCE)
+        set(GMX_SOFTWARE_INVSQRT OFF CACHE STRING 
+                "The OpenMM build does not need GROMACS software 1/sqrt!" FORCE)
     endif(GMX_SOFTWARE_INVSQRT)
-    if(NOT GMX_ACCELERATION MATCHES "^(none|None|NONE)")
-        message(WARNING "CPU-based acceleration turned off, OpenMM does not support/need any!")        
-       unset(GMX_ACCELERATION CACHE)
+    string(TOUPPER ${GMX_ACCELERATION} GMX_ACCELERATION)
+    if(NOT GMX_ACCELERATION STREQUAL "NONE")
+        message(STATUS "Switching off CPU-based acceleration, the OpenMM build does not support/need any!")    
         set(GMX_ACCELERATION "none" CACHE STRING 
-               "CPU-based acceleration turned off, OpenMM does not support/need any!" FORCE)
+               "Switching off CPU-based acceleration, the OpenMM build does not support/need any!" FORCE)
     endif()
     if(GMX_FAHCORE)
         message(FATAL_ERROR "The OpenMM build does not support FAH build!")
     endif(GMX_FAHCORE)
-    set(GMX_DOUBLE OFF FORCE )
+    if(GMX_DOUBLE)
+        message(FATAL_ERROR  "The OpenMM-build does not support double precision calculations!")
+    endif()
     # mark as advanced the unused variables
     mark_as_advanced(FORCE GMX_ACCELERATION GMX_MPI GMX_FFT_LIBRARY 
         GMX_QMMM_PROGRAM GMX_THREADS GMX_DOUBLE)
@@ -439,7 +453,7 @@ gmx_test_inline_asm_msvc_x86(GMX_X86_MSVC_INLINE_ASM)
 if (${GMX_ACCELERATION} STREQUAL "auto" AND NOT GMX_OPENMM)
   if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(i.86|x86|x64|x86_64|AMD64|amd64)")
 
-    set(GMX_ACCELERATION "SSE" CACHE STRING "Accelerated kernels. Pick one of: auto, none, SSE, BlueGene, Power6, ia64, altivec" FORCE)
+    set(GMX_ACCELERATION "SSE" CACHE STRING "Accelerated kernels. Pick one of: auto, none, SSE, BlueGene, Power6, ia64, altivec, fortran" FORCE)
     
     if (GMX_64_BIT)
       set(GMX_X86_64_ASM ON CACHE BOOL "Add SSE assembly files for x86_64" FORCE)
@@ -449,7 +463,7 @@ if (${GMX_ACCELERATION} STREQUAL "auto" AND NOT GMX_OPENMM)
 
     # Determine the assembler/compiler to use
   else()
-    set(GMX_ACCELERATION "none" CACHE STRING "Accelerated kernels. Pick one of: auto, none, SSE, BlueGene, Power6, ia64, altivec" FORCE)
+    set(GMX_ACCELERATION "none" CACHE STRING "Accelerated kernels. Pick one of: auto, none, SSE, BlueGene, Power6, ia64, altivec, fortran" FORCE)
   endif()
 endif (${GMX_ACCELERATION} STREQUAL "auto" AND NOT GMX_OPENMM)
 
@@ -461,27 +475,6 @@ if(NOT GMX_SYSTEM_XDR)
     set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_INTERNAL_XDR")
 endif(NOT GMX_SYSTEM_XDR)
 
-if(GMX_FORTRAN OR GMX_POWER6)
-    enable_language(Fortran)
-    include(FortranCInterface)
-    discover_fortran_mangling(prefix isupper suffix extra_under_score found)
-    if(extra_under_score)
-        set(extrasuffix "_")
-    endif(extra_under_score)
-
-    if(isupper)
-        set(F77_FUNCDEF   "${prefix} ## NAME ## ${suffix}")
-        set(F77_FUNCDEF_  "${prefix} ## NAME ## ${suffix}${extrasuffix}")
-    else(isupper)
-        set(F77_FUNCDEF   "${prefix} ## name ## ${suffix}")
-        set(F77_FUNCDEF_  "${prefix} ## name ## ${suffix}${extrasuffix}")
-    endif(isupper)
-else(GMX_FORTRAN OR GMX_POWER6)
-        set(F77_FUNCDEF   "name ## _")
-        set(F77_FUNCDEF_  "name ## _")
-endif(GMX_FORTRAN OR GMX_POWER6)
-
-
 # Process nonbonded accelerated kernels settings
 string(TOUPPER ${GMX_ACCELERATION} ${GMX_ACCELERATION})
 if(${GMX_ACCELERATION} STREQUAL "NONE")
@@ -511,11 +504,11 @@ elseif(${GMX_ACCELERATION} STREQUAL "SSE")
       if(GMX_DOUBLE)
         set(GMX_IA32_SSE2 1)
       else()
-       set(GMX_IA32_SSE 1)
+       set(GMX_IA32_SSE 1)
       endif()
     elseif(GMX_X86_64_ASM)
       if(GMX_DOUBLE)
-       set(GMX_X86_64_SSE2 1)
+       set(GMX_X86_64_SSE2 1)
       else()
         set(GMX_X86_64_SSE 1)
       endif()
@@ -530,6 +523,9 @@ elseif(${GMX_ACCELERATION} STREQUAL "SSE")
 
 elseif(${GMX_ACCELERATION} STREQUAL "FORTRAN")
     set(GMX_FORTRAN 1)
+    #these are switch on by default sometimes
+    set(GMX_IA32_ASM 0)
+    set(GMX_GMX_X86_64_ASM 0)
 elseif(${GMX_ACCELERATION} STREQUAL "BLUEGENE")
     set(GMX_BLUEGENE 1)
 elseif(${GMX_ACCELERATION} STREQUAL "POWER6")
@@ -547,11 +543,31 @@ else(${GMX_ACCELERATION} STREQUAL "NONE")
     MESSAGE(FATAL_ERROR "Unrecognized option for accelerated kernels: ${GMX_ACCELERATION}. Pick one of auto, none, SSE, Fortran, BlueGene, Power6, ia64, altivec")
 endif(${GMX_ACCELERATION} STREQUAL "NONE")
 
+if(GMX_FORTRAN OR GMX_POWER6)
+    if (GMX_THREADS)
+        message(FATAL_ERROR "FORTRAN/POWER6 is incompatible with threads and only provides a speed-up on certain IBM compilers. Disable FORTRAN (or threads if you really want to use FORTRAN kernels).")
+    endif(GMX_THREADS)
+    enable_language(Fortran)
+    include(FortranCInterface)
+    discover_fortran_mangling(prefix isupper suffix extra_under_score found)
+    if(extra_under_score)
+        set(extrasuffix "_")
+    endif(extra_under_score)
+    if(prefix)
+      set(prefix "${prefix} ##")
+    endif(prefix)
 
-
-
-
-
+    if(isupper)
+        set(F77_FUNCDEF   "${prefix} NAME ## ${suffix}")
+        set(F77_FUNCDEF_  "${prefix} NAME ## ${suffix}${extrasuffix}")
+    else(isupper)
+        set(F77_FUNCDEF   "${prefix} name ## ${suffix}")
+        set(F77_FUNCDEF_  "${prefix} name ## ${suffix}${extrasuffix}")
+    endif(isupper)
+else(GMX_FORTRAN OR GMX_POWER6)
+        set(F77_FUNCDEF   "name ## _")
+        set(F77_FUNCDEF_  "name ## _")
+endif(GMX_FORTRAN OR GMX_POWER6)
 
 # Process QM/MM Settings
 string(TOUPPER ${GMX_QMMM_PROGRAM} ${GMX_QMMM_PROGRAM})
@@ -678,7 +694,11 @@ endif (NOT DEFINED GROMACS_C_FLAGS_SET)
 ########################################################################
 # Specify install locations and which subdirectories to process        #
 ########################################################################
-set(LIB_INSTALL_DIR  ${CMAKE_INSTALL_PREFIX}/lib)
+if ( DEFINED LIB )
+    set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${LIB}")
+else()
+    set(LIB_INSTALL_DIR  ${CMAKE_INSTALL_PREFIX}/lib)
+endif()
 set(BIN_INSTALL_DIR  ${CMAKE_INSTALL_PREFIX}/bin)
 set(DATA_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/gromacs)
 set(MAN_INSTALL_DIR  ${CMAKE_INSTALL_PREFIX}/share/man)
index 52abb079ab6eb2221d62cb97585d5c4b4a100060..febdec51c310a36a9ef8eb66a387886ab4a2489e 100644 (file)
@@ -44,6 +44,9 @@ EXTRA_DIST = config/depcomp \
 
 
 install-exec-hook:
+if NO_LA_FILES
+       cd $(DESTDIR)$(libdir) && rm -f libmd@LIBSUFFIX@.la libgmx@LIBSUFFIX@.la libgmxpreprocess@LIBSUFFIX@.la libgmxana@LIBSUFFIX@.la
+endif
        @echo ""
        @echo "GROMACS is installed under $(prefix)."
        @echo "Make sure to update your PATH and MANPATH to find the"
@@ -67,6 +70,9 @@ install-mdrun:
        (cd $(top_builddir)/src/mdlib && $(MAKE) install ; exit 0)
        (cd $(top_builddir)/src/kernel && $(MAKE) install-libLTLIBRARIES ; exit 0)
        (cd $(top_builddir)/src/kernel && $(MAKE) install-mdrun ; exit 0)
+if NO_LA_FILES
+       cd $(DESTDIR)$(libdir) && rm -f libmd@LIBSUFFIX@.la libgmx@LIBSUFFIX@.la libgmxpreprocess@LIBSUFFIX@.la libgmxana@LIBSUFFIX@.la
+endif
 
 fahcore:
        (cd $(top_builddir)/src/gmxlib && $(MAKE) ; exit 0)
diff --git a/README b/README
index d24640e3c902f648c0ef821d59b405fa543d81b1..398c9fca27ec27446c4c5b32b695e0c5bc7d9769 100644 (file)
--- a/README
+++ b/README
@@ -2,8 +2,10 @@
                Welcome to the official version of GROMACS!
 
 If you are familiar with unix, it should be fairly trivial to compile and
-install GROMACS. Installation instructions are available in the INSTALL file,
-and a more extended step-by-step guide can be found on http://www.gromacs.org .
+install GROMACS. Installation instructions are available in the INSTALL.* 
+files (there is one for automake users, INSTALL.automake and one for cmake
+users, INSTALL.cmake). A more extended step-by-step guide can be found 
+on our website http://www.gromacs.org .
 
 Of course we will do our utmost to help you with any problems, but PLEASE 
 READ THE INSTALLATION INSTRUCTIONS BEFORE CONTACTING US!
index 6e2f396d3aefbce82b4c8e024f88b716a27515ec..8c5fb69f768be0e4daab6401240bafbd1e1e8bb5 100644 (file)
@@ -2075,6 +2075,7 @@ else
     CPPFLAGS="$save_CPPFLAGS"
     LDFLAGS="$save_LDFLAGS"
     LIBS="$save_LIBS"
+    DLOPEN_LIBS="$lt_cv_dlopen_libs"
     ;;
   esac
 
index ff1ca8f34e9528be2169cfa09bafaf92b78afdd0..ebdad8f4c779b6c3bedff127896fb1c62319129c 100644 (file)
@@ -54,6 +54,12 @@ AC_ARG_ENABLE(fortran,
 # always use CC for linking:
 AC_SUBST(F77LINK,"\$(LINK)")
 
+#On some systems GNU libtool's la files are more confusing for libtool than helpful due to the 
+#hard coded paths/libs in the files. And for better linking we have pkg-config files (.pc).
+AC_ARG_ENABLE(la-files,
+       [AS_HELP_STRING([--disable-la-files],[Do NOT install GNU libtool's la files])],,
+       [enable_la_files=yes])
+AM_CONDITIONAL(NO_LA_FILES,[test "$enable_la_files" = no])
 
 
 
@@ -461,6 +467,9 @@ if test "$enable_threads" = "yes"; then
   if test "$with_fft" = "fftw2"; then
     AC_MSG_ERROR([fftw2 can't be used with threads. Use fftw3 or mkl.])
   fi 
+  if test "$enable_fortran" = "yes"; then
+    AC_MSG_ERROR([FORTRAN is incompatible with threads and only provides a speed-up on certain IBM compilers. Use --disable-threads if you really want to use FORTRAN kernels.])
+  fi
   AC_CHECK_HEADERS(unistd.h)
   AC_CHECK_HEADERS(sys/time.h)
   AC_CHECK_HEADERS(sched.h)
@@ -567,6 +576,7 @@ AC_PROG_INSTALL
 AC_PROG_LN_S
 AC_PROG_MAKE_SET
 AC_LIBTOOL_WIN32_DLL
+AC_LIBTOOL_DLOPEN
 AC_PROG_LIBTOOL
 AC_SYS_LARGEFILE
 #
@@ -1168,13 +1178,22 @@ if test "$with_dlopen" = "yes"; then
       CFLAGS_RET=$CFLAGS
       #LDFLAGS="$lt_cv_dlopen_libs $LDFLAGS" #can't make the macro, which is getting lt_cv_dlopen_libs, to work
       LDFLAGS_RET=$LDFLAGS
+      LIBS_RET=$LIBS
       if test "$enable_all_static" = "yes"; then  #make sure we test also whether it works static
         LDFLAGS="$LDFLAGS -static"
       fi
       CFLAGS="-I$srcdir/include -DGMX_DLOPEN $CFLAGS"
-      AC_TRY_LINK([#include "$srcdir/src/gmxlib/vmddlopen.c"],,[AC_MSG_RESULT([yes])\
-       AC_DEFINE(GMX_DLOPEN,,[Compile with dlopen])],AC_MSG_RESULT([no]))
+      LIBS="$DLOPEN_LIBS $LIBS"
+      AC_TRY_LINK([#include "$srcdir/src/gmxlib/vmddlopen.c"],,[
+        AC_MSG_RESULT([yes])
+       AC_DEFINE(GMX_DLOPEN,,[Compile with dlopen])
+       AC_SUBST(DLOPEN_LIBS)
+      ],[
+       AC_MSG_RESULT([no])
+       AC_SUBST(DLOPEN_LIBS,"")
+      ])
       CFLAGS=$CFLAGS_RET
+      LIBS=$LIBS_RET
       LDFLAGS=$LDFLAGS_RET
 fi
 
index cafabf2c893c4804ebedcb5438749b658ba3bc40..487bdba60a758cc01b441236ae508c910a17e0ae 100644 (file)
@@ -56,7 +56,7 @@ CopyrightText[] = {
   "Written by Emile Apol, Rossen Apostolov, Herman J.C. Berendsen,",
   "Aldert van Buuren, Pär Bjelkmar, Rudi van Drunen, Anton Feenstra, ",
   "Gerrit Groenhof, Peter Kasson, Per Larsson, Pieter Meulenhoff, ",
-  "Teemu Murtola, Szilard Pall, Sander Pronk, Roland Schultz, ",
+  "Teemu Murtola, Szilard Pall, Sander Pronk, Roland Schulz, ",
   "Michael Shirts, Alfons Sijbers, Peter Tieleman,\n",
   "Berk Hess, David van der Spoel, and Erik Lindahl.\n",
   "Copyright (c) 1991-2000, University of Groningen, The Netherlands.",
index f2d2b3761ebc850a8e4b1e04f8df213f1480de06..a9ac497c6873248df9b21d4458ce8d9d769fdbfc 100644 (file)
@@ -392,7 +392,7 @@ gmx_bool has_dihedral(int Dih,t_dlist *dl);
 t_dlist *mk_dlist(FILE *log, 
                         t_atoms *atoms, int *nlist,
                         gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, gmx_bool bHChi,
-                        int maxchi,int r0,int naa,char **aa);
+                        int maxchi, int r0, gmx_residuetype_t rt);
                         
 void pr_dlist(FILE *fp,int nl,t_dlist dl[],real dt,  int printtype,
                     gmx_bool bPhi, gmx_bool bPsi,gmx_bool bChi,gmx_bool bOmega, int maxchi);
index b327bd34d974302e96b45cdda3f4537bf5a5bc19..ad91baa98d7eaeaea1992e5a7e877da7e008f668 100644 (file)
@@ -123,6 +123,15 @@ gmx_residuetype_is_dna(gmx_residuetype_t rt, const char *resnm);
 gmx_bool 
 gmx_residuetype_is_rna(gmx_residuetype_t rt, const char *resnm);
 
+int
+gmx_residuetype_get_size(gmx_residuetype_t rt);
+
+int
+gmx_residuetype_get_index(gmx_residuetype_t rt, const char *resnm);
+
+const char *
+gmx_residuetype_get_name(gmx_residuetype_t rt, int index);
+
 
 
 
index b288e4a18a9c9680d066739162a2d4cc9df186b2..db0f7d7c05922c8a8d25b0e88896230bd3fae2a4 100644 (file)
@@ -50,7 +50,7 @@
 #include "vsite.h"
 #include "pull.h"
 #include "update.h"
-#include "gmx_membed.h"
+#include "membed.h"
 
 #ifdef __cplusplus
 extern "C" {
similarity index 100%
rename from include/gmx_membed.h
rename to include/membed.h
index 75c76443e8d16ac92593975b6289a732464666ca..9c6ee1215ea9fa7f18eab9f70ebf454eb2312d60 100644 (file)
@@ -63,6 +63,8 @@ int gmx_pme_destroy(FILE *log,gmx_pme_t *pmedata);
 #define GMX_PME_SOLVE         (1<<1)
 #define GMX_PME_CALC_F        (1<<2)
 #define GMX_PME_CALC_ENER_VIR (1<<3)
+/* This forces the grid to be backtransformed even without GMX_PME_CALC_F */
+#define GMX_PME_CALC_POT      (1<<4)
 #define GMX_PME_DO_ALL_F  (GMX_PME_SPREAD_Q | GMX_PME_SOLVE | GMX_PME_CALC_F)
 
 int gmx_pme_do(gmx_pme_t pme,
index 293530b14a9e61abe9931169e272c290d1267343..52717cc5fb4c2175b159cc81c4d313445c966eca 100644 (file)
@@ -8,8 +8,12 @@
 tmppath=""
 for i in `echo $LD_LIBRARY_PATH | sed "s/:/ /g"`; do
   if test "$i" != "$GMXLDLIB"; then
+    if test "${tmppath}" == ""; then
+      tmppath=$i
+    else
     tmppath=${tmppath}:$i
   fi
+  fi
 done
 LD_LIBRARY_PATH=$tmppath
 
@@ -38,6 +42,9 @@ for i in `echo $MANPATH | sed "s/:/ /g"`; do
     tmppath=${tmppath}:$i
   fi
 done
+if test "$tmppath" == ""; then
+    tmppath=":"
+fi
 MANPATH=$tmppath
 
 ##########################################################
index fcad8c712410164a6fcbc82669004735d899f778..e0b69b472df1de5a6d34aac207f4f69bf11922f8 100644 (file)
@@ -8,8 +8,12 @@
 tmppath=""
 for i in `echo $LD_LIBRARY_PATH | sed "s/:/ /g"`; do
   if test "$i" != "$GMXLDLIB"; then
+    if test "${tmppath}" == ""; then
+      tmppath=$i
+    else
     tmppath=${tmppath}:$i
   fi
+  fi
 done
 LD_LIBRARY_PATH=$tmppath
 
@@ -38,6 +42,9 @@ for i in `echo $MANPATH | sed "s/:/ /g"`; do
     tmppath=${tmppath}:$i
   fi
 done
+if test "$tmppath" == ""; then
+    tmppath=":"
+fi
 MANPATH=$tmppath
 
 ##########################################################
index ff9eba8d6b8c7ace39d1b31ad770cd9ec9cbe363..0e18ba3dbe516b025bb8de4802daa7382c8e4744 100644 (file)
@@ -16,7 +16,13 @@ if (! $?GMXMAN) setenv GMXMAN ""
 # remove previous gromacs part from ld_library_path
 set tmppath = ""
 foreach i ( `echo $LD_LIBRARY_PATH | sed "s/:/ /g"` )
-  if ( "$i" != "$GMXLDLIB" ) set tmppath = "${tmppath}:$i"
+  if ( "$i" != "$GMXLDLIB" ) then
+    if ("${tmppath}" == "") then
+      set tmppath = "$i"
+    else
+      set tmppath = "${tmppath}:$i"
+    endif
+  endif
 end
 setenv LD_LIBRARY_PATH $tmppath
 
@@ -39,6 +45,9 @@ set tmppath = ""
 foreach i ( `echo $MANPATH | sed "s/:/ /g"` )
   if ( "$i" != "$GMXMAN" ) set tmppath = "${tmppath}:$i"
 end
+if ("$tmppath" == "") then
+    set tmppath = ":"
+endif
 setenv MANPATH $tmppath
 
 ##########################################################
index f4dc0df8046c7abc36ea7489aa41c94b94dce486..766446010275e7be80aa9ab133d17b6caa4bde14 100644 (file)
@@ -16,7 +16,13 @@ if (! $?GMXMAN) setenv GMXMAN ""
 # remove previous gromacs part from ld_library_path
 set tmppath = ""
 foreach i ( `echo $LD_LIBRARY_PATH | sed "s/:/ /g"` )
-  if ( "$i" != "$GMXLDLIB" ) set tmppath = "${tmppath}:$i"
+  if ( "$i" != "$GMXLDLIB" ) then
+    if ("${tmppath}" == "") then
+      set tmppath = "$i"
+    else
+      set tmppath = "${tmppath}:$i"
+    endif
+  endif
 end
 setenv LD_LIBRARY_PATH $tmppath
 
@@ -39,6 +45,9 @@ set tmppath = ""
 foreach i ( `echo $MANPATH | sed "s/:/ /g"` )
   if ( "$i" != "$GMXMAN" ) set tmppath = "${tmppath}:$i"
 end
+if ("$tmppath" == "") then
+    set tmppath = ":"
+endif
 setenv MANPATH $tmppath
 
 ##########################################################
index fef40840b0f6c99a79f9bc742f41332bef1359ea..0a29da2418cc26a67967057f3f036f0aad8b204d 100644 (file)
@@ -8,8 +8,12 @@
 tmppath=""
 for i in `echo $LD_LIBRARY_PATH | sed "s/:/ /g"`; do
   if test "$i" != "$GMXLDLIB"; then
+    if test "${tmppath}" = ""; then
+      tmppath=$i
+    else
     tmppath=${tmppath}:$i
   fi
+  fi
 done
 LD_LIBRARY_PATH=$tmppath
 
@@ -38,6 +42,9 @@ for i in `echo $MANPATH | sed "s/:/ /g"`; do
     tmppath=${tmppath}:$i
   fi
 done
+if test "$tmppath" = ""; then
+    tmppath=":"
+fi
 MANPATH=$tmppath
 
 ##########################################################
index 079c29bb35d4b3f5168b686cf221322df8826212..45522bbdfcdba76cd423c8fedbd1d356a9bf24c5 100644 (file)
@@ -8,8 +8,12 @@
 tmppath=""
 for i in `echo $LD_LIBRARY_PATH | sed "s/:/ /g"`; do
   if test "$i" != "$GMXLDLIB"; then
+    if test "${tmppath}" = ""; then
+      tmppath=$i
+    else
     tmppath=${tmppath}:$i
   fi
+  fi
 done
 LD_LIBRARY_PATH=$tmppath
 
@@ -38,6 +42,9 @@ for i in `echo $MANPATH | sed "s/:/ /g"`; do
     tmppath=${tmppath}:$i
   fi
 done
+if test "$tmppath" = ""; then
+    tmppath=":"
+fi
 MANPATH=$tmppath
 
 ##########################################################
index 9cbf19db3326bebe106e5f6a3061a540794a31cc..c132a4af150727b3c63517a6d455fb1f51e29c64 100644 (file)
@@ -45,7 +45,7 @@ IF YOU'RE NOT SURE ABOUT WHAT YOU'RE DOING, DON'T DO IT!
   nstpcouple, tau_p, compressibility, ref_p, refcoord_scaling)
 <li><A HREF="#sa"><b>simulated annealing</b></A> (annealing, annealing_npoints, annealing_time, annealing_temp)
 <li><A HREF="#vel"><b>velocity generation</b></A> (gen_vel, gen_temp, gen_seed)
-<li><A HREF="#bond"><b>bonds</b></A> (constraints, constraint_algorithm, unconstrained_start, shake_tol, lincs_order, lincs_iter, lincs_warnangle, morse)
+<li><A HREF="#bond"><b>bonds</b></A> (constraints, constraint_algorithm, continuation, shake_tol, lincs_order, lincs_iter, lincs_warnangle, morse)
 <li><A HREF="#egexcl"><b>Energy group exclusions</b></A> (energygrp_excl)
 <li><A HREF="#walls"><b>Walls</b></A> (nwall, wall_type, wall_r_linpot, wall_atomtype,
 wall_density, wall_ewald_zfac)
@@ -1047,7 +1047,8 @@ when inter charge-group constraints are present.
 SHAKE can not be used with energy minimization.
 </dd>
 </dl></dd>
-<dt><b>unconstrained_start:</b></dt>
+<dt><b>continuation:</b></dt>
+<dd>This option was formerly known as <tt>unconstrained_start</tt>.</dd>
 <dd><dl compact>
 <dt><b>no</b></dt>
 <dd>apply constraints to the start configuration and reset shells</dd>
@@ -1646,7 +1647,7 @@ for the corresponding atom</dd>
 
 <dt></dt><b>sa_algorithm</b>
 <dd><dl compact="compact">
-<dt><b>Ace-approx</b></dt>
+<dt><b>Ace-approximation</b></dt>
 <dd>Use an Ace-type approximation (default)</dd>
 <dt><b>None</b></dt>
 <dd>No non-polar solvation calculation done. For GBSA only the polar part gets 
@@ -1800,7 +1801,7 @@ reals to your subroutine. Check the inputrec definition in
 <A HREF="#tc">tc_grps</A><br>
 <A HREF="#tc">tcoupl</A><br>
 <A HREF="#run">tinit</A><br>
-<A HREF="#bond">unconstrained_start</A><br>
+<A HREF="#bond">continuation</A><br>
 <A HREF="#user">user1_grps</A><br>
 <A HREF="#user">user2_grps</A><br>
 <A HREF="#user">userint1</A><br>
index 674e8e24db30b7de4a7e575f9070b8ecd5909d8b..458e25b4311e21d19a6c6de981fa9de69ded57fa 100644 (file)
@@ -41,7 +41,7 @@ Makefile.@host@ Makefile.@host@_double: Template.mak Makefile
 CLEANFILES = Makefile.@host@ Makefile.@host@_double *~ \\\#*
 
 template_SOURCES = template.c
-#noinst_PROGRAMS = template
+noinst_PROGRAMS = template
 LDADD = ../../src/mdlib/libmd@LIBSUFFIX@.la ../../src/gmxlib/libgmx@LIBSUFFIX@.la
 #template.$(OBJEXT): gromacs
 
index 454f75649d23617489cd08e1e1963d311805e2d4..b09c02ac9157c03938c732c285acddda059bb6a4 100644 (file)
@@ -11,7 +11,10 @@ aminoacids.hdb   cmap.itp         forcefield.doc   rna.rtp   \
 aminoacids.n.tdb dna.rtp          forcefield.itp   spc.itp     \
 aminoacids.r2b   ffbonded.itp     gb.itp           tip3p.itp   \
 aminoacids.rtp   ffnabonded.itp   ions.itp         tip4p.itp   \
-spce.itp       tips3p.itp      watermodels.dat    tip5p.itp
+spce.itp       tips3p.itp      watermodels.dat    tip5p.itp    \
+dna.hdb                dna.n.tdb       dna.c.tdb       dna.arn \
+rna.hdb                rna.n.tdb       rna.c.tdb       rna.arn \
+rna.r2b
 
 EXTRA_DIST = ${topol_DATA}
 
diff --git a/share/top/charmm27.ff/dna.arn b/share/top/charmm27.ff/dna.arn
new file mode 100644 (file)
index 0000000..1d12b6a
--- /dev/null
@@ -0,0 +1,12 @@
+DNA  C7   C5M
+DNA  H71  H51
+DNA  H72  H52
+DNA  H73  H53
+DNA  OP1  O1P
+DNA  OP2  O2P
+DNA  H2'  H2'1
+DNA  H2'' H2'2
+DNA  H5'  H5'1
+DNA  H5'' H5'2
+DNA  HO5' H5T
+DNA  HO3' H3T
diff --git a/share/top/charmm27.ff/dna.c.tdb b/share/top/charmm27.ff/dna.c.tdb
new file mode 100644 (file)
index 0000000..892bc18
--- /dev/null
@@ -0,0 +1,10 @@
+[ None ]
+
+[ 3' ]
+[ replace ]
+C3'    C3'     CN7     12.011     0.14 
+H3'    H3'     HN7     1.008      0.09
+O3'    O3'     ON5     15.9994   -0.66
+[ Add ]
+1      2       H3T     O3'     C3'     C4'
+               HN5     1.008     0.43 
diff --git a/share/top/charmm27.ff/dna.hdb b/share/top/charmm27.ff/dna.hdb
new file mode 100644 (file)
index 0000000..12af372
--- /dev/null
@@ -0,0 +1,36 @@
+DA     8
+2      6       H5'     C5'     O5'     C4'     
+1      5       H4'     C4'     C5'     O4'     C3'     
+1      5       H1'     C1'     O4'     N9      C2'     
+1      1       H8      C8      N9      N7      
+2      3       H6      N6      C6      C5      
+1      1       H2      C2      N1      N3      
+1      5       H3'     C3'     C4'     C2'     O3'     
+2      6       H2'     C2'     C1'     C3'     
+DT     8
+2      6       H5'     C5'     O5'     C4'     
+1      5       H4'     C4'     C5'     O4'     C3'     
+1      5       H1'     C1'     O4'     N1      C2'     
+1      1       H6      C6      N1      C5      
+3      4       H5      C5M     C5      C6      
+1      1       H3      N3      C4      C2      
+1      5       H3'     C3'     C4'     C2'     O3'     
+2      6       H2'     C2'     C1'     C3'     
+DG     8
+2      6       H5'     C5'     O5'     C4'     
+1      5       H4'     C4'     C5'     O4'     C3'     
+1      5       H1'     C1'     O4'     N9      C2'     
+1      1       H8      C8      N9      N7      
+1      1       H1      N1      C6      C2      
+2      3       H2      N2      C2      N1      
+1      5       H3'     C3'     C4'     C2'     O3'     
+2      6       H2'     C2'     C1'     C3'     
+DC     8
+2      6       H5'     C5'     O5'     C4'     
+1      5       H4'     C4'     C5'     O4'     C3'     
+1      5       H1'     C1'     O4'     N1      C2'     
+1      1       H6      C6      N1      C5      
+1      1       H5      C5      C6      C4      
+2      3       H4      N4      C4      C5      
+1      5       H3'     C3'     C4'     C2'     O3'     
+2      6       H2'     C2'     C1'     C3'     
diff --git a/share/top/charmm27.ff/dna.n.tdb b/share/top/charmm27.ff/dna.n.tdb
new file mode 100644 (file)
index 0000000..26faf9c
--- /dev/null
@@ -0,0 +1,16 @@
+[ None ]
+
+[ 5' ]
+[ delete ]
+ P
+ O1P
+ O2P
+[ replace ]
+O5'    O5'     ON5     15.9994   -0.66   
+C5'    C5'     CN8B    12.011     0.05
+[ Add ]
+ 1  2  H5T     O5'     C5'     C4'
+       HN5     1.008   0.43
+
+
+
diff --git a/share/top/charmm27.ff/dna.r2b b/share/top/charmm27.ff/dna.r2b
deleted file mode 100644 (file)
index a7c195c..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-; rtp residue to rtp building block table
-;GMX   Force-field
-DA    DA       DA5     DA3     -
-DG    DG       DG5     DG3     -
-DC    DC       DC5     DC3     -
-DT    DT       DT5     DT3     -
-
index 983b381a57babeba0eb106098ff099139fa9aad4..485ea0182d202fe88d61938281bcbb52bcb1aa25 100644 (file)
@@ -112,200 +112,6 @@ N7        C8
 N6     C6      H61     H62
 C6     N1      C5      N6
 
-[ DA5 ]
-;             H61  H62;
-;               \  /
-;                N6
-;                |
-;                C6
-;              //  \
-;              N1   C5--N7\\
-;              |    ||     C8-H8
-;              C2   C4--N9/
-;             / \\ /     \
-;           H2   N3       \
-;                          \
-;                           \
-;                            \
-;               H5'1H4'  O4'  \
-;                |    \ /   \  \
-;        H5T-O5'-C5'---C4'    C1'
-;                |     \     / \
-;               H5'2  C3'--C2' H1'
-;                    / \    / \
-;                 O3' H3' H2'1 H2'2
-;                  |  
-;                     
-;
-[ atoms ]
-H5T     HN5      0.43   0
-O5'    ON5     -0.66   1
-C5'    CN8B     0.05   2
-H5'1   HN8      0.09   3
-H5'2   HN8      0.09   4
-C4'    CN7      0.16   5
-H4'    HN7      0.09   6
-O4'    ON6     -0.50   7
-C1'    CN7B     0.16   8
-H1'    HN7      0.09   9
-N9     NN2     -0.05   10
-C5     CN5      0.28   11
-N7     NN4     -0.71   12
-C8     CN4      0.34   13
-H8     HN3      0.12   14
-N1     NN3A    -0.74   15
-C2     CN4      0.50   16
-H2     HN3      0.13   17
-N3     NN3A    -0.75   18
-C4     CN5      0.43   19
-C6     CN2      0.46   20
-N6     NN1     -0.77   21
-H61    HN1      0.38   22
-H62    HN1      0.38   23
-C2'    CN8     -0.18   24
-H2'1   HN8      0.09   25
-H2'2   HN8      0.09   26
-C3'    CN7      0.01   27
-H3'    HN7      0.09   28
-O3'    ON2     -0.57   29
-[ bonds ]
-H5T    O5'
-O5'    C5'
-C5'    C4'
-C4'    O4'
-C4'    C3'
-O4'    C1'
-C1'    N9
-C1'    C2'
-N9     C4
-N9     C8
-C4     N3
-C2     N1
-C6     N6
-N6     H61
-N6     H62
-C6     C5
-C5     N7
-C2'    C3'
-C3'    O3'
-C1'    H1'
-C2'    H2'1
-C2'    H2'2
-C3'    H3'
-C4'    H4'
-C5'    H5'1
-C5'    H5'2
-C8     H8
-C2     H2
-N1     C6
-C2     N3
-C4     C5
-N7     C8
-[ impropers ]
-N6     C6      H61     H62
-C6     N1      C5      N6
-
-
-[ DA3 ]
-;             H61  H62;
-;               \  /
-;                N6
-;                |
-;                C6
-;              //  \
-;              N1   C5--N7\\
-;              |    ||     C8-H8
-;              C2   C4--N9/
-;             / \\ /     \
-;           H2   N3       \
-;                          \
-;                           \
-;                            \
-;        O1P   H5'1 H4'  O4'  \
-;         |      |    \ /   \  \
-;        -P-O5'-C5'---C4'    C1'
-;         |      |     \     / \
-;        O2P    H5'2   C3'--C2' H1'
-;                     / \    / \
-;                  O3' H3' H2'1 H2'2
-;                   |  
-;                  H3T
-
-[ atoms ]
-P      P        1.50   0
-O1P    ON3     -0.78   1
-O2P    ON3     -0.78   2
-O5'    ON2     -0.57   3
-C5'    CN8B    -0.08   4
-H5'1   HN8      0.09   5
-H5'2   HN8      0.09   6
-C4'    CN7      0.16   7
-H4'    HN7      0.09   8
-O4'    ON6     -0.50   9
-C1'    CN7B     0.16   10
-H1'    HN7      0.09   11
-N9     NN2     -0.05   12
-C5     CN5      0.28   13
-N7     NN4     -0.71   14
-C8     CN4      0.34   15
-H8     HN3      0.12   16
-N1     NN3A    -0.74   17
-C2     CN4      0.50   18
-H2     HN3      0.13   19
-N3     NN3A    -0.75   20
-C4     CN5      0.43   21
-C6     CN2      0.46   22
-N6     NN1     -0.77   23
-H61    HN1      0.38   24
-H62    HN1      0.38   25
-C2'    CN8     -0.18   26
-H2'1   HN8      0.09   27
-H2'2   HN8      0.09   28
-C3'    CN7      0.14   29
-H3'    HN7      0.09   30
-O3'    ON5     -0.66   31
-H3T     HN5      0.43   32
-[ bonds ]
--O3'     P
-P      O1P
-P      O2P
-P      O5'
-O5'    C5'
-C5'    C4'
-C4'    O4'
-C4'    C3'
-O4'    C1'
-C1'    N9
-C1'    C2'
-N9     C4
-N9     C8
-C4     N3
-C2     N1
-C6     N6
-N6     H61
-N6     H62
-C6     C5
-C5     N7
-C2'    C3'
-C3'    O3'
-O3'    H3T
-C1'    H1'
-C2'    H2'1
-C2'    H2'2
-C3'    H3'
-C4'    H4'
-C5'    H5'1
-C5'    H5'2
-C8     H8
-C2     H2
-N1     C6
-C2     N3
-C4     C5
-N7     C8
-[ impropers ]
-N6     C6      H61     H62
-C6     N1      C5      N6
-
 ;--------------------------------------------------------------------------
 [ DC ]
 ;
@@ -353,296 +159,16 @@ H5       HN3      0.07   16
 C2     CN1      0.52   17
 O2     ON1C    -0.49   18
 N3     NN3     -0.66   19
-C4     CN2      0.65   20
-N4     NN1     -0.75   21
-H41    HN1      0.37   22
-H42    HN1      0.33   23
-C2'    CN8     -0.18   24
-H2'1   HN8      0.09   25
-H2'2   HN8      0.09   26
-C3'    CN7      0.01   27
-H3'    HN7      0.09   28
-O3'    ON2     -0.57   29
-[ bonds ]
--O3'     P
-P      O1P
-P      O2P
-P      O5'
-O5'    C5'
-C5'    C4'
-C4'    O4'
-C4'    C3'
-O4'    C1'
-C1'    N1
-C1'    C2'
-N1     C2
-N1     C6
-C2     N3
-C4     N4
-N4     H41
-N4     H42
-C4     C5
-C2'    C3'
-C3'    O3'
-C1'    H1'
-C2'    H2'1
-C2'    H2'2
-C3'    H3'
-C4'    H4'
-C5'    H5'1
-C5'    H5'2
-C5     H5
-C6     H6
-C2     O2
-C5     C6
-N3     C4
-[ impropers ]
-C2     N1      N3      O2
-C4     N3      C5      N4
-N4     C4      H41     H42
-
-[ DC5 ]
-;
-;                      H42  H41
-;                        \  /    
-;                         N4
-;                         |
-;                         C4
-;                        /  \\
-;                    H5-C5   N3
-;                       ||   |
-;                    H6-C6   C2
-;                        \  / \\
-;                         N1   O2
-;                          \
-;                           \
-;                            \ 
-;               H5'1H4'  O4'  \
-;                |    \ /   \  \
-;       H5T-O5'-C5'---C4'    C1'
-;                |     \     / \
-;               H5'2  C3'--C2' H1'
-;                    / \    / \
-;                 O3' H3' H2'1 H2'2
-;                   |  
-;   
-[ atoms ]
-H5T     HN5      0.43   0
-O5'    ON5     -0.66   1
-C5'    CN8B     0.05   2
-H5'1   HN8      0.09   3
-H5'2   HN8      0.09   4
-C4'    CN7      0.16   5
-H4'    HN7      0.09   6
-O4'    ON6     -0.50   7
-C1'    CN7B     0.16   8
-H1'    HN7      0.09   9
-N1     NN2     -0.13   10
-C6     CN3      0.05   11
-H6     HN3      0.17   12
-C5     CN3     -0.13   13
-H5     HN3      0.07   14
-C2     CN1      0.52   15
-O2     ON1C    -0.49   16
-N3     NN3     -0.66   17
-C4     CN2      0.65   18
-N4     NN1     -0.75   19
-H41    HN1      0.37   20
-H42    HN1      0.33   21
-C2'    CN8     -0.18   22
-H2'1   HN8      0.09   23
-H2'2   HN8      0.09   24
-C3'    CN7      0.01   25
-H3'    HN7      0.09   26
-O3'    ON2     -0.57   27
-[ bonds ]
-H5T    O5'
-O5'    C5'
-C5'    C4'
-C4'    O4'
-C4'    C3'
-O4'    C1'
-C1'    N1
-C1'    C2'
-N1     C2
-N1     C6
-C2     N3
-C4     N4
-N4     H41
-N4     H42
-C4     C5
-C2'    C3'
-C3'    O3'
-C1'    H1'
-C2'    H2'1
-C2'    H2'2
-C3'    H3'
-C4'    H4'
-C5'    H5'1
-C5'    H5'2
-C5     H5
-C6     H6
-C2     O2
-C5     C6
-N3     C4
-[ impropers ]
-C2     N1      N3      O2
-C4     N3      C5      N4
-N4     C4      H41     H42
-
-[ DC3 ]
-;
-;                      H42  H41
-;                        \  /    
-;                         N4
-;                         |
-;                         C4
-;                        /  \\
-;                    H5-C5   N3
-;                       ||   |
-;                    H6-C6   C2
-;                        \  / \\
-;                         N1   O2
-;                          \
-;                           \
-;                            \ 
-;        O1P    H5'1H4'  O4'  \
-;         |      |    \ /   \  \
-;        -P-O5'-C5'---C4'    C1'
-;         |      |     \     / \
-;        O2P    H5'2  C3'--C2' H1'
-;                    / \    / \
-;                 O3' H3' H2'1 H2'2
-;                   |  
-;                  H3T
-[ atoms ]
-P      P        1.50   0
-O1P    ON3     -0.78   1
-O2P    ON3     -0.78   2
-O5'    ON2     -0.57   3
-C5'    CN8B    -0.08   4
-H5'1   HN8      0.09   5
-H5'2   HN8      0.09   6
-C4'    CN7      0.16   7
-H4'    HN7      0.09   8
-O4'    ON6     -0.50   9
-C1'    CN7B     0.16   10
-H1'    HN7      0.09   11
-N1     NN2     -0.13   12
-C6     CN3      0.05   13
-H6     HN3      0.17   14
-C5     CN3     -0.13   15
-H5     HN3      0.07   16
-C2     CN1      0.52   17
-O2     ON1C    -0.49   18
-N3     NN3     -0.66   19
-C4     CN2      0.65   20
-N4     NN1     -0.75   21
-H41    HN1      0.37   22
-H42    HN1      0.33   23
-C2'    CN8     -0.18   24
-H2'1   HN8      0.09   25
-H2'2   HN8      0.09   26
-C3'    CN7      0.14   27
-H3'    HN7      0.09   28
-O3'    ON5     -0.66   29
-H3T     HN5      0.43   30
-[ bonds ]
--O3'     P
-P      O1P
-P      O2P
-P      O5'
-O5'    C5'
-C5'    C4'
-C4'    O4'
-C4'    C3'
-O4'    C1'
-C1'    N1
-C1'    C2'
-N1     C2
-N1     C6
-C2     N3
-C4     N4
-N4     H41
-N4     H42
-C4     C5
-C2'    C3'
-C3'    O3'
-O3'    H3T
-C1'    H1'
-C2'    H2'1
-C2'    H2'2
-C3'    H3'
-C4'    H4'
-C5'    H5'1
-C5'    H5'2
-C5     H5
-C6     H6
-C2     O2
-C5     C6
-N3     C4
-[ impropers ]
-C2     N1      N3      O2
-C4     N3      C5      N4
-N4     C4      H41     H42
-
-; --------------------------------------------------------------------
-[ DG ]
-;               O6
-;               ||   
-;               C6    
-;              /  \  
-;          H1-N1   C5--N7\\
-;             |    ||     C8-H8
-;             C2   C4--N9/
-;            / \\ /      \
-;      H21-N2   N3        \
-;          |               \
-;         H22               \
-;                            \
-;        O1P    H5'1 H4'  O4'  \
-;         |      |    \ /   \  \
-;        -P-O5'-C5'---C4'    C1'
-;         |      |     \     / \
-;        O2P    H5'2   C3'--C2' H1'
-;                    / \    / \
-;                 O3' H3' H2'1 H2'2
-;                  |  
-;                     
-[ atoms ]
-P      P        1.50   0
-O1P    ON3     -0.78   1
-O2P    ON3     -0.78   2
-O5'    ON2     -0.57   3
-C5'    CN8B    -0.08   4
-H5'1   HN8      0.09   5
-H5'2   HN8      0.09   6
-C4'    CN7      0.16   7
-H4'    HN7      0.09   8
-O4'    ON6     -0.50   9
-C1'    CN7B     0.16   10
-H1'    HN7      0.09   11
-N9     NN2B    -0.02   12
-C4     CN5      0.26   13
-N2     NN1     -0.68   14
-H21    HN1      0.32   15
-H22    HN1      0.35   16
-N3     NN3G    -0.74   17
-C2     CN2      0.75   18
-N1     NN2G    -0.34   19
-H1     HN2      0.26   20
-C6     CN1      0.54   21
-O6     ON1     -0.51   22
-C5     CN5G     0.00   23
-N7     NN4     -0.60   24
-C8     CN4      0.25   25
-H8     HN3      0.16   26
-C2'    CN8     -0.18   27
-H2'1   HN8      0.09   28
-H2'2   HN8      0.09   29
-C3'    CN7      0.01   30
-H3'    HN7      0.09   31
-O3'    ON2     -0.57   32
+C4     CN2      0.65   20
+N4     NN1     -0.75   21
+H41    HN1      0.37   22
+H42    HN1      0.33   23
+C2'    CN8     -0.18   24
+H2'1   HN8      0.09   25
+H2'2   HN8      0.09   26
+C3'    CN7      0.01   27
+H3'    HN7      0.09   28
+O3'    ON2     -0.57   29
 [ bonds ]
 -O3'     P
 P      O1P
@@ -653,112 +179,15 @@ C5'      C4'
 C4'    O4'
 C4'    C3'
 O4'    C1'
-C1'    N9
+C1'    N1
 C1'    C2'
-N9     C4
-N9     C8
-C4     N3
-C2     N2
-C2     N1
-N2     H21
-N2     H22
-N1     H1
+N1     C2
 N1     C6
-C6     C5
-C5     N7
-C2'    C3'
-C3'    O3'
-C1'    H1'
-C2'    H2'1
-C2'    H2'2
-C3'    H3'
-C4'    H4'
-C5'    H5'1
-C5'    H5'2
-C8     H8
 C2     N3
+C4     N4
+N4     H41
+N4     H42
 C4     C5
-N7     C8
-C6     O6
-[ impropers ]
-C2     N3      N1      N2
-C6     N1      C5      O6
-N2     H21     C2      H22
-
-[ DG5 ]
-;               O6
-;               ||   
-;               C6    
-;              /  \  
-;          H1-N1   C5--N7\\
-;             |    ||     C8-H8
-;             C2   C4--N9/
-;            / \\ /      \
-;      H21-N2   N3        \
-;          |               \
-;         H22               \
-;                            \
-;               H5'1H4'  O4'  \
-;                |    \ /   \  \
-;        H5T-O5'-C5'---C4'    C1'
-;                |     \     / \
-;               H5'2  C3'--C2' H1'
-;                    / \    / \
-;                 O3' H3' H2'1 H2'2
-;                  |  
-;                     
-[ atoms ]
-H5T     HN5      0.43   0
-O5'    ON5     -0.66   1
-C5'    CN8B     0.05   2
-H5'1   HN8      0.09   3
-H5'2   HN8      0.09   4
-C4'    CN7      0.16   5
-H4'    HN7      0.09   6
-O4'    ON6     -0.50   7
-C1'    CN7B     0.16   8
-H1'    HN7      0.09   9
-N9     NN2B    -0.02   10
-C4     CN5      0.26   11
-N2     NN1     -0.68   12
-H21    HN1      0.32   13
-H22    HN1      0.35   14
-N3     NN3G    -0.74   15
-C2     CN2      0.75   16
-N1     NN2G    -0.34   17
-H1     HN2      0.26   18
-C6     CN1      0.54   19
-O6     ON1     -0.51   20
-C5     CN5G     0.00   21
-N7     NN4     -0.60   22
-C8     CN4      0.25   23
-H8     HN3      0.16   24
-C2'    CN8     -0.18   25
-H2'1   HN8      0.09   26
-H2'2   HN8      0.09   27
-C3'    CN7      0.01   28
-H3'    HN7      0.09   29
-O3'    ON2     -0.57   30
-[ bonds ]
-H5T     O5'
-O5'    C5'
-C5'    C4'
-C4'    O4'
-C4'    C3'
-O4'    C1'
-C1'    N9
-C1'    C2'
-N9     C4
-N9     C8
-C4     N3
-C2     N2
-C2     N1
-N2     H21
-N2     H22
-N1     H1
-N1     C6
-C6     C5
-C5     N7
 C2'    C3'
 C3'    O3'
 C1'    H1'
@@ -768,17 +197,18 @@ C3'       H3'
 C4'    H4'
 C5'    H5'1
 C5'    H5'2
-C8     H8
-C2     N3
-C4     C5
-N7     C8
-C6     O6
+C5     H5
+C6     H6
+C2     O2
+C5     C6
+N3     C4
 [ impropers ]
-C2     N3      N1      N2
-C6     N1      C5      O6
-N2     H21     C2      H22
-[ DG3 ]
+C2     N1      N3      O2
+C4     N3      C5      N4
+N4     C4      H41     H42
+
+; --------------------------------------------------------------------
+[ DG ]
 ;               O6
 ;               ||   
 ;               C6    
@@ -797,9 +227,9 @@ N2  H21     C2      H22
 ;         |      |     \     / \
 ;        O2P    H5'2   C3'--C2' H1'
 ;                    / \    / \
-;                  O3' H3' H2'1 H2'2
-;                   |  
-;                  H3T
+;                 O3' H3' H2'1 H2'2
+;                  |  
+;                     
 [ atoms ]
 P      P        1.50   0
 O1P    ON3     -0.78   1
@@ -831,10 +261,9 @@ H8 HN3      0.16   26
 C2'    CN8     -0.18   27
 H2'1   HN8      0.09   28
 H2'2   HN8      0.09   29
-C3'    CN7      0.14   30
+C3'    CN7      0.01   30
 H3'    HN7      0.09   31
-O3'    ON5     -0.66   32
-H3T     HN5      0.43   33
+O3'    ON2     -0.57   32
 [ bonds ]
 -O3'     P
 P      O1P
@@ -860,7 +289,6 @@ C6  C5
 C5     N7
 C2'    C3'
 C3'    O3'
-O3'    H3T
 C1'    H1'
 C2'    H2'1
 C2'    H2'2
@@ -975,192 +403,3 @@ C2        N1      N3      O2
 C4     N3      C5      O4
 C5     C4      C6      C5M
 
-[ DT5 ]
-;                  H51    O4
-;                   |     ||
-;               H52-C5M   C4    H3
-;                   |  \ /  \  /
-;                  H53  C5   N3
-;                       ||   |
-;                    H6-C6   C2
-;                        \  / \\  
-;                         N1   O2
-;                          \
-;                           \
-;                            \ 
-;               H5'1H4'  O4'  \
-;                |    \ /   \  \
-;       H5T-O5'-C5'---C4'    C1'
-;                |     \     / \
-;               H5'2  C3'--C2' H1'
-;                    / \    / \
-;                 O3' H3' H2'1 H2'2
-;                   |  
-;                     
-;
-[ atoms ]
-H5T     HN5      0.43   0
-O5'    ON5     -0.66   1
-C5'    CN8B     0.05   2
-H5'1   HN8      0.09   3
-H5'2   HN8      0.09   4
-C4'    CN7      0.16   5
-H4'    HN7      0.09   6
-O4'    ON6     -0.50   7
-C1'    CN7B     0.16   8
-H1'    HN7      0.09   9
-N1     NN2B    -0.34   10
-C6     CN3      0.17   11
-H6     HN3      0.17   12
-C2     CN1T     0.51   13
-O2     ON1     -0.41   14
-N3     NN2U    -0.46   15
-H3     HN2      0.36   16
-C4     CN1      0.50   17
-O4     ON1     -0.45   18
-C5     CN3T    -0.15   19
-C5M    CN9     -0.11   20
-H51    HN9      0.07   21
-H52    HN9      0.07   22
-H53    HN9      0.07   23
-C2'    CN8     -0.18   24
-H2'1   HN8      0.09   25
-H2'2   HN8      0.09   26
-C3'    CN7      0.01   27
-H3'    HN7      0.09   28
-O3'    ON2     -0.57   29
-[ bonds ]
-H5T    O5'
-O5'    C5'
-C5'    C4'
-C4'    O4'
-C4'    C3'
-O4'    C1'
-C1'    N1
-C1'    C2'
-N1     C2
-N1     C6
-C2     N3
-N3     H3
-N3     C4
-C4     C5
-C5     C5M
-C2'    C3'
-C3'    O3'
-C1'    H1'
-C2'    H2'1
-C2'    H2'2
-C3'    H3'
-C4'    H4'
-C5'    H5'1
-C5'    H5'2
-C6     H6
-C5M    H51
-C5M    H52
-C5M    H53
-C2     O2
-C4     O4
-C5     C6
-[ impropers ]
-C2     N1      N3      O2
-C4     N3      C5      O4
-C5     C4      C6      C5M
-
-[ DT3 ]
-;                  H51    O4
-;                   |     ||
-;               H52-C5M   C4    H3
-;                   |  \ /  \  /
-;                  H53  C5   N3
-;                       ||   |
-;                    H6-C6   C2
-;                        \  / \\  
-;                         N1   O2
-;                          \
-;                           \
-;                            \ 
-;        O1P    H5'1H4'  O4'  \
-;         |      |    \ /   \  \
-;        -P-O5'-C5'---C4'    C1'
-;         |      |     \     / \
-;        O2P    H5'2  C3'--C2' H1'
-;                    / \    / \
-;                 O3' H3' H2'1 H2'2
-;                   |  
-;                  H3T
-;
-[ atoms ]
-P      P        1.50   0
-O1P    ON3     -0.78   1
-O2P    ON3     -0.78   2
-O5'    ON2     -0.57   3
-C5'    CN8B    -0.08   4
-H5'1   HN8      0.09   5
-H5'2   HN8      0.09   6
-C4'    CN7      0.16   7
-H4'    HN7      0.09   8
-O4'    ON6     -0.50   9
-C1'    CN7B     0.16   10
-H1'    HN7      0.09   11
-N1     NN2B    -0.34   12
-C6     CN3      0.17   13
-H6     HN3      0.17   14
-C2     CN1T     0.51   15
-O2     ON1     -0.41   16
-N3     NN2U    -0.46   17
-H3     HN2      0.36   18
-C4     CN1      0.50   19
-O4     ON1     -0.45   20
-C5     CN3T    -0.15   21
-C5M    CN9     -0.11   22
-H51    HN9      0.07   23
-H52    HN9      0.07   24
-H53    HN9      0.07   25
-C2'    CN8     -0.18   26
-H2'1   HN8      0.09   27
-H2'2   HN8      0.09   28
-C3'    CN7      0.14   29
-H3'    HN7      0.09   30
-O3'    ON5     -0.66   31
-H3T     HN5      0.43   32
-[ bonds ]
--O3'     P
-P      O1P
-P      O2P
-P      O5'
-O5'    C5'
-C5'    C4'
-C4'    O4'
-C4'    C3'
-O4'    C1'
-C1'    N1
-C1'    C2'
-N1     C2
-N1     C6
-C2     N3
-N3     H3
-N3     C4
-C4     C5
-C5     C5M
-C2'    C3'
-C3'    O3'
-O3'    H3T
-C1'    H1'
-C2'    H2'1
-C2'    H2'2
-C3'    H3'
-C4'    H4'
-C5'    H5'1
-C5'    H5'2
-C6     H6
-C5M    H51
-C5M    H52
-C5M    H53
-C2     O2
-C4     O4
-C5     C6
-[ impropers ]
-C2     N1      N3      O2
-C4     N3      C5      O4
-C5     C4      C6      C5M
-
index fd6223814c18cf711d995682cd9ad3ce044330a0..41a6f2058c38c8d9d1c02c9e5cdb2b386aace2bf 100644 (file)
@@ -155,6 +155,7 @@ HW  1       1.008000        0.41    A       0.0     0.0     ; SPC H
 MNH3   0       0.000000        0.00    A       0.0     0.0
 MNH2   0       0.000000        0.00    A       0.0     0.0
 MCH3   0       0.000000        0.00    A       0.0     0.0
+MCH3S  0       0.000000        0.00    A       0.0     0.0
 ; Ions and noble gases (useful for tutorials)
 Cu2+   29      63.54600        2.00    A       2.08470e-01     4.76976e+00
 Ar     18      39.94800        0.00    A       3.41000e-01     2.74580e-02
diff --git a/share/top/charmm27.ff/rna.arn b/share/top/charmm27.ff/rna.arn
new file mode 100644 (file)
index 0000000..ed58c40
--- /dev/null
@@ -0,0 +1,8 @@
+RNA  OP1  O1P
+RNA  OP2  O2P
+RNA  H2'  H2'1
+RNA  H2'' H2'2
+RNA  H5'  H5'1
+RNA  H5'' H5'2
+RNA  HO5' H5T
+RNA  HO3' H3T
diff --git a/share/top/charmm27.ff/rna.c.tdb b/share/top/charmm27.ff/rna.c.tdb
new file mode 100644 (file)
index 0000000..892bc18
--- /dev/null
@@ -0,0 +1,10 @@
+[ None ]
+
+[ 3' ]
+[ replace ]
+C3'    C3'     CN7     12.011     0.14 
+H3'    H3'     HN7     1.008      0.09
+O3'    O3'     ON5     15.9994   -0.66
+[ Add ]
+1      2       H3T     O3'     C3'     C4'
+               HN5     1.008     0.43 
diff --git a/share/top/charmm27.ff/rna.hdb b/share/top/charmm27.ff/rna.hdb
new file mode 100644 (file)
index 0000000..d3e4546
--- /dev/null
@@ -0,0 +1,40 @@
+RA     9
+2      6       H5'     C5'     O5'     C4'     
+1      5       H4'     C4'     C5'     O4'     C3'     
+1      5       H1'     C1'     O4'     N9      C2'     
+1      1       H8      C8      N9      N7      
+2      3       H6      N6      C6      C5      
+1      1       H2      C2      N1      N3      
+1      5       H3'     C3'     C4'     C2'     O3'     
+1      5       H2'2    C2'     C1'     C3'     O2'     
+1      2       H2'1    O2'     C2'     C1'     
+RU     9
+2      6       H5'     C5'     O5'     C4'     
+1      5       H4'     C4'     C5'     O4'     C3'     
+1      5       H1'     C1'     O4'     N1      C2'     
+1      1       H6      C6      N1      C5      
+1      1       H5      C5      C6      C4      
+1      1       H3      N3      C4      C2      
+1      5       H3'     C3'     C4'     C2'     O3'     
+1      5       H2'2    C2'     C1'     C3'     O2'     
+1      2       H2'1    O2'     C2'     C1'     
+RG     9
+2      6       H5'     C5'     O5'     C4'     
+1      5       H4'     C4'     C5'     O4'     C3'     
+1      5       H1'     C1'     O4'     N9      C2'     
+1      1       H8      C8      N9      N7      
+1      1       H1      N1      C6      C2      
+2      3       H2      N2      C2      N1      
+1      5       H3'     C3'     C4'     C2'     O3'     
+1      5       H2'2    C2'     C1'     C3'     O2'     
+1      2       H2'1    O2'     C2'     C1'     
+RC     9
+2      6       H5'     C5'     O5'     C4'     
+1      5       H4'     C4'     C5'     O4'     C3'     
+1      5       H1'     C1'     O4'     N1      C2'     
+1      1       H6      C6      N1      C5      
+1      1       H5      C5      C6      C4      
+2      3       H4      N4      C4      C5      
+1      5       H3'     C3'     C4'     C2'     O3'     
+1      5       H2'2    C2'     C1'     C3'     O2'     
+1      2       H2'1    O2'     C2'     C1'     
diff --git a/share/top/charmm27.ff/rna.n.tdb b/share/top/charmm27.ff/rna.n.tdb
new file mode 100644 (file)
index 0000000..26faf9c
--- /dev/null
@@ -0,0 +1,16 @@
+[ None ]
+
+[ 5' ]
+[ delete ]
+ P
+ O1P
+ O2P
+[ replace ]
+O5'    O5'     ON5     15.9994   -0.66   
+C5'    C5'     CN8B    12.011     0.05
+[ Add ]
+ 1  2  H5T     O5'     C5'     C4'
+       HN5     1.008   0.43
+
+
+
index 10cf12155a00ba1aa4078a7694c0e87a7358b4c6..d30b5290fedcffc4252305621bfd3c3d75a34a51 100644 (file)
@@ -1,6 +1,6 @@
 ; rtp residue to rtp building block table
 ;GMX   Force-field
-A     RA       RA5     RA3     RA
-G     RG       RG5     RG3     RG
-C     RC       RC5     RC3     RC
-U     RU       RU5     RU3     RU
+A     RA
+G     RG
+C     RC
+U     RU
index dd53e919c1364601f6aca61abb510cbc437b94d4..3abc189d2a173b16f7aaf05f595456dd68362019 100644 (file)
@@ -114,204 +114,6 @@ N7        C8
 N6     C6      H61     H62
 C6     N1      C5      N6
 
-[ RA5 ]
- ;             H61  H62;
- ;               \  /
- ;                N6
- ;                |
- ;                C6
- ;              //  \
- ;              N1   C5--N7\\
- ;              |    ||     C8-H8
- ;              C2   C4--N9/
- ;             / \\ /     \
- ;           H2   N3       \
- ;                          \
- ;                           \
- ;                            \
- ;               H5'1H4'  O4'  \
- ;                |    \ /   \  \
- ;        H5T-O5'-C5'---C4'    C1'
- ;                |     \     / \
- ;               H5'2  C3'--C2' H1'
- ;                     / \   / \
- ;                  O3' H3' O2' H2'2
- ;                   |       |
- ;                          H2'1
- ;
-[ atoms ]
-H5T     HN5      0.43   0
-O5'    ON5     -0.66   1
-C5'    CN8B     0.05   2
-H5'1   HN8      0.09   3
-H5'2   HN8      0.09   4
-C4'    CN7      0.16   5
-H4'    HN7      0.09   6
-O4'    ON6B    -0.50   7
-C1'    CN7B     0.16   8
-H1'    HN7      0.09   9
-N9     NN2     -0.05   10
-C5     CN5      0.28   11
-N7     NN4     -0.71   12
-C8     CN4      0.34   13
-H8     HN3      0.12   14
-N1     NN3A    -0.74   15
-C2     CN4      0.50   16
-H2     HN3      0.13   17
-N3     NN3A    -0.75   18
-C4     CN5      0.43   19
-C6     CN2      0.46   20
-N6     NN1     -0.77   21
-H61    HN1      0.38   22
-H62    HN1      0.38   23
-C2'    CN7B     0.14   24
-H2'2   HN7      0.09   25
-O2'    ON5     -0.66   26
-H2'1   HN5      0.43   27
-C3'    CN7      0.01   28
-H3'    HN7      0.09   29
-O3'    ON2     -0.57   30
-[ bonds ]
-H5T    O5'
-O5'    C5'
-C5'    C4'
-C4'    O4'
-C4'    C3'
-O4'    C1'
-C1'    N9
-C1'    C2'
-N9     C4
-N9     C8
-C4     N3
-C2     N1
-C6     N6
-N6     H61
-N6     H62
-C6     C5
-C5     N7
-C2'    C3'
-C2'    O2'
-O2'    H2'1
-C3'    O3'
-C1'    H1'
-C2'    H2'2
-C3'    H3'
-C4'    H4'
-C5'    H5'1
-C5'    H5'2
-C8     H8
-C2     H2
-N1     C6
-C2     N3
-C4     C5
-N7     C8
-[ impropers ]
-N6     C6      H61     H62
-C6     N1      C5      N6
-
-
-[ RA3 ]
- ;             H61  H62;
- ;               \  /
- ;                N6
- ;                |
- ;                C6
- ;              //  \
- ;              N1   C5--N7\\
- ;              |    ||     C8-H8
- ;              C2   C4--N9/
- ;             / \\ /     \
- ;           H2   N3       \
- ;                          \
- ;                           \
- ;                            \
- ;        O1P   H5'1 H4'  O4'  \
- ;         |      |    \ /   \  \
- ;        -P-O5'-C5'---C4'    C1'
- ;         |      |     \     / \
- ;        O2P    H5'2   C3'--C2' H1'
- ;                     / \   / \
- ;                  O3' H3' O2' H2'2
- ;                   |       |
- ;                  H3T     H2'1
- ;
-[ atoms ]
-P      P        1.50   0
-O1P    ON3     -0.78   1
-O2P    ON3     -0.78   2
-O5'    ON2     -0.57   3
-C5'    CN8B    -0.08   4
-H5'1   HN8      0.09   5
-H5'2   HN8      0.09   6
-C4'    CN7      0.16   7
-H4'    HN7      0.09   8
-O4'    ON6B    -0.50   9
-C1'    CN7B     0.16   10
-H1'    HN7      0.09   11
-N9     NN2     -0.05   12
-C5     CN5      0.28   13
-N7     NN4     -0.71   14
-C8     CN4      0.34   15
-H8     HN3      0.12   16
-N1     NN3A    -0.74   17
-C2     CN4      0.50   18
-H2     HN3      0.13   19
-N3     NN3A    -0.75   20
-C4     CN5      0.43   21
-C6     CN2      0.46   22
-N6     NN1     -0.77   23
-H61    HN1      0.38   24
-H62    HN1      0.38   25
-C2'    CN7B     0.14   26
-H2'2   HN7      0.09   27
-O2'    ON5     -0.66   28
-H2'1   HN5      0.43   29
-C3'    CN7      0.14   30
-H3'    HN7      0.09   31
-O3'    ON5     -0.66   32
-H3T     HN5      0.43   33
-[ bonds ]
--O3'     P
-P      O1P
-P      O2P
-P      O5'
-O5'    C5'
-C5'    C4'
-C4'    O4'
-C4'    C3'
-O4'    C1'
-C1'    N9
-C1'    C2'
-N9     C4
-N9     C8
-C4     N3
-C2     N1
-C6     N6
-N6     H61
-N6     H62
-C6     C5
-C5     N7
-C2'    C3'
-C2'    O2'
-O2'    H2'1
-C3'    O3'
-O3'    H3T
-C1'    H1'
-C2'    H2'2
-C3'    H3'
-C4'    H4'
-C5'    H5'1
-C5'    H5'2
-C8     H8
-C2     H2
-N1     C6
-C2     N3
-C4     C5
-N7     C8
-[ impropers ]
-N6     C6      H61     H62
-C6     N1      C5      N6
-
 ;--------------------------------------------------------------------------
 [ RC ]
 ;
@@ -339,323 +141,37 @@ C6       N1      C5      N6
 ;                   |       |
 ;                          H2'1
 [ atoms ]
-P      P        1.50   0
-O1P    ON3     -0.78   1
-O2P    ON3     -0.78   2
-O5'    ON2     -0.57   3
-C5'    CN8B    -0.08   4
-H5'1   HN8      0.09   5
-H5'2   HN8      0.09   6
-C4'    CN7      0.16   7
-H4'    HN7      0.09   8
-O4'    ON6B    -0.50   9
-C1'    CN7B     0.16   10
-H1'    HN7      0.09   11
-N1     NN2     -0.13   12
-C6     CN3      0.05   13
-H6     HN3      0.17   14
-C5     CN3     -0.13   15
-H5     HN3      0.07   16
-C2     CN1      0.52   17
-O2     ON1C    -0.49   18
-N3     NN3     -0.66   19
-C4     CN2      0.65   20
-N4     NN1     -0.75   21
-H41    HN1      0.37   22
-H42    HN1      0.33   23
-C2'    CN7B     0.14   24
-H2'2   HN7      0.09   25
-O2'    ON5     -0.66   26
-H2'1   HN5      0.43   27
-C3'    CN7      0.01   28
-H3'    HN7      0.09   29
-O3'    ON2     -0.57   30
-[ bonds ]
--O3'     P
-P      O1P
-P      O2P
-P      O5'
-O5'    C5'
-C5'    C4'
-C4'    O4'
-C4'    C3'
-O4'    C1'
-C1'    N1
-C1'    C2'
-N1     C2
-N1     C6
-C2     N3
-C4     N4
-N4     H41
-N4     H42
-C4     C5
-C2'    C3'
-C3'    O3'
-C2'    O2'
-O2'    H2'1
-C1'    H1'
-C2'    H2'2
-C3'    H3'
-C4'    H4'
-C5'    H5'1
-C5'    H5'2
-C5     H5
-C6     H6
-C2     O2
-C5     C6
-N3     C4
-[ impropers ]
-C2     N1      N3      O2
-C4     N3      C5      N4
-N4     C4      H41     H42
-
-[ RC5 ]
-;
-;                      H42  H41
-;                        \  /    
-;                         N4
-;                         |
-;                         C4
-;                        /  \\
-;                    H5-C5   N3
-;                       ||   |
-;                    H6-C6   C2
-;                        \  / \\
-;                         N1   O2
-;                          \
-;                           \
-;                            \ 
-;               H5'1H4'  O4'  \
-;                |    \ /   \  \
-;       H5T-O5'-C5'---C4'    C1'
-;                |     \     / \
-;               H5'2  C3'--C2' H1'
-;                     / \   / \ 
-;                  O3' H3' O2' H2'2 
-;                   |       |
-;                          H2'1
-[ atoms ]
-H5T     HN5      0.43   0
-O5'    ON5     -0.66   1
-C5'    CN8B     0.05   2
-H5'1   HN8      0.09   3
-H5'2   HN8      0.09   4
-C4'    CN7      0.16   5
-H4'    HN7      0.09   6
-O4'    ON6B    -0.50   7
-C1'    CN7B     0.16   8
-H1'    HN7      0.09   9
-N1     NN2     -0.13   10
-C6     CN3      0.05   11
-H6     HN3      0.17   12
-C5     CN3     -0.13   13
-H5     HN3      0.07   14
-C2     CN1      0.52   15
-O2     ON1C    -0.49   16
-N3     NN3     -0.66   17
-C4     CN2      0.65   18
-N4     NN1     -0.75   19
-H41    HN1      0.37   20
-H42    HN1      0.33   21
-C2'    CN7B     0.14   22
-H2'2   HN7      0.09   23
-O2'    ON5     -0.66   24
-H2'1   HN5      0.43   25
-C3'    CN7      0.01   26
-H3'    HN7      0.09   27
-O3'    ON2     -0.57   28
-[ bonds ]
-H5T    O5'
-O5'    C5'
-C5'    C4'
-C4'    O4'
-C4'    C3'
-O4'    C1'
-C1'    N1
-C1'    C2'
-N1     C2
-N1     C6
-C2     N3
-C4     N4
-N4     H41
-N4     H42
-C4     C5
-C2'    C3'
-C3'    O3'
-C2'    O2'
-O2'    H2'1
-C1'    H1'
-C2'    H2'2
-C3'    H3'
-C4'    H4'
-C5'    H5'1
-C5'    H5'2
-C5     H5
-C6     H6
-C2     O2
-C5     C6
-N3     C4
-[ impropers ]
-C2     N1      N3      O2
-C4     N3      C5      N4
-N4     C4      H41     H42
-
-[ RC3 ]
-;
-;                      H42  H41
-;                        \  /    
-;                         N4
-;                         |
-;                         C4
-;                        /  \\
-;                    H5-C5   N3
-;                       ||   |
-;                    H6-C6   C2
-;                        \  / \\
-;                         N1   O2
-;                          \
-;                           \
-;                            \ 
-;        O1P    H5'1H4'  O4'  \
-;         |      |    \ /   \  \
-;        -P-O5'-C5'---C4'    C1'
-;         |      |     \     / \
-;        O2P    H5'2  C3'--C2' H1'
-;                     / \   / \ 
-;                  O3' H3' O2' H2'2 
-;                   |       |
-;                  H3T     H2'1
-[ atoms ]
-P      P        1.50   0
-O1P    ON3     -0.78   1
-O2P    ON3     -0.78   2
-O5'    ON2     -0.57   3
-C5'    CN8B    -0.08   4
-H5'1   HN8      0.09   5
-H5'2   HN8      0.09   6
-C4'    CN7      0.16   7
-H4'    HN7      0.09   8
-O4'    ON6B    -0.50   9
-C1'    CN7B     0.16   10
-H1'    HN7      0.09   11
-N1     NN2     -0.13   12
-C6     CN3      0.05   13
-H6     HN3      0.17   14
-C5     CN3     -0.13   15
-H5     HN3      0.07   16
-C2     CN1      0.52   17
-O2     ON1C    -0.49   18
-N3     NN3     -0.66   19
-C4     CN2      0.65   20
-N4     NN1     -0.75   21
-H41    HN1      0.37   22
-H42    HN1      0.33   23
-C2'    CN7B     0.14   24
-H2'2   HN7      0.09   25
-O2'    ON5     -0.66   26
-H2'1   HN5      0.43   27
-C3'    CN7      0.14   28
-H3'    HN7      0.09   29
-O3'    ON5     -0.66   30
-H3T     HN5      0.43   31
-[ bonds ]
--O3'     P
-P      O1P
-P      O2P
-P      O5'
-O5'    C5'
-C5'    C4'
-C4'    O4'
-C4'    C3'
-O4'    C1'
-C1'    N1
-C1'    C2'
-N1     C2
-N1     C6
-C2     N3
-C4     N4
-N4     H41
-N4     H42
-C4     C5
-C2'    C3'
-C3'    O3'
-O3'    H3T
-C2'    O2'
-O2'    H2'1
-C1'    H1'
-C2'    H2'2
-C3'    H3'
-C4'    H4'
-C5'    H5'1
-C5'    H5'2
-C5     H5
-C6     H6
-C2     O2
-C5     C6
-N3     C4
-[ impropers ]
-C2     N1      N3      O2
-C4     N3      C5      N4
-N4     C4      H41     H42
-
-; --------------------------------------------------------------------
-[ RG ]
-;               O6
-;               ||   
-;               C6    
-;              /  \  
-;          H1-N1   C5--N7\\
-;             |    ||     C8-H8
-;             C2   C4--N9/
-;            / \\ /      \
-;      H21-N2   N3        \
-;          |               \
-;         H22               \
-;                            \
-;        O1P    H5'1 H4'  O4'  \
-;         |      |    \ /   \  \
-;        -P-O5'-C5'---C4'    C1'
-;         |      |     \     / \
-;        O2P    H5'2   C3'--C2' H1'
-;                      / \   / \
-;                     O3' H3' O2' H2'2 
-;                     |       |
-;                             H2'1
-[ atoms ]
-P      P        1.50   0
-O1P    ON3     -0.78   1
-O2P    ON3     -0.78   2
-O5'    ON2     -0.57   3
-C5'    CN8B    -0.08   4
-H5'1   HN8      0.09   5
-H5'2   HN8      0.09   6
-C4'    CN7      0.16   7
-H4'    HN7      0.09   8
-O4'    ON6B    -0.50   9
-C1'    CN7B     0.16   10
-H1'    HN7      0.09   11
-N9     NN2B    -0.02   12
-C4     CN5      0.26   13
-N2     NN1     -0.68   14
-H21    HN1      0.32   15
-H22    HN1      0.35   16
-N3     NN3G    -0.74   17
-C2     CN2      0.75   18
-N1     NN2G    -0.34   19
-H1     HN2      0.26   20
-C6     CN1      0.54   21
-O6     ON1     -0.51   22
-C5     CN5G     0.00   23
-N7     NN4     -0.60   24
-C8     CN4      0.25   25
-H8     HN3      0.16   26
-C2'    CN7B     0.14   27
-H2'2   HN7      0.09   28
-O2'    ON5     -0.66   29
-H2'1   HN5      0.43   30
-C3'    CN7      0.01   31
-H3'    HN7      0.09   32
-O3'    ON2     -0.57   33
+P      P        1.50   0
+O1P    ON3     -0.78   1
+O2P    ON3     -0.78   2
+O5'    ON2     -0.57   3
+C5'    CN8B    -0.08   4
+H5'1   HN8      0.09   5
+H5'2   HN8      0.09   6
+C4'    CN7      0.16   7
+H4'    HN7      0.09   8
+O4'    ON6B    -0.50   9
+C1'    CN7B     0.16   10
+H1'    HN7      0.09   11
+N1     NN2     -0.13   12
+C6     CN3      0.05   13
+H6     HN3      0.17   14
+C5     CN3     -0.13   15
+H5     HN3      0.07   16
+C2     CN1      0.52   17
+O2     ON1C    -0.49   18
+N3     NN3     -0.66   19
+C4     CN2      0.65   20
+N4     NN1     -0.75   21
+H41    HN1      0.37   22
+H42    HN1      0.33   23
+C2'    CN7B     0.14   24
+H2'2   HN7      0.09   25
+O2'    ON5     -0.66   26
+H2'1   HN5      0.43   27
+C3'    CN7      0.01   28
+H3'    HN7      0.09   29
+O3'    ON2     -0.57   30
 [ bonds ]
 -O3'     P
 P      O1P
@@ -666,114 +182,15 @@ C5'      C4'
 C4'    O4'
 C4'    C3'
 O4'    C1'
-C1'    N9
+C1'    N1
 C1'    C2'
-N9     C4
-N9     C8
-C4     N3
-C2     N2
-C2     N1
-N2     H21
-N2     H22
-N1     H1
+N1     C2
 N1     C6
-C6     C5
-C5     N7
-C2'    C3'
-C3'    O3'
-C2'    O2'
-O2'    H2'1
-C1'    H1'
-C2'    H2'2
-C3'    H3'
-C4'    H4'
-C5'    H5'1
-C5'    H5'2
-C8     H8
 C2     N3
+C4     N4
+N4     H41
+N4     H42
 C4     C5
-N7     C8
-C6     O6
-[ impropers ]
-C2     N3      N1      N2
-C6     N1      C5      O6
-N2     H21     C2      H22
-
-[ RG5 ]
-;               O6
-;               ||   
-;               C6    
-;              /  \  
-;          H1-N1   C5--N7\\
-;             |    ||     C8-H8
-;             C2   C4--N9/
-;            / \\ /      \
-;      H21-N2   N3        \
-;          |               \
-;         H22               \
-;                            \
-;               H5'1H4'  O4'  \
-;                |    \ /   \  \
-;        H5T-O5'-C5'---C4'    C1'
-;                |     \     / \
-;               H5'2  C3'--C2' H1'
-;                     / \   / \
-;                   O3' H3' O2' H2'2 
-;                    |       |
-;                            H2'1
-[ atoms ]
-H5T     HN5      0.43   0
-O5'    ON5     -0.66   1
-C5'    CN8B     0.05   2
-H5'1   HN8      0.09   3
-H5'2   HN8      0.09   4
-C4'    CN7      0.16   5
-H4'    HN7      0.09   6
-O4'    ON6B    -0.50   7
-C1'    CN7B     0.16   8
-H1'    HN7      0.09   9
-N9     NN2B    -0.02   10
-C4     CN5      0.26   11
-N2     NN1     -0.68   12
-H21    HN1      0.32   13
-H22    HN1      0.35   14
-N3     NN3G    -0.74   15
-C2     CN2      0.75   16
-N1     NN2G    -0.34   17
-H1     HN2      0.26   18
-C6     CN1      0.54   19
-O6     ON1     -0.51   20
-C5     CN5G     0.00   21
-N7     NN4     -0.60   22
-C8     CN4      0.25   23
-H8     HN3      0.16   24
-C2'    CN7B     0.14   25
-H2'2   HN7      0.09   26
-O2'    ON5     -0.66   27
-H2'1   HN5      0.43   28
-C3'    CN7      0.01   29
-H3'    HN7      0.09   30
-O3'    ON2     -0.57   31
-[ bonds ]
-H5T     O5'
-O5'    C5'
-C5'    C4'
-C4'    O4'
-C4'    C3'
-O4'    C1'
-C1'    N9
-C1'    C2'
-N9     C4
-N9     C8
-C4     N3
-C2     N2
-C2     N1
-N2     H21
-N2     H22
-N1     H1
-N1     C6
-C6     C5
-C5     N7
 C2'    C3'
 C3'    O3'
 C2'    O2'
@@ -784,17 +201,18 @@ C3'       H3'
 C4'    H4'
 C5'    H5'1
 C5'    H5'2
-C8     H8
-C2     N3
-C4     C5
-N7     C8
-C6     O6
+C5     H5
+C6     H6
+C2     O2
+C5     C6
+N3     C4
 [ impropers ]
-C2     N3      N1      N2
-C6     N1      C5      O6
-N2     H21     C2      H22
-[ RG3 ]
+C2     N1      N3      O2
+C4     N3      C5      N4
+N4     C4      H41     H42
+
+; --------------------------------------------------------------------
+[ RG ]
 ;               O6
 ;               ||   
 ;               C6    
@@ -815,7 +233,7 @@ N2  H21     C2      H22
 ;                      / \   / \
 ;                     O3' H3' O2' H2'2 
 ;                     |       |
-;                    H3T     H2'1
+;                             H2'1
 [ atoms ]
 P      P        1.50   0
 O1P    ON3     -0.78   1
@@ -848,10 +266,9 @@ C2'        CN7B     0.14   27
 H2'2   HN7      0.09   28
 O2'    ON5     -0.66   29
 H2'1   HN5      0.43   30
-C3'    CN7      0.14   31
+C3'    CN7      0.01   31
 H3'    HN7      0.09   32
-O3'    ON5     -0.66   33
-H3T     HN5      0.43   34
+O3'    ON2     -0.57   33
 [ bonds ]
 -O3'     P
 P      O1P
@@ -877,7 +294,6 @@ C6  C5
 C5     N7
 C2'    C3'
 C3'    O3'
-O3'    H3T
 C2'    O2'
 O2'    H2'1
 C1'    H1'
@@ -987,183 +403,4 @@ C5        C6
 [ impropers ]
 C2     N1      N3      O2
 C4     N3      C5      O4
-[ RU5 ]
- ;                         O4                               
- ;                         ||
- ;                         C4    H3
- ;                        /  \  /
- ;                    H5-C5   N3
- ;                       ||   |
- ;                    H6-C6   C2
- ;                        \  / \\    
- ;                         N1   O2
- ;                          \
- ;                           \
- ;                            \ 
- ;              H5'1 H4'  O4'  \
- ;                |    \ /   \  \
- ;       H5T-O5'-C5'---C4'    C1'
- ;                |     \     / \
- ;               H5'2  C3'--C2' H1'
- ;                     / \   / \
- ;                   O3' H3' O2' H2'2
- ;                    |       | 
- ;                           H2'1
- ;
-[ atoms ]
-H5T     HN5      0.43   0
-O5'    ON5     -0.66   1
-C5'    CN8B     0.05   2
-H5'1   HN8      0.09   3
-H5'2   HN8      0.09   4
-C4'    CN7      0.16   5
-H4'    HN7      0.09   6
-O4'    ON6B    -0.50   7
-C1'    CN7B     0.16   8
-H1'    HN7      0.09   9
-N1     NN2B    -0.34   10
-C6     CN3      0.20   11
-H6     HN3      0.14   12
-C2     CN1T     0.55   13
-O2     ON1     -0.45   14
-N3     NN2U    -0.46   15
-H3     HN2      0.36   16
-C4     CN1      0.53   17
-O4     ON1     -0.48   18
-C5     CN3     -0.15   19
-H5     HN3      0.10   20
-C2'    CN7B     0.14   21
-H2'2   HN7      0.09   22
-O2'    ON5     -0.66   23
-H2'1   HN5      0.43   24
-C3'    CN7      0.01   25
-H3'    HN7      0.09   26
-O3'    ON2     -0.57   27
-[ bonds ]
-H5T    O5'
-O5'    C5'
-C5'    C4'
-C4'    O4'
-C4'    C3'
-O4'    C1'
-C1'    N1
-C1'    C2'
-N1     C2
-N1     C6
-C2     N3
-N3     H3
-N3     C4
-C4     C5
-C2'    C3'
-C3'    O3'
-C2'    O2'
-O2'    H2'1
-C1'    H1'
-C2'    H2'2
-C3'    H3'
-C4'    H4'
-C5'    H5'1
-C5'    H5'2
-C5     H5
-C6     H6
-C2     O2
-C4     O4
-C5     C6
-[ impropers ]
-C2     N1      N3      O2
-C4     N3      C5      O4
-
-[ RU3 ]
- ;                         O4                               
- ;                         ||
- ;                         C4    H3
- ;                        /  \  /
- ;                    H5-C5   N3
- ;                       ||   |
- ;                    H6-C6   C2
- ;                        \  / \\    
- ;                         N1   O2
- ;                          \
- ;                           \
- ;                            \ 
- ;        O1P    H5'1H4'  O4'  \
- ;         |      |    \ /   \  \
- ;        -P-O5'-C5'---C4'    C1'
- ;         |      |     \     / \
- ;        O2P    H5'2  C3'--C2' H1'
- ;                     / \   / \
- ;                   O3' H3' O2' H2'2
- ;                    |       | 
- ;                   H3T     H2'1
- ;
-[ atoms ]
-P      P        1.50   0
-O1P    ON3     -0.78   1
-O2P    ON3     -0.78   2
-O5'    ON2     -0.57   3
-C5'    CN8B    -0.08   4
-H5'1   HN8      0.09   5
-H5'2   HN8      0.09   6
-C4'    CN7      0.16   7
-H4'    HN7      0.09   8
-O4'    ON6B    -0.50   9
-C1'    CN7B     0.16   10
-H1'    HN7      0.09   11
-N1     NN2B    -0.34   12
-C6     CN3      0.20   13
-H6     HN3      0.14   14
-C2     CN1T     0.55   15
-O2     ON1     -0.45   16
-N3     NN2U    -0.46   17
-H3     HN2      0.36   18
-C4     CN1      0.53   19
-O4     ON1     -0.48   20
-C5     CN3     -0.15   21
-H5     HN3      0.10   22
-C2'    CN7B     0.14   23
-H2'2   HN7      0.09   24
-O2'    ON5     -0.66   25
-H2'1   HN5      0.43   26
-C3'    CN7      0.14   27
-H3'    HN7      0.09   28
-O3'    ON5     -0.66   29
-H3T     HN5      0.43   30
-[ bonds ]
--O3'     P
-P      O1P
-P      O2P
-P      O5'
-O5'    C5'
-C5'    C4'
-C4'    O4'
-C4'    C3'
-O4'    C1'
-C1'    N1
-C1'    C2'
-N1     C2
-N1     C6
-C2     N3
-N3     H3
-N3     C4
-C4     C5
-C2'    C3'
-C3'    O3'
-O3'    H3T
-C2'    O2'
-O2'    H2'1
-C1'    H1'
-C2'    H2'2
-C3'    H3'
-C4'    H4'
-C5'    H5'1
-C5'    H5'2
-C5     H5
-C6     H6
-C2     O2
-C4     O4
-C5     C6
-[ impropers ]
-C2     N1      N3      O2
-C4     N3      C5      O4
 
index fa17ed1c9d01dcef432363017da6cff43740f4c0..b59676bc5bd5c4712fca7bd9604204529d09d52c 100644 (file)
@@ -1,4 +1,4 @@
-363
+365
 ��ߦ��ߨ���߬��������߻���ߦ��߷���ߋ�߻�߶�ߦ��������׷���������߶��
 �߳���ߋ��߳���߫���ߨ���߫���߻���׫������
 �����߽����߲�߷������ײ��������
 �����،ߑ�߈��߆��ߜ��ߍ���ߐ�ߞ�ߚ����������׸�����߸��������
 �ߓ���ߋ�߈����ߋ���߶ߙ���ߓ���߶ߛ�ߌ���������׼���߼�������
 ���߶ߗ���ߚ���������ߓ�����ߋ���ߚ���������ߚ����׻���߯������
+�����ߐ�ߜ�����������ߞ��ߋ��ߌ������߲�ߌ������ߖ�߈�������ߑ�����ߜ��������ײ�������
+��،ߊ����ߜ���ߋ���ߐ���߆��ߞ��߶ߔ����״���߽����
index a0939261188ae5483b4017c814f8c322a3069197..48c3d7af658f24e22601e3def9fd2116c57b62ca 100644 (file)
@@ -84,7 +84,7 @@ CU2+          1
 
 [ atoms ]
 ; id   at type res nr  residu name     at name  cg nr  charge   mass
-1      CU2+    1       CU2+            CU       1      2        63.54600
+1      Cu2+    1       CU2+            CU       1      2        63.54600
 
 [ moleculetype ]
 ; molname      nrexcl
@@ -92,7 +92,7 @@ ZN2+          1
 
 [ atoms ]
 ; id   at type res nr  residu name     at name  cg nr  charge   mass
-1      ZN2+    1       ZN2+            ZN       1      2        65.37000
+1      Zn2+    1       ZN2+            ZN       1      2        65.37000
 
 [ moleculetype ]
 ; molname      nrexcl
index b78966cbfac45c27f7634ecf462d5d6c751409d5..4cbe2e9bdf7bce0b70faf5b3fd03405a6ed1b492 100644 (file)
@@ -62,6 +62,18 @@ if(GMX_X86_64_ASM)
   endif()
 endif(GMX_X86_64_ASM)
 
+if(GMX_FORTRAN)
+  if (GMX_DOUBLE)
+    file(GLOB FORTRAN_SOURCES nonbonded/nb_kernel_f77_double/*.[cf])
+  else(GMX_DOUBLE)
+    file(GLOB FORTRAN_SOURCES nonbonded/nb_kernel_f77_single/*.[cf])
+  endif(GMX_DOUBLE)
+endif(GMX_FORTRAN)
+
+if(GMX_POWER6)
+  file(GLOB FORTRAN_SOURCES nonbonded/nb_kernel_power6/*.[cF])
+endif(GMX_POWER6)
+
 if(NOT GMX_EXTERNAL_BLAS)
   file(GLOB BLAS_SOURCES gmx_blas/*.c)
 endif(NOT GMX_EXTERNAL_BLAS)
@@ -118,7 +130,7 @@ else(GMX_ASM_USEASM-NASM)
 endif(GMX_ASM_USEASM-NASM)
 endif(NOT GMX_OPENMM)
 
-add_library(gmx ${GMXLIB_SOURCES} ${BLAS_SOURCES} ${LAPACK_SOURCES} ${GMX_SSEKERNEL_C_SRC} ${GMX_SSEKERNEL_ASM_SRC} ${THREAD_MPI_SRC})
+add_library(gmx ${GMXLIB_SOURCES} ${BLAS_SOURCES} ${LAPACK_SOURCES} ${GMX_SSEKERNEL_C_SRC} ${GMX_SSEKERNEL_ASM_SRC} ${FORTRAN_SOURCES} ${THREAD_MPI_SRC})
 target_link_libraries(gmx ${GMX_EXTRA_LIBRARIES}  ${THREAD_LIB})
 add_dependencies(gmx gmx_version) 
 set_target_properties(gmx PROPERTIES OUTPUT_NAME "gmx${GMX_LIBS_SUFFIX}" SOVERSION ${SOVERSION} INSTALL_NAME_DIR "${LIB_INSTALL_DIR}")
index 2acf712fb09c9985ab7cd0dde773d37073556c1a..c6ca5b70c961d5dcc2fed46a5f95b5618ec9245a 100644 (file)
@@ -45,7 +45,7 @@ libgmx@LIBSUFFIX@_la_DEPENDENCIES = nonbonded/libnonbonded.la         \
 
 #      
 #
-libgmx@LIBSUFFIX@_la_LDFLAGS = -no-undefined -version-info @SHARED_VERSION_INFO@ $(PTHREAD_LIBS)
+libgmx@LIBSUFFIX@_la_LDFLAGS = -no-undefined -version-info @SHARED_VERSION_INFO@ @DLOPEN_LIBS@ $(PTHREAD_LIBS)
 
 libgmx@LIBSUFFIX@_la_SOURCES = \
        3dview.c        atomprop.c      bondfree.c      \
index 0d0b74a5db4e2b86fc8840dbd46499c0bb418991..c31137433a262beef2f9b0c62ec2206ee72fed9b 100644 (file)
@@ -1457,23 +1457,32 @@ static void read_checkpoint(const char *fn,FILE **pfplog,
     int  natoms,ngtc,nnhpres,nhchainlength,fflags,flags_eks,flags_enh;
     int  d;
     int  ret;
-       gmx_file_position_t *outputfiles;
-       int  nfiles;
-       t_fileio *chksum_file;
-       FILE* fplog = *pfplog;
-       unsigned char digest[16];
+    gmx_file_position_t *outputfiles;
+    int  nfiles;
+    t_fileio *chksum_file;
+    FILE* fplog = *pfplog;
+    unsigned char digest[16];
 #if !((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
-       struct flock fl = { 0, SEEK_SET, 0,       F_WRLCK,     0 }; 
+    struct flock fl;  /* don't initialize here: the struct order is OS 
+                         dependent! */
 #endif
-       
+
     const char *int_warn=
-        "WARNING: The checkpoint file was generator with integrator %s,\n"
-        "         while the simulation uses integrator %s\n\n";
+              "WARNING: The checkpoint file was generated with integrator %s,\n"
+              "         while the simulation uses integrator %s\n\n";
     const char *sd_note=
         "NOTE: The checkpoint file was for %d nodes doing SD or BD,\n"
         "      while the simulation uses %d SD or BD nodes,\n"
         "      continuation will be exact, except for the random state\n\n";
     
+#if !((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__) 
+    fl.l_type=F_WRLCK;
+    fl.l_whence=SEEK_SET;
+    fl.l_start=0;
+    fl.l_len=0;
+    fl.l_pid=0;
+#endif
+
     if (PARTDECOMP(cr))
     {
         gmx_fatal(FARGS,
@@ -1745,16 +1754,19 @@ static void read_checkpoint(const char *fn,FILE **pfplog,
             if (outputfiles[i].chksum_size != -1)
             {
                 if (gmx_fio_get_file_md5(chksum_file,outputfiles[i].offset,
-                                     digest) != outputfiles[i].chksum_size)
+                                     digest) != outputfiles[i].chksum_size)  /*at the end of the call the file position is at the end of the file*/
                 {
                     gmx_fatal(FARGS,"Can't read %d bytes of '%s' to compute checksum. The file has been replaced or its contents has been modified.",
                               outputfiles[i].chksum_size, 
                               outputfiles[i].filename);
                 }
             } 
-            else if (i==0)  /*log file need to be seeked even when not reading md5*/
+            if (i==0)  /*log file needs to be seeked in case we need to truncate (other files are truncated below)*/
             {
-                gmx_fio_seek(chksum_file,outputfiles[i].offset);
+                if (gmx_fio_seek(chksum_file,outputfiles[i].offset))
+                {
+                       gmx_fatal(FARGS,"Seek error! Failed to truncate log-file: %s.", strerror(errno));
+                }
             }
 #endif
             
index 353fba1781ef6a25a612bdfe53133f60bb2e8e80..982ca55b1de85d6187c860f15979de526952005c 100644 (file)
@@ -358,6 +358,11 @@ void please_cite(FILE *fp,const char *key)
       "GROMACS 4: Algorithms for highly efficient, load-balanced, and scalable molecular simulation",
       "J. Chem. Theory Comput.",
       4, 2008, "435-447" },
+    { "Hub2010",
+      "J. S. Hub, B. L. de Groot and D. van der Spoel",
+      "g_wham - A free weighted histogram analysis implementation including robust error and autocorrelation estimates",
+      "J. Chem. Theory Comput.",
+      0, 2010, "0000-0000"}, 
     { "In-Chul99a",
       "Y. In-Chul and M. L. Berkowitz",
       "Ewald summation for systems with slab geometry",
diff --git a/src/gmxlib/ftocstr.c b/src/gmxlib/ftocstr.c
deleted file mode 100644 (file)
index b874ee0..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 
- *                This source code is part of
- * 
- *                 G   R   O   M   A   C   S
- * 
- *          GROningen MAchine for Chemical Simulations
- * 
- *                        VERSION 3.2.0
- * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team,
- * check out http://www.gromacs.org for more information.
-
- * 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 2
- * of the License, or (at your option) any later version.
- * 
- * If you want to redistribute modifications, please consider that
- * scientific software is very special. Version control is crucial -
- * bugs must be traceable. We will be happy to consider code for
- * inclusion in the official distribution, but derived work must not
- * be called official GROMACS. Details are found in the README & COPYING
- * files - if they are missing, get the official version at www.gromacs.org.
- * 
- * To help us fund GROMACS development, we humbly ask that you cite
- * the papers on the package - you can find them in the top README file.
- * 
- * For more info, check our website at http://www.gromacs.org
- * 
- * And Hey:
- * GROningen Mixture of Alchemy and Childrens' Stories
- */
-/* This file is completely threadsafe - keep it that way! */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-int ftocstr(char *ds, int dl, char *ss, int sl)
-    /* dst, src ptrs */
-    /* dst max len */
-    /* src len */
-{
-    char *p;
-
-    p = ss + sl;
-    while ( --p >= ss && *p == ' ' );
-    sl = p - ss + 1;
-    dl--;
-    ds[0] = 0;
-    if (sl > dl)
-      return 1;
-    while (sl--)
-      (*ds++ = *ss++);
-    *ds = '\0';
-    return 0;
-}
-
-
-int ctofstr(char *ds, int dl, char *ss)
-     /* dest space */
-     /* max dest length */
-     /* src string (0-term) */
-{
-    while (dl && *ss) {
-       *ds++ = *ss++;
-       dl--;
-    }
-    while (dl--)
-       *ds++ = ' ';
-    return 0;
-}
index 587a554a923564c8462822f3c342c7f1c83ace5d..832d6e0d2f4648e42b05adde472c07e21da787a7 100644 (file)
@@ -1087,7 +1087,7 @@ int gmx_fio_seek(t_fileio* fio, gmx_off_t fpos)
     gmx_fio_lock(fio);
     if (fio->fp)
     {
-        gmx_fseek(fio->fp, fpos, SEEK_SET);
+        rc = gmx_fseek(fio->fp, fpos, SEEK_SET);
     }
     else
     {
index 4156d70405edbf6f9d30b6dedb597edab3cc0df8..0cb96f65d215944c381281358b8eeaea56edd5c1 100644 (file)
@@ -662,6 +662,42 @@ gmx_residuetype_is_rna(gmx_residuetype_t rt, const char *resnm)
     return rc;
 }
 
+/* Return the size of the arrays */
+int
+gmx_residuetype_get_size(gmx_residuetype_t rt)
+{
+    return rt->n;
+}
+
+/* Search for a residuetype with name resnm within the
+ * gmx_residuetype database. Return the index if found,
+ * otherwise -1.
+ */
+int
+gmx_residuetype_get_index(gmx_residuetype_t rt, const char *resnm)
+{
+    int i,rc;
+
+    rc=-1;
+    for(i=0;i<rt->n && rc;i++)
+    {
+        rc=gmx_strcasecmp(rt->resname[i],resnm);
+    }
+
+    return (0 == rc) ? i-1 : -1;
+}
+
+/* Return the name of the residuetype with the given index, or
+ * NULL if not found. */
+const char *
+gmx_residuetype_get_name(gmx_residuetype_t rt, int index)
+{
+  if(index >= 0 && index < rt->n) {
+    return rt->resname[index];
+  } else {
+    return NULL;
+  }
+}
 
 
 
index 6365da6a937f8a8137946a6ec2d8efbce63dd16e..df1ad2ff3abc8f5c202890b8b68b572f71a3197b 100644 (file)
@@ -173,7 +173,7 @@ const char *egb_names[egbNR+1] = {
 };
 
 const char *esa_names[esaNR+1] = {
-  "Ace-approx", "None", "Still", NULL
+  "Ace-approximation", "None", "Still", NULL
 };
 
 const char *ewt_names[ewtNR+1] = {
index 76f40036d7ba203ff0c9f93b9cab5fe86020b6e5..45ca192cf6e5fabedec6e18961dbf9145b20cd55 100644 (file)
@@ -1770,6 +1770,16 @@ init_method(t_selelem *sel, t_topology *top, int isize)
                 }
             }
         }
+        /* Clear the values for dynamic output to avoid valgrind warnings. */
+        if ((sel->flags & SEL_DYNAMIC) && sel->v.type == REAL_VALUE)
+        {
+            int i;
+
+            for (i = 0; i < sel->v.nr; ++i)
+            {
+                sel->v.u.r[i] = 0.0;
+            }
+        }
     }
 
     return 0;
index 06a4d8b7062b13aa2af56492cedaf1714a092530..9fbe3c064fd6872f689514f905c8f9e9449e9eff 100644 (file)
@@ -1079,13 +1079,16 @@ _gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t *data, t_selelem *sel,
     if (left->mempool)
     {
         _gmx_selvalue_setstore(&left->v, sel->v.u.ptr);
-        rc = _gmx_selelem_mempool_reserve(right, g->isize);
-        if (rc != 0)
+        if (right)
         {
-            return rc;
+            rc = _gmx_selelem_mempool_reserve(right, g->isize);
+            if (rc != 0)
+            {
+                return rc;
+            }
         }
     }
-    else if (right->mempool)
+    else if (right && right->mempool)
     {
         _gmx_selvalue_setstore(&right->v, sel->v.u.ptr);
     }
@@ -1123,9 +1126,12 @@ _gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t *data, t_selelem *sel,
     if (left->mempool)
     {
         _gmx_selvalue_setstore(&left->v, NULL);
-        _gmx_selelem_mempool_release(right);
+        if (right)
+        {
+            _gmx_selelem_mempool_release(right);
+        }
     }
-    else if (right->mempool)
+    else if (right && right->mempool)
     {
         _gmx_selvalue_setstore(&right->v, NULL);
     }
index e8aac56206f8d79b83ac9a7ae4e84f7a8a54ef5f..3e57a98218e146464191d14b3073035b2f722fbc 100644 (file)
      OR = 286,
      AND = 287,
      NOT = 288,
-     UNARY_NEG = 289
+     UNARY_NEG = 289,
+     NUM_REDUCT = 290
    };
 #endif
 /* Tokens.  */
 #define AND 287
 #define NOT 288
 #define UNARY_NEG 289
+#define NUM_REDUCT 290
 
 
 
@@ -208,7 +210,7 @@ typedef union YYSTYPE
     struct t_selexpr_param     *param;
 }
 /* Line 187 of yacc.c.  */
-#line 212 "parser.c"
+#line 214 "parser.c"
        YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
@@ -221,7 +223,7 @@ typedef union YYSTYPE
 
 
 /* Line 216 of yacc.c.  */
-#line 225 "parser.c"
+#line 227 "parser.c"
 
 #ifdef short
 # undef short
@@ -436,20 +438,20 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  2
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   329
+#define YYLAST   417
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  44
+#define YYNTOKENS  49
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  20
+#define YYNNTS  26
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  76
+#define YYNRULES  91
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  125
+#define YYNSTATES  150
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   289
+#define YYMAXUTOK   290
 
 #define YYTRANSLATE(YYX)                                               \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -461,15 +463,15 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-      41,    42,    36,    34,    43,    35,     2,    37,     2,     2,
+      42,    43,    36,    34,    45,    35,     2,    37,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,    40,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,    41,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,    39,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,    44,     2,    46,    39,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,    47,     2,    48,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -485,63 +487,72 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
-      25,    26,    27,    28,    29,    30,    31,    32,    33,    38
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    38,
+      40
 };
 
 #if YYDEBUG
 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
    YYRHS.  */
-static const yytype_uint8 yyprhs[] =
+static const yytype_uint16 yyprhs[] =
 {
        0,     0,     3,     4,     7,    10,    13,    14,    16,    18,
       20,    22,    25,    29,    33,    37,    39,    41,    44,    47,
-      49,    51,    55,    59,    61,    63,    65,    67,    70,    74,
-      78,    82,    86,    89,    92,    94,    96,    99,   103,   107,
-     111,   113,   115,   118,   122,   126,   130,   134,   138,   141,
-     145,   149,   151,   154,   162,   166,   169,   173,   175,   177,
-     179,   181,   184,   185,   188,   191,   192,   194,   196,   199,
-     203,   205,   207,   209,   211,   215,   219
+      49,    51,    55,    59,    61,    64,    66,    69,    71,    73,
+      75,    77,    80,    84,    88,    92,    96,    99,   102,   104,
+     106,   109,   113,   117,   121,   123,   125,   128,   132,   136,
+     140,   144,   148,   151,   155,   159,   161,   164,   172,   176,
+     179,   183,   185,   187,   189,   191,   194,   195,   198,   201,
+     202,   204,   208,   210,   213,   217,   219,   223,   225,   228,
+     232,   234,   236,   238,   240,   242,   244,   246,   248,   250,
+     254,   258
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int8 yyrhs[] =
 {
-      45,     0,    -1,    -1,    45,    46,    -1,    47,    10,    -1,
-       1,    10,    -1,    -1,    48,    -1,     6,    -1,    52,    -1,
-      50,    -1,    52,    50,    -1,     9,    40,    53,    -1,     9,
-      40,    55,    -1,     9,    40,    57,    -1,     4,    -1,    49,
-      -1,     4,     5,    -1,    49,     5,    -1,    57,    -1,    53,
-      -1,    41,    50,    42,    -1,    50,    23,    58,    -1,     6,
-      -1,     7,    -1,     8,    -1,     9,    -1,    33,    53,    -1,
-      53,    32,    53,    -1,    53,    31,    53,    -1,    41,    53,
-      42,    -1,    55,    28,    55,    -1,    11,    52,    -1,    11,
-       6,    -1,    24,    -1,    18,    -1,    54,    19,    -1,    54,
-      17,    62,    -1,    54,    16,    62,    -1,    54,    21,    58,
-      -1,     6,    -1,     7,    -1,    54,    16,    -1,    54,    20,
-      58,    -1,    55,    34,    55,    -1,    55,    35,    55,    -1,
-      55,    36,    55,    -1,    55,    37,    55,    -1,    35,    55,
-      -1,    55,    39,    55,    -1,    41,    55,    42,    -1,    52,
-      -1,    54,    17,    -1,    41,    51,    43,    51,    43,    51,
-      42,    -1,    41,    57,    42,    -1,    22,    58,    -1,    18,
-      27,    53,    -1,    14,    -1,    13,    -1,    15,    -1,    59,
-      -1,    59,    26,    -1,    -1,    59,    60,    -1,    25,    61,
-      -1,    -1,    62,    -1,    63,    -1,    62,    63,    -1,    62,
-      43,    63,    -1,    53,    -1,    57,    -1,    55,    -1,    56,
-      -1,     6,    12,     6,    -1,     6,    12,     7,    -1,     7,
-      12,    51,    -1
+      50,     0,    -1,    -1,    50,    51,    -1,    52,    10,    -1,
+       1,    10,    -1,    -1,    53,    -1,     6,    -1,    59,    -1,
+      55,    -1,    59,    55,    -1,     9,    41,    60,    -1,     9,
+      41,    62,    -1,     9,    41,    64,    -1,     4,    -1,    54,
+      -1,     4,     5,    -1,    54,     5,    -1,    64,    -1,    60,
+      -1,    42,    55,    43,    -1,    55,    23,    65,    -1,     6,
+      -1,    35,     6,    -1,     7,    -1,    35,     7,    -1,    56,
+      -1,    57,    -1,     8,    -1,     9,    -1,    33,    60,    -1,
+      60,    32,    60,    -1,    60,    31,    60,    -1,    42,    60,
+      43,    -1,    62,    28,    62,    -1,    11,    59,    -1,    11,
+       6,    -1,    24,    -1,    18,    -1,    61,    19,    -1,    61,
+      17,    70,    -1,    61,    16,    70,    -1,    61,    21,    65,
+      -1,     6,    -1,     7,    -1,    61,    16,    -1,    61,    20,
+      65,    -1,    62,    34,    62,    -1,    62,    35,    62,    -1,
+      62,    36,    62,    -1,    62,    37,    62,    -1,    35,    62,
+      -1,    62,    39,    62,    -1,    42,    62,    43,    -1,    59,
+      -1,    61,    17,    -1,    44,    58,    45,    58,    45,    58,
+      46,    -1,    42,    64,    43,    -1,    22,    65,    -1,    18,
+      27,    60,    -1,    14,    -1,    13,    -1,    15,    -1,    66,
+      -1,    66,    26,    -1,    -1,    66,    67,    -1,    25,    68,
+      -1,    -1,    69,    -1,    47,    69,    48,    -1,    72,    -1,
+      69,    72,    -1,    69,    45,    72,    -1,    71,    -1,    47,
+      71,    48,    -1,    73,    -1,    71,    73,    -1,    71,    45,
+      73,    -1,    60,    -1,    64,    -1,    62,    -1,    63,    -1,
+      74,    -1,    56,    -1,    57,    -1,    59,    -1,    74,    -1,
+      56,    12,    56,    -1,    56,    12,    57,    -1,    57,    12,
+      58,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   178,   178,   179,   188,   189,   209,   213,   214,   223,
-     233,   235,   237,   239,   241,   247,   248,   251,   252,   256,
-     257,   262,   263,   274,   275,   278,   279,   287,   293,   299,
-     311,   315,   323,   329,   337,   338,   342,   347,   352,   360,
-     372,   379,   389,   394,   402,   404,   406,   408,   410,   412,
-     414,   421,   428,   440,   445,   449,   457,   468,   472,   476,
-     485,   487,   492,   493,   498,   505,   506,   510,   511,   513,
-     517,   519,   521,   523,   525,   530,   535
+       0,   182,   182,   183,   192,   193,   213,   217,   218,   227,
+     237,   239,   241,   243,   245,   251,   252,   255,   256,   260,
+     261,   266,   267,   279,   280,   284,   285,   288,   289,   292,
+     293,   301,   307,   313,   325,   329,   337,   343,   351,   352,
+     356,   361,   366,   374,   386,   393,   403,   408,   416,   418,
+     420,   422,   424,   426,   428,   435,   442,   454,   459,   463,
+     471,   482,   486,   490,   499,   501,   506,   507,   512,   519,
+     520,   521,   525,   526,   528,   533,   534,   538,   539,   541,
+     545,   547,   549,   551,   553,   557,   562,   567,   572,   576,
+     581,   586
 };
 #endif
 
@@ -556,12 +567,14 @@ static const char *const yytname[] =
   "KEYWORD_STR", "KEYWORD_POS", "KEYWORD_GROUP", "METHOD_NUMERIC",
   "METHOD_GROUP", "METHOD_POS", "MODIFIER", "EMPTY_POSMOD", "PARAM",
   "END_OF_METHOD", "OF", "CMP_OP", "PARAM_REDUCT", "XOR", "OR", "AND",
-  "NOT", "'+'", "'-'", "'*'", "'/'", "UNARY_NEG", "'^'", "'='", "'('",
-  "')'", "','", "$accept", "commands", "command", "cmd_plain",
-  "help_request", "help_topic", "selection", "number", "string",
+  "NOT", "'+'", "'-'", "'*'", "'/'", "UNARY_NEG", "'^'", "NUM_REDUCT",
+  "'='", "'('", "')'", "'['", "','", "']'", "'{'", "'}'", "$accept",
+  "commands", "command", "cmd_plain", "help_request", "help_topic",
+  "selection", "integer_number", "real_number", "number", "string",
   "sel_expr", "pos_mod", "num_expr", "str_expr", "pos_expr",
   "method_params", "method_param_list", "method_param", "value_list",
-  "value_list_nonempty", "value_item", 0
+  "value_list_contents", "basic_value_list", "basic_value_list_contents",
+  "value_item", "basic_value_item", "value_item_range", 0
 };
 #endif
 
@@ -574,21 +587,23 @@ static const yytype_uint16 yytoknum[] =
      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
      275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
      285,   286,   287,   288,    43,    45,    42,    47,   289,    94,
-      61,    40,    41,    44
+     290,    61,    40,    41,    91,    44,    93,   123,   125
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    44,    45,    45,    46,    46,    47,    47,    47,    47,
-      47,    47,    47,    47,    47,    48,    48,    49,    49,    50,
-      50,    50,    50,    51,    51,    52,    52,    53,    53,    53,
-      53,    53,    53,    53,    54,    54,    53,    53,    53,    53,
-      55,    55,    55,    55,    55,    55,    55,    55,    55,    55,
-      55,    56,    56,    57,    57,    57,    57,    53,    55,    57,
-      58,    58,    59,    59,    60,    61,    61,    62,    62,    62,
-      63,    63,    63,    63,    63,    63,    63
+       0,    49,    50,    50,    51,    51,    52,    52,    52,    52,
+      52,    52,    52,    52,    52,    53,    53,    54,    54,    55,
+      55,    55,    55,    56,    56,    57,    57,    58,    58,    59,
+      59,    60,    60,    60,    60,    60,    60,    60,    61,    61,
+      60,    60,    60,    60,    62,    62,    62,    62,    62,    62,
+      62,    62,    62,    62,    62,    63,    63,    64,    64,    64,
+      64,    60,    62,    64,    65,    65,    66,    66,    67,    68,
+      68,    68,    69,    69,    69,    70,    70,    71,    71,    71,
+      72,    72,    72,    72,    72,    73,    73,    73,    73,    74,
+      74,    74
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
@@ -596,12 +611,14 @@ static const yytype_uint8 yyr2[] =
 {
        0,     2,     0,     2,     2,     2,     0,     1,     1,     1,
        1,     2,     3,     3,     3,     1,     1,     2,     2,     1,
-       1,     3,     3,     1,     1,     1,     1,     2,     3,     3,
-       3,     3,     2,     2,     1,     1,     2,     3,     3,     3,
-       1,     1,     2,     3,     3,     3,     3,     3,     2,     3,
-       3,     1,     2,     7,     3,     2,     3,     1,     1,     1,
-       1,     2,     0,     2,     2,     0,     1,     1,     2,     3,
-       1,     1,     1,     1,     3,     3,     3
+       1,     3,     3,     1,     2,     1,     2,     1,     1,     1,
+       1,     2,     3,     3,     3,     3,     2,     2,     1,     1,
+       2,     3,     3,     3,     1,     1,     2,     3,     3,     3,
+       3,     3,     2,     3,     3,     1,     2,     7,     3,     2,
+       3,     1,     1,     1,     1,     2,     0,     2,     2,     0,
+       1,     3,     1,     2,     3,     1,     3,     1,     2,     3,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     3,
+       3,     3
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -609,151 +626,177 @@ static const yytype_uint8 yyr2[] =
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       2,     0,     1,     0,    15,    40,    41,    25,    26,     0,
-      58,    57,    59,    35,    62,    34,     0,     0,     0,     3,
-       0,     7,    16,    10,     9,    20,     0,     0,    19,     5,
-      17,     0,    33,    26,    32,     0,    55,    60,    40,    35,
-       0,    27,     0,     0,    48,    40,    41,     0,     0,    20,
-       0,    19,     4,    18,    62,    11,     0,     0,    42,     0,
-      36,    62,    62,     0,     0,     0,     0,     0,     0,     0,
-      12,    13,    14,    56,    65,    61,    63,     0,     0,    42,
-      21,     0,    30,    50,    54,    22,    29,    28,    40,    41,
-      51,    70,     0,    72,    73,    71,    38,    67,    37,    43,
-      39,    31,    44,    45,    46,    47,    49,     0,    64,    66,
-      23,    24,     0,     0,     0,    52,     0,    68,     0,    74,
-      75,    76,    69,     0,    53
+       2,     0,     1,     0,    15,    44,    45,    29,    30,     0,
+      62,    61,    63,    39,    66,    38,     0,     0,     0,     0,
+       3,     0,     7,    16,    10,     9,    20,     0,     0,    19,
+       5,    17,     0,    37,    30,    36,     0,    59,    64,    44,
+      39,     0,    31,     0,     0,    52,     0,    20,     0,    19,
+      23,    25,     0,    27,    28,     0,     4,    18,    66,    11,
+       0,     0,    46,     0,    40,    66,    66,     0,     0,     0,
+       0,     0,     0,     0,    12,    13,    14,    60,    69,    65,
+      67,     0,     0,    46,    21,    34,    54,    58,    24,    26,
+       0,    22,    33,    32,     0,    85,    86,    87,    42,    75,
+      77,    88,    41,    47,    43,    35,    48,    49,    50,    51,
+      53,     0,    44,    45,     0,     0,     0,     0,    55,    80,
+       0,    82,    83,    81,    68,    70,    72,    84,     0,     0,
+       0,     0,     0,    78,    44,    45,     0,    56,     0,    73,
+       0,    76,    89,    90,    91,    79,    71,    74,     0,    57
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int8 yydefgoto[] =
 {
-      -1,     1,    19,    20,    21,    22,    23,    48,    90,    91,
-      26,    93,    94,    95,    36,    37,    76,   108,    98,    97
+      -1,     1,    20,    21,    22,    23,    24,    95,    96,    55,
+      97,   119,    27,    28,   122,   123,    37,    38,    80,   124,
+     125,   102,    99,   126,   100,   101
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -87
+#define YYPACT_NINF -93
 static const yytype_int16 yypact[] =
 {
-     -87,   124,   -87,    -1,     6,     8,   -87,   -87,    12,    56,
-     -87,   -87,   -87,    17,   -87,   -87,   278,   288,   200,   -87,
-      53,   -87,    75,    66,   225,     0,   133,    84,   -87,   -87,
-     -87,   239,   -87,   -87,   -87,   278,   -87,    57,   -87,   -87,
-     278,   -87,   288,   -14,    55,    54,    58,   -16,    63,   -18,
-      68,    69,   -87,   -87,   -87,    66,   278,   278,   186,   186,
-     -87,   -87,   -87,   288,   288,   288,   288,   288,   288,   264,
-       0,    84,   -87,     0,   186,   -87,   -87,   -18,    51,   -87,
-     -87,   102,   -87,   -87,   -87,   -87,    83,   -87,   110,   114,
-     -87,     0,   164,    19,   -87,   -87,   155,   -87,   155,   -87,
-     -87,    19,    38,    38,    55,    55,    55,    69,   -87,   155,
-     -87,   -87,    93,   107,   102,   186,   186,   -87,   102,   -87,
-     -87,   -87,   -87,    85,   -87
+     -93,   155,   -93,    10,    19,    26,   -93,   -93,    -3,    73,
+     -93,   -93,   -93,    22,   -93,   -93,   356,   372,   317,    11,
+     -93,    79,   -93,    86,    70,   317,    29,   384,   180,   -93,
+     -93,   -93,   342,   -93,   -93,   -93,   356,   -93,     6,   -93,
+     -93,   356,   -93,   372,   -10,    57,   -20,   -17,   256,    54,
+     -93,   -93,    88,   -93,   -93,    55,   -93,   -93,   -93,    70,
+     356,   356,   197,   174,   -93,   -93,   -93,   372,   372,   372,
+     372,   372,   372,   342,    29,   180,   -93,    29,   221,   -93,
+     -93,   -17,   223,   -93,   -93,   -93,   -93,   -93,   -93,   -93,
+      11,   -93,    69,   -93,    78,    90,    94,   -93,   -93,   244,
+     -93,   -93,   -93,   -93,   -93,   267,    36,    36,    57,    57,
+      57,    54,    95,    96,   375,   303,    90,    94,   -93,    29,
+     392,   267,   -93,   -93,   -93,   263,   -93,   -93,    71,    35,
+      11,    11,    78,   -93,   105,   106,   178,   174,   303,   -93,
+      11,   -93,   -93,   -93,   -93,   -93,   -93,   -93,    80,   -93
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int8 yypgoto[] =
 {
-     -87,   -87,   -87,   -87,   -87,   -87,    15,   -78,    28,    60,
-     -17,     3,   -87,     4,   -46,   -87,   -87,   -87,   -57,   -86
+     -93,   -93,   -93,   -93,   -93,   -93,   -13,     0,    14,   -81,
+      -1,    87,    -4,   -16,   -93,     3,   -36,   -93,   -93,   -93,
+      12,    81,    39,   -91,   -92,   -67
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -25
-static const yytype_int8 yytable[] =
+#define YYTABLE_NINF -27
+static const yytype_int16 yytable[] =
 {
-      43,    96,    79,   112,    27,    28,    61,    54,    85,    29,
-     117,    30,   117,    56,    57,    99,   100,   109,    -8,    27,
-      44,    50,    51,   117,    82,    43,    80,    27,    28,    24,
-     122,    56,    57,    47,    71,    72,   121,    34,    27,    55,
-     123,    92,    92,    50,    35,    78,    43,    43,    43,    43,
-      43,    43,    31,    64,    65,    66,    67,    92,    68,    27,
-      27,    25,    32,    52,     7,    33,   101,   102,   103,   104,
-     105,   106,    50,   107,    66,    67,    41,    68,    49,    92,
-      53,    92,    74,    75,    25,    64,    65,    66,    67,    54,
-      68,    70,    92,    83,    68,    73,    63,   -23,    92,    92,
-      77,   -24,    64,    65,    66,    67,    81,    68,   110,   111,
-      83,    84,    63,   119,   120,    57,    86,    87,    64,    65,
-      66,    67,   113,    68,     2,     3,   114,   124,     4,    77,
-       5,     6,     7,     8,    -6,     9,   118,    10,    11,    12,
-       0,     0,    13,     0,     0,     0,    14,     0,    15,    58,
-      59,     0,    60,    61,    62,     0,     0,    16,     0,    17,
-       0,    88,    89,     7,    33,    18,     9,     0,    10,    11,
+      25,    45,    48,    58,    29,    46,    83,   133,    35,   128,
+      65,   127,    59,    44,    60,    61,    75,    50,    51,    53,
+      30,    49,    91,    84,    31,    48,    85,    82,    29,   103,
+     104,    78,    79,    54,   139,    76,    -8,   133,    32,    44,
+     145,    50,    51,     7,    34,   139,    52,   147,   127,    36,
+     144,   105,   106,   107,   108,   109,   110,    48,   127,   148,
+      60,    61,   121,    44,    44,    44,    44,    44,    44,   127,
+      52,   127,    70,    71,   120,    72,   111,   118,   116,    33,
+     132,     7,    34,   141,    50,    51,     7,    34,    26,    56,
+      53,    57,   117,    58,    88,    89,    72,    87,    45,   121,
+      90,    61,   130,    42,    54,    47,   131,   -23,   -25,   121,
+      44,   120,    26,    52,   118,   116,   140,   -24,   -26,    74,
+     121,   120,   121,    77,   118,   116,   149,   136,    81,   117,
+     142,    53,   120,   129,   120,   118,   116,   118,   116,   117,
+      53,     0,     0,    98,   143,    54,     0,    92,    93,     0,
+     117,     0,   117,     0,    54,     2,     3,     0,     0,     4,
+      81,     5,     6,     7,     8,    -6,     9,     0,    10,    11,
       12,     0,     0,    13,     0,     0,     0,    14,     0,    15,
-      58,   115,     0,    60,    61,    62,     0,     0,    16,     0,
-      17,     0,    88,    89,     7,    33,    69,     9,   116,    10,
-      11,    12,     0,     0,    13,     0,    45,    46,    14,     0,
-      15,     9,     0,    10,    11,    12,     0,     0,    13,    16,
-       0,    17,    14,     0,    15,     0,     0,    69,     0,     0,
-       0,    38,     6,    16,     0,    17,     9,     0,    10,    11,
-      12,    18,     0,    13,     0,    38,     6,    14,     0,    15,
-       9,     0,    10,    11,    12,     0,     0,    13,    16,     0,
-      17,    14,     0,    15,     0,     0,    18,     0,     0,     0,
-      45,    46,    16,     0,    17,     9,     0,    10,    11,    12,
-      69,     0,    13,     0,    38,     6,    14,     0,    15,     9,
-       0,    10,    11,     0,    38,     6,    39,    16,     0,    17,
-       0,    10,    15,     0,     0,    69,    39,     0,     0,     0,
-       0,    16,    15,    17,     0,     0,     0,     0,     0,    40,
-       0,     0,     0,    17,     0,     0,     0,     0,     0,    42
+      50,    51,     7,    34,   112,   113,     7,    34,    16,     9,
+      17,    10,    11,    12,     0,     0,    13,    18,     0,    19,
+      14,     0,    15,    50,    51,     7,    34,     0,    67,    52,
+       0,    16,     0,   114,    68,    69,    70,    71,     0,    72,
+      73,    94,    19,   138,     0,     0,   146,   112,   113,     7,
+      34,     0,     9,     0,    10,    11,    12,     0,     0,    13,
+       0,     0,     0,    14,    94,    15,     0,     0,     0,     0,
+      50,    51,     7,    34,    16,     0,   114,    68,    69,    70,
+      71,     0,    72,    73,     0,    19,    86,     0,   115,   112,
+     113,     7,    34,     0,     9,     0,    10,    11,    12,    52,
+       0,    13,     0,     0,    67,    14,     0,    15,     0,   132,
+      68,    69,    70,    71,     0,    72,    16,     0,   114,    86,
+       0,    68,    69,    70,    71,    73,    72,    19,   138,   112,
+     113,     7,    34,     0,     9,     0,    10,    11,    12,     0,
+       0,    13,     0,    39,     6,    14,     0,    15,     9,     0,
+      10,    11,    12,     0,     0,    13,    16,     0,   114,    14,
+       0,    15,     0,     0,     0,    73,     0,    19,    39,     6,
+      16,     0,    17,     9,     0,    10,    11,    12,     0,    18,
+      13,    19,    39,     6,    14,     0,    15,     9,     0,    10,
+      11,     0,     0,     0,    40,    16,     0,    17,    39,     6,
+      15,   134,   135,     0,    73,    10,    19,     0,    10,    16,
+      40,    17,     0,    40,     0,     0,    15,     0,    41,    15,
+      62,    63,     0,    64,    65,    66,     0,    17,    62,   137,
+      17,    64,    65,    66,    43,     0,     0,    43
 };
 
-static const yytype_int8 yycheck[] =
+static const yytype_int16 yycheck[] =
 {
-      17,    58,    16,    81,     1,     1,    20,    23,    54,    10,
-      96,     5,    98,    31,    32,    61,    62,    74,    10,    16,
-      17,    18,    18,   109,    42,    42,    42,    24,    24,     1,
-     116,    31,    32,    18,    31,    31,   114,     9,    35,    24,
-     118,    58,    59,    40,    27,    42,    63,    64,    65,    66,
-      67,    68,    40,    34,    35,    36,    37,    74,    39,    56,
-      57,     1,     6,    10,     8,     9,    63,    64,    65,    66,
-      67,    68,    69,    69,    36,    37,    16,    39,    18,    96,
-       5,    98,    25,    26,    24,    34,    35,    36,    37,    23,
-      39,    31,   109,    42,    39,    35,    28,    43,   115,   116,
-      40,    43,    34,    35,    36,    37,    43,    39,     6,     7,
-      42,    42,    28,     6,     7,    32,    56,    57,    34,    35,
-      36,    37,    12,    39,     0,     1,    12,    42,     4,    69,
-       6,     7,     8,     9,    10,    11,    43,    13,    14,    15,
-      -1,    -1,    18,    -1,    -1,    -1,    22,    -1,    24,    16,
-      17,    -1,    19,    20,    21,    -1,    -1,    33,    -1,    35,
-      -1,     6,     7,     8,     9,    41,    11,    -1,    13,    14,
+       1,    17,    18,    23,     1,    18,    16,    99,     9,    90,
+      20,    78,    25,    17,    31,    32,    32,     6,     7,    19,
+      10,    18,    58,    43,     5,    41,    43,    43,    25,    65,
+      66,    25,    26,    19,   125,    32,    10,   129,    41,    43,
+     132,     6,     7,     8,     9,   136,    35,   138,   115,    27,
+     131,    67,    68,    69,    70,    71,    72,    73,   125,   140,
+      31,    32,    78,    67,    68,    69,    70,    71,    72,   136,
+      35,   138,    36,    37,    78,    39,    73,    78,    78,     6,
+      45,     8,     9,    48,     6,     7,     8,     9,     1,    10,
+      90,     5,    78,    23,     6,     7,    39,    43,   114,   115,
+      45,    32,    12,    16,    90,    18,    12,    12,    12,   125,
+     114,   115,    25,    35,   115,   115,    45,    12,    12,    32,
+     136,   125,   138,    36,   125,   125,    46,   115,    41,   115,
+     130,   131,   136,    94,   138,   136,   136,   138,   138,   125,
+     140,    -1,    -1,    62,   130,   131,    -1,    60,    61,    -1,
+     136,    -1,   138,    -1,   140,     0,     1,    -1,    -1,     4,
+      73,     6,     7,     8,     9,    10,    11,    -1,    13,    14,
       15,    -1,    -1,    18,    -1,    -1,    -1,    22,    -1,    24,
-      16,    17,    -1,    19,    20,    21,    -1,    -1,    33,    -1,
-      35,    -1,     6,     7,     8,     9,    41,    11,    43,    13,
-      14,    15,    -1,    -1,    18,    -1,     6,     7,    22,    -1,
-      24,    11,    -1,    13,    14,    15,    -1,    -1,    18,    33,
-      -1,    35,    22,    -1,    24,    -1,    -1,    41,    -1,    -1,
-      -1,     6,     7,    33,    -1,    35,    11,    -1,    13,    14,
-      15,    41,    -1,    18,    -1,     6,     7,    22,    -1,    24,
-      11,    -1,    13,    14,    15,    -1,    -1,    18,    33,    -1,
-      35,    22,    -1,    24,    -1,    -1,    41,    -1,    -1,    -1,
-       6,     7,    33,    -1,    35,    11,    -1,    13,    14,    15,
-      41,    -1,    18,    -1,     6,     7,    22,    -1,    24,    11,
-      -1,    13,    14,    -1,     6,     7,    18,    33,    -1,    35,
-      -1,    13,    24,    -1,    -1,    41,    18,    -1,    -1,    -1,
-      -1,    33,    24,    35,    -1,    -1,    -1,    -1,    -1,    41,
-      -1,    -1,    -1,    35,    -1,    -1,    -1,    -1,    -1,    41
+       6,     7,     8,     9,     6,     7,     8,     9,    33,    11,
+      35,    13,    14,    15,    -1,    -1,    18,    42,    -1,    44,
+      22,    -1,    24,     6,     7,     8,     9,    -1,    28,    35,
+      -1,    33,    -1,    35,    34,    35,    36,    37,    -1,    39,
+      42,    47,    44,    45,    -1,    -1,    48,     6,     7,     8,
+       9,    -1,    11,    -1,    13,    14,    15,    -1,    -1,    18,
+      -1,    -1,    -1,    22,    47,    24,    -1,    -1,    -1,    -1,
+       6,     7,     8,     9,    33,    -1,    35,    34,    35,    36,
+      37,    -1,    39,    42,    -1,    44,    43,    -1,    47,     6,
+       7,     8,     9,    -1,    11,    -1,    13,    14,    15,    35,
+      -1,    18,    -1,    -1,    28,    22,    -1,    24,    -1,    45,
+      34,    35,    36,    37,    -1,    39,    33,    -1,    35,    43,
+      -1,    34,    35,    36,    37,    42,    39,    44,    45,     6,
+       7,     8,     9,    -1,    11,    -1,    13,    14,    15,    -1,
+      -1,    18,    -1,     6,     7,    22,    -1,    24,    11,    -1,
+      13,    14,    15,    -1,    -1,    18,    33,    -1,    35,    22,
+      -1,    24,    -1,    -1,    -1,    42,    -1,    44,     6,     7,
+      33,    -1,    35,    11,    -1,    13,    14,    15,    -1,    42,
+      18,    44,     6,     7,    22,    -1,    24,    11,    -1,    13,
+      14,    -1,    -1,    -1,    18,    33,    -1,    35,     6,     7,
+      24,     6,     7,    -1,    42,    13,    44,    -1,    13,    33,
+      18,    35,    -1,    18,    -1,    -1,    24,    -1,    42,    24,
+      16,    17,    -1,    19,    20,    21,    -1,    35,    16,    17,
+      35,    19,    20,    21,    42,    -1,    -1,    42
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,    45,     0,     1,     4,     6,     7,     8,     9,    11,
-      13,    14,    15,    18,    22,    24,    33,    35,    41,    46,
-      47,    48,    49,    50,    52,    53,    54,    55,    57,    10,
-       5,    40,     6,     9,    52,    27,    58,    59,     6,    18,
-      41,    53,    41,    54,    55,     6,     7,    50,    51,    53,
-      55,    57,    10,     5,    23,    50,    31,    32,    16,    17,
-      19,    20,    21,    28,    34,    35,    36,    37,    39,    41,
-      53,    55,    57,    53,    25,    26,    60,    53,    55,    16,
-      42,    43,    42,    42,    42,    58,    53,    53,     6,     7,
-      52,    53,    54,    55,    56,    57,    62,    63,    62,    58,
-      58,    55,    55,    55,    55,    55,    55,    57,    61,    62,
-       6,     7,    51,    12,    12,    17,    43,    63,    43,     6,
-       7,    51,    63,    51,    42
+       0,    50,     0,     1,     4,     6,     7,     8,     9,    11,
+      13,    14,    15,    18,    22,    24,    33,    35,    42,    44,
+      51,    52,    53,    54,    55,    59,    60,    61,    62,    64,
+      10,     5,    41,     6,     9,    59,    27,    65,    66,     6,
+      18,    42,    60,    42,    61,    62,    55,    60,    62,    64,
+       6,     7,    35,    56,    57,    58,    10,     5,    23,    55,
+      31,    32,    16,    17,    19,    20,    21,    28,    34,    35,
+      36,    37,    39,    42,    60,    62,    64,    60,    25,    26,
+      67,    60,    62,    16,    43,    43,    43,    43,     6,     7,
+      45,    65,    60,    60,    47,    56,    57,    59,    70,    71,
+      73,    74,    70,    65,    65,    62,    62,    62,    62,    62,
+      62,    64,     6,     7,    35,    47,    56,    57,    59,    60,
+      61,    62,    63,    64,    68,    69,    72,    74,    58,    71,
+      12,    12,    45,    73,     6,     7,    69,    17,    45,    72,
+      45,    48,    56,    57,    58,    73,    48,    72,    58,    46
 };
 
 #define yyerrok                (yyerrstatus = 0)
@@ -1268,99 +1311,119 @@ yydestruct (yymsg, yytype, yyvaluep, scanner)
   switch (yytype)
     {
       case 5: /* "HELP_TOPIC" */
-#line 158 "parser.y"
+#line 161 "parser.y"
        { free((yyvaluep->str));                     };
-#line 1274 "parser.c"
+#line 1317 "parser.c"
        break;
       case 8: /* "STR" */
-#line 158 "parser.y"
+#line 161 "parser.y"
        { free((yyvaluep->str));                     };
-#line 1279 "parser.c"
+#line 1322 "parser.c"
        break;
       case 9: /* "IDENTIFIER" */
-#line 158 "parser.y"
+#line 161 "parser.y"
        { free((yyvaluep->str));                     };
-#line 1284 "parser.c"
+#line 1327 "parser.c"
        break;
       case 25: /* "PARAM" */
-#line 159 "parser.y"
+#line 162 "parser.y"
        { if((yyvaluep->str)) free((yyvaluep->str));              };
-#line 1289 "parser.c"
+#line 1332 "parser.c"
        break;
       case 28: /* "CMP_OP" */
-#line 158 "parser.y"
+#line 161 "parser.y"
        { free((yyvaluep->str));                     };
-#line 1294 "parser.c"
+#line 1337 "parser.c"
        break;
-      case 46: /* "command" */
-#line 160 "parser.y"
+      case 51: /* "command" */
+#line 163 "parser.y"
        { if((yyvaluep->sel)) _gmx_selelem_free((yyvaluep->sel)); };
-#line 1299 "parser.c"
+#line 1342 "parser.c"
        break;
-      case 47: /* "cmd_plain" */
-#line 160 "parser.y"
+      case 52: /* "cmd_plain" */
+#line 163 "parser.y"
        { if((yyvaluep->sel)) _gmx_selelem_free((yyvaluep->sel)); };
-#line 1304 "parser.c"
+#line 1347 "parser.c"
        break;
-      case 50: /* "selection" */
-#line 161 "parser.y"
+      case 55: /* "selection" */
+#line 164 "parser.y"
        { _gmx_selelem_free_chain((yyvaluep->sel));  };
-#line 1309 "parser.c"
+#line 1352 "parser.c"
        break;
-      case 52: /* "string" */
-#line 158 "parser.y"
+      case 59: /* "string" */
+#line 161 "parser.y"
        { free((yyvaluep->str));                     };
-#line 1314 "parser.c"
+#line 1357 "parser.c"
        break;
-      case 53: /* "sel_expr" */
-#line 162 "parser.y"
+      case 60: /* "sel_expr" */
+#line 165 "parser.y"
        { _gmx_selelem_free((yyvaluep->sel));        };
-#line 1319 "parser.c"
+#line 1362 "parser.c"
        break;
-      case 55: /* "num_expr" */
-#line 162 "parser.y"
+      case 62: /* "num_expr" */
+#line 165 "parser.y"
        { _gmx_selelem_free((yyvaluep->sel));        };
-#line 1324 "parser.c"
+#line 1367 "parser.c"
        break;
-      case 56: /* "str_expr" */
-#line 162 "parser.y"
+      case 63: /* "str_expr" */
+#line 165 "parser.y"
        { _gmx_selelem_free((yyvaluep->sel));        };
-#line 1329 "parser.c"
+#line 1372 "parser.c"
        break;
-      case 57: /* "pos_expr" */
-#line 162 "parser.y"
+      case 64: /* "pos_expr" */
+#line 165 "parser.y"
        { _gmx_selelem_free((yyvaluep->sel));        };
-#line 1334 "parser.c"
+#line 1377 "parser.c"
        break;
-      case 58: /* "method_params" */
-#line 163 "parser.y"
+      case 65: /* "method_params" */
+#line 166 "parser.y"
        { _gmx_selexpr_free_params((yyvaluep->param)); };
-#line 1339 "parser.c"
+#line 1382 "parser.c"
        break;
-      case 59: /* "method_param_list" */
-#line 163 "parser.y"
+      case 66: /* "method_param_list" */
+#line 166 "parser.y"
        { _gmx_selexpr_free_params((yyvaluep->param)); };
-#line 1344 "parser.c"
+#line 1387 "parser.c"
        break;
-      case 60: /* "method_param" */
-#line 163 "parser.y"
+      case 67: /* "method_param" */
+#line 166 "parser.y"
        { _gmx_selexpr_free_params((yyvaluep->param)); };
-#line 1349 "parser.c"
+#line 1392 "parser.c"
        break;
-      case 61: /* "value_list" */
-#line 164 "parser.y"
+      case 68: /* "value_list" */
+#line 167 "parser.y"
        { _gmx_selexpr_free_values((yyvaluep->val)); };
-#line 1354 "parser.c"
+#line 1397 "parser.c"
        break;
-      case 62: /* "value_list_nonempty" */
-#line 164 "parser.y"
+      case 69: /* "value_list_contents" */
+#line 167 "parser.y"
        { _gmx_selexpr_free_values((yyvaluep->val)); };
-#line 1359 "parser.c"
+#line 1402 "parser.c"
        break;
-      case 63: /* "value_item" */
-#line 164 "parser.y"
+      case 70: /* "basic_value_list" */
+#line 168 "parser.y"
+       { _gmx_selexpr_free_values((yyvaluep->val)); };
+#line 1407 "parser.c"
+       break;
+      case 71: /* "basic_value_list_contents" */
+#line 168 "parser.y"
+       { _gmx_selexpr_free_values((yyvaluep->val)); };
+#line 1412 "parser.c"
+       break;
+      case 72: /* "value_item" */
+#line 167 "parser.y"
+       { _gmx_selexpr_free_values((yyvaluep->val)); };
+#line 1417 "parser.c"
+       break;
+      case 73: /* "basic_value_item" */
+#line 168 "parser.y"
+       { _gmx_selexpr_free_values((yyvaluep->val)); };
+#line 1422 "parser.c"
+       break;
+      case 74: /* "value_item_range" */
+#line 167 "parser.y"
        { _gmx_selexpr_free_values((yyvaluep->val)); };
-#line 1364 "parser.c"
+#line 1427 "parser.c"
        break;
 
       default:
@@ -1669,12 +1732,12 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-#line 178 "parser.y"
+#line 182 "parser.y"
     { (yyval.sel) = NULL ;}
     break;
 
   case 3:
-#line 180 "parser.y"
+#line 184 "parser.y"
     {
                  (yyval.sel) = _gmx_sel_append_selection((yyvsp[(2) - (2)].sel), (yyvsp[(1) - (2)].sel), scanner);
                  if (_gmx_sel_parser_should_finish(scanner))
@@ -1683,12 +1746,12 @@ yyreduce:
     break;
 
   case 4:
-#line 188 "parser.y"
+#line 192 "parser.y"
     { (yyval.sel) = (yyvsp[(1) - (2)].sel); ;}
     break;
 
   case 5:
-#line 190 "parser.y"
+#line 194 "parser.y"
     {
                  (yyval.sel) = NULL;
                  _gmx_selparser_error("invalid selection '%s'",
@@ -1707,7 +1770,7 @@ yyreduce:
     break;
 
   case 6:
-#line 209 "parser.y"
+#line 213 "parser.y"
     {
                  (yyval.sel) = NULL;
                  _gmx_sel_handle_empty_cmd(scanner);
@@ -1715,12 +1778,12 @@ yyreduce:
     break;
 
   case 7:
-#line 213 "parser.y"
+#line 217 "parser.y"
     { (yyval.sel) = NULL; ;}
     break;
 
   case 8:
-#line 215 "parser.y"
+#line 219 "parser.y"
     {
                  t_selelem *s, *p;
                  s = _gmx_sel_init_group_by_id((yyvsp[(1) - (1)].i), scanner);
@@ -1732,7 +1795,7 @@ yyreduce:
     break;
 
   case 9:
-#line 224 "parser.y"
+#line 228 "parser.y"
     {
                  t_selelem *s, *p;
                  s = _gmx_sel_init_group_by_name((yyvsp[(1) - (1)].str), scanner);
@@ -1745,52 +1808,52 @@ yyreduce:
     break;
 
   case 10:
-#line 234 "parser.y"
+#line 238 "parser.y"
     { (yyval.sel) = _gmx_sel_init_selection(NULL, (yyvsp[(1) - (1)].sel), scanner); ;}
     break;
 
   case 11:
-#line 236 "parser.y"
+#line 240 "parser.y"
     { (yyval.sel) = _gmx_sel_init_selection((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].sel), scanner);   ;}
     break;
 
   case 12:
-#line 238 "parser.y"
+#line 242 "parser.y"
     { (yyval.sel) = _gmx_sel_assign_variable((yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].sel), scanner);  ;}
     break;
 
   case 13:
-#line 240 "parser.y"
+#line 244 "parser.y"
     { (yyval.sel) = _gmx_sel_assign_variable((yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].sel), scanner);  ;}
     break;
 
   case 14:
-#line 242 "parser.y"
+#line 246 "parser.y"
     { (yyval.sel) = _gmx_sel_assign_variable((yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].sel), scanner);  ;}
     break;
 
   case 15:
-#line 247 "parser.y"
+#line 251 "parser.y"
     { _gmx_sel_handle_help_cmd(NULL, scanner); ;}
     break;
 
   case 17:
-#line 251 "parser.y"
+#line 255 "parser.y"
     { _gmx_sel_handle_help_cmd((yyvsp[(2) - (2)].str), scanner); ;}
     break;
 
   case 18:
-#line 252 "parser.y"
+#line 256 "parser.y"
     { _gmx_sel_handle_help_cmd((yyvsp[(2) - (2)].str), scanner); ;}
     break;
 
   case 19:
-#line 256 "parser.y"
+#line 260 "parser.y"
     { (yyval.sel) = (yyvsp[(1) - (1)].sel); ;}
     break;
 
   case 20:
-#line 258 "parser.y"
+#line 262 "parser.y"
     {
                  (yyval.sel) = _gmx_sel_init_position((yyvsp[(1) - (1)].sel), NULL, scanner);
                  if ((yyval.sel) == NULL) YYERROR;
@@ -1798,12 +1861,12 @@ yyreduce:
     break;
 
   case 21:
-#line 262 "parser.y"
+#line 266 "parser.y"
     { (yyval.sel) = (yyvsp[(2) - (3)].sel); ;}
     break;
 
   case 22:
-#line 264 "parser.y"
+#line 268 "parser.y"
     {
                  (yyval.sel) = _gmx_sel_init_modifier((yyvsp[(2) - (3)].meth), (yyvsp[(3) - (3)].param), (yyvsp[(1) - (3)].sel), scanner);
                  if ((yyval.sel) == NULL) YYERROR;
@@ -1811,27 +1874,47 @@ yyreduce:
     break;
 
   case 23:
-#line 274 "parser.y"
+#line 279 "parser.y"
     { (yyval.r) = (yyvsp[(1) - (1)].i); ;}
     break;
 
   case 24:
-#line 275 "parser.y"
-    { (yyval.r) = (yyvsp[(1) - (1)].r); ;}
+#line 280 "parser.y"
+    { (yyval.r) = -(yyvsp[(2) - (2)].i); ;}
     break;
 
   case 25:
-#line 278 "parser.y"
-    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
+#line 284 "parser.y"
+    { (yyval.r) = (yyvsp[(1) - (1)].r); ;}
     break;
 
   case 26:
-#line 279 "parser.y"
-    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
+#line 285 "parser.y"
+    { (yyval.r) = -(yyvsp[(2) - (2)].r); ;}
     break;
 
   case 27:
 #line 288 "parser.y"
+    { (yyval.r) = (yyvsp[(1) - (1)].r); ;}
+    break;
+
+  case 28:
+#line 289 "parser.y"
+    { (yyval.r) = (yyvsp[(1) - (1)].r); ;}
+    break;
+
+  case 29:
+#line 292 "parser.y"
+    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
+    break;
+
+  case 30:
+#line 293 "parser.y"
+    { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
+    break;
+
+  case 31:
+#line 302 "parser.y"
     {
                  (yyval.sel) = _gmx_selelem_create(SEL_BOOLEAN);
                  (yyval.sel)->u.boolt = BOOL_NOT;
@@ -1839,8 +1922,8 @@ yyreduce:
              ;}
     break;
 
-  case 28:
-#line 294 "parser.y"
+  case 32:
+#line 308 "parser.y"
     {
                  (yyval.sel) = _gmx_selelem_create(SEL_BOOLEAN);
                  (yyval.sel)->u.boolt = BOOL_AND;
@@ -1848,8 +1931,8 @@ yyreduce:
              ;}
     break;
 
-  case 29:
-#line 300 "parser.y"
+  case 33:
+#line 314 "parser.y"
     {
                  (yyval.sel) = _gmx_selelem_create(SEL_BOOLEAN);
                  (yyval.sel)->u.boolt = BOOL_OR;
@@ -1857,21 +1940,21 @@ yyreduce:
              ;}
     break;
 
-  case 30:
-#line 311 "parser.y"
+  case 34:
+#line 325 "parser.y"
     { (yyval.sel) = (yyvsp[(2) - (3)].sel); ;}
     break;
 
-  case 31:
-#line 316 "parser.y"
+  case 35:
+#line 330 "parser.y"
     {
                  (yyval.sel) = _gmx_sel_init_comparison((yyvsp[(1) - (3)].sel), (yyvsp[(3) - (3)].sel), (yyvsp[(2) - (3)].str), scanner);
                  if ((yyval.sel) == NULL) YYERROR;
              ;}
     break;
 
-  case 32:
-#line 324 "parser.y"
+  case 36:
+#line 338 "parser.y"
     {
                  (yyval.sel) = _gmx_sel_init_group_by_name((yyvsp[(2) - (2)].str), scanner);
                  free((yyvsp[(2) - (2)].str));
@@ -1879,58 +1962,58 @@ yyreduce:
              ;}
     break;
 
-  case 33:
-#line 330 "parser.y"
+  case 37:
+#line 344 "parser.y"
     {
                  (yyval.sel) = _gmx_sel_init_group_by_id((yyvsp[(2) - (2)].i), scanner);
                  if ((yyval.sel) == NULL) YYERROR;
              ;}
     break;
 
-  case 34:
-#line 337 "parser.y"
+  case 38:
+#line 351 "parser.y"
     { (yyval.str) = NULL; ;}
     break;
 
-  case 35:
-#line 338 "parser.y"
+  case 39:
+#line 352 "parser.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str);   ;}
     break;
 
-  case 36:
-#line 343 "parser.y"
+  case 40:
+#line 357 "parser.y"
     {
                  (yyval.sel) = _gmx_sel_init_keyword((yyvsp[(2) - (2)].meth), NULL, (yyvsp[(1) - (2)].str), scanner);
                  if ((yyval.sel) == NULL) YYERROR;
              ;}
     break;
 
-  case 37:
-#line 348 "parser.y"
+  case 41:
+#line 362 "parser.y"
     {
                  (yyval.sel) = _gmx_sel_init_keyword((yyvsp[(2) - (3)].meth), process_value_list((yyvsp[(3) - (3)].val), NULL), (yyvsp[(1) - (3)].str), scanner);
                  if ((yyval.sel) == NULL) YYERROR;
              ;}
     break;
 
-  case 38:
-#line 353 "parser.y"
+  case 42:
+#line 367 "parser.y"
     {
                  (yyval.sel) = _gmx_sel_init_keyword((yyvsp[(2) - (3)].meth), process_value_list((yyvsp[(3) - (3)].val), NULL), (yyvsp[(1) - (3)].str), scanner);
                  if ((yyval.sel) == NULL) YYERROR;
              ;}
     break;
 
-  case 39:
-#line 361 "parser.y"
+  case 43:
+#line 375 "parser.y"
     {
                  (yyval.sel) = _gmx_sel_init_method((yyvsp[(2) - (3)].meth), (yyvsp[(3) - (3)].param), (yyvsp[(1) - (3)].str), scanner);
                  if ((yyval.sel) == NULL) YYERROR;
              ;}
     break;
 
-  case 40:
-#line 373 "parser.y"
+  case 44:
+#line 387 "parser.y"
     {
                  (yyval.sel) = _gmx_selelem_create(SEL_CONST);
                  _gmx_selelem_set_vtype((yyval.sel), INT_VALUE);
@@ -1939,8 +2022,8 @@ yyreduce:
              ;}
     break;
 
-  case 41:
-#line 380 "parser.y"
+  case 45:
+#line 394 "parser.y"
     {
                  (yyval.sel) = _gmx_selelem_create(SEL_CONST);
                  _gmx_selelem_set_vtype((yyval.sel), REAL_VALUE);
@@ -1949,59 +2032,59 @@ yyreduce:
              ;}
     break;
 
-  case 42:
-#line 390 "parser.y"
+  case 46:
+#line 404 "parser.y"
     {
                  (yyval.sel) = _gmx_sel_init_keyword((yyvsp[(2) - (2)].meth), NULL, (yyvsp[(1) - (2)].str), scanner);
                  if ((yyval.sel) == NULL) YYERROR;
              ;}
     break;
 
-  case 43:
-#line 395 "parser.y"
+  case 47:
+#line 409 "parser.y"
     {
                  (yyval.sel) = _gmx_sel_init_method((yyvsp[(2) - (3)].meth), (yyvsp[(3) - (3)].param), (yyvsp[(1) - (3)].str), scanner);
                  if ((yyval.sel) == NULL) YYERROR;
              ;}
     break;
 
-  case 44:
-#line 403 "parser.y"
+  case 48:
+#line 417 "parser.y"
     { (yyval.sel) = _gmx_sel_init_arithmetic((yyvsp[(1) - (3)].sel), (yyvsp[(3) - (3)].sel), '+', scanner); ;}
     break;
 
-  case 45:
-#line 405 "parser.y"
+  case 49:
+#line 419 "parser.y"
     { (yyval.sel) = _gmx_sel_init_arithmetic((yyvsp[(1) - (3)].sel), (yyvsp[(3) - (3)].sel), '-', scanner); ;}
     break;
 
-  case 46:
-#line 407 "parser.y"
+  case 50:
+#line 421 "parser.y"
     { (yyval.sel) = _gmx_sel_init_arithmetic((yyvsp[(1) - (3)].sel), (yyvsp[(3) - (3)].sel), '*', scanner); ;}
     break;
 
-  case 47:
-#line 409 "parser.y"
+  case 51:
+#line 423 "parser.y"
     { (yyval.sel) = _gmx_sel_init_arithmetic((yyvsp[(1) - (3)].sel), (yyvsp[(3) - (3)].sel), '/', scanner); ;}
     break;
 
-  case 48:
-#line 411 "parser.y"
+  case 52:
+#line 425 "parser.y"
     { (yyval.sel) = _gmx_sel_init_arithmetic((yyvsp[(2) - (2)].sel), NULL, '-', scanner); ;}
     break;
 
-  case 49:
-#line 413 "parser.y"
+  case 53:
+#line 427 "parser.y"
     { (yyval.sel) = _gmx_sel_init_arithmetic((yyvsp[(1) - (3)].sel), (yyvsp[(3) - (3)].sel), '^', scanner); ;}
     break;
 
-  case 50:
-#line 414 "parser.y"
+  case 54:
+#line 428 "parser.y"
     { (yyval.sel) = (yyvsp[(2) - (3)].sel); ;}
     break;
 
-  case 51:
-#line 422 "parser.y"
+  case 55:
+#line 436 "parser.y"
     {
                  (yyval.sel) = _gmx_selelem_create(SEL_CONST);
                  _gmx_selelem_set_vtype((yyval.sel), STR_VALUE);
@@ -2010,146 +2093,210 @@ yyreduce:
              ;}
     break;
 
-  case 52:
-#line 429 "parser.y"
+  case 56:
+#line 443 "parser.y"
     {
                  (yyval.sel) = _gmx_sel_init_keyword((yyvsp[(2) - (2)].meth), NULL, (yyvsp[(1) - (2)].str), scanner);
                  if ((yyval.sel) == NULL) YYERROR;
              ;}
     break;
 
-  case 53:
-#line 441 "parser.y"
+  case 57:
+#line 455 "parser.y"
     { (yyval.sel) = _gmx_sel_init_const_position((yyvsp[(2) - (7)].r), (yyvsp[(4) - (7)].r), (yyvsp[(6) - (7)].r)); ;}
     break;
 
-  case 54:
-#line 445 "parser.y"
+  case 58:
+#line 459 "parser.y"
     { (yyval.sel) = (yyvsp[(2) - (3)].sel); ;}
     break;
 
-  case 55:
-#line 450 "parser.y"
+  case 59:
+#line 464 "parser.y"
     {
                  (yyval.sel) = _gmx_sel_init_method((yyvsp[(1) - (2)].meth), (yyvsp[(2) - (2)].param), NULL, scanner);
                  if ((yyval.sel) == NULL) YYERROR;
              ;}
     break;
 
-  case 56:
-#line 458 "parser.y"
+  case 60:
+#line 472 "parser.y"
     {
                  (yyval.sel) = _gmx_sel_init_position((yyvsp[(3) - (3)].sel), (yyvsp[(1) - (3)].str), scanner);
                  if ((yyval.sel) == NULL) YYERROR;
              ;}
     break;
 
-  case 57:
-#line 469 "parser.y"
+  case 61:
+#line 483 "parser.y"
     { (yyval.sel) = _gmx_sel_init_variable_ref((yyvsp[(1) - (1)].sel)); ;}
     break;
 
-  case 58:
-#line 473 "parser.y"
+  case 62:
+#line 487 "parser.y"
     { (yyval.sel) = _gmx_sel_init_variable_ref((yyvsp[(1) - (1)].sel)); ;}
     break;
 
-  case 59:
-#line 477 "parser.y"
+  case 63:
+#line 491 "parser.y"
     { (yyval.sel) = _gmx_sel_init_variable_ref((yyvsp[(1) - (1)].sel)); ;}
     break;
 
-  case 60:
-#line 486 "parser.y"
+  case 64:
+#line 500 "parser.y"
     { (yyval.param) = process_param_list((yyvsp[(1) - (1)].param)); ;}
     break;
 
-  case 61:
-#line 488 "parser.y"
+  case 65:
+#line 502 "parser.y"
     { (yyval.param) = process_param_list((yyvsp[(1) - (2)].param)); ;}
     break;
 
-  case 62:
-#line 492 "parser.y"
+  case 66:
+#line 506 "parser.y"
     { (yyval.param) = NULL;              ;}
     break;
 
-  case 63:
-#line 494 "parser.y"
+  case 67:
+#line 508 "parser.y"
     { (yyvsp[(2) - (2)].param)->next = (yyvsp[(1) - (2)].param); (yyval.param) = (yyvsp[(2) - (2)].param); ;}
     break;
 
-  case 64:
-#line 499 "parser.y"
+  case 68:
+#line 513 "parser.y"
     {
                  (yyval.param) = _gmx_selexpr_create_param((yyvsp[(1) - (2)].str));
                  (yyval.param)->value = process_value_list((yyvsp[(2) - (2)].val), &(yyval.param)->nval);
              ;}
     break;
 
-  case 65:
-#line 505 "parser.y"
+  case 69:
+#line 519 "parser.y"
     { (yyval.val) = NULL; ;}
     break;
 
-  case 66:
-#line 506 "parser.y"
+  case 70:
+#line 520 "parser.y"
     { (yyval.val) = (yyvsp[(1) - (1)].val);   ;}
     break;
 
-  case 67:
-#line 510 "parser.y"
+  case 71:
+#line 521 "parser.y"
+    { (yyval.val) = (yyvsp[(2) - (3)].val);   ;}
+    break;
+
+  case 72:
+#line 525 "parser.y"
     { (yyval.val) = (yyvsp[(1) - (1)].val); ;}
     break;
 
-  case 68:
-#line 512 "parser.y"
+  case 73:
+#line 527 "parser.y"
     { (yyvsp[(2) - (2)].val)->next = (yyvsp[(1) - (2)].val); (yyval.val) = (yyvsp[(2) - (2)].val); ;}
     break;
 
-  case 69:
-#line 514 "parser.y"
+  case 74:
+#line 529 "parser.y"
     { (yyvsp[(3) - (3)].val)->next = (yyvsp[(1) - (3)].val); (yyval.val) = (yyvsp[(3) - (3)].val); ;}
     break;
 
-  case 70:
-#line 518 "parser.y"
+  case 75:
+#line 533 "parser.y"
+    { (yyval.val) = (yyvsp[(1) - (1)].val); ;}
+    break;
+
+  case 76:
+#line 534 "parser.y"
+    { (yyval.val) = (yyvsp[(2) - (3)].val); ;}
+    break;
+
+  case 77:
+#line 538 "parser.y"
+    { (yyval.val) = (yyvsp[(1) - (1)].val); ;}
+    break;
+
+  case 78:
+#line 540 "parser.y"
+    { (yyvsp[(2) - (2)].val)->next = (yyvsp[(1) - (2)].val); (yyval.val) = (yyvsp[(2) - (2)].val); ;}
+    break;
+
+  case 79:
+#line 542 "parser.y"
+    { (yyvsp[(3) - (3)].val)->next = (yyvsp[(1) - (3)].val); (yyval.val) = (yyvsp[(3) - (3)].val); ;}
+    break;
+
+  case 80:
+#line 546 "parser.y"
     { (yyval.val) = _gmx_selexpr_create_value_expr((yyvsp[(1) - (1)].sel)); ;}
     break;
 
-  case 71:
-#line 520 "parser.y"
+  case 81:
+#line 548 "parser.y"
     { (yyval.val) = _gmx_selexpr_create_value_expr((yyvsp[(1) - (1)].sel)); ;}
     break;
 
-  case 72:
-#line 522 "parser.y"
+  case 82:
+#line 550 "parser.y"
     { (yyval.val) = _gmx_selexpr_create_value_expr((yyvsp[(1) - (1)].sel)); ;}
     break;
 
-  case 73:
-#line 524 "parser.y"
+  case 83:
+#line 552 "parser.y"
     { (yyval.val) = _gmx_selexpr_create_value_expr((yyvsp[(1) - (1)].sel)); ;}
     break;
 
-  case 74:
-#line 526 "parser.y"
+  case 84:
+#line 553 "parser.y"
+    { (yyval.val) = (yyvsp[(1) - (1)].val); ;}
+    break;
+
+  case 85:
+#line 558 "parser.y"
     {
                  (yyval.val) = _gmx_selexpr_create_value(INT_VALUE);
-                 (yyval.val)->u.i.i1 = (yyvsp[(1) - (3)].i); (yyval.val)->u.i.i2 = (yyvsp[(3) - (3)].i);
+                 (yyval.val)->u.i.i1 = (yyval.val)->u.i.i2 = (yyvsp[(1) - (1)].r);
              ;}
     break;
 
-  case 75:
-#line 531 "parser.y"
+  case 86:
+#line 563 "parser.y"
     {
                  (yyval.val) = _gmx_selexpr_create_value(REAL_VALUE);
-                 (yyval.val)->u.r.r1 = (yyvsp[(1) - (3)].i); (yyval.val)->u.r.r2 = (yyvsp[(3) - (3)].r);
+                 (yyval.val)->u.r.r1 = (yyval.val)->u.r.r2 = (yyvsp[(1) - (1)].r);
              ;}
     break;
 
-  case 76:
-#line 536 "parser.y"
+  case 87:
+#line 568 "parser.y"
+    {
+                 (yyval.val) = _gmx_selexpr_create_value(STR_VALUE);
+                 (yyval.val)->u.s = (yyvsp[(1) - (1)].str);
+             ;}
+    break;
+
+  case 88:
+#line 572 "parser.y"
+    { (yyval.val) = (yyvsp[(1) - (1)].val); ;}
+    break;
+
+  case 89:
+#line 577 "parser.y"
+    {
+                 (yyval.val) = _gmx_selexpr_create_value(INT_VALUE);
+                 (yyval.val)->u.i.i1 = (yyvsp[(1) - (3)].r); (yyval.val)->u.i.i2 = (yyvsp[(3) - (3)].r);
+             ;}
+    break;
+
+  case 90:
+#line 582 "parser.y"
+    {
+                 (yyval.val) = _gmx_selexpr_create_value(REAL_VALUE);
+                 (yyval.val)->u.r.r1 = (yyvsp[(1) - (3)].r); (yyval.val)->u.r.r2 = (yyvsp[(3) - (3)].r);
+             ;}
+    break;
+
+  case 91:
+#line 587 "parser.y"
     {
                  (yyval.val) = _gmx_selexpr_create_value(REAL_VALUE);
                  (yyval.val)->u.r.r1 = (yyvsp[(1) - (3)].r); (yyval.val)->u.r.r2 = (yyvsp[(3) - (3)].r);
@@ -2158,7 +2305,7 @@ yyreduce:
 
 
 /* Line 1267 of yacc.c.  */
-#line 2162 "parser.c"
+#line 2309 "parser.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -2372,7 +2519,7 @@ yyreturn:
 }
 
 
-#line 542 "parser.y"
+#line 593 "parser.y"
 
 
 static t_selexpr_value *
index 088158bd72fd40369d7a2b874d7348dba2db6c7e..e240cb388f0cda4034603de307bddadcb15b9de2 100644 (file)
@@ -70,7 +70,8 @@
      OR = 286,
      AND = 287,
      NOT = 288,
-     UNARY_NEG = 289
+     UNARY_NEG = 289,
+     NUM_REDUCT = 290
    };
 #endif
 /* Tokens.  */
 #define AND 287
 #define NOT 288
 #define UNARY_NEG 289
+#define NUM_REDUCT 290
 
 
 
@@ -125,7 +127,7 @@ typedef union YYSTYPE
     struct t_selexpr_param     *param;
 }
 /* Line 1489 of yacc.c.  */
-#line 129 "parser.h"
+#line 131 "parser.h"
        YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
index 6738ff11e500ac23d7b7a11686166e80a4527669..551e0cf7abe10d55da34d2f0c907c3744182e093 100644 (file)
@@ -137,9 +137,11 @@ yyerror(yyscan_t, char const *s);
 %left           '*' '/'
 %right          UNARY_NEG   /* Dummy token for unary negation precedence */
 %right          '^'
+%nonassoc       NUM_REDUCT  /* Dummy token for numerical keyword reduction precedence */
 
 /* Simple non-terminals */
-%type <r>     number
+%type <r>     integer_number
+%type <r>     real_number number
 %type <str>   string
 %type <str>   pos_mod
 
@@ -153,7 +155,8 @@ yyerror(yyscan_t, char const *s);
 
 /* Parameter/value non-terminals */
 %type <param> method_params method_param_list method_param
-%type <val>   value_list value_list_nonempty value_item
+%type <val>   value_list value_list_contents value_item value_item_range
+%type <val>   basic_value_list basic_value_list_contents basic_value_item
 
 %destructor { free($$);                     } HELP_TOPIC STR IDENTIFIER CMP_OP string
 %destructor { if($$) free($$);              } PARAM
@@ -161,9 +164,10 @@ yyerror(yyscan_t, char const *s);
 %destructor { _gmx_selelem_free_chain($$);  } selection
 %destructor { _gmx_selelem_free($$);        } sel_expr num_expr str_expr pos_expr
 %destructor { _gmx_selexpr_free_params($$); } method_params method_param_list method_param
-%destructor { _gmx_selexpr_free_values($$); } value_list value_list_nonempty value_item
+%destructor { _gmx_selexpr_free_values($$); } value_list value_list_contents value_item value_item_range
+%destructor { _gmx_selexpr_free_values($$); } basic_value_list basic_value_list_contents basic_value_item
 
-%expect 91
+%expect 50
 %debug
 %pure-parser
 
@@ -271,8 +275,18 @@ selection:   pos_expr           { $$ = $1; }
  * BASIC NON-TERMINAL SYMBOLS
  ********************************************************************/
 
-number:      TOK_INT            { $$ = $1; }
-           | TOK_REAL               { $$ = $1; }
+integer_number:
+             TOK_INT            { $$ = $1; }
+           | '-' TOK_INT        { $$ = -$2; }
+;
+
+real_number:
+             TOK_REAL           { $$ = $1; }
+           | '-' TOK_REAL       { $$ = -$2; }
+;
+
+number:      integer_number     { $$ = $1; }
+           | real_number        { $$ = $1; }
 ;
 
 string:      STR                { $$ = $1; }
@@ -344,12 +358,12 @@ sel_expr:    pos_mod KEYWORD_GROUP
                  $$ = _gmx_sel_init_keyword($2, NULL, $1, scanner);
                  if ($$ == NULL) YYERROR;
              }
-           | pos_mod KEYWORD_STR value_list_nonempty
+           | pos_mod KEYWORD_STR basic_value_list
              {
                  $$ = _gmx_sel_init_keyword($2, process_value_list($3, NULL), $1, scanner);
                  if ($$ == NULL) YYERROR;
              }
-           | pos_mod KEYWORD_NUMERIC value_list_nonempty
+           | pos_mod KEYWORD_NUMERIC basic_value_list
              {
                  $$ = _gmx_sel_init_keyword($2, process_value_list($3, NULL), $1, scanner);
                  if ($$ == NULL) YYERROR;
@@ -386,7 +400,7 @@ num_expr:    TOK_INT
 ;
 
 /* Numeric selection methods */
-num_expr:    pos_mod KEYWORD_NUMERIC
+num_expr:    pos_mod KEYWORD_NUMERIC    %prec NUM_REDUCT
              {
                  $$ = _gmx_sel_init_keyword($2, NULL, $1, scanner);
                  if ($$ == NULL) YYERROR;
@@ -437,7 +451,7 @@ str_expr:    string
  ********************************************************************/
 
 /* Constant position expressions */
-pos_expr:    '(' number ',' number ',' number ')'
+pos_expr:    '[' number ',' number ',' number ']'
              { $$ = _gmx_sel_init_const_position($2, $4, $6); }
 ;
 
@@ -502,15 +516,29 @@ method_param:
              }
 ;
 
-value_list:  /* empty */         { $$ = NULL; }
-           | value_list_nonempty { $$ = $1;   }
+value_list:  /* empty */                         { $$ = NULL; }
+           | value_list_contents                 { $$ = $1;   }
+           | '{' value_list_contents '}'         { $$ = $2;   }
 ;
 
-value_list_nonempty:
+value_list_contents:
              value_item          { $$ = $1; }
-           | value_list_nonempty value_item
+           | value_list_contents value_item
                                  { $2->next = $1; $$ = $2; }
-           | value_list_nonempty ',' value_item
+           | value_list_contents ',' value_item
+                                 { $3->next = $1; $$ = $3; }
+;
+
+basic_value_list:
+             basic_value_list_contents           { $$ = $1; }
+           | '{' basic_value_list_contents '}'   { $$ = $2; }
+;
+
+basic_value_list_contents:
+             basic_value_item    { $$ = $1; }
+           | basic_value_list_contents basic_value_item
+                                 { $2->next = $1; $$ = $2; }
+           | basic_value_list_contents ',' basic_value_item
                                  { $3->next = $1; $$ = $3; }
 ;
 
@@ -522,17 +550,40 @@ value_item:  sel_expr            %prec PARAM_REDUCT
              { $$ = _gmx_selexpr_create_value_expr($1); }
            | str_expr            %prec PARAM_REDUCT
              { $$ = _gmx_selexpr_create_value_expr($1); }
-           | TOK_INT TO TOK_INT
+           | value_item_range    { $$ = $1; }
+;
+
+basic_value_item:
+             integer_number      %prec PARAM_REDUCT
+             {
+                 $$ = _gmx_selexpr_create_value(INT_VALUE);
+                 $$->u.i.i1 = $$->u.i.i2 = $1;
+             }
+           | real_number         %prec PARAM_REDUCT
+             {
+                 $$ = _gmx_selexpr_create_value(REAL_VALUE);
+                 $$->u.r.r1 = $$->u.r.r2 = $1;
+             }
+           | string              %prec PARAM_REDUCT
+             {
+                 $$ = _gmx_selexpr_create_value(STR_VALUE);
+                 $$->u.s = $1;
+             }
+           | value_item_range    { $$ = $1; }
+;
+
+value_item_range:
+             integer_number TO integer_number
              {
                  $$ = _gmx_selexpr_create_value(INT_VALUE);
                  $$->u.i.i1 = $1; $$->u.i.i2 = $3;
              }
-           | TOK_INT TO TOK_REAL
+           | integer_number TO real_number
              {
                  $$ = _gmx_selexpr_create_value(REAL_VALUE);
                  $$->u.r.r1 = $1; $$->u.r.r2 = $3;
              }
-           | TOK_REAL TO number
+           | real_number TO number
              {
                  $$ = _gmx_selexpr_create_value(REAL_VALUE);
                  $$->u.r.r1 = $1; $$->u.r.r2 = $3;
index 7236ecc2778150fded09c8dea48d1f110a7e3699..de74a3d8a80c6e266a9e3ce43b7960e1988612b6 100644 (file)
@@ -365,19 +365,17 @@ struct yy_trans_info
        flex_int32_t yy_verify;
        flex_int32_t yy_nxt;
        };
-static yyconst flex_int16_t yy_accept[93] =
+static yyconst flex_int16_t yy_accept[89] =
     {   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-       27,   25,   23,    6,   20,   25,    1,   25,   25,   25,
-        2,    6,   21,   25,   22,   25,   24,   22,   22,   22,
-       22,   22,   22,   25,   22,   22,   22,   22,   22,   11,
-        8,   10,   10,    9,   23,   21,    0,    4,    0,    1,
-       17,    0,    0,    3,    3,    2,   24,   24,   22,    5,
-       22,   22,   22,   18,   15,   22,   18,   16,   13,   22,
-       12,   22,   22,    8,    9,    0,    0,    0,    3,   17,
-       22,   20,   19,   13,   22,    3,    0,    3,   22,    7,
-       14,    0
-
+       27,   25,   23,    6,   20,   25,    1,   25,   25,    2,
+        6,   21,   25,   22,   25,   24,   22,   22,   22,   22,
+       22,   22,   25,   22,   22,   22,   22,   22,   11,    8,
+       10,   10,    9,   23,   21,    0,    4,    0,    1,   17,
+        3,    3,    2,   24,   24,   22,    5,   22,   22,   22,
+       18,   15,   22,   18,   16,   13,   22,   12,   22,   22,
+        8,    9,    0,    0,    3,   17,   22,   20,   19,   13,
+       22,    0,    3,    3,   22,    7,   14,    0
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
@@ -386,16 +384,16 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    2,    4,    5,    6,    1,    1,    7,    1,    1,
-        1,    1,    8,    1,    9,   10,    1,   11,   11,   11,
-       11,   11,   11,   11,   11,   11,   11,    1,   12,   13,
-       14,   13,    1,    1,   15,   15,   15,   15,   16,   15,
-       15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
-       15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
-        1,   17,    1,    1,   18,    1,   19,   15,   15,   20,
-
-       21,   22,   23,   24,   15,   15,   15,   25,   15,   26,
-       27,   28,   15,   29,   30,   31,   32,   15,   15,   33,
-       34,   15,    1,   35,    1,    1,    1,    1,    1,    1,
+        1,    1,    8,    1,    8,    9,    1,   10,   10,   10,
+       10,   10,   10,   10,   10,   10,   10,    1,   11,   12,
+       13,   12,    1,    1,   14,   14,   14,   14,   15,   14,
+       14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
+       14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
+        1,   16,    1,    1,   17,    1,   18,   14,   14,   19,
+
+       20,   21,   22,   23,   14,   14,   14,   24,   14,   25,
+       26,   27,   14,   28,   29,   30,   31,   14,   14,   32,
+       33,   14,    1,   34,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -412,96 +410,94 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[36] =
+static yyconst flex_int32_t yy_meta[35] =
     {   0,
-        1,    1,    2,    1,    1,    1,    1,    1,    1,    3,
-        4,    1,    1,    1,    4,    4,    1,    4,    4,    4,
+        1,    1,    2,    1,    1,    1,    1,    1,    3,    4,
+        1,    1,    1,    4,    4,    1,    4,    4,    4,    4,
         4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
-        4,    4,    4,    4,    1
+        4,    4,    4,    1
     } ;
 
-static yyconst flex_int16_t yy_base[98] =
+static yyconst flex_int16_t yy_base[94] =
     {   0,
-        0,    0,  144,  143,   10,   12,  145,  144,   46,    0,
-      167,  172,  164,  172,  151,   77,    0,  157,   30,  152,
-       74,  172,  148,  147,    0,  157,  149,  132,  128,  129,
-      126,  127,  126,  117,   64,  124,   70,  129,  128,  172,
-      146,  172,  172,    0,  145,  172,   83,  172,  141,    0,
-      172,  134,   87,   90,   91,   94,  134,  108,    0,  172,
-      123,  115,  110,    0,    0,  111,  172,    0,  108,  116,
-        0,  107,  111,  133,    0,   34,  112,  123,  103,    0,
-       97,    0,    0,    0,   97,  111,   98,   80,   61,    0,
-        0,  172,  123,  127,  129,   83,   79
+        0,    0,  131,  130,   10,   12,  132,  131,   45,    0,
+      153,  158,  150,  158,  138,   75,    0,  143,  139,   72,
+      158,  135,  134,    0,  143,  136,  119,  115,  116,  113,
+      114,  113,  104,   62,  111,   68,  116,  115,  158,  132,
+      158,  158,    0,  131,  158,   79,  158,  127,    0,  158,
+       84,   87,   91,  122,   31,    0,  158,  111,  103,   98,
+        0,    0,   99,  158,    0,   96,  104,    0,   95,   99,
+      120,    0,   34,  107,   76,    0,   82,    0,    0,    0,
+       83,   99,   98,   95,   76,    0,    0,  158,  111,  115,
+      117,   94,   84
 
     } ;
 
-static yyconst flex_int16_t yy_def[98] =
+static yyconst flex_int16_t yy_def[94] =
     {   0,
-       92,    1,    1,    1,    1,    1,    1,    1,   92,    9,
-       92,   92,   92,   92,   92,   93,   94,   92,   92,   92,
-       95,   92,   92,   92,   96,   92,   95,   96,   96,   96,
-       96,   96,   96,   92,   96,   96,   96,   96,   96,   92,
-       92,   92,   92,   97,   92,   92,   93,   92,   92,   94,
-       92,   92,   92,   92,   92,   95,   95,   95,   96,   92,
-       96,   96,   96,   96,   96,   96,   92,   96,   96,   96,
-       96,   96,   96,   92,   97,   92,   92,   92,   95,   96,
-       96,   96,   96,   96,   96,   92,   92,   92,   96,   96,
-       96,    0,   92,   92,   92,   92,   92
+       88,    1,    1,    1,    1,    1,    1,    1,   88,    9,
+       88,   88,   88,   88,   88,   89,   90,   88,   88,   91,
+       88,   88,   88,   92,   88,   91,   92,   92,   92,   92,
+       92,   92,   88,   92,   92,   92,   92,   92,   88,   88,
+       88,   88,   93,   88,   88,   89,   88,   88,   90,   88,
+       88,   88,   91,   91,   91,   92,   88,   92,   92,   92,
+       92,   92,   92,   88,   92,   92,   92,   92,   92,   92,
+       88,   93,   88,   88,   91,   92,   92,   92,   92,   92,
+       92,   88,   88,   88,   92,   92,   92,    0,   88,   88,
+       88,   88,   88
 
     } ;
 
-static yyconst flex_int16_t yy_nxt[208] =
+static yyconst flex_int16_t yy_nxt[193] =
     {   0,
        12,   13,   14,   15,   16,   17,   18,   12,   19,   20,
-       21,   22,   23,   24,   25,   25,   26,   27,   28,   25,
-       25,   25,   29,   25,   25,   30,   31,   25,   25,   25,
-       32,   25,   33,   25,   34,   36,   37,   36,   37,   52,
-       53,   78,   78,   38,   86,   38,   40,   41,   42,   40,
-       40,   40,   40,   40,   40,   40,   40,   43,   40,   40,
-       44,   44,   40,   40,   44,   44,   44,   44,   44,   44,
-       44,   44,   44,   44,   44,   44,   44,   44,   44,   44,
-       40,   48,   75,   55,   56,   68,   59,   48,   91,   58,
-       88,   70,   64,   49,   58,   71,   55,   53,   64,   49,
-
-       54,   54,   76,   55,   56,   77,   77,   76,   88,   58,
-       77,   77,   92,   79,   58,   78,   78,   92,   79,   87,
-       87,   86,   88,   47,   90,   47,   47,   50,   89,   50,
-       50,   57,   57,   86,   74,   85,   71,   84,   82,   83,
-       82,   81,   80,   92,   54,   47,   45,   74,   73,   72,
-       69,   67,   66,   65,   64,   63,   62,   61,   92,   60,
-       46,   46,   54,   51,   46,   45,   92,   39,   39,   35,
-       35,   11,   92,   92,   92,   92,   92,   92,   92,   92,
-       92,   92,   92,   92,   92,   92,   92,   92,   92,   92,
-       92,   92,   92,   92,   92,   92,   92,   92,   92,   92,
-
-       92,   92,   92,   92,   92,   92,   92
+       21,   22,   23,   24,   24,   25,   26,   27,   24,   24,
+       24,   28,   24,   24,   29,   30,   24,   24,   24,   31,
+       24,   32,   24,   33,   35,   36,   35,   36,   74,   88,
+       75,   82,   37,   83,   37,   39,   40,   41,   39,   39,
+       39,   39,   39,   39,   39,   42,   39,   39,   43,   43,
+       39,   39,   43,   43,   43,   43,   43,   43,   43,   43,
+       43,   43,   43,   43,   43,   43,   43,   43,   39,   47,
+       52,   53,   65,   47,   88,   75,   55,   72,   67,   61,
+       48,   55,   68,   51,   48,   61,   51,   56,   73,   52,
+
+       53,   73,   87,   73,   84,   55,   73,   83,   83,   86,
+       55,   46,   85,   46,   46,   49,   84,   49,   49,   54,
+       54,   71,   81,   68,   80,   78,   79,   78,   77,   76,
+       88,   46,   44,   71,   70,   69,   66,   64,   63,   62,
+       61,   60,   59,   58,   88,   57,   45,   45,   51,   50,
+       45,   44,   88,   38,   38,   34,   34,   11,   88,   88,
+       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
+       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
+       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
+       88,   88
+
     } ;
 
-static yyconst flex_int16_t yy_chk[208] =
+static yyconst flex_int16_t yy_chk[193] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    5,    5,    6,    6,   19,
-       19,   76,   76,    5,   76,    6,    9,    9,    9,    9,
+        1,    1,    1,    1,    5,    5,    6,    6,   55,   55,
+       55,   73,    5,   73,    6,    9,    9,    9,    9,    9,
         9,    9,    9,    9,    9,    9,    9,    9,    9,    9,
         9,    9,    9,    9,    9,    9,    9,    9,    9,    9,
-        9,    9,    9,    9,    9,    9,    9,    9,    9,    9,
-        9,   16,   97,   21,   21,   35,   96,   47,   89,   21,
-       88,   37,   35,   16,   21,   37,   53,   53,   37,   47,
-
-       54,   55,   53,   56,   56,   54,   55,   53,   87,   56,
-       54,   55,   79,   79,   56,   58,   58,   58,   58,   77,
-       77,   86,   77,   93,   85,   93,   93,   94,   81,   94,
-       94,   95,   95,   78,   74,   73,   72,   70,   69,   66,
-       63,   62,   61,   57,   52,   49,   45,   41,   39,   38,
-       36,   34,   33,   32,   31,   30,   29,   28,   27,   26,
-       24,   23,   20,   18,   15,   13,   11,    8,    7,    4,
-        3,   92,   92,   92,   92,   92,   92,   92,   92,   92,
-       92,   92,   92,   92,   92,   92,   92,   92,   92,   92,
-       92,   92,   92,   92,   92,   92,   92,   92,   92,   92,
-
-       92,   92,   92,   92,   92,   92,   92
+        9,    9,    9,    9,    9,    9,    9,    9,    9,   16,
+       20,   20,   34,   46,   75,   75,   20,   93,   36,   34,
+       16,   20,   36,   51,   46,   36,   52,   92,   51,   53,
+
+       53,   52,   85,   51,   84,   53,   52,   83,   82,   81,
+       53,   89,   77,   89,   89,   90,   74,   90,   90,   91,
+       91,   71,   70,   69,   67,   66,   63,   60,   59,   58,
+       54,   48,   44,   40,   38,   37,   35,   33,   32,   31,
+       30,   29,   28,   27,   26,   25,   23,   22,   19,   18,
+       15,   13,   11,    8,    7,    4,    3,   88,   88,   88,
+       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
+       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
+       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
+       88,   88
+
     } ;
 
 /* The intent behind this definition is that it'll catch
@@ -571,7 +567,7 @@ static yyconst flex_int16_t yy_chk[208] =
 
 
 
-#line 575 "scanner.c"
+#line 571 "scanner.c"
 
 #define INITIAL 0
 #define matchof 1
@@ -834,7 +830,7 @@ YY_DECL
     }
 
 
-#line 838 "scanner.c"
+#line 834 "scanner.c"
 
        if ( !yyg->yy_init )
                {
@@ -887,13 +883,13 @@ yy_match:
                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                {
                                yy_current_state = (int) yy_def[yy_current_state];
-                               if ( yy_current_state >= 93 )
+                               if ( yy_current_state >= 89 )
                                        yy_c = yy_meta[(unsigned int) yy_c];
                                }
                        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
                        ++yy_cp;
                        }
-               while ( yy_current_state != 92 );
+               while ( yy_current_state != 88 );
                yy_cp = yyg->yy_last_accepting_cpos;
                yy_current_state = yyg->yy_last_accepting_state;
 
@@ -1060,7 +1056,7 @@ YY_RULE_SETUP
 #line 156 "scanner.l"
 YY_FATAL_ERROR( "flex scanner jammed" );
        YY_BREAK
-#line 1064 "scanner.c"
+#line 1060 "scanner.c"
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(matchof):
 case YY_STATE_EOF(matchbool):
@@ -1359,7 +1355,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                        {
                        yy_current_state = (int) yy_def[yy_current_state];
-                       if ( yy_current_state >= 93 )
+                       if ( yy_current_state >= 89 )
                                yy_c = yy_meta[(unsigned int) yy_c];
                        }
                yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1388,11 +1384,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
                yy_current_state = (int) yy_def[yy_current_state];
-               if ( yy_current_state >= 93 )
+               if ( yy_current_state >= 89 )
                        yy_c = yy_meta[(unsigned int) yy_c];
                }
        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-       yy_is_jam = (yy_current_state == 92);
+       yy_is_jam = (yy_current_state == 88);
 
        return yy_is_jam ? 0 : yy_current_state;
 }
index f3404ca9487e9187603acb54b0f88d822c09211d..b23b2b3389b6369004f845b9c3fec8270d3ff40e 100644 (file)
@@ -58,7 +58,7 @@ INTEGER    [[:digit:]]+
 DSEQ       ([[:digit:]]+)
 FRAC       (([[:digit:]]*"."{DSEQ})|{DSEQ}".")
 EXP        ([eE][+-]?{DSEQ})
-REAL       ("-"?(({FRAC}{EXP}?)|({DSEQ}{EXP})))
+REAL       (({FRAC}{EXP}?)|({DSEQ}{EXP}))
 STRING     (\"([^\"\\\n]|(\\\"))*\")
 IDENTIFIER ([[:alpha:]][_[:alnum:]]*)
 CMPOP      (([<>]=?)|([!=]=))
index 7fa44b88c6edbe538f410ab936e603d581d97072..0bbe59fabac7654136541e33396261d4779a8d32 100644 (file)
@@ -113,7 +113,7 @@ static const char *help_eval[] = {
     "remaining expressions are not evaluated at all.",
     "This can be used to optimize the selections: you should write the",
     "most restrictive and/or the most inexpensive expressions first in",
-    "gmx_boolean expressions.",
+    "boolean expressions.",
     "The relative ordering between dynamic and static expressions does not",
     "matter: all static expressions are evaluated only once, before the first",
     "frame, and the result becomes the leftmost expression.[PAR]",
@@ -186,6 +186,14 @@ static const char *help_limits[] = {
     "of groups of three or four atoms).",
     "For such programs, it is up to the user to provide a proper selection",
     "expression that always returns such positions.",
+    "[PAR]",
+
+    "Due to technical reasons, having a negative value as the first value in",
+    "expressions like[BR]",
+    "[TT]charge -1 to -0.7[tt][BR]",
+    "result in a syntax error. A workaround is to write[BR]",
+    "[TT]charge {-1 to -0.7}[tt][BR]",
+    "instead.",
 };
 
 static const char *help_positions[] = {
@@ -193,7 +201,7 @@ static const char *help_positions[] = {
 
     "Possible ways of specifying positions in selections are:[PAR]",
 
-    "1. A constant position can be defined as [TT](XX, YY, ZZ)[tt], where",
+    "1. A constant position can be defined as [TT][XX, YY, ZZ][tt], where",
     "[TT]XX[tt], [TT]YY[tt] and [TT]ZZ[tt] are real numbers.[PAR]",
 
     "2. [TT]com of ATOM_EXPR [pbc][tt] or [TT]cog of ATOM_EXPR [pbc][tt]",
index 57b7ce1238bf4580f26445e7697a33502b6867ac..15a868e9967c7a8b07d2ba4b5fb2630f4f6e83d3 100644 (file)
@@ -211,12 +211,19 @@ gmx_bool read_next_vmd_frame(int status,t_trxframe *fr)
 #endif
 
     fr->bX = 1;
+    fr->bBox = 1;
     vec[0] = .1*ts.A; vec[1] = .1*ts.B; vec[2] = .1*ts.C;
     angle[0] = ts.alpha; angle[1] = ts.beta; angle[2] = ts.gamma; 
     matrix_convert(fr->box,vec,angle);
-    fr->bTime = 1;
-    fr->time = ts.physical_time;
-
+    if (fr->vmdplugin.api->abiversion>10)
+    {
+        fr->bTime = TRUE;
+        fr->time = ts.physical_time;
+    }
+    else
+    {
+        fr->bTime = FALSE;
+    }
 
 
     return 1;
@@ -334,16 +341,22 @@ int read_first_vmd_frame(int *status,const char *fn,t_trxframe *fr,int flags)
         return 0;
     }
 
-    if (fr->natoms < 1) {
-        fprintf(stderr, "\nNo atoms found by VMD plugin in %s.\n"
-            "Or format does not record number of atoms.\n", fn );
+    if (fr->natoms == MOLFILE_NUMATOMS_UNKNOWN) {
+        fprintf(stderr, "\nFormat of file %s does not record number of atoms.\n", fn);
+        return 0;
+    } else if (fr->natoms == MOLFILE_NUMATOMS_NONE) {
+        fprintf(stderr, "\nNo atoms found by VMD plugin in file %s.\n", fn );
+        return 0;
+    } else if (fr->natoms < 1) { /*should not be reached*/
+        fprintf(stderr, "\nUnknown number of atoms %d for VMD plugin opening file %s.\n",
+                fr->natoms, fn );
         return 0;
     }
     
     snew(fr->x,fr->natoms);
 
     fr->vmdplugin.bV = 0;
-    if (fr->vmdplugin.api->read_timestep_metadata) 
+    if (fr->vmdplugin.api->abiversion > 10 && fr->vmdplugin.api->read_timestep_metadata)
     {
         fr->vmdplugin.api->read_timestep_metadata(fr->vmdplugin.handle, metadata);
         fr->vmdplugin.bV = metadata->has_velocities; 
index 8c6e4a0f2d0b0f6a16d17cb426287857e4ec7c13..c26c887ee57fbfb4416f117ec6cc35f0d0ab883b 100644 (file)
@@ -36,7 +36,8 @@ set(GMXPREPROCESS_SOURCES
 set(MDRUN_SOURCES 
     gctio.c    ionize.c runner.c
     do_gct.c     repl_ex.c  xutils.c
-    md.c         mdrun.c    genalg.c md_openmm.c)
+    md.c         mdrun.c    genalg.c membed.c
+    md_openmm.c)
 
 add_library(gmxpreprocess ${GMXPREPROCESS_SOURCES})
 target_link_libraries(gmxpreprocess md)
@@ -56,11 +57,9 @@ if(GMX_OPENMM)
     else()
         add_definitions( -DOPENMM_PLUGIN_DIR="" )
     endif()
-    add_library(openmm_api_wrapper openmm_wrapper.cpp)
-    target_link_libraries(openmm_api_wrapper gmx gmx_gpu_utils ${OpenMM_LIBRARIES})
-#    remove_definitions( -DOPENMM_PLUGIN_DIR="${OpenMM_PLUGIN_DIR}" )  # TODO where should this go?!
+    add_library(openmm_api_wrapper STATIC openmm_wrapper.cpp)
+    target_link_libraries(openmm_api_wrapper gmx_gpu_utils ${OpenMM_LIBRARIES})
     set(GMX_OPENMM_LIBRARIES openmm_api_wrapper gmx_gpu_utils ${OpenMM_LIBRARIES})   
-       install(TARGETS openmm_api_wrapper DESTINATION ${LIB_INSTALL_DIR})   
 endif(GMX_OPENMM)
 
 if(GMX_FAHCORE)
@@ -103,13 +102,7 @@ set_target_properties(gmxcheck PROPERTIES OUTPUT_NAME "gmxcheck${GMX_BINARY_SUFF
 
 add_executable(mdrun ${MDRUN_SOURCES})
 target_link_libraries(mdrun ${GMX_EXTRA_LIBRARIES} ${GMX_OPENMM_LIBRARIES})
-# set binary name to mdrun-gpu
-if(GMX_OPENMM)
-    set(_mdrun_exec_name "mdrun-gpu")    
-else()
-    set(_mdrun_exec_name "mdrun${GMX_BINARY_SUFFIX}")
-endif()
-set_target_properties(mdrun PROPERTIES OUTPUT_NAME "${_mdrun_exec_name}")
+set_target_properties(mdrun PROPERTIES OUTPUT_NAME "mdrun${GMX_BINARY_SUFFIX}")
 
 # this is to circumvent the following MSVC error: 
 # warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs
@@ -133,12 +126,49 @@ install(TARGETS
         RUNTIME DESTINATION ${BIN_INSTALL_DIR})
 
 
-get_target_property(MDRUN_PATH mdrun LOCATION)
+# if we build shared gromacs libs, when installing throught the install-mdrun target 
+# these libs need to be installed as well
+if(BUILD_SHARED_LIBS)
+    # in MDRUN_LIBS we store the libraries MDRUN links against (NOTE: hardcoded!!!)
+    set(MDRUN_LIBS gmxpreprocess md gmx)
+    
+    # generate install-libXXX custom target for each shared lib that mdrun links against
+    foreach(_lib ${MDRUN_LIBS})
+        # double-check that the type is SHARED
+        get_target_property(_type ${_lib} TYPE)
+        if(NOT ${_type} STREQUAL "SHARED_LIBRARY")
+            message(FATAL_ERROR " Internal error: library ${_lib} is not shared so it's not supposed to be processed for installing")
+        endif()
+
+        # figure out the path and filename under which the lib will be installed
+        # (libname with pre- and suffix)
+        get_target_property(_lib_path ${_lib} LOCATION)
+        string(REGEX REPLACE "/" ";" _lib_fname ${_lib_path})
+        list(REVERSE _lib_fname)
+        list(GET _lib_fname 0 _lib_fname)
+
+        # create custom target for copying each library to the install location 
+        # TODO: need to fix this to have the .so.6 form
+        add_custom_target(install-${_lib}
+            COMMAND ${CMAKE_COMMAND} -E copy 
+                "${_lib_path}" "${LIB_INSTALL_DIR}/${_lib_fname}.${SOVERSION}"
+            COMMAND ${CMAKE_COMMAND} -E create_symlink 
+                "${_lib_fname}.${SOVERSION}" "${LIB_INSTALL_DIR}/${_lib_fname}"
+            COMMENT "Installing library ${_lib}")
+        add_dependencies(install-${_lib} ${_lib})
+
+        # gather the custom target names in a string
+        # set(_lib_install_targets "${_lib_install_targets} install-lib${_lib}")
+        list(APPEND _lib_install_targets "install-${_lib}")
+    endforeach(_lib)
+endif(BUILD_SHARED_LIBS)
+
+get_target_property(_mdrun_path mdrun LOCATION)
 add_custom_target(install-mdrun
-        COMMAND ${CMAKE_COMMAND} -E copy "${MDRUN_PATH}" 
-            "${CMAKE_INSTALL_PREFIX}/bin/${_mdrun_exec_name}"
-        DEPENDS mdrun
-        COMMENT "Installing mdrun")
+    COMMAND ${CMAKE_COMMAND} -E copy "${_mdrun_path}" 
+        "${BIN_INSTALL_DIR}/${_mdrun_exec_name}"
+    COMMENT "Installing mdrun")
+add_dependencies(install-mdrun mdrun ${_lib_install_targets})
 
 endif(GMX_FAHCORE)
 
index 32fa7423defc935253b249e77496fd809071f11a..7033012def36dd735e99f1b187239af567fc4087 100644 (file)
@@ -58,7 +58,7 @@ bin_PROGRAMS = \
 g_x2top_SOURCES = g_x2top.c nm2type.c g_x2top.h
 
 mdrun_SOURCES = \
-       gctio.c         gmx_membed.c    gmx_membed.h    \
+       gctio.c         membed.c        membed.h    \
        ionize.c        ionize.h        xmdrun.h        \
        do_gct.c        repl_ex.c       repl_ex.h       \
        xutils.c        runner.c        md.c            mdrun.c         \
index 25f4aa12dbea6eed2420b726abc6d3593a41f232..f06debc0b4973db321c18b03054102649c5f1298 100644 (file)
@@ -18,21 +18,13 @@ endif()
 CUDA_INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
 set(CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE OFF)        
 if(CMAKE_BUILD_TYPE STREQUAL "DEBUG")
-    CUDA_ADD_LIBRARY(gmx_gpu_utils  
-        gmx_gpu_utils.cu 
-        memtestG80_core.cu 
+    CUDA_ADD_LIBRARY(gmx_gpu_utils STATIC
+        gmx_gpu_utils.cu memtestG80_core.cu 
         OPTIONS ${_os_def}
-        DEBUG -g -D_DEBUG_=1 
-        )
+        DEBUG -g -D_DEBUG_=1 )
 else()
-    CUDA_ADD_LIBRARY(gmx_gpu_utils 
-        gmx_gpu_utils.cu 
-        memtestG80_core.cu 
-        OPTIONS ${_os_def}
-        )
+    CUDA_ADD_LIBRARY(gmx_gpu_utils STATIC
+        gmx_gpu_utils.cu memtestG80_core.cu 
+        OPTIONS ${_os_def} )
 endif()
 CUDA_BUILD_CLEAN_TARGET()
-
-target_link_libraries(gmx_gpu_utils gmx)
-install(TARGETS gmx_gpu_utils DESTINATION ${LIB_INSTALL_DIR})   
-
index 0f9e7794d9dbaed2de4d7411c40a8ca44fb56484..72efea555fdc5b0941eddad56fe7f907048b7078 100644 (file)
@@ -183,6 +183,148 @@ static void check_cg_sizes(const char *topfn,t_block *cgs,warninp_t wi)
     }
 }
 
+static void check_bonds_timestep(gmx_mtop_t *mtop,double dt,warninp_t wi)
+{
+    /* This check is not intended to ensure accurate integration,
+     * rather it is to signal mistakes in the mdp settings.
+     * A common mistake is to forget to turn on constraints
+     * for MD after energy minimization with flexible bonds.
+     * This check can also detect too large time steps for flexible water
+     * models, but such errors will often be masked by the constraints
+     * mdp options, which turns flexible water into water with bond constraints,
+     * but without an angle constraint. Unfortunately such incorrect use
+     * of water models can not easily be detected without checking
+     * for specific model names.
+     *
+     * The stability limit of leap-frog or velocity verlet is 4.44 steps
+     * per oscillational period.
+     * But accurate bonds distributions are lost far before that limit.
+     * To allow relatively common schemes (although not common with Gromacs)
+     * of dt=1 fs without constraints and dt=2 fs with only H-bond constraints
+     * we set the note limit to 10.
+     */
+    int       min_steps_warn=5;
+    int       min_steps_note=10;
+    t_iparams *ip;
+    int       molt;
+    gmx_moltype_t *moltype,*w_moltype;
+    t_atom    *atom;
+    t_ilist   *ilist,*ilb,*ilc,*ils;
+    int       ftype;
+    int       i,a1,a2,w_a1,w_a2,j;
+    real      twopi2,limit2,fc,re,m1,m2,period2,w_period2;
+    gmx_bool  bFound,bWater,bWarn;
+    char      warn_buf[STRLEN];
+
+    ip = mtop->ffparams.iparams;
+
+    twopi2 = sqr(2*M_PI);
+
+    limit2 = sqr(min_steps_note*dt);
+
+    w_a1 = w_a2 = -1;
+    w_period2 = -1.0;
+    
+    w_moltype = NULL;
+    for(molt=0; molt<mtop->nmoltype; molt++)
+    {
+        moltype = &mtop->moltype[molt];
+        atom  = moltype->atoms.atom;
+        ilist = moltype->ilist;
+        ilc = &ilist[F_CONSTR];
+        ils = &ilist[F_SETTLE];
+        for(ftype=0; ftype<F_NRE; ftype++)
+        {
+            if (!(ftype == F_BONDS || ftype == F_G96BONDS || ftype == F_HARMONIC))
+            {
+                continue;
+            }
+            
+            ilb = &ilist[ftype];
+            for(i=0; i<ilb->nr; i+=3)
+            {
+                fc = ip[ilb->iatoms[i]].harmonic.krA;
+                re = ip[ilb->iatoms[i]].harmonic.rA;
+                if (ftype == F_G96BONDS)
+                {
+                    /* Convert squared sqaure fc to harmonic fc */
+                    fc = 2*fc*re;
+                }
+                a1 = ilb->iatoms[i+1];
+                a2 = ilb->iatoms[i+2];
+                m1 = atom[a1].m;
+                m2 = atom[a2].m;
+                if (fc > 0 && m1 > 0 && m2 > 0)
+                {
+                    period2 = twopi2*m1*m2/((m1 + m2)*fc);
+                }
+                else
+                {
+                    period2 = GMX_FLOAT_MAX;
+                }
+                if (debug)
+                {
+                    fprintf(debug,"fc %g m1 %g m2 %g period %g\n",
+                            fc,m1,m2,sqrt(period2));
+                }
+                if (period2 < limit2)
+                {
+                    bFound = FALSE;
+                    for(j=0; j<ilc->nr; j+=3)
+                    {
+                        if ((ilc->iatoms[j+1] == a1 && ilc->iatoms[j+2] == a2) ||
+                            (ilc->iatoms[j+1] == a2 && ilc->iatoms[j+2] == a1))
+                            {
+                                bFound = TRUE;
+                            }
+                        }
+                    for(j=0; j<ils->nr; j+=2)
+                    {
+                        if ((a1 >= ils->iatoms[j+1] && a1 < ils->iatoms[j+1]+3) &&
+                            (a2 >= ils->iatoms[j+1] && a2 < ils->iatoms[j+1]+3))
+                        {
+                            bFound = TRUE;
+                        }
+                    }
+                    if (!bFound &&
+                        (w_moltype == NULL || period2 < w_period2))
+                    {
+                        w_moltype = moltype;
+                        w_a1      = a1;
+                        w_a2      = a2;
+                        w_period2 = period2;
+                    }
+                }
+            }
+        }
+    }
+    
+    if (w_moltype != NULL)
+    {
+        bWarn = (w_period2 < sqr(min_steps_warn*dt));
+        /* A check that would recognize most water models */
+        bWater = ((*w_moltype->atoms.atomname[0])[0] == 'O' &&
+                  w_moltype->atoms.nr <= 5);
+        sprintf(warn_buf,"The bond in molecule-type %s between atoms %d %s and %d %s has an estimated oscillational period of %.1e ps, which is less than %d times the time step of %.1e ps.\n"
+                "%s",
+                *w_moltype->name,
+                w_a1+1,*w_moltype->atoms.atomname[w_a1],
+                w_a2+1,*w_moltype->atoms.atomname[w_a2],
+                sqrt(w_period2),bWarn ? min_steps_warn : min_steps_note,dt,
+                bWater ?
+                "Maybe you asked for fexible water." :
+                "Maybe you forgot to change the constraints mdp option.");
+        if (bWarn)
+        {
+            warning(wi,warn_buf);
+        }
+        else
+        {
+            warning_note(wi,warn_buf);
+        }
+    }
+}
+
 static void check_vel(gmx_mtop_t *mtop,rvec v[])
 {
   gmx_mtop_atomloop_all_t aloop;
@@ -1056,7 +1198,7 @@ int main (int argc, char *argv[])
   char         warn_buf[STRLEN];
 
   t_filenm fnm[] = {
-    { efMDP, NULL,  NULL,        ffOPTRD },
+    { efMDP, NULL,  NULL,        ffREAD  },
     { efMDP, "-po", "mdout",     ffWRITE },
     { efSTX, "-c",  NULL,        ffREAD  },
     { efSTX, "-r",  NULL,        ffOPTRD },
@@ -1275,6 +1417,11 @@ int main (int argc, char *argv[])
       check_cg_sizes(ftp2fn(efTOP,NFILE,fnm),&sys->moltype[i].cgs,wi);
   }
 
+  if (EI_DYNAMICS(ir->eI) && ir->eI != eiBD)
+  {
+      check_bonds_timestep(sys,ir->delta_t,wi);
+  }
+
   check_warning_error(wi,FARGS);
        
   if (bVerbose) 
index 9e235ed97070a0e6119b82e81a012b307e07ad0a..b0a1e5a218edf68dde5f3909e6e3daddc48a8edf 100644 (file)
@@ -89,7 +89,7 @@
 #include "checkpoint.h"
 #include "mtop_util.h"
 #include "sighandler.h"
-#include "gmx_membed.h"
+#include "membed.h"
 
 #ifdef GMX_LIB_MPI
 #include <mpi.h>
@@ -2706,25 +2706,17 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
         bStartingFromCpt = FALSE;
 
         /* #######  SET VARIABLES FOR NEXT ITERATION IF THEY STILL NEED IT ###### */
-        /* Complicated conditional when bGStatEveryStep=FALSE.
-         * We can not just use bGStat, since then the simulation results
-         * would depend on nstenergy and nstlog or step_nscheck.
+        /* With all integrators, except VV, we need to retain the pressure
+         * at the current step for coupling at the next step.
          */
-        if (((state->flags & (1<<estPRES_PREV)) || 
-             (state->flags & (1<<estSVIR_PREV)) ||
-             (state->flags & (1<<estFVIR_PREV))) &&
+        if ((state->flags & (1<<estPRES_PREV)) &&
             (bGStatEveryStep ||
-             (ir->nstlist > 0 && step % ir->nstlist == 0) ||
-             (ir->nstlist < 0 && nlh.nabnsb > 0) ||
-             (ir->nstlist == 0 && bGStat))) 
+             (ir->nstpcouple > 0 && step % ir->nstpcouple == 0)))
         {
             /* Store the pressure in t_state for pressure coupling
              * at the next MD step.
              */
-            if (state->flags & (1<<estPRES_PREV))
-            {
-                copy_mat(pres,state->pres_prev);
-            }
+            copy_mat(pres,state->pres_prev);
         }
         
         /* #######  END SET VARIABLES FOR NEXT ITERATION ###### */
index 00f674b24ed2fd5eee4734ce6943a46972f3fb58..6043d8feba0d6958fac3e3be92ca948ff9c967b9 100644 (file)
@@ -90,7 +90,7 @@
 #include "genborn.h"
 #include "string2.h"
 #include "copyrite.h"
-#include "gmx_membed.h"
+#include "membed.h"
 
 #ifdef GMX_THREADS
 #include "tmpi.h"
@@ -256,6 +256,13 @@ double do_md_openmm(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
     const char *ommOptions = NULL;
     void   *openmmData;
 
+#ifdef GMX_DOUBLE
+    /* Checks in cmake should prevent the compilation in double precision
+     * with OpenMM, but just to be sure we check here.
+     */
+    gmx_fatal(FARGS,"Compilation was performed in double precision, but OpenMM only supports single precision. If you want to use to OpenMM, compile in single precision.");
+#endif
+
     bAppend  = (Flags & MD_APPENDFILES);
     check_ir_old_tpx_versions(cr,fplog,ir,top_global);
 
@@ -528,7 +535,7 @@ double do_md_openmm(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
 
             openmm_copy_state(openmmData, state, &t, f, enerd, bX, bV, bF, do_ene);
 
-            upd_mdebin(mdebin, FALSE,TRUE,
+            upd_mdebin(mdebin,FALSE,TRUE,
                        t,mdatoms->tmass,enerd,state,lastbox,
                        shake_vir,force_vir,total_vir,pres,
                        ekind,mu_tot,constr);
similarity index 99%
rename from src/kernel/gmx_membed.c
rename to src/kernel/membed.c
index debba53ab1aa52b984e2e4c22e95ff0fa823f881..039fabf76552074e17bb66a976f9cecf87737750 100644 (file)
@@ -55,7 +55,7 @@
 #include "mtop_util.h"
 #include "tpxio.h"
 #include "string2.h"
-#include "gmx_membed.h"
+#include "membed.h"
 #include "pbc.h"
 #include "readinp.h"
 
index 6771c75a845d5e55548331628eb98e3e2e5472e6..6445b6a102970c4ca9013ce707414e818c1fe867 100644 (file)
@@ -2532,11 +2532,10 @@ void check_chargegroup_radii(const gmx_mtop_t *mtop,const t_inputrec *ir,
              * not be zero at the cut-off.
              */
             if (EVDW_IS_ZERO_AT_CUTOFF(ir->vdwtype) &&
-                rvdw1 + rvdw2 > ir->rlistlong - ir->rvdw)
+                rvdw1 + rvdw2 > ir->rlist - ir->rvdw)
             {
-                sprintf(warn_buf,"The sum of the two largest charge group radii (%f) is larger than %s (%f) - rvdw (%f)\n",
+                sprintf(warn_buf,"The sum of the two largest charge group radii (%f) is larger than rlist (%f) - rvdw (%f)\n",
                         rvdw1+rvdw2,
-                        ir->rlistlong > ir->rlist ? "rlistlong" : "rlist",
                         ir->rlist,ir->rvdw);
                 if (ir_NVE(ir))
                 {
index 94621948f2ef42e3a363715daffe7ff450863e98..a328fbf75a65d9d76c53381a3d37afc8749fe609 100644 (file)
@@ -52,6 +52,7 @@
 #include "mdrun.h"
 #include "network.h"
 #include "pull.h"
+#include "pull_rotation.h"
 #include "names.h"
 #include "disre.h"
 #include "orires.h"
@@ -72,8 +73,8 @@
 #include "sighandler.h"
 #include "tpxio.h"
 #include "txtdump.h"
-#include "pull_rotation.h"
-#include "gmx_membed.h"
+#include "membed.h"
+
 #include "md_openmm.h"
 
 #ifdef GMX_LIB_MPI
@@ -605,8 +606,12 @@ int mdrunner(int nthreads_requested, FILE *fplog,t_commrec *cr,int nfile,
         /* PME, if used, is done on all nodes with 1D decomposition */
         cr->npmenodes = 0;
         cr->duty = (DUTY_PP | DUTY_PME);
-        npme_major = cr->nnodes;
+        npme_major = 1;
         npme_minor = 1;
+        if (!EI_TPI(inputrec->eI))
+        {
+            npme_major = cr->nnodes;
+        }
         
         if (inputrec->ePBC == epbcSCREW)
         {
index 719938af7d6e4e669f849fad30ea235dfd6fd5d3..6d0917912c27648b8deb1868f6e2da31601b05e7 100644 (file)
@@ -454,6 +454,11 @@ void do_force_lowlevel(FILE       *fplog,   gmx_large_int_t step,
                     {
                         pme_flags |= GMX_PME_CALC_ENER_VIR;
                     }
+                    if (fr->n_tpi > 0)
+                    {
+                        /* We don't calculate f, but we do want the potential */
+                        pme_flags |= GMX_PME_CALC_POT;
+                    }
                     wallcycle_start(wcycle,ewcPMEMESH);
                     status = gmx_pme_do(fr->pmedata,
                                         md->start,md->homenr - fr->n_tpi,
index 03316c731e0c2d0641fb869c9e645b3b6120ee0d..7c01576d6ad289b270cee04684ddc2f6e4f7a6df 100644 (file)
@@ -772,7 +772,7 @@ void update_forcerec(FILE *log,t_forcerec *fr,matrix box)
 
 void set_avcsixtwelve(FILE *fplog,t_forcerec *fr,const gmx_mtop_t *mtop)
 {
-    const t_atoms *atoms;
+    const t_atoms *atoms,*atoms_tpi;
     const t_blocka *excl;
     int    mb,nmol,nmolc,i,j,tpi,tpj,j1,j2,k,n,nexcl,q;
 #if (defined SIZEOF_LONG_LONG_INT) && (SIZEOF_LONG_LONG_INT >= 8)    
@@ -882,15 +882,9 @@ void set_avcsixtwelve(FILE *fplog,t_forcerec *fr,const gmx_mtop_t *mtop)
             /* Only correct for the interaction of the test particle
              * with the rest of the system.
              */
-            atoms = &mtop->moltype[mtop->molblock[mtop->nmolblock-1].type].atoms;
-            if (q == 0)
-            {
-                tpi = atoms->atom[atoms->nr-1].type;
-            }
-            else
-            {
-                tpi = atoms->atom[atoms->nr-1].typeB;
-            }
+            atoms_tpi =
+                &mtop->moltype[mtop->molblock[mtop->nmolblock-1].type].atoms;
+
             npair = 0;
             for(mb=0; mb<mtop->nmolblock; mb++) {
                 nmol  = mtop->molblock[mb].nmol;
@@ -900,9 +894,14 @@ void set_avcsixtwelve(FILE *fplog,t_forcerec *fr,const gmx_mtop_t *mtop)
                     /* Remove the interaction of the test charge group
                      * with itself.
                      */
-                    if (mb == mtop->nmolblock-1 && j >= atoms->nr - fr->n_tpi)
+                    if (mb == mtop->nmolblock-1)
                     {
                         nmolc--;
+                        
+                        if (mb == 0 && nmol == 1)
+                        {
+                            gmx_fatal(FARGS,"Old format tpr with TPI, please generate a new tpr file");
+                        }
                     }
                     if (q == 0)
                     {
@@ -912,16 +911,27 @@ void set_avcsixtwelve(FILE *fplog,t_forcerec *fr,const gmx_mtop_t *mtop)
                     {
                         tpj = atoms->atom[j].typeB;
                     }
-                    if (bBHAM)
-                    {
-                        csix    += nmolc*BHAMC(nbfp,ntp,tpi,tpj);
-                    }
-                    else
+                    for(i=0; i<fr->n_tpi; i++)
                     {
-                        csix    += nmolc*C6 (nbfp,ntp,tpi,tpj);
-                        ctwelve += nmolc*C12(nbfp,ntp,tpi,tpj);
+                        if (q == 0)
+                        {
+                            tpi = atoms_tpi->atom[i].type;
+                        }
+                        else
+                        {
+                            tpi = atoms_tpi->atom[i].typeB;
+                        }
+                        if (bBHAM)
+                        {
+                            csix    += nmolc*BHAMC(nbfp,ntp,tpi,tpj);
+                        }
+                        else
+                        {
+                            csix    += nmolc*C6 (nbfp,ntp,tpi,tpj);
+                            ctwelve += nmolc*C12(nbfp,ntp,tpi,tpj);
+                        }
+                        npair += nmolc;
                     }
-                    npair += nmolc;
                 }
             }
         }
index 467f16c9fa9452702b63f5cebbf9a6e56b99dd3d..23999584166b17d8a492bdd6e21379bc8e581dd5 100644 (file)
@@ -49,6 +49,13 @@ static gmx_bool gmx_fft_threads_initialized=FALSE;
 #define FFTW_UNLOCK 
 #endif /* GMX_THREADS */
 
+/* We assume here that aligned memory starts at multiple of 16 bytes and unaligned memory starts at multiple of 8 bytes. The later is guranteed for all malloc implementation. 
+   Consequesences:
+   - It is not allowed to use these FFT plans from memory which doesn't have a starting address as a multiple of 8 bytes. 
+     This is OK as long as the memory directly comes from malloc and is not some subarray within alloated memory.
+   - This has to be fixed if any future architecute requires memory to be aligned to multiples of 32 bytes.
+*/
+
 struct gmx_fft
 {
     /* Three alternatives (unaligned/aligned, out-of-place/in-place, forward/backward)
@@ -743,7 +750,7 @@ gmx_fft_1d               (gmx_fft_t                  fft,
                           void *                     in_data,
                           void *                     out_data)
 {
-    int           aligned   = (((size_t)in_data & (size_t)out_data & 0xf)==0);
+    int           aligned   = ((((size_t)in_data | (size_t)out_data) & 0xf)==0);
     int           inplace   = (in_data == out_data);
     int           isforward = (dir == GMX_FFT_FORWARD);
     
@@ -777,7 +784,7 @@ gmx_fft_1d_real          (gmx_fft_t                  fft,
                           void *                     in_data,
                           void *                     out_data)
 {
-    int           aligned   = (((size_t)in_data & (size_t)out_data & 0xf)==0);
+    int           aligned   = ((((size_t)in_data | (size_t)out_data) & 0xf)==0);
     int           inplace   = (in_data == out_data);
     int           isforward = (dir == GMX_FFT_REAL_TO_COMPLEX);
     
@@ -818,7 +825,7 @@ gmx_fft_2d               (gmx_fft_t                  fft,
                           void *                     in_data,
                           void *                     out_data)
 {
-    int           aligned   = (((size_t)in_data & (size_t)out_data & 0xf)==0);
+    int           aligned   = ((((size_t)in_data | (size_t)out_data) & 0xf)==0);
     int           inplace   = (in_data == out_data);
     int           isforward = (dir == GMX_FFT_FORWARD);
     
@@ -844,7 +851,7 @@ gmx_fft_2d_real          (gmx_fft_t                  fft,
                           void *                     in_data,
                           void *                     out_data)
 {
-    int           aligned   = (((size_t)in_data & (size_t)out_data & 0xf)==0);
+    int           aligned   = ((((size_t)in_data | (size_t)out_data) & 0xf)==0);
     int           inplace   = (in_data == out_data);
     int           isforward = (dir == GMX_FFT_REAL_TO_COMPLEX);
     
@@ -880,7 +887,7 @@ gmx_fft_3d               (gmx_fft_t                  fft,
                           void *                     in_data,
                           void *                     out_data)
 {
-    int           aligned   = (((size_t)in_data & (size_t)out_data & 0xf)==0);
+    int           aligned   = ((((size_t)in_data | (size_t)out_data) & 0xf)==0);
     int           inplace   = (in_data == out_data);
     int           isforward = (dir == GMX_FFT_FORWARD);
     
@@ -906,7 +913,7 @@ gmx_fft_3d_real          (gmx_fft_t                  fft,
                           void *                     in_data,
                           void *                     out_data)
 {
-    int           aligned   = (((size_t)in_data & (size_t)out_data & 0xf)==0);
+    int           aligned   = ((((size_t)in_data | (size_t)out_data) & 0xf)==0);
     int           inplace   = (in_data == out_data);
     int           isforward = (dir == GMX_FFT_REAL_TO_COMPLEX);
     
index b351bb847fb573d76ce457eec5b28696d84a5a19..d0fad47e1a09ebed74c47e40d38e8a7fab5c46ee 100644 (file)
@@ -179,7 +179,9 @@ t_mdebin *init_mdebin(ener_file_t fp_ene,
         md->bEInd[i]=FALSE;
     }
 
-    for(i=0; i<F_NRE; i++) {
+#ifndef GMX_OPENMM
+    for(i=0; i<F_NRE; i++)
+    {
         md->bEner[i] = FALSE;
         if (i == F_LJ)
             md->bEner[i] = !bBHAM;
@@ -238,6 +240,13 @@ t_mdebin *init_mdebin(ener_file_t fp_ene,
         else
             md->bEner[i] = (gmx_mtop_ftype_count(mtop,i) > 0);
     }
+#else
+    /* OpenMM always produces only the following 4 energy terms */
+    md->bEner[F_EPOT] = TRUE;
+    md->bEner[F_EKIN] = TRUE;
+    md->bEner[F_ETOT] = TRUE;
+    md->bEner[F_TEMP] = TRUE;
+#endif
 
     md->f_nre=0;
     for(i=0; i<F_NRE; i++)
index ebc766cbc8c9c34f9087e99637f90a0f03d70e6e..c11481d7577792c903af98bd9f91ae363505a688 100644 (file)
@@ -75,7 +75,7 @@
 #include "mtop_util.h"
 #include "gmxfio.h"
 #include "pme.h"
-#include "gmx_membed.h"
+#include "membed.h"
 
 typedef struct {
   t_state s;
index 8d1182ed59d03f25af16e9cef8c777636ffffe8f..aec0dc6a5ae16cad21cbbb4aee7fb425fd7bc810 100644 (file)
@@ -2056,12 +2056,16 @@ int gmx_pme_init(gmx_pme_t *         pmedata,
     pme->nnodes_minor        = nnodes_minor;
 
 #ifdef GMX_MPI
-    if (PAR(cr)) 
+    if (nnodes_major*nnodes_minor > 1 && PAR(cr)) 
     {
         pme->mpi_comm        = cr->mpi_comm_mygroup;
         
         MPI_Comm_rank(pme->mpi_comm,&pme->nodeid);
         MPI_Comm_size(pme->mpi_comm,&pme->nnodes);
+        if (pme->nnodes != nnodes_major*nnodes_minor)
+        {
+            gmx_incons("PME node count mismatch");
+        }
     }
 #endif
 
@@ -2619,7 +2623,8 @@ int gmx_pme_do(gmx_pme_t pme,
             inc_nrnb(nrnb,eNR_SOLVEPME,loop_count);
         }
 
-        if (flags & GMX_PME_CALC_F)
+        if ((flags & GMX_PME_CALC_F) ||
+            (flags & GMX_PME_CALC_POT))
         {
             
             /* do 3d-invfft */
@@ -2652,7 +2657,10 @@ int gmx_pme_do(gmx_pme_t pme,
             }
 #endif
             where();
+        }
 
+        if (flags & GMX_PME_CALC_F)
+        {
             unwrap_periodic_pmegrid(pme,grid);
             
             /* interpolate forces for our local atoms */
index 0b05ab3670097d835c9bdba9826a62c5fd03cb22..18f8b7f6223a1bc5483e1d0f4afa843d8341f6d2 100644 (file)
@@ -29,7 +29,7 @@ add_library(gmxana
             gmx_editconf.c  gmx_genbox.c    gmx_genion.c    gmx_genconf.c   
             gmx_genpr.c     gmx_eneconv.c   gmx_vanhove.c   gmx_wheel.c     
             addconf.c       calcpot.c       edittop.c       gmx_bar.c
-            gmx_membed.c       gmx_pme_error.c )
+            gmx_pme_error.c    )
 
 
 target_link_libraries(gmxana md gmx)
@@ -51,7 +51,7 @@ set(GMX_TOOLS_PROGRAMS
     g_rmsf g_rotacf g_saltbr g_sas g_select g_sgangle g_sham g_sorient
     g_spol g_spatial g_tcaf g_traj g_tune_pme g_vanhove
     g_velacc g_clustsize g_mdmat g_wham g_sigeps g_bar
-    g_membed g_pme_error g_rmsdist g_rotmat)
+    g_pme_error g_rmsdist g_rotmat)
 
 
 
index 7aca3607601a4bcd426a27dce20ff849d775caae..7ce8dbc44a866d36da77bf5689d0ee877096dfd1 100644 (file)
@@ -37,7 +37,7 @@ libgmxana@LIBSUFFIX@_la_SOURCES = \
        gmx_polystat.c  gmx_potential.c gmx_rama.c      \
        gmx_rdf.c       gmx_rms.c       gmx_rmsdist.c   gmx_rmsf.c      \
        gmx_rotacf.c    gmx_rotmat.c    gmx_saltbr.c    gmx_sas.c       \
-       gmx_select.c    gmx_pme_error.c \
+       gmx_select.c    gmx_pme_error.c gmx_membed.c    \
        gmx_sgangle.c   gmx_sorient.c   gmx_spol.c      gmx_tcaf.c      \
        gmx_traj.c      gmx_velacc.c    gmx_helixorient.c \
        gmx_clustsize.c gmx_mdmat.c     gmx_wham.c      eigio.h         \
@@ -45,7 +45,7 @@ libgmxana@LIBSUFFIX@_la_SOURCES = \
        gmx_trjconv.c   gmx_trjcat.c    gmx_trjorder.c  gmx_xpm2ps.c    \
        gmx_editconf.c  gmx_genbox.c    gmx_genion.c    gmx_genconf.c   \
        gmx_genpr.c     gmx_eneconv.c   gmx_vanhove.c   gmx_wheel.c     \
-       addconf.c       addconf.h       gmx_tune_pme.c  gmx_membed.c    \
+       addconf.c       addconf.h       gmx_tune_pme.c  \
        calcpot.c       calcpot.h       edittop.c
 
 bin_PROGRAMS = \
@@ -64,7 +64,7 @@ bin_PROGRAMS = \
        g_enemat        g_energy        g_lie           g_filter        \
        g_gyrate        g_h2order       g_hbond         g_helix         \
        g_mindist       g_msd           g_morph         g_nmeig         \
-       g_nmens         g_order         \
+       g_nmens         g_order         g_membed        \
        g_polystat      g_potential     g_rama          \
        g_rdf           g_rms           g_rmsdist       g_rmsf          \
        g_rotacf        g_rotmat        g_saltbr        g_sas           \
@@ -72,7 +72,7 @@ bin_PROGRAMS = \
        g_sham          g_sorient       g_spol          \
        g_spatial       g_pme_error     \
        g_tcaf          g_traj          g_tune_pme   \
-       g_vanhove       g_velacc        g_membed      \
+       g_vanhove       g_velacc        \
        g_clustsize     g_mdmat         g_wham          \
        g_sigeps
 
index ce9a61aea8f6ebb07c0ee2353d7b80e4674da759..7ff0660a54f44f0e1bd30a1375271ed9685f73d1 100644 (file)
 #include "smalloc.h"
 #include "gstat.h"
 #include "gmx_fatal.h"
+#include "index.h"
        
 t_dlist *mk_dlist(FILE *log, 
                  t_atoms *atoms, int *nlist,
                  gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, gmx_bool bHChi,
-                 int maxchi,int r0,int naa,char **aa)
+                 int maxchi, int r0, gmx_residuetype_t rt)
 {
   int     ires,i,j,k,ii;
   t_dihatms atm,prev;
@@ -167,11 +168,7 @@ t_dlist *mk_dlist(FILE *log,
       }
       if ((atm.minC != -1) && (atm.minO != -1))
        nc[6]++;
-      for(k=0; (k<naa); k++) {
-       if (gmx_strcasecmp(aa[k],thisres) == 0)
-         break;
-      }
-      dl[nl].index=k;
+      dl[nl].index=gmx_residuetype_get_index(rt,thisres);
       
       sprintf(dl[nl].name,"%s%d",thisres,ires+r0);
       nl++;
index e97133fe0711374aaabe901cbc95eb6735216a32..bf18bdba3f31fba695b2ec3e0e06394c9042175f 100644 (file)
@@ -385,7 +385,7 @@ static int reset_em_all(int nlist,t_dlist dlist[],int nf,
   return j ; 
 }
 
-static void histogramming(FILE *log,int nbin, int naa,char **aa,
+static void histogramming(FILE *log,int nbin,gmx_residuetype_t rt,
                          int nf,int maxchi,real **dih,
                          int nlist,t_dlist dlist[],
                          atom_id index[],
@@ -426,7 +426,10 @@ static void histogramming(FILE *log,int nbin, int naa,char **aa,
   gmx_bool    bBfac,bOccup;
   char    hisfile[256],hhisfile[256],sshisfile[256],title[256],*ss_str=NULL;
   char **leg; 
-  
+  const char *residue_name;
+  int     rt_size;
+
+  rt_size = gmx_residuetype_get_size(rt);
   if (bSSHisto) {
     fp = ffopen(ssdump,"r");
     if(1 != fscanf(fp,"%d",&nres))
@@ -444,8 +447,8 @@ static void histogramming(FILE *log,int nbin, int naa,char **aa,
     /* Four dimensional array... Very cool */
     snew(his_aa_ss,3);
     for(i=0; (i<3); i++) {
-      snew(his_aa_ss[i],naa+1);
-      for(j=0; (j<=naa); j++) {
+      snew(his_aa_ss[i],rt_size+1);
+      for(j=0; (j<=rt_size); j++) {
        snew(his_aa_ss[i][j],edMax);
        for(Dih=0; (Dih<edMax); Dih++)
          snew(his_aa_ss[i][j][Dih],nbin+1);
@@ -454,8 +457,8 @@ static void histogramming(FILE *log,int nbin, int naa,char **aa,
   }
   snew(his_aa,edMax);
   for(Dih=0; (Dih<edMax); Dih++) {
-    snew(his_aa[Dih],naa+1);
-    for(i=0; (i<=naa); i++) {
+    snew(his_aa[Dih],rt_size+1);
+    for(i=0; (i<=rt_size); i++) {
       snew(his_aa[Dih][i],nbin+1);
     }
   }
@@ -611,7 +614,7 @@ static void histogramming(FILE *log,int nbin, int naa,char **aa,
   /* finished -jc stuff */ 
 
   snew(normhisto,nbin);
-  for(i=0; (i<naa); i++) {
+  for(i=0; (i<rt_size); i++) {
     for(Dih=0; (Dih<edMax); Dih++){
       /* First check whether something is in there */
       for(j=0; (j<nbin); j++)
@@ -625,23 +628,24 @@ static void histogramming(FILE *log,int nbin, int naa,char **aa,
        if (bNormalize)
          normalize_histo(nbin,his_aa[Dih][i],(360.0/nbin),normhisto);
        
+       residue_name = gmx_residuetype_get_name(rt,i);
        switch (Dih) {
        case edPhi:
-         sprintf(hisfile,"histo-phi%s",aa[i]);
-         sprintf(title,"\\xf\\f{} Distribution for %s",aa[i]);
+         sprintf(hisfile,"histo-phi%s",residue_name);
+         sprintf(title,"\\xf\\f{} Distribution for %s",residue_name);
          break;
        case edPsi:
-         sprintf(hisfile,"histo-psi%s",aa[i]);
-         sprintf(title,"\\xy\\f{} Distribution for %s",aa[i]);
+         sprintf(hisfile,"histo-psi%s",residue_name);
+         sprintf(title,"\\xy\\f{} Distribution for %s",residue_name);
          break;
        case edOmega:
-         sprintf(hisfile,"histo-omega%s",aa[i]);
-         sprintf(title,"\\xw\\f{} Distribution for %s",aa[i]);
+         sprintf(hisfile,"histo-omega%s",residue_name);
+         sprintf(title,"\\xw\\f{} Distribution for %s",residue_name);
          break;
        default:
-         sprintf(hisfile,"histo-chi%d%s",Dih-NONCHI+1,aa[i]);
+         sprintf(hisfile,"histo-chi%d%s",Dih-NONCHI+1,residue_name);
          sprintf(title,"\\xc\\f{}\\s%d\\N Distribution for %s",
-                 Dih-NONCHI+1,aa[i]);
+                 Dih-NONCHI+1,residue_name);
        }
        strcpy(hhisfile,hisfile);
        strcat(hhisfile,".xvg");
@@ -689,7 +693,7 @@ static void histogramming(FILE *log,int nbin, int naa,char **aa,
   if (bSSHisto) {
     /* Four dimensional array... Very cool */
     for(i=0; (i<3); i++) {
-      for(j=0; (j<=naa); j++) {
+      for(j=0; (j<=rt_size); j++) {
        for(Dih=0; (Dih<edMax); Dih++)
          sfree(his_aa_ss[i][j][Dih]);
        sfree(his_aa_ss[i][j]);
@@ -1113,18 +1117,18 @@ int gmx_chi(int argc,char *argv[])
   };
 
   FILE       *log;
-  int        natoms,nlist,naa,idum,nbin; 
+  int        natoms,nlist,idum,nbin;
   t_atoms    atoms;
   rvec       *x;
   int        ePBC;
   matrix     box;
   char       title[256],grpname[256]; 
   t_dlist    *dlist;
-  char       **aa;
   gmx_bool       bChi,bCorr,bSSHisto;
   gmx_bool       bDo_rt, bDo_oh, bDo_ot, bDo_jc ; 
   real       dt=0, traj_t_ns;
   output_env_t oenv;
+  gmx_residuetype_t rt;
   
   atom_id    isize,*index;
   int        ndih,nactdih,nf;
@@ -1203,8 +1207,8 @@ int gmx_chi(int argc,char *argv[])
   read_stx_conf(ftp2fn(efSTX,NFILE,fnm),title,&atoms,x,NULL,&ePBC,box);
   fprintf(log,"Title: %s\n",title);
   
-  naa=get_strings("aminoacids.dat",&aa);
-  dlist=mk_dlist(log,&atoms,&nlist,bPhi,bPsi,bChi,bHChi,maxchi,r0,naa,aa);
+  gmx_residuetype_init(&rt);
+  dlist=mk_dlist(log,&atoms,&nlist,bPhi,bPsi,bChi,bHChi,maxchi,r0,rt);
   fprintf(stderr,"%d residues with dihedrals found\n", nlist);
   
   if (nlist == 0) 
@@ -1239,7 +1243,7 @@ int gmx_chi(int argc,char *argv[])
     dump_em_all(nlist,dlist,nf,time,dih,maxchi,bPhi,bPsi,bChi,bOmega,bRAD,oenv);
   
   /* Histogramming & J coupling constants & calc of S2 order params */
-  histogramming(log,nbin,naa,aa,nf,maxchi,dih,nlist,dlist,index,
+  histogramming(log,nbin,rt,nf,maxchi,dih,nlist,dlist,index,
                bPhi,bPsi,bOmega,bChi,
                bNormHisto,bSSHisto,ftp2fn(efDAT,NFILE,fnm),bfac_max,&atoms,
                bDo_jc,opt2fn("-jc",NFILE,fnm),oenv);
@@ -1318,6 +1322,8 @@ int gmx_chi(int argc,char *argv[])
   if (bCorr)
     do_view(oenv,opt2fn("-corr",NFILE,fnm),"-nxy");
     
+  gmx_residuetype_destroy(rt);
+
   thanx(stderr);
     
   return 0;
index 0d0acae7f0d00e82e2740ebea95c739e741f8dd3..545dcb154bba99b8b2dfa377514d39edfbf87ec2 100644 (file)
@@ -365,8 +365,10 @@ void plot_density(real *slDensity[], const char *afile, int nslices,
 int gmx_density(int argc,char *argv[])
 {
   const char *desc[] = {
-    "Compute partial densities across the box, using an index file. Densities",
-    "in kg/m^3, number densities or electron densities can be",
+    "Compute partial densities across the box, using an index file.[PAR]",
+    "For the total density of NPT simulations, use [TT]g_energy[tt] instead.",
+    "[PAR]",
+    "Densities in kg/m^3, number densities or electron densities can be",
     "calculated. For electron densities, a file describing the number of",
     "electrons for each type of atom should be provided using [TT]-ei[tt].",
     "It should look like:[BR]",
index 1558c241b80f941bb5c0b72f3158c2c91c56bf8e..33d98b90b14082f6a268ce9fb971c0ed6a092428 100644 (file)
@@ -118,9 +118,8 @@ typedef struct {
 
 void sort_molecule(t_atoms **atoms_solvt,rvec *x,rvec *v,real *r)
 {
-  int atnr,i,j,moltp=0,nrmoltypes,resnr;
+  int atnr,i,j,moltp=0,nrmoltypes,resi_o,resi_n,resnr;
   t_moltypes *moltypes;
-  int *tps;
   t_atoms *atoms,*newatoms;
   rvec *newx, *newv=NULL;
   real *newr;
@@ -130,7 +129,6 @@ void sort_molecule(t_atoms **atoms_solvt,rvec *x,rvec *v,real *r)
   atoms = *atoms_solvt;
 
   /* copy each residue from *atoms to a molecule in *molecule */
-  snew(tps,atoms->nr);
   moltypes=NULL;
   nrmoltypes=0;
   atnr=0;
@@ -156,7 +154,6 @@ void sort_molecule(t_atoms **atoms_solvt,rvec *x,rvec *v,real *r)
       }
       moltypes[moltp].nmol++;
     }
-    tps[i]=moltp;
   }
   
   fprintf(stderr,"Found %d%s molecule type%s:\n",
@@ -189,18 +186,40 @@ void sort_molecule(t_atoms **atoms_solvt,rvec *x,rvec *v,real *r)
     if (v) snew(newv,atoms->nr);
     snew(newr,atoms->nr);
     
-    for (i=0; i<atoms->nr; i++) {
-      resnr = moltypes[tps[i]].res0 +
-       (moltypes[tps[i]].i-moltypes[tps[i]].i0) / moltypes[tps[i]].natoms;
-      newatoms->atom[moltypes[tps[i]].i].resind = resnr;
-      newatoms->resinfo[resnr] = atoms->resinfo[atoms->atom[i].resind];
-      newatoms->resinfo[resnr].nr = resnr + 1;
-      newatoms->atomname[moltypes[tps[i]].i] = atoms->atomname[i];
-      newatoms->atom[moltypes[tps[i]].i] = atoms->atom[i];
-      copy_rvec(x[i],newx[moltypes[tps[i]].i]);
-      if (v) copy_rvec(v[i],newv[moltypes[tps[i]].i]);
-      newr[moltypes[tps[i]].i] = r[i];
-      moltypes[tps[i]].i++;
+    resi_n = 0;
+    resnr = 1;
+    j = 0;
+    for(moltp=0; moltp<nrmoltypes; moltp++) {
+      i = 0;
+      while (i < atoms->nr) {
+       resi_o = atoms->atom[i].resind;
+       if (strcmp(*atoms->resinfo[resi_o].name,moltypes[moltp].name) == 0) {
+         /* Copy the residue info */
+         newatoms->resinfo[resi_n]    = atoms->resinfo[resi_o];
+         newatoms->resinfo[resi_n].nr = resnr;
+         /* Copy the atom info */
+         do {
+           newatoms->atom[j]        = atoms->atom[i];
+           newatoms->atomname[j]    = atoms->atomname[i];
+           newatoms->atom[j].resind = resi_n;
+           copy_rvec(x[i],newx[j]);
+           if (v != NULL) {
+             copy_rvec(v[i],newv[j]);
+           }
+           newr[j] = r[i];
+           i++;
+           j++;
+         } while (i < atoms->nr && atoms->atom[i].resind == resi_o);
+         /* Increase the new residue counters */
+         resi_n++;
+         resnr++;
+       } else {
+         /* Skip this residue */
+         do {
+           i++;
+         } while (i < atoms->nr && atoms->atom[i].resind == resi_o);
+       }
+      }
     }
     
     /* put them back into the original arrays and throw away temporary arrays */
index 9d81e5db38cb04acbe169c3a40f4111655abd2a1..86df2a18ff74603854ea486c1efba8c3885636b9 100644 (file)
 #include "main.h"
 #include "gmx_ana.h"
 
-#ifdef GMX_LIB_MPI
-#include <mpi.h>
-#endif
-#ifdef GMX_THREADS
-#include "tmpi.h"
-#endif
-
-/* afm stuf */
-#include "pull.h"
-
-/* We use the same defines as in mvdata.c here */
-#define  block_bc(cr,   d) gmx_bcast(     sizeof(d),     &(d),(cr))
-#define nblock_bc(cr,nr,d) gmx_bcast((nr)*sizeof((d)[0]), (d),(cr))
-#define   snew_bc(cr,d,nr) { if (!MASTER(cr)) snew((d),(nr)); }
-
-/* The following two variables and the signal_handler function
- * is used from pme.c as well
- */
-
-typedef struct {
-       t_state s;
-       rvec    *f;
-       real    epot;
-       real    fnorm;
-       real    fmax;
-       int     a_fmax;
-} em_state_t;
-
-typedef struct {
-       int    it_xy;
-       int    it_z;
-       int    xy_step;
-       int    z_step;
-       rvec    xmin;
-       rvec    xmax;
-       rvec    *geom_cent;
-       int    pieces;
-       int    *nidx;
-       atom_id **subindex;
-} pos_ins_t;
-
-typedef struct {
-       int             id;
-       char    *name;
-       int     nr;
-       int     natoms;     /*nr of atoms per lipid*/
-       int     mol1;       /*id of the first lipid molecule*/
-       real    area;
-} lip_t;
-
-typedef struct {
-       char    *name;
-       t_block mem_at;
-       int             *mol_id;
-       int             nmol;
-       real    lip_area;
-       real    zmin;
-       real    zmax;
-       real    zmed;
-} mem_t;
-
-typedef struct {
-       int             *mol;
-       int             *block;
-       int     nr;
-} rm_t;
-
-int search_string(char *s,int ng,char ***gn)
-{
-       int i;
-
-       for(i=0; (i<ng); i++)
-               if (gmx_strcasecmp(s,*gn[i]) == 0)
-                       return i;
-
-       gmx_fatal(FARGS,"Group %s not found in indexfile.\nMaybe you have non-default groups in your mdp file, while not using the '-n' option of grompp.\nIn that case use the '-n' option.\n",s);
-
-       return -1;
-}
-
-int get_mol_id(int at,int nmblock,gmx_molblock_t *mblock, int *type, int *block)
-{
-       int mol_id=0;
-       int i;
-
-       for(i=0;i<nmblock;i++)
-       {
-               if(at<(mblock[i].nmol*mblock[i].natoms_mol))
-               {
-                       mol_id+=at/mblock[i].natoms_mol;
-                       *type = mblock[i].type;
-                       *block = i;
-                       return mol_id;
-               } else {
-                       at-= mblock[i].nmol*mblock[i].natoms_mol;
-                       mol_id+=mblock[i].nmol;
-               }
-       }
-
-       gmx_fatal(FARGS,"Something is wrong in mol ids, at %d, mol_id %d",at,mol_id);
-
-       return -1;
-}
-
-int get_block(int mol_id,int nmblock,gmx_molblock_t *mblock)
-{
-       int i;
-       int nmol=0;
-
-       for(i=0;i<nmblock;i++)
-       {
-               nmol+=mblock[i].nmol;
-               if(mol_id<nmol)
-                       return i;
-       }
-
-       gmx_fatal(FARGS,"mol_id %d larger than total number of molecules %d.\n",mol_id,nmol);
-
-       return -1;
-}
-
-int get_tpr_version(const char *infile)
-{
-       char    buf[STRLEN];
-       gmx_bool        bDouble;
-       int     precision,fver;
-        t_fileio *fio;
-
-       fio = open_tpx(infile,"r");
-       gmx_fio_checktype(fio);
-
-       precision = sizeof(real);
-
-       gmx_fio_do_string(fio,buf);
-       if (strncmp(buf,"VERSION",7))
-               gmx_fatal(FARGS,"Can not read file %s,\n"
-                               "             this file is from a Gromacs version which is older than 2.0\n"
-                               "             Make a new one with grompp or use a gro or pdb file, if possible",
-                               gmx_fio_getname(fio));
-       gmx_fio_do_int(fio,precision);
-       bDouble = (precision == sizeof(double));
-       if ((precision != sizeof(float)) && !bDouble)
-               gmx_fatal(FARGS,"Unknown precision in file %s: real is %d bytes "
-                               "instead of %d or %d",
-                               gmx_fio_getname(fio),precision,sizeof(float),sizeof(double));
-       gmx_fio_setprecision(fio,bDouble);
-       fprintf(stderr,"Reading file %s, %s (%s precision)\n",
-                       gmx_fio_getname(fio),buf,bDouble ? "double" : "single");
-
-       gmx_fio_do_int(fio,fver);
-
-       close_tpx(fio);
-
-       return fver;
-}
-
-void set_inbox(int natom, rvec *x)
-{
-       rvec tmp;
-       int  i;
-
-       tmp[XX]=tmp[YY]=tmp[ZZ]=0.0;
-       for(i=0;i<natom;i++)
-       {
-               if(x[i][XX]<tmp[XX])            tmp[XX]=x[i][XX];
-               if(x[i][YY]<tmp[YY])            tmp[YY]=x[i][YY];
-               if(x[i][ZZ]<tmp[ZZ])            tmp[ZZ]=x[i][ZZ];
-       }
-
-       for(i=0;i<natom;i++)
-                       rvec_inc(x[i],tmp);
-}
-
-int get_mtype_list(t_block *at, gmx_mtop_t *mtop, t_block *tlist)
-{
-       int i,j,nr,mol_id;
-        int type=0,block=0;
-       gmx_bool bNEW;
-
-       nr=0;
-       snew(tlist->index,at->nr);
-       for (i=0;i<at->nr;i++)
-       {
-               bNEW=TRUE;
-               mol_id = get_mol_id(at->index[i],mtop->nmolblock,mtop->molblock,&type,&block);
-               for(j=0;j<nr;j++)
-               {
-                       if(tlist->index[j]==type)
-                                               bNEW=FALSE;
-               }
-               if(bNEW==TRUE)
-               {
-                       tlist->index[nr]=type;
-                       nr++;
-               }
-       }
-
-       srenew(tlist->index,nr);
-       return nr;
-}
-
-void check_types(t_block *ins_at,t_block *rest_at,gmx_mtop_t *mtop)
-{
-       t_block         *ins_mtype,*rest_mtype;
-       int                     i,j;
-
-       snew(ins_mtype,1);
-       snew(rest_mtype,1);
-    ins_mtype->nr  = get_mtype_list(ins_at , mtop, ins_mtype );
-    rest_mtype->nr = get_mtype_list(rest_at, mtop, rest_mtype);
-
-    for(i=0;i<ins_mtype->nr;i++)
-    {
-       for(j=0;j<rest_mtype->nr;j++)
-       {
-               if(ins_mtype->index[i]==rest_mtype->index[j])
-                       gmx_fatal(FARGS,"Moleculetype %s is found both in the group to insert and the rest of the system.\n"
-                                       "Because we need to exclude all interactions between the atoms in the group to\n"
-                                       "insert, the same moleculetype can not be used in both groups. Change the\n"
-                                       "moleculetype of the molecules %s in the inserted group. Do not forget to provide\n"
-                                       "an appropriate *.itp file",*(mtop->moltype[rest_mtype->index[j]].name),
-                                       *(mtop->moltype[rest_mtype->index[j]].name));
-       }
-    }
-
-    sfree(ins_mtype->index);
-    sfree(rest_mtype->index);
-    sfree(ins_mtype);
-    sfree(rest_mtype);
-}
-
-int init_ins_at(t_block *ins_at,t_block *rest_at,t_state *state, pos_ins_t *pos_ins,gmx_groups_t *groups,int ins_grp_id, real xy_max)
-{
-       int i,gid,c=0;
-       real x,xmin,xmax,y,ymin,ymax,z,zmin,zmax;
-
-       snew(rest_at->index,state->natoms);
-
-       xmin=xmax=state->x[ins_at->index[0]][XX];
-       ymin=ymax=state->x[ins_at->index[0]][YY];
-       zmin=zmax=state->x[ins_at->index[0]][ZZ];
-
-       for(i=0;i<state->natoms;i++)
-       {
-               gid = groups->grpnr[egcFREEZE][i];
-               if(groups->grps[egcFREEZE].nm_ind[gid]==ins_grp_id)
-               {
-                       x=state->x[i][XX];
-                       if (x<xmin)                     xmin=x;
-                       if (x>xmax)                     xmax=x;
-                       y=state->x[i][YY];
-                       if (y<ymin)                             ymin=y;
-                       if (y>ymax)                             ymax=y;
-                       z=state->x[i][ZZ];
-                       if (z<zmin)                             zmin=z;
-                       if (z>zmax)                             zmax=z;
-               } else {
-                       rest_at->index[c]=i;
-                       c++;
-               }
-       }
-
-       rest_at->nr=c;
-       srenew(rest_at->index,c);
-
-       if(xy_max>1.000001)
-       {
-               pos_ins->xmin[XX]=xmin-((xmax-xmin)*xy_max-(xmax-xmin))/2;
-               pos_ins->xmin[YY]=ymin-((ymax-ymin)*xy_max-(ymax-ymin))/2;
-
-               pos_ins->xmax[XX]=xmax+((xmax-xmin)*xy_max-(xmax-xmin))/2;
-               pos_ins->xmax[YY]=ymax+((ymax-ymin)*xy_max-(ymax-ymin))/2;
-       } else {
-               pos_ins->xmin[XX]=xmin;
-               pos_ins->xmin[YY]=ymin;
-
-               pos_ins->xmax[XX]=xmax;
-               pos_ins->xmax[YY]=ymax;
-       }
-
-       /* 6.0 is estimated thickness of bilayer */
-       if( (zmax-zmin) < 6.0 )
-       {
-               pos_ins->xmin[ZZ]=zmin+(zmax-zmin)/2.0-3.0;
-               pos_ins->xmax[ZZ]=zmin+(zmax-zmin)/2.0+3.0;
-       } else {
-               pos_ins->xmin[ZZ]=zmin;
-               pos_ins->xmax[ZZ]=zmax;
-       }
-
-       return c;
-}
-
-real est_prot_area(pos_ins_t *pos_ins,rvec *r,t_block *ins_at, mem_t *mem_p)
-{
-       real x,y,dx=0.15,dy=0.15,area=0.0;
-       real add;
-       int c,at;
-
-       for(x=pos_ins->xmin[XX];x<pos_ins->xmax[XX];x+=dx)
-       {
-               for(y=pos_ins->xmin[YY];y<pos_ins->xmax[YY];y+=dy)
-               {
-                       c=0;
-                       add=0.0;
-                       do
-                       {
-                               at=ins_at->index[c];
-                               if ( (r[at][XX]>=x) && (r[at][XX]<x+dx) &&
-                                               (r[at][YY]>=y) && (r[at][YY]<y+dy) &&
-                                               (r[at][ZZ]>mem_p->zmin+1.0) && (r[at][ZZ]<mem_p->zmax-1.0) )
-                                       add=1.0;
-                               c++;
-                       } while ( (c<ins_at->nr) && (add<0.5) );
-                       area+=add;
-               }
-       }
-       area=area*dx*dy;
-
-       return area;
-}
-
-void init_lip(matrix box, gmx_mtop_t *mtop, lip_t *lip)
-{
-       int i;
-       real mem_area;
-       int mol1=0;
-
-       mem_area = box[XX][XX]*box[YY][YY]-box[XX][YY]*box[YY][XX];
-       for(i=0;i<mtop->nmolblock;i++)
-       {
-               if(mtop->molblock[i].type == lip->id)
-               {
-                       lip->nr=mtop->molblock[i].nmol;
-                       lip->natoms=mtop->molblock[i].natoms_mol;
-               }
-       }
-       lip->area=2.0*mem_area/(double)lip->nr;
-
-       for (i=0;i<lip->id;i++)
-               mol1+=mtop->molblock[i].nmol;
-       lip->mol1=mol1;
-}
-
-int init_mem_at(mem_t *mem_p, gmx_mtop_t *mtop, rvec *r, matrix box, pos_ins_t *pos_ins)
-{
-       int i,j,at,mol,nmol,nmolbox,count;
-       t_block *mem_a;
-       real z,zmin,zmax,mem_area;
-       gmx_bool bNew;
-       atom_id *mol_id;
-       int type=0,block=0;
-
-       nmol=count=0;
-       mem_a=&(mem_p->mem_at);
-       snew(mol_id,mem_a->nr);
-/*     snew(index,mem_a->nr); */
-       zmin=pos_ins->xmax[ZZ];
-       zmax=pos_ins->xmin[ZZ];
-       for(i=0;i<mem_a->nr;i++)
-       {
-               at=mem_a->index[i];
-               if(     (r[at][XX]>pos_ins->xmin[XX]) && (r[at][XX]<pos_ins->xmax[XX]) &&
-                       (r[at][YY]>pos_ins->xmin[YY]) && (r[at][YY]<pos_ins->xmax[YY]) &&
-                       (r[at][ZZ]>pos_ins->xmin[ZZ]) && (r[at][ZZ]<pos_ins->xmax[ZZ]) )
-               {
-                       mol = get_mol_id(at,mtop->nmolblock,mtop->molblock,&type,&block);
-
-                       bNew=TRUE;
-                       for(j=0;j<nmol;j++)
-                               if(mol == mol_id[j])
-                                       bNew=FALSE;
-
-                       if(bNew)
-                       {
-                               mol_id[nmol]=mol;
-                               nmol++;
-                       }
-
-                       z=r[at][ZZ];
-                       if(z<zmin)                                      zmin=z;
-                       if(z>zmax)                                      zmax=z;
-
-/*                     index[count]=at;*/
-                       count++;
-               }
-       }
-
-       mem_p->nmol=nmol;
-       srenew(mol_id,nmol);
-       mem_p->mol_id=mol_id;
-/*     srenew(index,count);*/
-/*     mem_p->mem_at.nr=count;*/
-/*     sfree(mem_p->mem_at.index);*/
-/*     mem_p->mem_at.index=index;*/
-
-       if((zmax-zmin)>(box[ZZ][ZZ]-0.5))
-               gmx_fatal(FARGS,"Something is wrong with your membrane. Max and min z values are %f and %f.\n"
-                               "Maybe your membrane is not centered in the box, but located at the box edge in the z-direction,\n"
-                               "so that one membrane is distributed over two periodic box images. Another possibility is that\n"
-                               "your water layer is not thick enough.\n",zmax,zmin);
-       mem_p->zmin=zmin;
-       mem_p->zmax=zmax;
-       mem_p->zmed=(zmax-zmin)/2+zmin;
-
-       /*number of membrane molecules in protein box*/
-       nmolbox = count/mtop->molblock[block].natoms_mol;
-       /*mem_area = box[XX][XX]*box[YY][YY]-box[XX][YY]*box[YY][XX];
-       mem_p->lip_area = 2.0*mem_area/(double)mem_p->nmol;*/
-       mem_area = (pos_ins->xmax[XX]-pos_ins->xmin[XX])*(pos_ins->xmax[YY]-pos_ins->xmin[YY]);
-       mem_p->lip_area = 2.0*mem_area/(double)nmolbox;
-
-       return mem_p->mem_at.nr;
-}
-
-void init_resize(t_block *ins_at,rvec *r_ins,pos_ins_t *pos_ins,mem_t *mem_p,rvec *r, gmx_bool bALLOW_ASYMMETRY)
-{
-       int i,j,at,c,outsidesum,gctr=0;
-    int idxsum=0;
-
-    /*sanity check*/
-    for (i=0;i<pos_ins->pieces;i++)
-          idxsum+=pos_ins->nidx[i];
-    if (idxsum!=ins_at->nr)
-          gmx_fatal(FARGS,"Piecewise sum of inserted atoms not same as size of group selected to insert.");
-
-    snew(pos_ins->geom_cent,pos_ins->pieces);
-    for (i=0;i<pos_ins->pieces;i++)
-    {
-       c=0;
-       outsidesum=0;
-       for(j=0;j<DIM;j++)
-               pos_ins->geom_cent[i][j]=0;
-
-       for(j=0;j<DIM;j++)
-               pos_ins->geom_cent[i][j]=0;
-       for (j=0;j<pos_ins->nidx[i];j++)
-       {
-               at=pos_ins->subindex[i][j];
-               copy_rvec(r[at],r_ins[gctr]);
-               if( (r_ins[gctr][ZZ]<mem_p->zmax) && (r_ins[gctr][ZZ]>mem_p->zmin) )
-               {
-                       rvec_inc(pos_ins->geom_cent[i],r_ins[gctr]);
-                       c++;
-               }
-               else
-                       outsidesum++;
-               gctr++;
-       }
-       if (c>0)
-               svmul(1/(double)c,pos_ins->geom_cent[i],pos_ins->geom_cent[i]);
-       if (!bALLOW_ASYMMETRY)
-               pos_ins->geom_cent[i][ZZ]=mem_p->zmed;
-
-       fprintf(stderr,"Embedding piece %d with center of geometry: %f %f %f\n",i,pos_ins->geom_cent[i][XX],pos_ins->geom_cent[i][YY],pos_ins->geom_cent[i][ZZ]);
-    }
-    fprintf(stderr,"\n");
-}
-
-void resize(t_block *ins_at, rvec *r_ins, rvec *r, pos_ins_t *pos_ins,rvec fac)
-{
-       int i,j,k,at,c=0;
-       for (k=0;k<pos_ins->pieces;k++)
-               for(i=0;i<pos_ins->nidx[k];i++)
-               {
-                       at=pos_ins->subindex[k][i];
-                       for(j=0;j<DIM;j++)
-                               r[at][j]=pos_ins->geom_cent[k][j]+fac[j]*(r_ins[c][j]-pos_ins->geom_cent[k][j]);
-                       c++;
-               }
-}
-
-int gen_rm_list(rm_t *rm_p,t_block *ins_at,t_block *rest_at,t_pbc *pbc, gmx_mtop_t *mtop,
-               rvec *r, rvec *r_ins, mem_t *mem_p, pos_ins_t *pos_ins, real probe_rad, int low_up_rm, gmx_bool bALLOW_ASYMMETRY)
-{
-       int i,j,k,l,at,at2,mol_id;
-        int type=0,block=0;
-       int nrm,nupper,nlower;
-       real r_min_rad,z_lip,min_norm;
-       gmx_bool bRM;
-       rvec dr,dr_tmp;
-       real *dist;
-       int *order;
-
-       r_min_rad=probe_rad*probe_rad;
-       snew(rm_p->mol,mtop->mols.nr);
-       snew(rm_p->block,mtop->mols.nr);
-       nrm=nupper=0;
-       nlower=low_up_rm;
-       for(i=0;i<ins_at->nr;i++)
-       {
-               at=ins_at->index[i];
-               for(j=0;j<rest_at->nr;j++)
-               {
-                       at2=rest_at->index[j];
-                       pbc_dx(pbc,r[at],r[at2],dr);
-
-                       if(norm2(dr)<r_min_rad)
-                       {
-                               mol_id = get_mol_id(at2,mtop->nmolblock,mtop->molblock,&type,&block);
-                               bRM=TRUE;
-                               for(l=0;l<nrm;l++)
-                                       if(rm_p->mol[l]==mol_id)
-                                               bRM=FALSE;
-                               if(bRM)
-                               {
-                                       /*fprintf(stderr,"%d wordt toegevoegd\n",mol_id);*/
-                                       rm_p->mol[nrm]=mol_id;
-                                       rm_p->block[nrm]=block;
-                                       nrm++;
-                                       z_lip=0.0;
-                                       for(l=0;l<mem_p->nmol;l++)
-                                       {
-                                               if(mol_id==mem_p->mol_id[l])
-                                               {
-                                                       for(k=mtop->mols.index[mol_id];k<mtop->mols.index[mol_id+1];k++)
-                                                               z_lip+=r[k][ZZ];
-                                                       z_lip/=mtop->molblock[block].natoms_mol;
-                                                       if(z_lip<mem_p->zmed)
-                                                               nlower++;
-                                                       else
-                                                               nupper++;
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-
-       /*make sure equal number of lipids from upper and lower layer are removed */
-       if( (nupper!=nlower) && (!bALLOW_ASYMMETRY) )
-       {
-               snew(dist,mem_p->nmol);
-               snew(order,mem_p->nmol);
-               for(i=0;i<mem_p->nmol;i++)
-               {
-                       at = mtop->mols.index[mem_p->mol_id[i]];
-                       pbc_dx(pbc,r[at],pos_ins->geom_cent[0],dr);
-                       if (pos_ins->pieces>1)
-                       {
-                               /*minimum dr value*/
-                               min_norm=norm2(dr);
-                               for (k=1;k<pos_ins->pieces;k++)
-                               {
-                                       pbc_dx(pbc,r[at],pos_ins->geom_cent[k],dr_tmp);
-                                       if (norm2(dr_tmp) < min_norm)
-                                       {
-                                               min_norm=norm2(dr_tmp);
-                                               copy_rvec(dr_tmp,dr);
-                                       }
-                               }
-                       }
-                       dist[i]=dr[XX]*dr[XX]+dr[YY]*dr[YY];
-                       j=i-1;
-                       while (j>=0 && dist[i]<dist[order[j]])
-                       {
-                               order[j+1]=order[j];
-                               j--;
-                       }
-                       order[j+1]=i;
-               }
-
-               i=0;
-               while(nupper!=nlower)
-               {
-                       mol_id=mem_p->mol_id[order[i]];
-                       block=get_block(mol_id,mtop->nmolblock,mtop->molblock);
-
-                       bRM=TRUE;
-                       for(l=0;l<nrm;l++)
-                               if(rm_p->mol[l]==mol_id)
-                                       bRM=FALSE;
-                       if(bRM)
-                       {
-                               z_lip=0;
-                               for(k=mtop->mols.index[mol_id];k<mtop->mols.index[mol_id+1];k++)
-                                       z_lip+=r[k][ZZ];
-                               z_lip/=mtop->molblock[block].natoms_mol;
-                               if(nupper>nlower && z_lip<mem_p->zmed)
-                               {
-                                       rm_p->mol[nrm]=mol_id;
-                                       rm_p->block[nrm]=block;
-                                       nrm++;
-                                       nlower++;
-                               }
-                               else if (nupper<nlower && z_lip>mem_p->zmed)
-                               {
-                                       rm_p->mol[nrm]=mol_id;
-                                       rm_p->block[nrm]=block;
-                                       nrm++;
-                                       nupper++;
-                               }
-                       }
-                       i++;
-
-                       if(i>mem_p->nmol)
-                               gmx_fatal(FARGS,"Trying to remove more lipid molecules than there are in the membrane");
-               }
-               sfree(dist);
-               sfree(order);
-       }
-
-       rm_p->nr=nrm;
-       srenew(rm_p->mol,nrm);
-       srenew(rm_p->block,nrm);
-
-       return nupper+nlower;
-}
-
-void rm_group(t_inputrec *ir, gmx_groups_t *groups, gmx_mtop_t *mtop, rm_t *rm_p, t_state *state, t_block *ins_at, pos_ins_t *pos_ins)
-{
-       int i,j,k,n,rm,mol_id,at,block;
-       rvec *x_tmp,*v_tmp;
-       atom_id *list,*new_mols;
-       unsigned char  *new_egrp[egcNR];
-       gmx_bool bRM;
-
-       snew(list,state->natoms);
-       n=0;
-       for(i=0;i<rm_p->nr;i++)
-       {
-               mol_id=rm_p->mol[i];
-               at=mtop->mols.index[mol_id];
-               block =rm_p->block[i];
-               mtop->molblock[block].nmol--;
-               for(j=0;j<mtop->molblock[block].natoms_mol;j++)
-               {
-                       list[n]=at+j;
-                       n++;
-               }
-
-               mtop->mols.index[mol_id]=-1;
-       }
-
-       mtop->mols.nr-=rm_p->nr;
-       mtop->mols.nalloc_index-=rm_p->nr;
-       snew(new_mols,mtop->mols.nr);
-       for(i=0;i<mtop->mols.nr+rm_p->nr;i++)
-       {
-               j=0;
-               if(mtop->mols.index[i]!=-1)
-               {
-                       new_mols[j]=mtop->mols.index[i];
-                       j++;
-               }
-       }
-       sfree(mtop->mols.index);
-       mtop->mols.index=new_mols;
-
-
-       mtop->natoms-=n;
-       state->natoms-=n;
-       state->nalloc=state->natoms;
-       snew(x_tmp,state->nalloc);
-       snew(v_tmp,state->nalloc);
-
-       for(i=0;i<egcNR;i++)
-       {
-               if(groups->grpnr[i]!=NULL)
-               {
-                       groups->ngrpnr[i]=state->natoms;
-                       snew(new_egrp[i],state->natoms);
-               }
-       }
-
-       rm=0;
-       for (i=0;i<state->natoms+n;i++)
-       {
-               bRM=FALSE;
-               for(j=0;j<n;j++)
-               {
-                       if(i==list[j])
-                       {
-                               bRM=TRUE;
-                               rm++;
-                       }
-               }
-
-               if(!bRM)
-               {
-                       for(j=0;j<egcNR;j++)
-                       {
-                               if(groups->grpnr[j]!=NULL)
-                               {
-                                       new_egrp[j][i-rm]=groups->grpnr[j][i];
-                               }
-                       }
-                       copy_rvec(state->x[i],x_tmp[i-rm]);
-                       copy_rvec(state->v[i],v_tmp[i-rm]);
-                       for(j=0;j<ins_at->nr;j++)
-                       {
-                               if (i==ins_at->index[j])
-                                       ins_at->index[j]=i-rm;
-                       }
-                       for(j=0;j<pos_ins->pieces;j++)
-                       {
-                               for(k=0;k<pos_ins->nidx[j];k++)
-                               {
-                                       if (i==pos_ins->subindex[j][k])
-                                               pos_ins->subindex[j][k]=i-rm;
-                               }
-                       }
-               }
-       }
-       sfree(state->x);
-       state->x=x_tmp;
-       sfree(state->v);
-       state->v=v_tmp;
-
-       for(i=0;i<egcNR;i++)
-       {
-               if(groups->grpnr[i]!=NULL)
-               {
-                       sfree(groups->grpnr[i]);
-                       groups->grpnr[i]=new_egrp[i];
-               }
-       }
-}
-
-int rm_bonded(t_block *ins_at, gmx_mtop_t *mtop)
-{
-       int i,j,m;
-       int type,natom,nmol,at,atom1=0,rm_at=0;
-       gmx_bool *bRM,bINS;
-       /*this routine lives dangerously by assuming that all molecules of a given type are in order in the structure*/
-       /*this routine does not live as dangerously as it seems. There is namely a check in mdrunner_membed to make
-         *sure that g_membed exits with a warning when there are molecules of the same type not in the 
-        *ins_at index group. MGWolf 050710 */
-
-
-       snew(bRM,mtop->nmoltype);
-       for (i=0;i<mtop->nmoltype;i++)
-       {
-               bRM[i]=TRUE;
-       }
-
-       for (i=0;i<mtop->nmolblock;i++) 
-       {
-           /*loop over molecule blocks*/
-               type        =mtop->molblock[i].type;
-               natom       =mtop->molblock[i].natoms_mol;
-               nmol            =mtop->molblock[i].nmol;
-
-               for(j=0;j<natom*nmol && bRM[type]==TRUE;j++) 
-               {
-                   /*loop over atoms in the block*/
-                       at=j+atom1; /*atom index = block index + offset*/
-                       bINS=FALSE;
-
-                       for (m=0;(m<ins_at->nr) && (bINS==FALSE);m++)
-                       {
-                           /*loop over atoms in insertion index group to determine if we're inserting one*/
-                               if(at==ins_at->index[m])
-                               {
-                                       bINS=TRUE;
-                               }
-                       }
-                       bRM[type]=bINS;
-               }
-               atom1+=natom*nmol; /*update offset*/
-               if(bRM[type])
-               {
-                       rm_at+=natom*nmol; /*increment bonded removal counter by # atoms in block*/
-               }
-       }
-
-       for(i=0;i<mtop->nmoltype;i++)
-       {
-               if(bRM[i])
-               {
-                       for(j=0;j<F_LJ;j++)
-                       {
-                               mtop->moltype[i].ilist[j].nr=0;
-                       }
-                       for(j=F_POSRES;j<=F_VSITEN;j++)
-                       {
-                               mtop->moltype[i].ilist[j].nr=0;
-                       }
-               }
-       }
-       sfree(bRM);
-
-       return rm_at;
-}
-
-void top_update(const char *topfile, char *ins, rm_t *rm_p, gmx_mtop_t *mtop)
-{
-#define TEMP_FILENM "temp.top"
-       int     bMolecules=0;
-       FILE    *fpin,*fpout;
-       char    buf[STRLEN],buf2[STRLEN],*temp;
-       int             i,*nmol_rm,nmol,line;
-
-       fpin  = ffopen(topfile,"r");
-       fpout = ffopen(TEMP_FILENM,"w");
-
-       snew(nmol_rm,mtop->nmoltype);
-       for(i=0;i<rm_p->nr;i++)
-               nmol_rm[rm_p->block[i]]++;
-
-       line=0;
-       while(fgets(buf,STRLEN,fpin))
-       {
-               line++;
-               if(buf[0]!=';')
-               {
-                       strcpy(buf2,buf);
-                       if ((temp=strchr(buf2,'\n')) != NULL)
-                               temp[0]='\0';
-                       ltrim(buf2);
-
-                       if (buf2[0]=='[')
-                       {
-                               buf2[0]=' ';
-                               if ((temp=strchr(buf2,'\n')) != NULL)
-                                       temp[0]='\0';
-                               rtrim(buf2);
-                               if (buf2[strlen(buf2)-1]==']')
-                               {
-                                       buf2[strlen(buf2)-1]='\0';
-                                       ltrim(buf2);
-                                       rtrim(buf2);
-                                       if (gmx_strcasecmp(buf2,"molecules")==0)
-                                               bMolecules=1;
-                               }
-                               fprintf(fpout,"%s",buf);
-                       } else if (bMolecules==1)
-                       {
-                               for(i=0;i<mtop->nmolblock;i++)
-                               {
-                                       nmol=mtop->molblock[i].nmol;
-                                       sprintf(buf,"%-15s %5d\n",*(mtop->moltype[mtop->molblock[i].type].name),nmol);
-                                       fprintf(fpout,"%s",buf);
-                               }
-                               bMolecules=2;
-                       } else if (bMolecules==2)
-                       {
-                               /* print nothing */
-                       } else 
-                       {
-                               fprintf(fpout,"%s",buf);
-                       }
-               } else 
-               {
-                       fprintf(fpout,"%s",buf);
-               }
-       }
-
-       fclose(fpout);
-       /* use ffopen to generate backup of topinout */
-       fpout=ffopen(topfile,"w");
-       fclose(fpout);
-       rename(TEMP_FILENM,topfile);
-#undef TEMP_FILENM
-}
-
-void md_print_warning(const t_commrec *cr,FILE *fplog,const char *buf)
-{
-    if (MASTER(cr))
-    {
-        fprintf(stderr,"\n%s\n",buf);
-    }
-    if (fplog)
-    {
-        fprintf(fplog,"\n%s\n",buf);
-    }
-}
-
-/*  simulation conditions to transmit. Keep in mind that they are
-    transmitted to other nodes through an MPI_Reduce after
-    casting them to a real (so the signals can be sent together with other
-    data). This means that the only meaningful values are positive,
-    negative or zero. */
-enum { eglsNABNSB, eglsCHKPT, eglsSTOPCOND, eglsRESETCOUNTERS, eglsNR };
-/* Is the signal in one simulation independent of other simulations? */
-gmx_bool gs_simlocal[eglsNR] = { TRUE, FALSE, FALSE, TRUE };
-
-typedef struct {
-    int nstms;       /* The frequency for intersimulation communication */
-    int sig[eglsNR]; /* The signal set by one process in do_md */
-    int set[eglsNR]; /* The communicated signal, equal for all processes */
-} globsig_t;
-
-
-static int multisim_min(const gmx_multisim_t *ms,int nmin,int n)
-{
-    int  *buf;
-    gmx_bool bPos,bEqual;
-    int  s,d;
-
-    snew(buf,ms->nsim);
-    buf[ms->sim] = n;
-    gmx_sumi_sim(ms->nsim,buf,ms);
-    bPos   = TRUE;
-    bEqual = TRUE;
-    for(s=0; s<ms->nsim; s++)
-    {
-        bPos   = bPos   && (buf[s] > 0);
-        bEqual = bEqual && (buf[s] == buf[0]);
-    }
-    if (bPos)
-    {
-        if (bEqual)
-        {
-            nmin = min(nmin,buf[0]);
-        }
-        else
-        {
-            /* Find the least common multiple */
-            for(d=2; d<nmin; d++)
-            {
-                s = 0;
-                while (s < ms->nsim && d % buf[s] == 0)
-                {
-                    s++;
-                }
-                if (s == ms->nsim)
-                {
-                    /* We found the LCM and it is less than nmin */
-                    nmin = d;
-                    break;
-                }
-            }
-        }
-    }
-    sfree(buf);
-
-    return nmin;
-}
-
-static int multisim_nstsimsync(const t_commrec *cr,
-                               const t_inputrec *ir,int repl_ex_nst)
-{
-    int nmin;
-
-    if (MASTER(cr))
-    {
-        nmin = INT_MAX;
-        nmin = multisim_min(cr->ms,nmin,ir->nstlist);
-        nmin = multisim_min(cr->ms,nmin,ir->nstcalcenergy);
-        nmin = multisim_min(cr->ms,nmin,repl_ex_nst);
-        if (nmin == INT_MAX)
-        {
-            gmx_fatal(FARGS,"Can not find an appropriate interval for inter-simulation communication, since nstlist, nstcalcenergy and -replex are all <= 0");
-        }
-        /* Avoid inter-simulation communication at every (second) step */
-        if (nmin <= 2)
-        {
-            nmin = 10;
-        }
-    }
-
-    gmx_bcast(sizeof(int),&nmin,cr);
-
-    return nmin;
-}
-
-static void init_global_signals(globsig_t *gs,const t_commrec *cr,
-                                const t_inputrec *ir,int repl_ex_nst)
-{
-    int i;
-
-    if (MULTISIM(cr))
-    {
-        gs->nstms = multisim_nstsimsync(cr,ir,repl_ex_nst);
-        if (debug)
-        {
-            fprintf(debug,"Syncing simulations for checkpointing and termination every %d steps\n",gs->nstms);
-        }
-    }
-    else
-    {
-        gs->nstms = 1;
-    }
-
-    for(i=0; i<eglsNR; i++)
-    {
-        gs->sig[i] = 0;
-        gs->set[i] = 0;
-    }
-}
-
-static void copy_coupling_state(t_state *statea,t_state *stateb,
-                                gmx_ekindata_t *ekinda,gmx_ekindata_t *ekindb, t_grpopts* opts)
-{
-
-    /* MRS note -- might be able to get rid of some of the arguments.  Look over it when it's all debugged */
-
-    int i,j,nc;
-
-    /* Make sure we have enough space for x and v */
-    if (statea->nalloc > stateb->nalloc)
-    {
-        stateb->nalloc = statea->nalloc;
-        srenew(stateb->x,stateb->nalloc);
-        srenew(stateb->v,stateb->nalloc);
-    }
-
-    stateb->natoms     = statea->natoms;
-    stateb->ngtc       = statea->ngtc;
-    stateb->nnhpres    = statea->nnhpres;
-    stateb->veta       = statea->veta;
-    if (ekinda)
-    {
-        copy_mat(ekinda->ekin,ekindb->ekin);
-        for (i=0; i<stateb->ngtc; i++)
-        {
-            ekindb->tcstat[i].T = ekinda->tcstat[i].T;
-            ekindb->tcstat[i].Th = ekinda->tcstat[i].Th;
-            copy_mat(ekinda->tcstat[i].ekinh,ekindb->tcstat[i].ekinh);
-            copy_mat(ekinda->tcstat[i].ekinf,ekindb->tcstat[i].ekinf);
-            ekindb->tcstat[i].ekinscalef_nhc =  ekinda->tcstat[i].ekinscalef_nhc;
-            ekindb->tcstat[i].ekinscaleh_nhc =  ekinda->tcstat[i].ekinscaleh_nhc;
-            ekindb->tcstat[i].vscale_nhc =  ekinda->tcstat[i].vscale_nhc;
-        }
-    }
-    copy_rvecn(statea->x,stateb->x,0,stateb->natoms);
-    copy_rvecn(statea->v,stateb->v,0,stateb->natoms);
-    copy_mat(statea->box,stateb->box);
-    copy_mat(statea->box_rel,stateb->box_rel);
-    copy_mat(statea->boxv,stateb->boxv);
-
-    for (i = 0; i<stateb->ngtc; i++)
-    {
-        nc = i*opts->nhchainlength;
-        for (j=0; j<opts->nhchainlength; j++)
-        {
-            stateb->nosehoover_xi[nc+j]  = statea->nosehoover_xi[nc+j];
-            stateb->nosehoover_vxi[nc+j] = statea->nosehoover_vxi[nc+j];
-        }
-    }
-    if (stateb->nhpres_xi != NULL)
-    {
-        for (i = 0; i<stateb->nnhpres; i++)
-        {
-            nc = i*opts->nhchainlength;
-            for (j=0; j<opts->nhchainlength; j++)
-            {
-                stateb->nhpres_xi[nc+j]  = statea->nhpres_xi[nc+j];
-                stateb->nhpres_vxi[nc+j] = statea->nhpres_vxi[nc+j];
-            }
-        }
-    }
-}
-
-static void compute_globals(FILE *fplog, gmx_global_stat_t gstat, t_commrec *cr, t_inputrec *ir,
-                            t_forcerec *fr, gmx_ekindata_t *ekind,
-                            t_state *state, t_state *state_global, t_mdatoms *mdatoms,
-                            t_nrnb *nrnb, t_vcm *vcm, gmx_wallcycle_t wcycle,
-                            gmx_enerdata_t *enerd,tensor force_vir, tensor shake_vir, tensor total_vir,
-                            tensor pres, rvec mu_tot, gmx_constr_t constr,
-                            globsig_t *gs,gmx_bool bInterSimGS,
-                            matrix box, gmx_mtop_t *top_global, real *pcurr,
-                            int natoms, gmx_bool *bSumEkinhOld, int flags)
-{
-    int  i,gsi;
-    real gs_buf[eglsNR];
-    tensor corr_vir,corr_pres;
-    gmx_bool bEner,bPres,bTemp;
-    gmx_bool bRerunMD, bStopCM, bGStat, bIterate,
-        bFirstIterate,bReadEkin,bEkinAveVel,bScaleEkin, bConstrain;
-    real prescorr,enercorr,dvdlcorr;
-
-    /* translate CGLO flags to gmx_booleans */
-    bRerunMD = flags & CGLO_RERUNMD;
-    bStopCM = flags & CGLO_STOPCM;
-    bGStat = flags & CGLO_GSTAT;
-    bReadEkin = (flags & CGLO_READEKIN);
-    bScaleEkin = (flags & CGLO_SCALEEKIN);
-    bEner = flags & CGLO_ENERGY;
-    bTemp = flags & CGLO_TEMPERATURE;
-    bPres  = (flags & CGLO_PRESSURE);
-    bConstrain = (flags & CGLO_CONSTRAINT);
-    bIterate = (flags & CGLO_ITERATE);
-    bFirstIterate = (flags & CGLO_FIRSTITERATE);
-
-    /* we calculate a full state kinetic energy either with full-step velocity verlet
-       or half step where we need the pressure */
-    bEkinAveVel = (ir->eI==eiVV || (ir->eI==eiVVAK && IR_NPT_TROTTER(ir) && bPres) || bReadEkin);
-
-    /* in initalization, it sums the shake virial in vv, and to
-       sums ekinh_old in leapfrog (or if we are calculating ekinh_old for other reasons */
-
-    /* ########## Kinetic energy  ############## */
-
-    if (bTemp)
-    {
-        /* Non-equilibrium MD: this is parallellized, but only does communication
-         * when there really is NEMD.
-         */
-
-        if (PAR(cr) && (ekind->bNEMD))
-        {
-            accumulate_u(cr,&(ir->opts),ekind);
-        }
-        debug_gmx();
-        if (bReadEkin)
-        {
-            restore_ekinstate_from_state(cr,ekind,&state_global->ekinstate);
-        }
-        else
-        {
-
-            calc_ke_part(state,&(ir->opts),mdatoms,ekind,nrnb,bEkinAveVel,bIterate);
-        }
-
-        debug_gmx();
-
-        /* Calculate center of mass velocity if necessary, also parallellized */
-        if (bStopCM && !bRerunMD && bEner)
-        {
-            calc_vcm_grp(fplog,mdatoms->start,mdatoms->homenr,mdatoms,
-                         state->x,state->v,vcm);
-        }
-    }
-
-    if (bTemp || bPres || bEner || bConstrain)
-    {
-        if (!bGStat)
-        {
-            /* We will not sum ekinh_old,
-             * so signal that we still have to do it.
-             */
-            *bSumEkinhOld = TRUE;
-
-        }
-        else
-        {
-            if (gs != NULL)
-            {
-                for(i=0; i<eglsNR; i++)
-                {
-                    gs_buf[i] = gs->sig[i];
-                }
-            }
-            if (PAR(cr))
-            {
-                wallcycle_start(wcycle,ewcMoveE);
-                GMX_MPE_LOG(ev_global_stat_start);
-                global_stat(fplog,gstat,cr,enerd,force_vir,shake_vir,mu_tot,
-                            ir,ekind,constr,vcm,
-                            gs != NULL ? eglsNR : 0,gs_buf,
-                            top_global,state,
-                            *bSumEkinhOld,flags);
-                GMX_MPE_LOG(ev_global_stat_finish);
-                wallcycle_stop(wcycle,ewcMoveE);
-            }
-            if (gs != NULL)
-            {
-                if (MULTISIM(cr) && bInterSimGS)
-                {
-                    if (MASTER(cr))
-                    {
-                        /* Communicate the signals between the simulations */
-                        gmx_sum_sim(eglsNR,gs_buf,cr->ms);
-                    }
-                    /* Communicate the signals form the master to the others */
-                    gmx_bcast(eglsNR*sizeof(gs_buf[0]),gs_buf,cr);
-                }
-                for(i=0; i<eglsNR; i++)
-                {
-                    if (bInterSimGS || gs_simlocal[i])
-                    {
-                        /* Set the communicated signal only when it is non-zero,
-                         * since signals might not be processed at each MD step.
-                         */
-                        gsi = (gs_buf[i] >= 0 ?
-                               (int)(gs_buf[i] + 0.5) :
-                               (int)(gs_buf[i] - 0.5));
-                        if (gsi != 0)
-                        {
-                            gs->set[i] = gsi;
-                        }
-                        /* Turn off the local signal */
-                        gs->sig[i] = 0;
-                    }
-                }
-            }
-            *bSumEkinhOld = FALSE;
-        }
-    }
-
-    if (!ekind->bNEMD && debug && bTemp && (vcm->nr > 0))
-    {
-        correct_ekin(debug,
-                     mdatoms->start,mdatoms->start+mdatoms->homenr,
-                     state->v,vcm->group_p[0],
-                     mdatoms->massT,mdatoms->tmass,ekind->ekin);
-    }
-
-    if (bEner) {
-        /* Do center of mass motion removal */
-        if (bStopCM && !bRerunMD) /* is this correct?  Does it get called too often with this logic? */
-        {
-            check_cm_grp(fplog,vcm,ir,1);
-            do_stopcm_grp(fplog,mdatoms->start,mdatoms->homenr,mdatoms->cVCM,
-                          state->x,state->v,vcm);
-            inc_nrnb(nrnb,eNR_STOPCM,mdatoms->homenr);
-        }
-    }
-
-    if (bTemp)
-    {
-        /* Sum the kinetic energies of the groups & calc temp */
-        /* compute full step kinetic energies if vv, or if vv-avek and we are computing the pressure with IR_NPT_TROTTER */
-        /* three maincase:  VV with AveVel (md-vv), vv with AveEkin (md-vv-avek), leap with AveEkin (md).
-           Leap with AveVel is also an option for the future but not supported now.
-           bEkinAveVel: If TRUE, we simply multiply ekin by ekinscale to get a full step kinetic energy.
-           If FALSE, we average ekinh_old and ekinh*ekinscale_nhc to get an averaged half step kinetic energy.
-           bSaveEkinOld: If TRUE (in the case of iteration = bIterate is TRUE), we don't reset the ekinscale_nhc.
-           If FALSE, we go ahead and erase over it.
-        */
-        enerd->term[F_TEMP] = sum_ekin(&(ir->opts),ekind,&(enerd->term[F_DKDL]),
-                                       bEkinAveVel,bIterate,bScaleEkin);
-
-        enerd->term[F_EKIN] = trace(ekind->ekin);
-    }
-
-    /* ##########  Long range energy information ###### */
-
-    if (bEner || bPres || bConstrain)
-    {
-        calc_dispcorr(fplog,ir,fr,0,top_global->natoms,box,state->lambda,
-                      corr_pres,corr_vir,&prescorr,&enercorr,&dvdlcorr);
-    }
-
-    if (bEner && bFirstIterate)
-    {
-        enerd->term[F_DISPCORR] = enercorr;
-        enerd->term[F_EPOT] += enercorr;
-        enerd->term[F_DVDL] += dvdlcorr;
-        if (fr->efep != efepNO) {
-            enerd->dvdl_lin += dvdlcorr;
-        }
-    }
-
-    /* ########## Now pressure ############## */
-    if (bPres || bConstrain)
-    {
-
-        m_add(force_vir,shake_vir,total_vir);
-
-        /* Calculate pressure and apply LR correction if PPPM is used.
-         * Use the box from last timestep since we already called update().
-         */
-
-        enerd->term[F_PRES] = calc_pres(fr->ePBC,ir->nwall,box,ekind->ekin,total_vir,pres,
-                                        (fr->eeltype==eelPPPM)?enerd->term[F_COUL_RECIP]:0.0);
-
-        /* Calculate long range corrections to pressure and energy */
-        /* this adds to enerd->term[F_PRES] and enerd->term[F_ETOT],
-           and computes enerd->term[F_DISPCORR].  Also modifies the
-           total_vir and pres tesors */
-
-        m_add(total_vir,corr_vir,total_vir);
-        m_add(pres,corr_pres,pres);
-        enerd->term[F_PDISPCORR] = prescorr;
-        enerd->term[F_PRES] += prescorr;
-        *pcurr = enerd->term[F_PRES];
-        /* calculate temperature using virial */
-        enerd->term[F_VTEMP] = calc_temp(trace(total_vir),ir->opts.nrdf[0]);
-
-    }
-}
-
-
-/* Definitions for convergence of iterated constraints */
-
-/* iterate constraints up to 50 times  */
-#define MAXITERCONST       50
-
-/* data type */
-typedef struct
-{
-    real f,fprev,x,xprev;
-    int iter_i;
-    gmx_bool bIterate;
-    real allrelerr[MAXITERCONST+2];
-    int num_close; /* number of "close" violations, caused by limited precision. */
-} gmx_iterate_t;
-
-#ifdef GMX_DOUBLE
-#define CONVERGEITER  0.000000001
-#define CLOSE_ENOUGH  0.000001000
-#else
-#define CONVERGEITER  0.0001
-#define CLOSE_ENOUGH  0.0050
-#endif
-
-/* we want to keep track of the close calls.  If there are too many, there might be some other issues.
-   so we make sure that it's either less than some predetermined number, or if more than that number,
-   only some small fraction of the total. */
-#define MAX_NUMBER_CLOSE        50
-#define FRACTION_CLOSE       0.001
-
-/* maximum length of cyclic traps to check, emerging from limited numerical precision  */
-#define CYCLEMAX            20
-
-static void gmx_iterate_init(gmx_iterate_t *iterate,gmx_bool bIterate)
-{
-    int i;
-
-    iterate->iter_i = 0;
-    iterate->bIterate = bIterate;
-    iterate->num_close = 0;
-    for (i=0;i<MAXITERCONST+2;i++)
-    {
-        iterate->allrelerr[i] = 0;
-    }
-}
-
-static gmx_bool done_iterating(const t_commrec *cr,FILE *fplog, int nsteps, gmx_iterate_t *iterate, gmx_bool bFirstIterate, real fom, real *newf)
-{
-    /* monitor convergence, and use a secant search to propose new
-       values.
-                                                                  x_{i} - x_{i-1}
-       The secant method computes x_{i+1} = x_{i} - f(x_{i}) * ---------------------
-                                                                f(x_{i}) - f(x_{i-1})
-
-       The function we are trying to zero is fom-x, where fom is the
-       "figure of merit" which is the pressure (or the veta value) we
-       would get by putting in an old value of the pressure or veta into
-       the incrementor function for the step or half step.  I have
-       verified that this gives the same answer as self consistent
-       iteration, usually in many fewer steps, especially for small tau_p.
-
-       We could possibly eliminate an iteration with proper use
-       of the value from the previous step, but that would take a bit
-       more bookkeeping, especially for veta, since tests indicate the
-       function of veta on the last step is not sufficiently close to
-       guarantee convergence this step. This is
-       good enough for now.  On my tests, I could use tau_p down to
-       0.02, which is smaller that would ever be necessary in
-       practice. Generally, 3-5 iterations will be sufficient */
-
-    real relerr,err;
-    char buf[256];
-    int i;
-    gmx_bool incycle;
-
-    if (bFirstIterate)
-    {
-        iterate->x = fom;
-        iterate->f = fom-iterate->x;
-        iterate->xprev = 0;
-        iterate->fprev = 0;
-        *newf = fom;
-    }
-    else
-    {
-        iterate->f = fom-iterate->x; /* we want to zero this difference */
-        if ((iterate->iter_i > 1) && (iterate->iter_i < MAXITERCONST))
-        {
-            if (iterate->f==iterate->fprev)
-            {
-                *newf = iterate->f;
-            }
-            else
-            {
-                *newf = iterate->x - (iterate->x-iterate->xprev)*(iterate->f)/(iterate->f-iterate->fprev);
-            }
-        }
-        else
-        {
-            /* just use self-consistent iteration the first step to initialize, or
-               if it's not converging (which happens occasionally -- need to investigate why) */
-            *newf = fom;
-        }
-    }
-    /* Consider a slight shortcut allowing us to exit one sooner -- we check the
-       difference between the closest of x and xprev to the new
-       value. To be 100% certain, we should check the difference between
-       the last result, and the previous result, or
-
-       relerr = (fabs((x-xprev)/fom));
-
-       but this is pretty much never necessary under typical conditions.
-       Checking numerically, it seems to lead to almost exactly the same
-       trajectories, but there are small differences out a few decimal
-       places in the pressure, and eventually in the v_eta, but it could
-       save an interation.
-
-       if (fabs(*newf-x) < fabs(*newf - xprev)) { xmin = x;} else { xmin = xprev;}
-       relerr = (fabs((*newf-xmin) / *newf));
-    */
-
-    err = fabs((iterate->f-iterate->fprev));
-    relerr = fabs(err/fom);
-
-    iterate->allrelerr[iterate->iter_i] = relerr;
-
-    if (iterate->iter_i > 0)
-    {
-        if (debug)
-        {
-            fprintf(debug,"Iterating NPT constraints: %6i %20.12f%14.6g%20.12f\n",
-                    iterate->iter_i,fom,relerr,*newf);
-        }
-
-        if ((relerr < CONVERGEITER) || (err < CONVERGEITER) || (fom==0) || ((iterate->x == iterate->xprev) && iterate->iter_i > 1))
-        {
-            iterate->bIterate = FALSE;
-            if (debug)
-            {
-                fprintf(debug,"Iterating NPT constraints: CONVERGED\n");
-            }
-            return TRUE;
-        }
-        if (iterate->iter_i > MAXITERCONST)
-        {
-            if (relerr < CLOSE_ENOUGH)
-            {
-                incycle = FALSE;
-                for (i=1;i<CYCLEMAX;i++) {
-                    if ((iterate->allrelerr[iterate->iter_i-(1+i)] == iterate->allrelerr[iterate->iter_i-1]) &&
-                        (iterate->allrelerr[iterate->iter_i-(1+i)] == iterate->allrelerr[iterate->iter_i-(1+2*i)])) {
-                        incycle = TRUE;
-                        if (debug)
-                        {
-                            fprintf(debug,"Exiting from an NPT iterating cycle of length %d\n",i);
-                        }
-                        break;
-                    }
-                }
-
-                if (incycle) {
-                    /* step 1: trapped in a numerical attractor */
-                    /* we are trapped in a numerical attractor, and can't converge any more, and are close to the final result.
-                       Better to give up convergence here than have the simulation die.
-                    */
-                    iterate->num_close++;
-                    return TRUE;
-                }
-                else
-                {
-                    /* Step #2: test if we are reasonably close for other reasons, then monitor the number.  If not, die */
-
-                    /* how many close calls have we had?  If less than a few, we're OK */
-                    if (iterate->num_close < MAX_NUMBER_CLOSE)
-                    {
-                        sprintf(buf,"Slight numerical convergence deviation with NPT at step %d, relative error only %10.5g, likely not a problem, continuing\n",nsteps,relerr);
-                        md_print_warning(cr,fplog,buf);
-                        iterate->num_close++;
-                        return TRUE;
-                        /* if more than a few, check the total fraction.  If too high, die. */
-                    } else if (iterate->num_close/(double)nsteps > FRACTION_CLOSE) {
-                        gmx_fatal(FARGS,"Could not converge NPT constraints, too many exceptions (%d%%\n",iterate->num_close/(double)nsteps);
-                    }
-                }
-            }
-            else
-            {
-                gmx_fatal(FARGS,"Could not converge NPT constraints\n");
-            }
-        }
-    }
-
-    iterate->xprev = iterate->x;
-    iterate->x = *newf;
-    iterate->fprev = iterate->f;
-    iterate->iter_i++;
-
-    return FALSE;
-}
-
-static void check_nst_param(FILE *fplog,t_commrec *cr,
-                            const char *desc_nst,int nst,
-                            const char *desc_p,int *p)
-{
-    char buf[STRLEN];
-
-    if (*p > 0 && *p % nst != 0)
-    {
-        /* Round up to the next multiple of nst */
-        *p = ((*p)/nst + 1)*nst;
-        sprintf(buf,"NOTE: %s changes %s to %d\n",desc_nst,desc_p,*p);
-        md_print_warning(cr,fplog,buf);
-    }
-}
-
-static void reset_all_counters(FILE *fplog,t_commrec *cr,
-                               gmx_large_int_t step,
-                               gmx_large_int_t *step_rel,t_inputrec *ir,
-                               gmx_wallcycle_t wcycle,t_nrnb *nrnb,
-                               gmx_runtime_t *runtime)
-{
-    char buf[STRLEN],sbuf[STEPSTRSIZE];
-
-    /* Reset all the counters related to performance over the run */
-    sprintf(buf,"Step %s: resetting all time and cycle counters\n",
-            gmx_step_str(step,sbuf));
-    md_print_warning(cr,fplog,buf);
-
-    wallcycle_stop(wcycle,ewcRUN);
-    wallcycle_reset_all(wcycle);
-    if (DOMAINDECOMP(cr))
-    {
-        reset_dd_statistics_counters(cr->dd);
-    }
-    init_nrnb(nrnb);
-    ir->init_step += *step_rel;
-    ir->nsteps    -= *step_rel;
-    *step_rel = 0;
-    wallcycle_start(wcycle,ewcRUN);
-    runtime_start(runtime);
-    print_date_and_time(fplog,cr->nodeid,"Restarted time",runtime);
-}
-
-static int check_nstglobalcomm(FILE *fplog,t_commrec *cr,
-                               int nstglobalcomm,t_inputrec *ir)
-{
-    char buf[STRLEN];
-
-    if (!EI_DYNAMICS(ir->eI))
-    {
-        nstglobalcomm = 1;
-    }
-
-    if (nstglobalcomm == -1)
-    {
-        if (ir->nstcalcenergy == 0 && ir->nstlist == 0)
-        {
-            nstglobalcomm = 10;
-            if (ir->nstenergy > 0 && ir->nstenergy < nstglobalcomm)
-            {
-                nstglobalcomm = ir->nstenergy;
-            }
-        }
-        else
-        {
-            /* We assume that if nstcalcenergy > nstlist,
-             * nstcalcenergy is a multiple of nstlist.
-             */
-            if (ir->nstcalcenergy == 0 ||
-                (ir->nstlist > 0 && ir->nstlist < ir->nstcalcenergy))
-            {
-                nstglobalcomm = ir->nstlist;
-            }
-            else
-            {
-                nstglobalcomm = ir->nstcalcenergy;
-            }
-        }
-    }
-    else
-    {
-        if (ir->nstlist > 0 &&
-            nstglobalcomm > ir->nstlist && nstglobalcomm % ir->nstlist != 0)
-        {
-            nstglobalcomm = (nstglobalcomm / ir->nstlist)*ir->nstlist;
-            sprintf(buf,"WARNING: nstglobalcomm is larger than nstlist, but not a multiple, setting it to %d\n",nstglobalcomm);
-            md_print_warning(cr,fplog,buf);
-        }
-        if (nstglobalcomm > ir->nstcalcenergy)
-        {
-            check_nst_param(fplog,cr,"-gcom",nstglobalcomm,
-                            "nstcalcenergy",&ir->nstcalcenergy);
-        }
-
-        check_nst_param(fplog,cr,"-gcom",nstglobalcomm,
-                        "nstenergy",&ir->nstenergy);
-
-        check_nst_param(fplog,cr,"-gcom",nstglobalcomm,
-                        "nstlog",&ir->nstlog);
-    }
-
-    if (ir->comm_mode != ecmNO && ir->nstcomm < nstglobalcomm)
-    {
-        sprintf(buf,"WARNING: Changing nstcomm from %d to %d\n",
-                ir->nstcomm,nstglobalcomm);
-        md_print_warning(cr,fplog,buf);
-        ir->nstcomm = nstglobalcomm;
-    }
-
-    return nstglobalcomm;
-}
-
-void check_ir_old_tpx_versions(t_commrec *cr,FILE *fplog,
-                               t_inputrec *ir,gmx_mtop_t *mtop)
-{
-    /* Check required for old tpx files */
-    if (IR_TWINRANGE(*ir) && ir->nstlist > 1 &&
-        ir->nstcalcenergy % ir->nstlist != 0)
-    {
-        md_print_warning(cr,fplog,"Old tpr file with twin-range settings: modifying energy calculation and/or T/P-coupling frequencies");
-
-        if (gmx_mtop_ftype_count(mtop,F_CONSTR) +
-            gmx_mtop_ftype_count(mtop,F_CONSTRNC) > 0 &&
-            ir->eConstrAlg == econtSHAKE)
-        {
-            md_print_warning(cr,fplog,"With twin-range cut-off's and SHAKE the virial and pressure are incorrect");
-            if (ir->epc != epcNO)
-            {
-                gmx_fatal(FARGS,"Can not do pressure coupling with twin-range cut-off's and SHAKE");
-            }
-        }
-        check_nst_param(fplog,cr,"nstlist",ir->nstlist,
-                        "nstcalcenergy",&ir->nstcalcenergy);
-       check_nst_param(fplog,cr,"nstcalcenergy",ir->nstcalcenergy,
-                       "nstenergy",&ir->nstenergy);
-        check_nst_param(fplog,cr,"nstcalcenergy",ir->nstcalcenergy,
-                        "nstlog",&ir->nstlog);
-        if (ir->efep != efepNO)
-        {
-            check_nst_param(fplog,cr,"nstcalcenergy",ir->nstcalcenergy,
-                            "nstdhdl",&ir->nstdhdl);
-        }
-    }
-}
-
-typedef struct {
-    gmx_bool       bGStatEveryStep;
-    gmx_large_int_t step_ns;
-    gmx_large_int_t step_nscheck;
-    gmx_large_int_t nns;
-    matrix     scale_tot;
-    int        nabnsb;
-    double     s1;
-    double     s2;
-    double     ab;
-    double     lt_runav;
-    double     lt_runav2;
-} gmx_nlheur_t;
-
-static void reset_nlistheuristics(gmx_nlheur_t *nlh,gmx_large_int_t step)
-{
-    nlh->lt_runav  = 0;
-    nlh->lt_runav2 = 0;
-    nlh->step_nscheck = step;
-}
-
-static void init_nlistheuristics(gmx_nlheur_t *nlh,
-                                 gmx_bool bGStatEveryStep,gmx_large_int_t step)
-{
-    nlh->bGStatEveryStep = bGStatEveryStep;
-    nlh->nns       = 0;
-    nlh->nabnsb    = 0;
-    nlh->s1        = 0;
-    nlh->s2        = 0;
-    nlh->ab        = 0;
-
-    reset_nlistheuristics(nlh,step);
-}
-
-static void update_nliststatistics(gmx_nlheur_t *nlh,gmx_large_int_t step)
-{
-    gmx_large_int_t nl_lt;
-    char sbuf[STEPSTRSIZE],sbuf2[STEPSTRSIZE];
-
-    /* Determine the neighbor list life time */
-    nl_lt = step - nlh->step_ns;
-    if (debug)
-    {
-        fprintf(debug,"%d atoms beyond ns buffer, updating neighbor list after %s steps\n",nlh->nabnsb,gmx_step_str(nl_lt,sbuf));
-    }
-    nlh->nns++;
-    nlh->s1 += nl_lt;
-    nlh->s2 += nl_lt*nl_lt;
-    nlh->ab += nlh->nabnsb;
-    if (nlh->lt_runav == 0)
-    {
-        nlh->lt_runav  = nl_lt;
-        /* Initialize the fluctuation average
-         * such that at startup we check after 0 steps.
-         */
-        nlh->lt_runav2 = sqr(nl_lt/2.0);
-    }
-    /* Running average with 0.9 gives an exp. history of 9.5 */
-    nlh->lt_runav2 = 0.9*nlh->lt_runav2 + 0.1*sqr(nlh->lt_runav - nl_lt);
-    nlh->lt_runav  = 0.9*nlh->lt_runav  + 0.1*nl_lt;
-    if (nlh->bGStatEveryStep)
-    {
-        /* Always check the nlist validity */
-        nlh->step_nscheck = step;
-    }
-    else
-    {
-        /* We check after:  <life time> - 2*sigma
-         * The factor 2 is quite conservative,
-         * but we assume that with nstlist=-1 the user
-         * prefers exact integration over performance.
-         */
-        nlh->step_nscheck = step
-                  + (int)(nlh->lt_runav - 2.0*sqrt(nlh->lt_runav2)) - 1;
-    }
-    if (debug)
-    {
-        fprintf(debug,"nlist life time %s run av. %4.1f sig %3.1f check %s check with -gcom %d\n",
-                gmx_step_str(nl_lt,sbuf),nlh->lt_runav,sqrt(nlh->lt_runav2),
-                gmx_step_str(nlh->step_nscheck-step+1,sbuf2),
-                (int)(nlh->lt_runav - 2.0*sqrt(nlh->lt_runav2)));
-    }
-}
-
-static void set_nlistheuristics(gmx_nlheur_t *nlh,gmx_bool bReset,gmx_large_int_t step)
-{
-    int d;
-
-    if (bReset)
-    {
-        reset_nlistheuristics(nlh,step);
-    }
-    else
-    {
-        update_nliststatistics(nlh,step);
-    }
-
-    nlh->step_ns = step;
-    /* Initialize the cumulative coordinate scaling matrix */
-    clear_mat(nlh->scale_tot);
-    for(d=0; d<DIM; d++)
-    {
-        nlh->scale_tot[d][d] = 1.0;
-    }
-}
-
-double do_md_membed(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
-             const output_env_t oenv, gmx_bool bVerbose,gmx_bool bCompact,
-             int nstglobalcomm,
-             gmx_vsite_t *vsite,gmx_constr_t constr,
-             int stepout,t_inputrec *ir,
-             gmx_mtop_t *top_global,
-             t_fcdata *fcd,
-             t_state *state_global,
-             t_mdatoms *mdatoms,
-             t_nrnb *nrnb,gmx_wallcycle_t wcycle,
-             gmx_edsam_t ed,t_forcerec *fr,
-             int repl_ex_nst,int repl_ex_seed,
-             real cpt_period,real max_hours,
-             const char *deviceOptions,
-             unsigned long Flags,
-             gmx_runtime_t *runtime,
-             rvec fac, rvec *r_ins, pos_ins_t *pos_ins, t_block *ins_at,
-             real xy_step, real z_step, int it_xy, int it_z)
-{
-    gmx_mdoutf_t *outf;
-    gmx_large_int_t step,step_rel;
-    double     run_time;
-    double     t,t0,lam0;
-    gmx_bool       bGStatEveryStep,bGStat,bNstEner,bCalcEnerPres;
-    gmx_bool       bNS,bNStList,bSimAnn,bStopCM,bRerunMD,bNotLastFrame=FALSE,
-               bFirstStep,bStateFromTPX,bInitStep,bLastStep,
-               bBornRadii,bStartingFromCpt;
-    gmx_bool       bDoDHDL=FALSE;
-    gmx_bool       do_ene,do_log,do_verbose,bRerunWarnNoV=TRUE,
-               bForceUpdate=FALSE,bCPT;
-    int        mdof_flags;
-    gmx_bool       bMasterState;
-    int        force_flags,cglo_flags;
-    tensor     force_vir,shake_vir,total_vir,tmp_vir,pres;
-    int        i,m;
-    t_trxstatus *status;
-    rvec       mu_tot;
-    t_vcm      *vcm;
-    t_state    *bufstate=NULL;
-    matrix     *scale_tot,pcoupl_mu,M,ebox;
-    gmx_nlheur_t nlh;
-    t_trxframe rerun_fr;
-/*    gmx_repl_ex_t repl_ex=NULL;*/
-    int        nchkpt=1;
-
-    gmx_localtop_t *top;
-    t_mdebin *mdebin=NULL;
-    t_state    *state=NULL;
-    rvec       *f_global=NULL;
-    int        n_xtc=-1;
-    rvec       *x_xtc=NULL;
-    gmx_enerdata_t *enerd;
-    rvec       *f=NULL;
-    gmx_global_stat_t gstat;
-    gmx_update_t upd=NULL;
-    t_graph    *graph=NULL;
-    globsig_t   gs;
-
-    gmx_bool        bFFscan;
-    gmx_groups_t *groups;
-    gmx_ekindata_t *ekind, *ekind_save;
-    gmx_shellfc_t shellfc;
-    int         count,nconverged=0;
-    real        timestep=0;
-    double      tcount=0;
-    gmx_bool        bIonize=FALSE;
-    gmx_bool        bTCR=FALSE,bConverged=TRUE,bOK,bSumEkinhOld,bExchanged;
-    gmx_bool        bAppend;
-    gmx_bool        bResetCountersHalfMaxH=FALSE;
-    gmx_bool        bVV,bIterations,bIterate,bFirstIterate,bTemp,bPres,bTrotter;
-    real        temp0,dvdl;
-    int         a0,a1,ii;
-    rvec        *xcopy=NULL,*vcopy=NULL,*cbuf=NULL;
-    matrix      boxcopy={{0}},lastbox;
-       real        veta_save,pcurr,scalevir,tracevir;
-       real        vetanew = 0;
-    double      cycles;
-       real        last_conserved = 0;
-    real        last_ekin = 0;
-       t_extmass   MassQ;
-    int         **trotter_seq;
-    char        sbuf[STEPSTRSIZE],sbuf2[STEPSTRSIZE];
-    int         handled_stop_condition=gmx_stop_cond_none; /* compare to get_stop_condition*/
-    gmx_iterate_t iterate;
-#ifdef GMX_FAHCORE
-    /* Temporary addition for FAHCORE checkpointing */
-    int chkpt_ret;
-#endif
-
-    /* Check for special mdrun options */
-    bRerunMD = (Flags & MD_RERUN);
-    bIonize  = (Flags & MD_IONIZE);
-    bFFscan  = (Flags & MD_FFSCAN);
-    bAppend  = (Flags & MD_APPENDFILES);
-    bGStatEveryStep = FALSE;
-    if (Flags & MD_RESETCOUNTERSHALFWAY)
-    {
-        if (ir->nsteps > 0)
-        {
-            /* Signal to reset the counters half the simulation steps. */
-            wcycle_set_reset_counters(wcycle,ir->nsteps/2);
-        }
-        /* Signal to reset the counters halfway the simulation time. */
-        bResetCountersHalfMaxH = (max_hours > 0);
-    }
-
-    /* md-vv uses averaged full step velocities for T-control
-       md-vv-avek uses averaged half step velocities for T-control (but full step ekin for P control)
-       md uses averaged half step kinetic energies to determine temperature unless defined otherwise by GMX_EKIN_AVE_VEL; */
-    bVV = EI_VV(ir->eI);
-    if (bVV) /* to store the initial velocities while computing virial */
-    {
-        snew(cbuf,top_global->natoms);
-    }
-    /* all the iteratative cases - only if there are constraints */
-    bIterations = ((IR_NPT_TROTTER(ir)) && (constr) && (!bRerunMD));
-    bTrotter = (bVV && (IR_NPT_TROTTER(ir) || (IR_NVT_TROTTER(ir))));
-
-    if (bRerunMD)
-    {
-        /* Since we don't know if the frames read are related in any way,
-         * rebuild the neighborlist at every step.
-         */
-        ir->nstlist       = 1;
-        ir->nstcalcenergy = 1;
-        nstglobalcomm     = 1;
-    }
-
-    check_ir_old_tpx_versions(cr,fplog,ir,top_global);
-
-    nstglobalcomm = check_nstglobalcomm(fplog,cr,nstglobalcomm,ir);
-    /*bGStatEveryStep = (nstglobalcomm == 1);*/
-    bGStatEveryStep = FALSE;
-
-    if (!bGStatEveryStep && ir->nstlist == -1 && fplog != NULL)
-    {
-        fprintf(fplog,
-                "To reduce the energy communication with nstlist = -1\n"
-                "the neighbor list validity should not be checked at every step,\n"
-                "this means that exact integration is not guaranteed.\n"
-                "The neighbor list validity is checked after:\n"
-                "  <n.list life time> - 2*std.dev.(n.list life time)  steps.\n"
-                "In most cases this will result in exact integration.\n"
-                "This reduces the energy communication by a factor of 2 to 3.\n"
-                "If you want less energy communication, set nstlist > 3.\n\n");
-    }
-
-    if (bRerunMD || bFFscan)
-    {
-        ir->nstxtcout = 0;
-    }
-    groups = &top_global->groups;
-
-    /* Initial values */
-    init_md(fplog,cr,ir,oenv,&t,&t0,&state_global->lambda,&lam0,
-            nrnb,top_global,&upd,
-            nfile,fnm,&outf,&mdebin,
-            force_vir,shake_vir,mu_tot,&bSimAnn,&vcm,state_global,Flags);
-
-    clear_mat(total_vir);
-    clear_mat(pres);
-    /* Energy terms and groups */
-    snew(enerd,1);
-    init_enerdata(top_global->groups.grps[egcENER].nr,ir->n_flambda,enerd);
-    if (DOMAINDECOMP(cr))
-    {
-        f = NULL;
-    }
-    else
-    {
-        snew(f,top_global->natoms);
-    }
-
-    /* Kinetic energy data */
-    snew(ekind,1);
-    init_ekindata(fplog,top_global,&(ir->opts),ekind);
-    /* needed for iteration of constraints */
-    snew(ekind_save,1);
-    init_ekindata(fplog,top_global,&(ir->opts),ekind_save);
-    /* Copy the cos acceleration to the groups struct */
-    ekind->cosacc.cos_accel = ir->cos_accel;
-
-    gstat = global_stat_init(ir);
-    debug_gmx();
-
-    /* Check for polarizable models and flexible constraints */
-    shellfc = init_shell_flexcon(fplog,
-                                 top_global,n_flexible_constraints(constr),
-                                 (ir->bContinuation ||
-                                  (DOMAINDECOMP(cr) && !MASTER(cr))) ?
-                                 NULL : state_global->x);
-
-/*    if (DEFORM(*ir))
-    {
-#ifdef GMX_THREADS
-        tMPI_Thread_mutex_lock(&deform_init_box_mutex);
-#endif
-        set_deform_reference_box(upd,
-                                 deform_init_init_step_tpx,
-                                 deform_init_box_tpx);
-#ifdef GMX_THREADS
-        tMPI_Thread_mutex_unlock(&deform_init_box_mutex);
-#endif
-    }*/
-
-/*    {
-        double io = compute_io(ir,top_global->natoms,groups,mdebin->ebin->nener,1);
-        if ((io > 2000) && MASTER(cr))
-            fprintf(stderr,
-                    "\nWARNING: This run will generate roughly %.0f Mb of data\n\n",
-                    io);
-    }*/
-
-    if (DOMAINDECOMP(cr)) {
-        top = dd_init_local_top(top_global);
-
-        snew(state,1);
-        dd_init_local_state(cr->dd,state_global,state);
-
-        if (DDMASTER(cr->dd) && ir->nstfout) {
-            snew(f_global,state_global->natoms);
-        }
-    } else {
-        if (PAR(cr)) {
-            /* Initialize the particle decomposition and split the topology */
-            top = split_system(fplog,top_global,ir,cr);
-
-            pd_cg_range(cr,&fr->cg0,&fr->hcg);
-            pd_at_range(cr,&a0,&a1);
-        } else {
-            top = gmx_mtop_generate_local_top(top_global,ir);
-
-            a0 = 0;
-            a1 = top_global->natoms;
-        }
-
-        state = partdec_init_local_state(cr,state_global);
-        f_global = f;
-
-        atoms2md(top_global,ir,0,NULL,a0,a1-a0,mdatoms);
-
-        if (vsite) {
-            set_vsite_top(vsite,top,mdatoms,cr);
-        }
-
-        if (ir->ePBC != epbcNONE && !ir->bPeriodicMols) {
-            graph = mk_graph(fplog,&(top->idef),0,top_global->natoms,FALSE,FALSE);
-        }
-
-        if (shellfc) {
-            make_local_shells(cr,mdatoms,shellfc);
-        }
-
-        if (ir->pull && PAR(cr)) {
-            dd_make_local_pull_groups(NULL,ir->pull,mdatoms);
-        }
-    }
-
-    if (DOMAINDECOMP(cr))
-    {
-        /* Distribute the charge groups over the nodes from the master node */
-        dd_partition_system(fplog,ir->init_step,cr,TRUE,1,
-                            state_global,top_global,ir,
-                            state,&f,mdatoms,top,fr,
-                            vsite,shellfc,constr,
-                            nrnb,wcycle,FALSE);
-    }
-
-    update_mdatoms(mdatoms,state->lambda);
-
-    if (MASTER(cr))
-    {
-        if (opt2bSet("-cpi",nfile,fnm))
-        {
-            /* Update mdebin with energy history if appending to output files */
-            if ( Flags & MD_APPENDFILES )
-            {
-                restore_energyhistory_from_state(mdebin,&state_global->enerhist);
-            }
-            else
-            {
-                /* We might have read an energy history from checkpoint,
-                 * free the allocated memory and reset the counts.
-                 */
-                done_energyhistory(&state_global->enerhist);
-                init_energyhistory(&state_global->enerhist);
-            }
-        }
-        /* Set the initial energy history in state by updating once */
-        update_energyhistory(&state_global->enerhist,mdebin);
-    }
-
-    if ((state->flags & (1<<estLD_RNG)) && (Flags & MD_READ_RNG)) {
-        /* Set the random state if we read a checkpoint file */
-        set_stochd_state(upd,state);
-    }
-
-    /* Initialize constraints */
-    if (constr) {
-        if (!DOMAINDECOMP(cr))
-            set_constraints(constr,top,ir,mdatoms,cr);
-    }
-
-    /* Check whether we have to GCT stuff */
- /*   bTCR = ftp2bSet(efGCT,nfile,fnm);
-    if (bTCR) {
-        if (MASTER(cr)) {
-            fprintf(stderr,"Will do General Coupling Theory!\n");
-        }
-        gnx = top_global->mols.nr;
-        snew(grpindex,gnx);
-        for(i=0; (i<gnx); i++) {
-            grpindex[i] = i;
-        }
-    }*/
-
-/*    if (repl_ex_nst > 0 && MASTER(cr))
-        repl_ex = init_replica_exchange(fplog,cr->ms,state_global,ir,
-                                        repl_ex_nst,repl_ex_seed);*/
-
-    if (!ir->bContinuation && !bRerunMD)
-    {
-        if (mdatoms->cFREEZE && (state->flags & (1<<estV)))
-        {
-            /* Set the velocities of frozen particles to zero */
-            for(i=mdatoms->start; i<mdatoms->start+mdatoms->homenr; i++)
-            {
-                for(m=0; m<DIM; m++)
-                {
-                    if (ir->opts.nFreeze[mdatoms->cFREEZE[i]][m])
-                    {
-                        state->v[i][m] = 0;
-                    }
-                }
-            }
-        }
-
-        if (constr)
-        {
-            /* Constrain the initial coordinates and velocities */
-            do_constrain_first(fplog,constr,ir,mdatoms,state,f,
-                               graph,cr,nrnb,fr,top,shake_vir);
-        }
-        if (vsite)
-        {
-            /* Construct the virtual sites for the initial configuration */
-            construct_vsites(fplog,vsite,state->x,nrnb,ir->delta_t,NULL,
-                             top->idef.iparams,top->idef.il,
-                             fr->ePBC,fr->bMolPBC,graph,cr,state->box);
-        }
-    }
-
-    debug_gmx();
-
-    /* I'm assuming we need global communication the first time! MRS */
-    cglo_flags = (CGLO_TEMPERATURE | CGLO_GSTAT
-                  | (bVV ? CGLO_PRESSURE:0)
-                  | (bVV ? CGLO_CONSTRAINT:0)
-                  | (bRerunMD ? CGLO_RERUNMD:0)
-                  | ((Flags & MD_READ_EKIN) ? CGLO_READEKIN:0));
-
-    bSumEkinhOld = FALSE;
-    compute_globals(fplog,gstat,cr,ir,fr,ekind,state,state_global,mdatoms,nrnb,vcm,
-                    wcycle,enerd,force_vir,shake_vir,total_vir,pres,mu_tot,
-                    constr,NULL,FALSE,state->box,
-                    top_global,&pcurr,top_global->natoms,&bSumEkinhOld,cglo_flags);
-    if (ir->eI == eiVVAK) {
-        /* a second call to get the half step temperature initialized as well */
-        /* we do the same call as above, but turn the pressure off -- internally, this
-           is recognized as a velocity verlet half-step kinetic energy calculation.
-           This minimized excess variables, but perhaps loses some logic?*/
-
-        compute_globals(fplog,gstat,cr,ir,fr,ekind,state,state_global,mdatoms,nrnb,vcm,
-                        wcycle,enerd,force_vir,shake_vir,total_vir,pres,mu_tot,
-                        constr,NULL,FALSE,state->box,
-                        top_global,&pcurr,top_global->natoms,&bSumEkinhOld,
-                        cglo_flags &~ CGLO_PRESSURE);
-    }
-
-    /* Calculate the initial half step temperature, and save the ekinh_old */
-    if (!(Flags & MD_STARTFROMCPT))
-    {
-        for(i=0; (i<ir->opts.ngtc); i++)
-        {
-            copy_mat(ekind->tcstat[i].ekinh,ekind->tcstat[i].ekinh_old);
-        }
-    }
-    if (ir->eI != eiVV) 
-    {
-        enerd->term[F_TEMP] *= 2; /* result of averages being done over previous and current step,
-                                     and there is no previous step */
-    }
-    temp0 = enerd->term[F_TEMP];
-
-    /* if using an iterative algorithm, we need to create a working directory for the state. */
-    if (bIterations)
-    {
-            bufstate = init_bufstate(state);
-    }
-    if (bFFscan)
-    {
-        snew(xcopy,state->natoms);
-        snew(vcopy,state->natoms);
-        copy_rvecn(state->x,xcopy,0,state->natoms);
-        copy_rvecn(state->v,vcopy,0,state->natoms);
-        copy_mat(state->box,boxcopy);
-    }
-
-    /* need to make an initiation call to get the Trotter variables set, as well as other constants for non-trotter
-       temperature control */
-    trotter_seq = init_npt_vars(ir,state,&MassQ,bTrotter);
-
-    if (MASTER(cr))
-    {
-        if (constr && !ir->bContinuation && ir->eConstrAlg == econtLINCS)
-        {
-            fprintf(fplog,
-                    "RMS relative constraint deviation after constraining: %.2e\n",
-                    constr_rmsd(constr,FALSE));
-        }
-        fprintf(fplog,"Initial temperature: %g K\n",enerd->term[F_TEMP]);
-        if (bRerunMD)
-        {
-            fprintf(stderr,"starting md rerun '%s', reading coordinates from"
-                    " input trajectory '%s'\n\n",
-                    *(top_global->name),opt2fn("-rerun",nfile,fnm));
-            if (bVerbose)
-            {
-                fprintf(stderr,"Calculated time to finish depends on nsteps from "
-                        "run input file,\nwhich may not correspond to the time "
-                        "needed to process input trajectory.\n\n");
-            }
-        }
-        else
-        {
-            char tbuf[20];
-            fprintf(stderr,"starting mdrun '%s'\n",
-                    *(top_global->name));
-            if (ir->nsteps >= 0)
-            {
-                sprintf(tbuf,"%8.1f",(ir->init_step+ir->nsteps)*ir->delta_t);
-            }
-            else
-            {
-                sprintf(tbuf,"%s","infinite");
-            }
-            if (ir->init_step > 0)
-            {
-                fprintf(stderr,"%s steps, %s ps (continuing from step %s, %8.1f ps).\n",
-                        gmx_step_str(ir->init_step+ir->nsteps,sbuf),tbuf,
-                        gmx_step_str(ir->init_step,sbuf2),
-                        ir->init_step*ir->delta_t);
-            }
-            else
-            {
-                fprintf(stderr,"%s steps, %s ps.\n",
-                        gmx_step_str(ir->nsteps,sbuf),tbuf);
-            }
-        }
-        fprintf(fplog,"\n");
-    }
-
-    /* Set and write start time */
-    runtime_start(runtime);
-    print_date_and_time(fplog,cr->nodeid,"Started mdrun",runtime);
-    wallcycle_start(wcycle,ewcRUN);
-    if (fplog)
-        fprintf(fplog,"\n");
-
-    /* safest point to do file checkpointing is here.  More general point would be immediately before integrator call */
-/*#ifdef GMX_FAHCORE
-    chkpt_ret=fcCheckPointParallel( cr->nodeid,
-                                    NULL,0);
-    if ( chkpt_ret == 0 )
-        gmx_fatal( 3,__FILE__,__LINE__, "Checkpoint error on step %d\n", 0 );
-#endif*/
-
-    debug_gmx();
-    /***********************************************************
-     *
-     *             Loop over MD steps
-     *
-     ************************************************************/
-
-    /* if rerunMD then read coordinates and velocities from input trajectory */
-    if (bRerunMD)
-    {
-        if (getenv("GMX_FORCE_UPDATE"))
-        {
-            bForceUpdate = TRUE;
-        }
-
-        bNotLastFrame = read_first_frame(oenv,&status,
-                                         opt2fn("-rerun",nfile,fnm),
-                                         &rerun_fr,TRX_NEED_X | TRX_READ_V);
-        if (rerun_fr.natoms != top_global->natoms)
-        {
-            gmx_fatal(FARGS,
-                      "Number of atoms in trajectory (%d) does not match the "
-                      "run input file (%d)\n",
-                      rerun_fr.natoms,top_global->natoms);
-        }
-        if (ir->ePBC != epbcNONE)
-        {
-            if (!rerun_fr.bBox)
-            {
-                gmx_fatal(FARGS,"Rerun trajectory frame step %d time %f does not contain a box, while pbc is used",rerun_fr.step,rerun_fr.time);
-            }
-            if (max_cutoff2(ir->ePBC,rerun_fr.box) < sqr(fr->rlistlong))
-            {
-                gmx_fatal(FARGS,"Rerun trajectory frame step %d time %f has too small box dimensions",rerun_fr.step,rerun_fr.time);
-            }
-
-            /* Set the shift vectors.
-             * Necessary here when have a static box different from the tpr box.
-             */
-            calc_shifts(rerun_fr.box,fr->shift_vec);
-        }
-    }
-
-    /* loop over MD steps or if rerunMD to end of input trajectory */
-    bFirstStep = TRUE;
-    /* Skip the first Nose-Hoover integration when we get the state from tpx */
-    bStateFromTPX = !opt2bSet("-cpi",nfile,fnm);
-    bInitStep = bFirstStep && (bStateFromTPX || bVV);
-    bStartingFromCpt = (Flags & MD_STARTFROMCPT) && bInitStep;
-    bLastStep    = FALSE;
-    bSumEkinhOld = FALSE;
-    bExchanged   = FALSE;
-
-    init_global_signals(&gs,cr,ir,repl_ex_nst);
-
-    step = ir->init_step;
-    step_rel = 0;
-
-    if (ir->nstlist == -1)
-    {
-        init_nlistheuristics(&nlh,bGStatEveryStep,step);
-    }
-
-    bLastStep = (bRerunMD || (ir->nsteps >= 0 && step_rel > ir->nsteps));
-    while (!bLastStep || (bRerunMD && bNotLastFrame)) {
-
-        wallcycle_start(wcycle,ewcSTEP);
-
-        GMX_MPE_LOG(ev_timestep1);
-
-        if (bRerunMD) {
-            if (rerun_fr.bStep) {
-                step = rerun_fr.step;
-                step_rel = step - ir->init_step;
-            }
-            if (rerun_fr.bTime) {
-                t = rerun_fr.time;
-            }
-            else
-            {
-                t = step;
-            }
-        }
-        else
-        {
-            bLastStep = (step_rel == ir->nsteps);
-            t = t0 + step*ir->delta_t;
-        }
-
-        if (ir->efep != efepNO)
-        {
-            if (bRerunMD && rerun_fr.bLambda && (ir->delta_lambda!=0))
-            {
-                state_global->lambda = rerun_fr.lambda;
-            }
-            else
-            {
-                state_global->lambda = lam0 + step*ir->delta_lambda;
-            }
-            state->lambda = state_global->lambda;
-            bDoDHDL = do_per_step(step,ir->nstdhdl);
-        }
-
-        if (bSimAnn)
-        {
-            update_annealing_target_temp(&(ir->opts),t);
-        }
-
-        if (bRerunMD)
-        {
-            if (!(DOMAINDECOMP(cr) && !MASTER(cr)))
-            {
-                for(i=0; i<state_global->natoms; i++)
-                {
-                    copy_rvec(rerun_fr.x[i],state_global->x[i]);
-                }
-                if (rerun_fr.bV)
-                {
-                    for(i=0; i<state_global->natoms; i++)
-                    {
-                        copy_rvec(rerun_fr.v[i],state_global->v[i]);
-                    }
-                }
-                else
-                {
-                    for(i=0; i<state_global->natoms; i++)
-                    {
-                        clear_rvec(state_global->v[i]);
-                    }
-                    if (bRerunWarnNoV)
-                    {
-                        fprintf(stderr,"\nWARNING: Some frames do not contain velocities.\n"
-                                "         Ekin, temperature and pressure are incorrect,\n"
-                                "         the virial will be incorrect when constraints are present.\n"
-                                "\n");
-                        bRerunWarnNoV = FALSE;
-                    }
-                }
-            }
-            copy_mat(rerun_fr.box,state_global->box);
-            copy_mat(state_global->box,state->box);
-
-            if (vsite && (Flags & MD_RERUN_VSITE))
-            {
-                if (DOMAINDECOMP(cr))
-                {
-                    gmx_fatal(FARGS,"Vsite recalculation with -rerun is not implemented for domain decomposition, use particle decomposition");
-                }
-                if (graph)
-                {
-                    /* Following is necessary because the graph may get out of sync
-                     * with the coordinates if we only have every N'th coordinate set
-                     */
-                    mk_mshift(fplog,graph,fr->ePBC,state->box,state->x);
-                    shift_self(graph,state->box,state->x);
-                }
-                construct_vsites(fplog,vsite,state->x,nrnb,ir->delta_t,state->v,
-                                 top->idef.iparams,top->idef.il,
-                                 fr->ePBC,fr->bMolPBC,graph,cr,state->box);
-                if (graph)
-                {
-                    unshift_self(graph,state->box,state->x);
-                }
-            }
-        }
-
-        /* Stop Center of Mass motion */
-        bStopCM = (ir->comm_mode != ecmNO && do_per_step(step,ir->nstcomm));
-
-        /* Copy back starting coordinates in case we're doing a forcefield scan */
-        if (bFFscan)
-        {
-            for(ii=0; (ii<state->natoms); ii++)
-            {
-                copy_rvec(xcopy[ii],state->x[ii]);
-                copy_rvec(vcopy[ii],state->v[ii]);
-            }
-            copy_mat(boxcopy,state->box);
-        }
-
-        if (bRerunMD)
-        {
-            /* for rerun MD always do Neighbour Searching */
-            bNS = (bFirstStep || ir->nstlist != 0);
-            bNStList = bNS;
-        }
-        else
-        {
-            /* Determine whether or not to do Neighbour Searching and LR */
-            bNStList = (ir->nstlist > 0  && step % ir->nstlist == 0);
-
-            bNS = (bFirstStep || bExchanged || bNStList ||
-                   (ir->nstlist == -1 && nlh.nabnsb > 0));
-
-            if (bNS && ir->nstlist == -1)
-            {
-                set_nlistheuristics(&nlh,bFirstStep || bExchanged,step);
-            }
-        }
-
-        /* < 0 means stop at next step, > 0 means stop at next NS step */
-        if ( (gs.set[eglsSTOPCOND] < 0 ) ||
-             ( (gs.set[eglsSTOPCOND] > 0 ) && ( bNS || ir->nstlist==0)) )
-        {
-            bLastStep = TRUE;
-        }
-
-        /* Determine whether or not to update the Born radii if doing GB */
-        bBornRadii=bFirstStep;
-        if (ir->implicit_solvent && (step % ir->nstgbradii==0))
-        {
-            bBornRadii=TRUE;
-        }
-
-        do_log = do_per_step(step,ir->nstlog) || bFirstStep || bLastStep;
-        do_verbose = bVerbose &&
-                  (step % stepout == 0 || bFirstStep || bLastStep);
-
-        if (bNS && !(bFirstStep && ir->bContinuation && !bRerunMD))
-        {
-            if (bRerunMD)
-            {
-                bMasterState = TRUE;
-            }
-            else
-            {
-                bMasterState = FALSE;
-                /* Correct the new box if it is too skewed */
-                if (DYNAMIC_BOX(*ir))
-                {
-                    if (correct_box(fplog,step,state->box,graph))
-                    {
-                        bMasterState = TRUE;
-                    }
-                }
-                if (DOMAINDECOMP(cr) && bMasterState)
-                {
-                    dd_collect_state(cr->dd,state,state_global);
-                }
-            }
-
-            if (DOMAINDECOMP(cr))
-            {
-                /* Repartition the domain decomposition */
-                wallcycle_start(wcycle,ewcDOMDEC);
-                dd_partition_system(fplog,step,cr,
-                                    bMasterState,nstglobalcomm,
-                                    state_global,top_global,ir,
-                                    state,&f,mdatoms,top,fr,
-                                    vsite,shellfc,constr,
-                                    nrnb,wcycle,do_verbose);
-                wallcycle_stop(wcycle,ewcDOMDEC);
-                /* If using an iterative integrator, reallocate space to match the decomposition */
-            }
-        }
-
-        if (MASTER(cr) && do_log && !bFFscan)
-        {
-            print_ebin_header(fplog,step,t,state->lambda);
-        }
-
-        if (ir->efep != efepNO)
-        {
-            update_mdatoms(mdatoms,state->lambda);
-        }
-
-        if (bRerunMD && rerun_fr.bV)
-        {
-
-            /* We need the kinetic energy at minus the half step for determining
-             * the full step kinetic energy and possibly for T-coupling.*/
-            /* This may not be quite working correctly yet . . . . */
-            compute_globals(fplog,gstat,cr,ir,fr,ekind,state,state_global,mdatoms,nrnb,vcm,
-                            wcycle,enerd,NULL,NULL,NULL,NULL,mu_tot,
-                            constr,NULL,FALSE,state->box,
-                            top_global,&pcurr,top_global->natoms,&bSumEkinhOld,
-                            CGLO_RERUNMD | CGLO_GSTAT | CGLO_TEMPERATURE);
-        }
-        clear_mat(force_vir);
-
-        /* Ionize the atoms if necessary */
-/*        if (bIonize)
-        {
-            ionize(fplog,oenv,mdatoms,top_global,t,ir,state->x,state->v,
-                   mdatoms->start,mdatoms->start+mdatoms->homenr,state->box,cr);
-        }*/
-
-        /* Update force field in ffscan program */
-/*        if (bFFscan)
-        {
-            if (update_forcefield(fplog,
-                                  nfile,fnm,fr,
-                                  mdatoms->nr,state->x,state->box)) {
-                if (gmx_parallel_env_initialized())
-                {
-                    gmx_finalize();
-                }
-                exit(0);
-            }
-        }*/
-
-        GMX_MPE_LOG(ev_timestep2);
-
-        /* We write a checkpoint at this MD step when:
-         * either at an NS step when we signalled through gs,
-         * or at the last step (but not when we do not want confout),
-         * but never at the first step or with rerun.
-         */
-/*        bCPT = (((gs.set[eglsCHKPT] && bNS) ||
-                 (bLastStep && (Flags & MD_CONFOUT))) &&
-                step > ir->init_step && !bRerunMD);
-        if (bCPT)
-        {
-            gs.set[eglsCHKPT] = 0;
-        }*/
-
-        /* Determine the energy and pressure:
-         * at nstcalcenergy steps and at energy output steps (set below).
-         */
-        bNstEner = (bGStatEveryStep || do_per_step(step,ir->nstcalcenergy));
-        bCalcEnerPres = bNstEner;
-
-        /* Do we need global communication ? */
-        bGStat = (bCalcEnerPres || bStopCM ||
-                  (ir->nstlist == -1 && !bRerunMD && step >= nlh.step_nscheck));
-
-        do_ene = (do_per_step(step,ir->nstenergy) || bLastStep);
-
-        if (do_ene || do_log)
-        {
-            bCalcEnerPres = TRUE;
-            bGStat    = TRUE;
-        }
-
-        /* these CGLO_ options remain the same throughout the iteration */
-        cglo_flags = ((bRerunMD ? CGLO_RERUNMD : 0) |
-                      (bStopCM ? CGLO_STOPCM : 0) |
-                      (bGStat ? CGLO_GSTAT : 0)
-            );
-
-        force_flags = (GMX_FORCE_STATECHANGED |
-                       ((DYNAMIC_BOX(*ir) || bRerunMD) ? GMX_FORCE_DYNAMICBOX : 0) |
-                       GMX_FORCE_ALLFORCES |
-                       (bNStList ? GMX_FORCE_DOLR : 0) |
-                       GMX_FORCE_SEPLRF |
-                       (bCalcEnerPres ? GMX_FORCE_VIRIAL : 0) |
-                       (bDoDHDL ? GMX_FORCE_DHDL : 0)
-            );
-
-        if (shellfc)
-        {
-            /* Now is the time to relax the shells */
-            count=relax_shell_flexcon(fplog,cr,bVerbose,bFFscan ? step+1 : step,
-                                      ir,bNS,force_flags,
-                                      bStopCM,top,top_global,
-                                      constr,enerd,fcd,
-                                      state,f,force_vir,mdatoms,
-                                      nrnb,wcycle,graph,groups,
-                                      shellfc,fr,bBornRadii,t,mu_tot,
-                                      state->natoms,&bConverged,vsite,
-                                      outf->fp_field);
-            tcount+=count;
-
-            if (bConverged)
-            {
-                nconverged++;
-            }
-        }
-        else
-        {
-            /* The coordinates (x) are shifted (to get whole molecules)
-             * in do_force.
-             * This is parallellized as well, and does communication too.
-             * Check comments in sim_util.c
-             */
-
-            do_force(fplog,cr,ir,step,nrnb,wcycle,top,top_global,groups,
-                     state->box,state->x,&state->hist,
-                     f,force_vir,mdatoms,enerd,fcd,
-                     state->lambda,graph,
-                     fr,vsite,mu_tot,t,outf->fp_field,ed,bBornRadii,
-                     (bNS ? GMX_FORCE_NS : 0) | force_flags);
-        }
-
-        GMX_BARRIER(cr->mpi_comm_mygroup);
-
- /*       if (bTCR)
-        {
-            mu_aver = calc_mu_aver(cr,state->x,mdatoms->chargeA,
-                                   mu_tot,&top_global->mols,mdatoms,gnx,grpindex);
-        }
-
-        if (bTCR && bFirstStep)
-        {
-            tcr=init_coupling(fplog,nfile,fnm,cr,fr,mdatoms,&(top->idef));
-            fprintf(fplog,"Done init_coupling\n");
-            fflush(fplog);
-        }*/
-
-        /*  ############### START FIRST UPDATE HALF-STEP ############### */
-
-        if (bVV && !bStartingFromCpt && !bRerunMD)
-        {
-            if (ir->eI == eiVV)
-            {
-                if (bInitStep)
-                {
-                    /* if using velocity verlet with full time step Ekin,
-                     * take the first half step only to compute the
-                     * virial for the first step. From there,
-                     * revert back to the initial coordinates
-                     * so that the input is actually the initial step.
-                     */
-                    copy_rvecn(state->v,cbuf,0,state->natoms); /* should make this better for parallelizing? */
-                }
-
-                /* this is for NHC in the Ekin(t+dt/2) version of vv */
-                if (!bInitStep)
-                {
-                 trotter_update(ir,step,ekind,enerd,state,total_vir,mdatoms,&MassQ,trotter_seq,ettTSEQ2);
-                }
-
-               if (ir->eI == eiVVAK)
-               {
-                 update_tcouple(fplog,step,ir,state,ekind,wcycle,upd,&MassQ,mdatoms);
-               }
-
-                update_coords(fplog,step,ir,mdatoms,state,
-                              f,fr->bTwinRange && bNStList,fr->f_twin,fcd,
-                              ekind,M,wcycle,upd,bInitStep,etrtVELOCITY1,
-                              cr,nrnb,constr,&top->idef);
-
-                if (bIterations)
-                {
-                    gmx_iterate_init(&iterate,bIterations && !bInitStep);
-                }
-                /* for iterations, we save these vectors, as we will be self-consistently iterating
-                   the calculations */
-                /*#### UPDATE EXTENDED VARIABLES IN TROTTER FORMULATION */
-
-                /* save the state */
-                if (bIterations && iterate.bIterate) {
-                    copy_coupling_state(state,bufstate,ekind,ekind_save,&(ir->opts));
-                }
-            }
-
-            bFirstIterate = TRUE;
-            while (bFirstIterate || (bIterations && iterate.bIterate))
-            {
-                if (bIterations && iterate.bIterate)
-                {
-                    copy_coupling_state(bufstate,state,ekind_save,ekind,&(ir->opts));
-                    if (bFirstIterate && bTrotter)
-                    {
-                        /* The first time through, we need a decent first estimate
-                           of veta(t+dt) to compute the constraints.  Do
-                           this by computing the box volume part of the
-                           trotter integration at this time. Nothing else
-                           should be changed by this routine here.  If
-                           !(first time), we start with the previous value
-                           of veta.  */
-
-                        veta_save = state->veta;
-                        trotter_update(ir,step,ekind,enerd,state,total_vir,mdatoms,&MassQ,trotter_seq,ettTSEQ0);
-                        vetanew = state->veta;
-                        state->veta = veta_save;
-                    }
-                }
-
-                bOK = TRUE;
-                if ( !bRerunMD || rerun_fr.bV || bForceUpdate) {  /* Why is rerun_fr.bV here?  Unclear. */
-                    dvdl = 0;
-
-                    update_constraints(fplog,step,&dvdl,ir,ekind,mdatoms,state,graph,f,
-                                       &top->idef,shake_vir,NULL,
-                                       cr,nrnb,wcycle,upd,constr,
-                                       bInitStep,TRUE,bCalcEnerPres,vetanew);
-
-                    if (!bOK && !bFFscan)
-                    {
-                        gmx_fatal(FARGS,"Constraint error: Shake, Lincs or Settle could not solve the constrains");
-                    }
-
-                }
-                else if (graph)
-                { /* Need to unshift here if a do_force has been
-                     called in the previous step */
-                    unshift_self(graph,state->box,state->x);
-                }
-
-
-                if (bVV) {
-                    /* if VV, compute the pressure and constraints */
-                    /* if VV2, the pressure and constraints only if using pressure control.*/
-                    bPres = (ir->eI==eiVV || IR_NPT_TROTTER(ir));
-                    bTemp = ((ir->eI==eiVV &&(!bInitStep)) || (ir->eI==eiVVAK && IR_NPT_TROTTER(ir)));
-                    compute_globals(fplog,gstat,cr,ir,fr,ekind,state,state_global,mdatoms,nrnb,vcm,
-                                    wcycle,enerd,force_vir,shake_vir,total_vir,pres,mu_tot,
-                                    constr,NULL,FALSE,state->box,
-                                    top_global,&pcurr,top_global->natoms,&bSumEkinhOld,
-                                    cglo_flags
-                                    | CGLO_ENERGY
-                                    | (bTemp ? CGLO_TEMPERATURE:0)
-                                    | (bPres ? CGLO_PRESSURE : 0)
-                                    | (bPres ? CGLO_CONSTRAINT : 0)
-                                    | (iterate.bIterate ? CGLO_ITERATE : 0)
-                                    | (bFirstIterate ? CGLO_FIRSTITERATE : 0)
-                                    | CGLO_SCALEEKIN
-                        );
-                }
-                /* explanation of above:
-                   a) We compute Ekin at the full time step
-                   if 1) we are using the AveVel Ekin, and it's not the
-                   initial step, or 2) if we are using AveEkin, but need the full
-                   time step kinetic energy for the pressure.
-                   b) If we are using EkinAveEkin for the kinetic energy for the temperture control, we still feed in
-                   EkinAveVel because it's needed for the pressure */
-
-                /* temperature scaling and pressure scaling to produce the extended variables at t+dt */
-                if (bVV && !bInitStep)
-                {
-                 trotter_update(ir,step,ekind,enerd,state,total_vir,mdatoms,&MassQ, trotter_seq,ettTSEQ2);
-                }
-
-                if (bIterations &&
-                    done_iterating(cr,fplog,step,&iterate,bFirstIterate,
-                                   state->veta,&vetanew))
-                {
-                    break;
-                }
-                bFirstIterate = FALSE;
-            }
-
-            if (bTrotter && !bInitStep) {
-                copy_mat(shake_vir,state->svir_prev);
-                copy_mat(force_vir,state->fvir_prev);
-                if (IR_NVT_TROTTER(ir) && ir->eI==eiVV) {
-                    /* update temperature and kinetic energy now that step is over - this is the v(t+dt) point */
-                    enerd->term[F_TEMP] = sum_ekin(&(ir->opts),ekind,NULL,(ir->eI==eiVV),FALSE,FALSE);
-                    enerd->term[F_EKIN] = trace(ekind->ekin);
-                }
-            }
-            /* if it's the initial step, we performed this first step just to get the constraint virial */
-            if (bInitStep && ir->eI==eiVV) {
-                copy_rvecn(cbuf,state->v,0,state->natoms);
-            }
-
-            if (fr->bSepDVDL && fplog && do_log)
-            {
-                fprintf(fplog,sepdvdlformat,"Constraint",0.0,dvdl);
-            }
-            enerd->term[F_DHDL_CON] += dvdl;
-
-            GMX_MPE_LOG(ev_timestep1);
-
-        }
-
-        /* MRS -- now done iterating -- compute the conserved quantity */
-        if (bVV) {
-            last_conserved = 0;
-            if (IR_NVT_TROTTER(ir) || IR_NPT_TROTTER(ir))
-            {
-                last_conserved =
-                    NPT_energy(ir,state,&MassQ);
-                if ((ir->eDispCorr != edispcEnerPres) && (ir->eDispCorr != edispcAllEnerPres))
-                {
-                    last_conserved -= enerd->term[F_DISPCORR];
-                }
-            }
-            if (ir->eI==eiVV) {
-                last_ekin = enerd->term[F_EKIN]; /* does this get preserved through checkpointing? */
-            }
-        }
-
-        /* ########  END FIRST UPDATE STEP  ############## */
-        /* ########  If doing VV, we now have v(dt) ###### */
-
-        /* ################## START TRAJECTORY OUTPUT ################# */
-
-        /* Now we have the energies and forces corresponding to the
-         * coordinates at time t. We must output all of this before
-         * the update.
-         * for RerunMD t is read from input trajectory
-         */
-        GMX_MPE_LOG(ev_output_start);
-
-        mdof_flags = 0;
-        if (do_per_step(step,ir->nstxout)) { mdof_flags |= MDOF_X; }
-        if (do_per_step(step,ir->nstvout)) { mdof_flags |= MDOF_V; }
-        if (do_per_step(step,ir->nstfout)) { mdof_flags |= MDOF_F; }
-        if (do_per_step(step,ir->nstxtcout)) { mdof_flags |= MDOF_XTC; }
-/*        if (bCPT) { mdof_flags |= MDOF_CPT; };*/
-
-#ifdef GMX_FAHCORE
-        if (MASTER(cr))
-            fcReportProgress( ir->nsteps, step );
-
-        if (bLastStep)
-        {
-            /* Enforce writing positions and velocities at end of run */
-            mdof_flags |= (MDOF_X | MDOF_V);
-        }
-            /* sync bCPT and fc record-keeping */
-/*            if (bCPT && MASTER(cr))
-                fcRequestCheckPoint();*/
-#endif
-
-        if (mdof_flags != 0)
-        {
-            wallcycle_start(wcycle,ewcTRAJ);
-/*            if (bCPT)
-            {
-                if (state->flags & (1<<estLD_RNG))
-                {
-                    get_stochd_state(upd,state);
-                }
-                if (MASTER(cr))
-                {
-                    if (bSumEkinhOld)
-                    {
-                        state_global->ekinstate.bUpToDate = FALSE;
-                    }
-                    else
-                    {
-                        update_ekinstate(&state_global->ekinstate,ekind);
-                        state_global->ekinstate.bUpToDate = TRUE;
-                    }
-                    update_energyhistory(&state_global->enerhist,mdebin);
-                }
-            }*/
-            write_traj(fplog,cr,outf,mdof_flags,top_global,
-                       step,t,state,state_global,f,f_global,&n_xtc,&x_xtc);
-/*            if (bCPT)
-            {
-                nchkpt++;
-                bCPT = FALSE;
-            }*/
-            debug_gmx();
-            if (bLastStep && step_rel == ir->nsteps &&
-                (Flags & MD_CONFOUT) && MASTER(cr) &&
-                !bRerunMD && !bFFscan)
-            {
-                /* x and v have been collected in write_traj,
-                 * because a checkpoint file will always be written
-                 * at the last step.
-                 */
-                fprintf(stderr,"\nWriting final coordinates.\n");
-                if (ir->ePBC != epbcNONE && !ir->bPeriodicMols &&
-                    DOMAINDECOMP(cr))
-                {
-                    /* Make molecules whole only for confout writing */
-                    do_pbc_mtop(fplog,ir->ePBC,state->box,top_global,state_global->x);
-                }
-/*                write_sto_conf_mtop(ftp2fn(efSTO,nfile,fnm),
-                                    *top_global->name,top_global,
-                                    state_global->x,state_global->v,
-                                    ir->ePBC,state->box);*/
-                debug_gmx();
-            }
-            wallcycle_stop(wcycle,ewcTRAJ);
-        }
-        GMX_MPE_LOG(ev_output_finish);
-
-        /* kludge -- virial is lost with restart for NPT control. Must restart */
-        if (bStartingFromCpt && bVV)
-        {
-            copy_mat(state->svir_prev,shake_vir);
-            copy_mat(state->fvir_prev,force_vir);
-        }
-        /*  ################## END TRAJECTORY OUTPUT ################ */
-
-        /* Determine the pressure:
-         * always when we want exact averages in the energy file,
-         * at ns steps when we have pressure coupling,
-         * otherwise only at energy output steps (set below).
-         */
-
-        bNstEner = (bGStatEveryStep || do_per_step(step,ir->nstcalcenergy));
-        bCalcEnerPres = bNstEner;
-
-        /* Do we need global communication ? */
-        bGStat = (bGStatEveryStep || bStopCM || bNS ||
-                  (ir->nstlist == -1 && !bRerunMD && step >= nlh.step_nscheck));
-
-        do_ene = (do_per_step(step,ir->nstenergy) || bLastStep);
-
-        if (do_ene || do_log)
-        {
-            bCalcEnerPres = TRUE;
-            bGStat        = TRUE;
-        }
-
-        /* Determine the wallclock run time up till now */
-        run_time = gmx_gettime() - (double)runtime->real;
-
-        /* Check whether everything is still allright */
-        if (((int)gmx_get_stop_condition() > handled_stop_condition)
-#ifdef GMX_THREADS
-           && MASTER(cr)
-#endif
-           )
-        {
-            /* this is just make gs.sig compatible with the hack
-               of sending signals around by MPI_Reduce with together with
-               other floats */
-            if ( gmx_get_stop_condition() == gmx_stop_cond_next_ns )
-                gs.sig[eglsSTOPCOND]=1;
-            if ( gmx_get_stop_condition() == gmx_stop_cond_next )
-                gs.sig[eglsSTOPCOND]=-1;
-            /* < 0 means stop at next step, > 0 means stop at next NS step */
-            if (fplog)
-            {
-                fprintf(fplog,
-                        "\n\nReceived the %s signal, stopping at the next %sstep\n\n",
-                        gmx_get_signal_name(),
-                        gs.sig[eglsSTOPCOND]==1 ? "NS " : "");
-                fflush(fplog);
-            }
-            fprintf(stderr,
-                    "\n\nReceived the %s signal, stopping at the next %sstep\n\n",
-                    gmx_get_signal_name(),
-                    gs.sig[eglsSTOPCOND]==1 ? "NS " : "");
-            fflush(stderr);
-            handled_stop_condition=(int)gmx_get_stop_condition();
-        }
-        else if (MASTER(cr) && (bNS || ir->nstlist <= 0) &&
-                 (max_hours > 0 && run_time > max_hours*60.0*60.0*0.99) &&
-                 gs.sig[eglsSTOPCOND] == 0 && gs.set[eglsSTOPCOND] == 0)
-        {
-            /* Signal to terminate the run */
-            gs.sig[eglsSTOPCOND] = 1;
-            if (fplog)
-            {
-                fprintf(fplog,"\nStep %s: Run time exceeded %.3f hours, will terminate the run\n",gmx_step_str(step,sbuf),max_hours*0.99);
-            }
-            fprintf(stderr, "\nStep %s: Run time exceeded %.3f hours, will terminate the run\n",gmx_step_str(step,sbuf),max_hours*0.99);
-        }
-
-        if (bResetCountersHalfMaxH && MASTER(cr) &&
-            run_time > max_hours*60.0*60.0*0.495)
-        {
-            gs.sig[eglsRESETCOUNTERS] = 1;
-        }
-
-        if (ir->nstlist == -1 && !bRerunMD)
-        {
-            /* When bGStatEveryStep=FALSE, global_stat is only called
-             * when we check the atom displacements, not at NS steps.
-             * This means that also the bonded interaction count check is not
-             * performed immediately after NS. Therefore a few MD steps could
-             * be performed with missing interactions.
-             * But wrong energies are never written to file,
-             * since energies are only written after global_stat
-             * has been called.
-             */
-            if (step >= nlh.step_nscheck)
-            {
-                nlh.nabnsb = natoms_beyond_ns_buffer(ir,fr,&top->cgs,
-                                                     nlh.scale_tot,state->x);
-            }
-            else
-            {
-                /* This is not necessarily true,
-                 * but step_nscheck is determined quite conservatively.
-                 */
-                nlh.nabnsb = 0;
-            }
-        }
-
-        /* In parallel we only have to check for checkpointing in steps
-         * where we do global communication,
-         *  otherwise the other nodes don't know.
-         */
-        if (MASTER(cr) && ((bGStat || !PAR(cr)) &&
-                           cpt_period >= 0 &&
-                           (cpt_period == 0 ||
-                            run_time >= nchkpt*cpt_period*60.0)) &&
-            gs.set[eglsCHKPT] == 0)
-        {
-            gs.sig[eglsCHKPT] = 1;
-        }
-
-        if (bIterations)
-        {
-            gmx_iterate_init(&iterate,bIterations);
-        }
-
-        /* for iterations, we save these vectors, as we will be redoing the calculations */
-        if (bIterations && iterate.bIterate)
-        {
-            copy_coupling_state(state,bufstate,ekind,ekind_save,&(ir->opts));
-        }
-        bFirstIterate = TRUE;
-        while (bFirstIterate || (bIterations && iterate.bIterate))
-        {
-            /* We now restore these vectors to redo the calculation with improved extended variables */
-            if (bIterations)
-            {
-                copy_coupling_state(bufstate,state,ekind_save,ekind,&(ir->opts));
-            }
-
-            /* We make the decision to break or not -after- the calculation of Ekin and Pressure,
-               so scroll down for that logic */
-
-            /* #########   START SECOND UPDATE STEP ################# */
-            GMX_MPE_LOG(ev_update_start);
-            bOK = TRUE;
-            if (!bRerunMD || rerun_fr.bV || bForceUpdate)
-            {
-                wallcycle_start(wcycle,ewcUPDATE);
-                dvdl = 0;
-                /* Box is changed in update() when we do pressure coupling,
-                 * but we should still use the old box for energy corrections and when
-                 * writing it to the energy file, so it matches the trajectory files for
-                 * the same timestep above. Make a copy in a separate array.
-                 */
-                copy_mat(state->box,lastbox);
-                /* UPDATE PRESSURE VARIABLES IN TROTTER FORMULATION WITH CONSTRAINTS */
-                if (bTrotter)
-                {
-                    if (bIterations && iterate.bIterate)
-                    {
-                        if (bFirstIterate)
-                        {
-                            scalevir = 1;
-                        }
-                        else
-                        {
-                            /* we use a new value of scalevir to converge the iterations faster */
-                            scalevir = tracevir/trace(shake_vir);
-                        }
-                        msmul(shake_vir,scalevir,shake_vir);
-                        m_add(force_vir,shake_vir,total_vir);
-                        clear_mat(shake_vir);
-                    }
-                    trotter_update(ir,step,ekind,enerd,state,total_vir,mdatoms,&MassQ, trotter_seq,ettTSEQ3);
-                }
-                /* We can only do Berendsen coupling after we have summed
-                 * the kinetic energy or virial. Since the happens
-                 * in global_state after update, we should only do it at
-                 * step % nstlist = 1 with bGStatEveryStep=FALSE.
-                 */
-
-               if (ir->eI != eiVVAK)
-                {
-                 update_tcouple(fplog,step,ir,state,ekind,wcycle,upd,&MassQ,mdatoms);
-                }
-                update_pcouple(fplog,step,ir,state,pcoupl_mu,M,wcycle,
-                                upd,bInitStep);
-
-               if (bVV)
-               {
-                   /* velocity half-step update */
-                   update_coords(fplog,step,ir,mdatoms,state,f,fr->bTwinRange && bNStList,fr->f_twin,fcd,
-                                 ekind,M,wcycle,upd,FALSE,etrtVELOCITY2,cr,nrnb,constr,&top->idef);
-               }
-
-                /* Above, initialize just copies ekinh into ekin,
-                 * it doesn't copy position (for VV),
-                 * and entire integrator for MD.
-                 */
-
-                if (ir->eI==eiVVAK)
-                {
-                    copy_rvecn(state->x,cbuf,0,state->natoms);
-                }
-
-                update_coords(fplog,step,ir,mdatoms,state,f,fr->bTwinRange && bNStList,fr->f_twin,fcd,
-                              ekind,M,wcycle,upd,bInitStep,etrtPOSITION,cr,nrnb,constr,&top->idef);
-                wallcycle_stop(wcycle,ewcUPDATE);
-
-                update_constraints(fplog,step,&dvdl,ir,ekind,mdatoms,state,graph,f,
-                                   &top->idef,shake_vir,force_vir,
-                                   cr,nrnb,wcycle,upd,constr,
-                                   bInitStep,FALSE,bCalcEnerPres,state->veta);
-
-                if (ir->eI==eiVVAK)
-                {
-                    /* erase F_EKIN and F_TEMP here? */
-                    /* just compute the kinetic energy at the half step to perform a trotter step */
-                    compute_globals(fplog,gstat,cr,ir,fr,ekind,state,state_global,mdatoms,nrnb,vcm,
-                                    wcycle,enerd,force_vir,shake_vir,total_vir,pres,mu_tot,
-                                    constr,NULL,FALSE,lastbox,
-                                    top_global,&pcurr,top_global->natoms,&bSumEkinhOld,
-                                    cglo_flags | CGLO_TEMPERATURE | CGLO_CONSTRAINT
-                        );
-                    wallcycle_start(wcycle,ewcUPDATE);
-                    trotter_update(ir,step,ekind,enerd,state,total_vir,mdatoms,&MassQ, trotter_seq,ettTSEQ4);
-                    /* now we know the scaling, we can compute the positions again again */
-                    copy_rvecn(cbuf,state->x,0,state->natoms);
-
-                    update_coords(fplog,step,ir,mdatoms,state,f,fr->bTwinRange && bNStList,fr->f_twin,fcd,
-                                  ekind,M,wcycle,upd,bInitStep,etrtPOSITION,cr,nrnb,constr,&top->idef);
-                    wallcycle_stop(wcycle,ewcUPDATE);
-
-                    /* do we need an extra constraint here? just need to copy out of state->v to upd->xp? */
-                    /* are the small terms in the shake_vir here due
-                     * to numerical errors, or are they important
-                     * physically? I'm thinking they are just errors, but not completely sure.
-                     * For now, will call without actually constraining, constr=NULL*/
-                    update_constraints(fplog,step,&dvdl,ir,ekind,mdatoms,state,graph,f,
-                                       &top->idef,tmp_vir,force_vir,
-                                       cr,nrnb,wcycle,upd,NULL,
-                                       bInitStep,FALSE,bCalcEnerPres,state->veta);
-                }
-                if (!bOK && !bFFscan)
-                {
-                    gmx_fatal(FARGS,"Constraint error: Shake, Lincs or Settle could not solve the constrains");
-                }
-
-                if (fr->bSepDVDL && fplog && do_log)
-                {
-                    fprintf(fplog,sepdvdlformat,"Constraint",0.0,dvdl);
-                }
-                enerd->term[F_DHDL_CON] += dvdl;
-            }
-            else if (graph)
-            {
-                /* Need to unshift here */
-                unshift_self(graph,state->box,state->x);
-            }
-
-            GMX_BARRIER(cr->mpi_comm_mygroup);
-            GMX_MPE_LOG(ev_update_finish);
-
-            if (vsite != NULL)
-            {
-                wallcycle_start(wcycle,ewcVSITECONSTR);
-                if (graph != NULL)
-                {
-                    shift_self(graph,state->box,state->x);
-                }
-                construct_vsites(fplog,vsite,state->x,nrnb,ir->delta_t,state->v,
-                                 top->idef.iparams,top->idef.il,
-                                 fr->ePBC,fr->bMolPBC,graph,cr,state->box);
-
-                if (graph != NULL)
-                {
-                    unshift_self(graph,state->box,state->x);
-                }
-                wallcycle_stop(wcycle,ewcVSITECONSTR);
-            }
-
-            /* ############## IF NOT VV, Calculate globals HERE, also iterate constraints ############ */
-            if (ir->nstlist == -1 && bFirstIterate)
-            {
-                gs.sig[eglsNABNSB] = nlh.nabnsb;
-            }
-            compute_globals(fplog,gstat,cr,ir,fr,ekind,state,state_global,mdatoms,nrnb,vcm,
-                            wcycle,enerd,force_vir,shake_vir,total_vir,pres,mu_tot,
-                            constr,
-                            bFirstIterate ? &gs : NULL,(step % gs.nstms == 0),
-                            lastbox,
-                            top_global,&pcurr,top_global->natoms,&bSumEkinhOld,
-                            cglo_flags
-                            | (!EI_VV(ir->eI) ? CGLO_ENERGY : 0)
-                            | (!EI_VV(ir->eI) ? CGLO_TEMPERATURE : 0)
-                            | (!EI_VV(ir->eI) || bRerunMD ? CGLO_PRESSURE : 0)
-                            | (bIterations && iterate.bIterate ? CGLO_ITERATE : 0)
-                            | (bFirstIterate ? CGLO_FIRSTITERATE : 0)
-                            | CGLO_CONSTRAINT
-                );
-            if (ir->nstlist == -1 && bFirstIterate)
-            {
-                nlh.nabnsb = gs.set[eglsNABNSB];
-                gs.set[eglsNABNSB] = 0;
-            }
-            /* bIterate is set to keep it from eliminating the old ekin kinetic energy terms */
-            /* #############  END CALC EKIN AND PRESSURE ################# */
-
-            /* Note: this is OK, but there are some numerical precision issues with using the convergence of
-               the virial that should probably be addressed eventually. state->veta has better properies,
-               but what we actually need entering the new cycle is the new shake_vir value. Ideally, we could
-               generate the new shake_vir, but test the veta value for convergence.  This will take some thought. */
-
-            if (bIterations &&
-                done_iterating(cr,fplog,step,&iterate,bFirstIterate,
-                               trace(shake_vir),&tracevir))
-            {
-                break;
-            }
-            bFirstIterate = FALSE;
-        }
-
-        update_box(fplog,step,ir,mdatoms,state,graph,f,
-                   ir->nstlist==-1 ? &nlh.scale_tot : NULL,pcoupl_mu,nrnb,wcycle,upd,bInitStep,FALSE);
-
-        /* ################# END UPDATE STEP 2 ################# */
-        /* #### We now have r(t+dt) and v(t+dt/2)  ############# */
-
-        /* The coordinates (x) were unshifted in update */
-/*        if (bFFscan && (shellfc==NULL || bConverged))
-        {
-            if (print_forcefield(fplog,enerd->term,mdatoms->homenr,
-                                 f,NULL,xcopy,
-                                 &(top_global->mols),mdatoms->massT,pres))
-            {
-                if (gmx_parallel_env_initialized())
-                {
-                    gmx_finalize();
-                }
-                fprintf(stderr,"\n");
-                exit(0);
-            }
-        }*/
-        if (!bGStat)
-        {
-            /* We will not sum ekinh_old,
-             * so signal that we still have to do it.
-             */
-            bSumEkinhOld = TRUE;
-        }
-
-/*        if (bTCR)
-        {*/
-            /* Only do GCT when the relaxation of shells (minimization) has converged,
-             * otherwise we might be coupling to bogus energies.
-             * In parallel we must always do this, because the other sims might
-             * update the FF.
-             */
-
-            /* Since this is called with the new coordinates state->x, I assume
-             * we want the new box state->box too. / EL 20040121
-             */
-/*            do_coupling(fplog,oenv,nfile,fnm,tcr,t,step,enerd->term,fr,
-                        ir,MASTER(cr),
-                        mdatoms,&(top->idef),mu_aver,
-                        top_global->mols.nr,cr,
-                        state->box,total_vir,pres,
-                        mu_tot,state->x,f,bConverged);
-            debug_gmx();
-        }*/
-
-        /* #########  BEGIN PREPARING EDR OUTPUT  ###########  */
-
-        sum_dhdl(enerd,state->lambda,ir);
-        /* use the directly determined last velocity, not actually the averaged half steps */
-        if (bTrotter && ir->eI==eiVV)
-        {
-            enerd->term[F_EKIN] = last_ekin;
-        }
-        enerd->term[F_ETOT] = enerd->term[F_EPOT] + enerd->term[F_EKIN];
-
-        switch (ir->etc)
-        {
-        case etcNO:
-            break;
-        case etcBERENDSEN:
-            break;
-        case etcNOSEHOOVER:
-            if (IR_NVT_TROTTER(ir)) {
-                enerd->term[F_ECONSERVED] = enerd->term[F_ETOT] + last_conserved;
-            } else {
-                enerd->term[F_ECONSERVED] = enerd->term[F_ETOT] +
-                    NPT_energy(ir,state,&MassQ);
-            }
-            break;
-        case etcVRESCALE:
-            enerd->term[F_ECONSERVED] =
-                enerd->term[F_ETOT] + vrescale_energy(&(ir->opts),
-                                                      state->therm_integral);
-            break;
-        default:
-            break;
-        }
-
-        /* Check for excessively large energies */
-/*        if (bIonize)
-        {
-#ifdef GMX_DOUBLE
-            real etot_max = 1e200;
-#else
-            real etot_max = 1e30;
-#endif
-            if (fabs(enerd->term[F_ETOT]) > etot_max)
-            {
-                fprintf(stderr,"Energy too large (%g), giving up\n",
-                        enerd->term[F_ETOT]);
-            }
-        }*/
-        /* #########  END PREPARING EDR OUTPUT  ###########  */
-
-        /* Time for performance */
-        if (((step % stepout) == 0) || bLastStep)
-        {
-            runtime_upd_proc(runtime);
-        }
-
-        /* Output stuff */
-        if (MASTER(cr))
-        {
-            gmx_bool do_dr,do_or;
-
-            if (!(bStartingFromCpt && (EI_VV(ir->eI))))
-            {
-                if (bNstEner)
-                {
-                    upd_mdebin(mdebin,bDoDHDL,TRUE,
-                               t,mdatoms->tmass,enerd,state,lastbox,
-                               shake_vir,force_vir,total_vir,pres,
-                               ekind,mu_tot,constr);
-                }
-                else
-                {
-                    upd_mdebin_step(mdebin);
-                }
-
-                do_dr  = do_per_step(step,ir->nstdisreout);
-                do_or  = do_per_step(step,ir->nstorireout);
-
-                print_ebin(outf->fp_ene,do_ene,do_dr,do_or,do_log?fplog:NULL,
-                           step,t,
-                           eprNORMAL,bCompact,mdebin,fcd,groups,&(ir->opts));
-            }
-            if (ir->ePull != epullNO)
-            {
-                pull_print_output(ir->pull,step,t);
-            }
-
-            if (do_per_step(step,ir->nstlog))
-            {
-                if(fflush(fplog) != 0)
-                {
-                    gmx_fatal(FARGS,"Cannot flush logfile - maybe you are out of quota?");
-                }
-            }
-        }
-
-
-        /* Remaining runtime */
-        if (MULTIMASTER(cr) && (do_verbose || gmx_got_usr_signal() ))
-        {
-            if (shellfc)
-            {
-                fprintf(stderr,"\n");
-            }
-            print_time(stderr,runtime,step,ir,cr);
-        }
-
-               /* Set new positions for the group to embed */
-               if(!bLastStep){
-                       if(step_rel<=it_xy)
-                       {
-                               fac[0]+=xy_step;
-                               fac[1]+=xy_step;
-                       } else if (step_rel<=(it_xy+it_z))
-                       {
-                               fac[2]+=z_step;
-                       }
-                       resize(ins_at,r_ins,state_global->x,pos_ins,fac);
-               }
-
-        /* Replica exchange */
-/*        bExchanged = FALSE;
-        if ((repl_ex_nst > 0) && (step > 0) && !bLastStep &&
-            do_per_step(step,repl_ex_nst))
-        {
-            bExchanged = replica_exchange(fplog,cr,repl_ex,
-                                          state_global,enerd->term,
-                                          state,step,t);
-        }
-        if (bExchanged && PAR(cr))
-        {
-            if (DOMAINDECOMP(cr))
-            {
-                dd_partition_system(fplog,step,cr,TRUE,1,
-                                    state_global,top_global,ir,
-                                    state,&f,mdatoms,top,fr,
-                                    vsite,shellfc,constr,
-                                    nrnb,wcycle,FALSE);
-            }
-            else
-            {
-                bcast_state(cr,state,FALSE);
-            }
-        }*/
-
-        bFirstStep = FALSE;
-        bInitStep = FALSE;
-        bStartingFromCpt = FALSE;
-
-        /* #######  SET VARIABLES FOR NEXT ITERATION IF THEY STILL NEED IT ###### */
-        /* Complicated conditional when bGStatEveryStep=FALSE.
-         * We can not just use bGStat, since then the simulation results
-         * would depend on nstenergy and nstlog or step_nscheck.
-         */
-        if (((state->flags & (1<<estPRES_PREV)) ||
-             (state->flags & (1<<estSVIR_PREV)) ||
-             (state->flags & (1<<estFVIR_PREV))) &&
-            (bGStatEveryStep ||
-             (ir->nstlist > 0 && step % ir->nstlist == 0) ||
-             (ir->nstlist < 0 && nlh.nabnsb > 0) ||
-             (ir->nstlist == 0 && bGStat)))
-        {
-            /* Store the pressure in t_state for pressure coupling
-             * at the next MD step.
-             */
-            if (state->flags & (1<<estPRES_PREV))
-            {
-                copy_mat(pres,state->pres_prev);
-            }
-        }
-
-        /* #######  END SET VARIABLES FOR NEXT ITERATION ###### */
-
-        if (bRerunMD)
-        {
-            /* read next frame from input trajectory */
-            bNotLastFrame = read_next_frame(oenv,status,&rerun_fr);
-        }
-
-        if (!bRerunMD || !rerun_fr.bStep)
-        {
-            /* increase the MD step number */
-            step++;
-            step_rel++;
-        }
-
-        cycles = wallcycle_stop(wcycle,ewcSTEP);
-        if (DOMAINDECOMP(cr) && wcycle)
-        {
-            dd_cycles_add(cr->dd,cycles,ddCyclStep);
-        }
-
-        if (step_rel == wcycle_get_reset_counters(wcycle) ||
-            gs.set[eglsRESETCOUNTERS] != 0)
-        {
-            /* Reset all the counters related to performance over the run */
-            reset_all_counters(fplog,cr,step,&step_rel,ir,wcycle,nrnb,runtime);
-            wcycle_set_reset_counters(wcycle,-1);
-            bResetCountersHalfMaxH = FALSE;
-            gs.set[eglsRESETCOUNTERS] = 0;
-        }
-    }
-    /* End of main MD loop */
-    debug_gmx();
-    write_sto_conf_mtop(ftp2fn(efSTO,nfile,fnm),
-                                        *top_global->name,top_global,
-                                        state_global->x,state_global->v,
-                                        ir->ePBC,state->box);
-
-    /* Stop the time */
-    runtime_end(runtime);
-
-    if (bRerunMD)
-    {
-        close_trj(status);
-    }
-
-    if (!(cr->duty & DUTY_PME))
-    {
-        /* Tell the PME only node to finish */
-        gmx_pme_finish(cr);
-    }
-
-    if (MASTER(cr))
-    {
-        if (ir->nstcalcenergy > 0 && !bRerunMD)
-        {
-            print_ebin(outf->fp_ene,FALSE,FALSE,FALSE,fplog,step,t,
-                       eprAVER,FALSE,mdebin,fcd,groups,&(ir->opts));
-        }
-    }
-
-    done_mdoutf(outf);
-
-    debug_gmx();
-
-    if (ir->nstlist == -1 && nlh.nns > 0 && fplog)
-    {
-        fprintf(fplog,"Average neighborlist lifetime: %.1f steps, std.dev.: %.1f steps\n",nlh.s1/nlh.nns,sqrt(nlh.s2/nlh.nns - sqr(nlh.s1/nlh.nns)));
-        fprintf(fplog,"Average number of atoms that crossed the half buffer length: %.1f\n\n",nlh.ab/nlh.nns);
-    }
-
-    if (shellfc && fplog)
-    {
-        fprintf(fplog,"Fraction of iterations that converged:           %.2f %%\n",
-                (nconverged*100.0)/step_rel);
-        fprintf(fplog,"Average number of force evaluations per MD step: %.2f\n\n",
-                tcount/step_rel);
-    }
-
-/*    if (repl_ex_nst > 0 && MASTER(cr))
-    {
-        print_replica_exchange_statistics(fplog,repl_ex);
-    }*/
-
-    runtime->nsteps_done = step_rel;
-
-    return 0;
-}
-
-
-int mdrunner_membed(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
-             const output_env_t oenv, gmx_bool bVerbose,gmx_bool bCompact,
-             int nstglobalcomm,
-             ivec ddxyz,int dd_node_order,real rdd,real rconstr,
-             const char *dddlb_opt,real dlb_scale,
-             const char *ddcsx,const char *ddcsy,const char *ddcsz,
-             int nstepout,int resetstep,int nmultisim,int repl_ex_nst,int repl_ex_seed,
-             real pforce,real cpt_period,real max_hours,
-             const char *deviceOptions,
-             unsigned long Flags,
-             real xy_fac, real xy_max, real z_fac, real z_max,
-             int it_xy, int it_z, real probe_rad, int low_up_rm,
-             int pieces, gmx_bool bALLOW_ASYMMETRY, int maxwarn)
-{
-    double     nodetime=0,realtime;
-    t_inputrec *inputrec;
-    t_state    *state=NULL;
-    matrix     box;
-    gmx_ddbox_t ddbox;
-    int        npme_major,npme_minor;
-    real       tmpr1,tmpr2;
-    t_nrnb     *nrnb;
-    gmx_mtop_t *mtop=NULL;
-    t_mdatoms  *mdatoms=NULL;
-    t_forcerec *fr=NULL;
-    t_fcdata   *fcd=NULL;
-    real       ewaldcoeff=0;
-    gmx_pme_t  *pmedata=NULL;
-    gmx_vsite_t *vsite=NULL;
-    gmx_constr_t constr;
-    int        i,m,nChargePerturbed=-1,status,nalloc;
-    char       *gro;
-    gmx_wallcycle_t wcycle;
-    gmx_bool       bReadRNG,bReadEkin;
-    int        list;
-    gmx_runtime_t runtime;
-    int        rc;
-    gmx_large_int_t reset_counters;
-    gmx_edsam_t ed=NULL;
-    t_commrec   *cr_old=cr;
-    int        nthreads=1,nthreads_requested=1;
-
-
-       char                    *ins;
-       int                     rm_bonded_at,fr_id,fr_i=0,tmp_id,warn=0;
-       int                     ng,j,max_lip_rm,ins_grp_id,ins_nat,mem_nat,ntype,lip_rm,tpr_version;
-       real                    xy_step=0,z_step=0;
-       real                    prot_area;
-       rvec                    *r_ins=NULL,fac;
-       t_block                 *ins_at,*rest_at;
-       pos_ins_t               *pos_ins;
-       mem_t                   *mem_p;
-       rm_t                    *rm_p;
-       gmx_groups_t            *groups;
-       gmx_bool                        bExcl=FALSE;
-       t_atoms                 atoms;
-       t_pbc                   *pbc;
-       char                    **piecename=NULL;
-
-    /* CAUTION: threads may be started later on in this function, so
-       cr doesn't reflect the final parallel state right now */
-    snew(inputrec,1);
-    snew(mtop,1);
-
-    if (bVerbose && SIMMASTER(cr))
-    {
-        fprintf(stderr,"Getting Loaded...\n");
-    }
-
-    if (Flags & MD_APPENDFILES)
-    {
-        fplog = NULL;
-    }
-
-    snew(state,1);
-    if (MASTER(cr))
-    {
-        /* Read (nearly) all data required for the simulation */
-        read_tpx_state(ftp2fn(efTPX,nfile,fnm),inputrec,state,NULL,mtop);
-
-        /* NOW the threads will be started: */
-#ifdef GMX_THREADS
-#endif
-    }
-    /* END OF CAUTION: cr is now reliable */
-
-    if (PAR(cr))
-    {
-        /* now broadcast everything to the non-master nodes/threads: */
-        init_parallel(fplog, cr, inputrec, mtop);
-    }
-    /* now make sure the state is initialized and propagated */
-    set_state_entries(state,inputrec,cr->nnodes);
-
-    if (can_use_allvsall(inputrec,mtop,TRUE,cr,fplog))
-    {
-        /* All-vs-all loops do not work with domain decomposition */
-        Flags |= MD_PARTDEC;
-    }
-
-    if (!EEL_PME(inputrec->coulombtype) || (Flags & MD_PARTDEC))
-    {
-        cr->npmenodes = 0;
-    }
-
-       snew(ins_at,1);
-       snew(pos_ins,1);
-       if(MASTER(cr))
-       {
-               tpr_version = get_tpr_version(ftp2fn(efTPX,nfile,fnm));
-               if (tpr_version<58)
-                       gmx_fatal(FARGS,"Version of *.tpr file to old (%d). Rerun grompp with gromacs VERSION 4.0.3 or newer.\n",tpr_version);
-
-               if( inputrec->eI != eiMD )
-                       gmx_input("Change integrator to md in mdp file.");
-
-               if(PAR(cr))
-                       gmx_input("Sorry, parallel g_membed is not yet fully functrional.");
-
-               groups=&(mtop->groups);
-
-               atoms=gmx_mtop_global_atoms(mtop);
-               snew(mem_p,1);
-               fprintf(stderr,"\nSelect a group to embed in the membrane:\n");
-               get_index(&atoms,ftp2fn_null(efNDX,nfile,fnm),1,&(ins_at->nr),&(ins_at->index),&ins);
-               ins_grp_id = search_string(ins,groups->ngrpname,(groups->grpname));
-               fprintf(stderr,"\nSelect a group to embed %s into (e.g. the membrane):\n",ins);
-               get_index(&atoms,ftp2fn_null(efNDX,nfile,fnm),1,&(mem_p->mem_at.nr),&(mem_p->mem_at.index),&(mem_p->name));
-
-               pos_ins->pieces=pieces;
-               snew(pos_ins->nidx,pieces);
-               snew(pos_ins->subindex,pieces);
-               snew(piecename,pieces); 
-               if (pieces>1)
-               {
-                       fprintf(stderr,"\nSelect pieces to embed:\n");
-                       get_index(&atoms,ftp2fn_null(efNDX,nfile,fnm),pieces,pos_ins->nidx,pos_ins->subindex,piecename);
-               }
-               else
-               {       
-                       /*use whole embedded group*/
-                       snew(pos_ins->nidx,1);
-                       snew(pos_ins->subindex,1);
-                       pos_ins->nidx[0]=ins_at->nr;
-                       pos_ins->subindex[0]=ins_at->index;
-               }
-
-               if(probe_rad<0.2199999)
-               {
-                       warn++;
-                       fprintf(stderr,"\nWarning %d:\nA probe radius (-rad) smaller than 0.2 can result in overlap between waters "
-                                       "and the group to embed, which will result in Lincs errors etc.\nIf you are sure, you can increase maxwarn.\n\n",warn);
-               }
-
-               if(xy_fac<0.09999999)
-               {
-                       warn++;
-                       fprintf(stderr,"\nWarning %d:\nThe initial size of %s is probably too smal.\n"
-                                       "If you are sure, you can increase maxwarn.\n\n",warn,ins);
-               }
-
-               if(it_xy<1000)
-               {
-                       warn++;
-                       fprintf(stderr,"\nWarning %d;\nThe number of steps used to grow the xy-coordinates of %s (%d) is probably too small.\n"
-                                       "Increase -nxy or, if you are sure, you can increase maxwarn.\n\n",warn,ins,it_xy);
-               }
-
-               if( (it_z<100) && ( z_fac<0.99999999 || z_fac>1.0000001) )
-                {
-                        warn++;
-                        fprintf(stderr,"\nWarning %d;\nThe number of steps used to grow the z-coordinate of %s (%d) is probably too small.\n"
-                                       "Increase -nz or, if you are sure, you can increase maxwarn.\n\n",warn,ins,it_z);
-                }
-
-               if(it_xy+it_z>inputrec->nsteps)
-               {
-                       warn++;
-                       fprintf(stderr,"\nWarning %d:\nThe number of growth steps (-nxy + -nz) is larger than the number of steps in the tpr.\n"
-                                       "If you are sure, you can increase maxwarn.\n\n",warn);
-               }
-
-               fr_id=-1;
-               if( inputrec->opts.ngfrz==1)
-                       gmx_fatal(FARGS,"You did not specify \"%s\" as a freezegroup.",ins);
-               for(i=0;i<inputrec->opts.ngfrz;i++)
-               {
-                       tmp_id = mtop->groups.grps[egcFREEZE].nm_ind[i];
-                       if(ins_grp_id==tmp_id)
-                       {
-                               fr_id=tmp_id;
-                               fr_i=i;
-                       }
-               }
-               if (fr_id == -1 )
-                       gmx_fatal(FARGS,"\"%s\" not as freezegroup defined in the mdp-file.",ins);
-
-               for(i=0;i<DIM;i++)
-                       if( inputrec->opts.nFreeze[fr_i][i] != 1)
-                               gmx_fatal(FARGS,"freeze dimensions for %s are not Y Y Y\n",ins);
-
-               ng = groups->grps[egcENER].nr;
-               if (ng == 1)
-                       gmx_input("No energy groups defined. This is necessary for energy exclusion in the freeze group");
-
-               for(i=0;i<ng;i++)
-               {
-                       for(j=0;j<ng;j++)
-                       {
-                               if (inputrec->opts.egp_flags[ng*i+j] == EGP_EXCL)
-                               {
-                                       bExcl = TRUE;
-                                       if ( (groups->grps[egcENER].nm_ind[i] != ins_grp_id) || (groups->grps[egcENER].nm_ind[j] != ins_grp_id) )
-                                               gmx_fatal(FARGS,"Energy exclusions \"%s\" and  \"%s\" do not match the group to embed \"%s\"",
-                                                               *groups->grpname[groups->grps[egcENER].nm_ind[i]],
-                                                               *groups->grpname[groups->grps[egcENER].nm_ind[j]],ins);
-                               }
-                       }
-               }
-               if (!bExcl)
-                       gmx_input("No energy exclusion groups defined. This is necessary for energy exclusion in the freeze group");
-
-               /* Set all atoms in box*/
-               /*set_inbox(state->natoms,state->x);*/
-
-               /* Guess the area the protein will occupy in the membrane plane  Calculate area per lipid*/
-               snew(rest_at,1);
-               ins_nat = init_ins_at(ins_at,rest_at,state,pos_ins,groups,ins_grp_id,xy_max);
-               /* Check moleculetypes in insertion group */
-               check_types(ins_at,rest_at,mtop);
-
-               mem_nat = init_mem_at(mem_p,mtop,state->x,state->box,pos_ins);
-
-               prot_area = est_prot_area(pos_ins,state->x,ins_at,mem_p);
-               if ( (prot_area>7.5) && ( (state->box[XX][XX]*state->box[YY][YY]-state->box[XX][YY]*state->box[YY][XX])<50) )
-               {
-                       warn++;
-                       fprintf(stderr,"\nWarning %d:\nThe xy-area is very small compared to the area of the protein.\n"
-                                       "This might cause pressure problems during the growth phase. Just try with\n"
-                                       "current setup (-maxwarn + 1), but if pressure problems occur, lower the\n"
-                                       "compressibility in the mdp-file or use no pressure coupling at all.\n\n",warn);
-               }
-               if(warn>maxwarn)
-                                       gmx_fatal(FARGS,"Too many warnings.\n");
-
-               printf("The estimated area of the protein in the membrane is %.3f nm^2\n",prot_area);
-               printf("\nThere are %d lipids in the membrane part that overlaps the protein.\nThe area per lipid is %.4f nm^2.\n",mem_p->nmol,mem_p->lip_area);
-
-               /* Maximum number of lipids to be removed*/
-               max_lip_rm=(int)(2*prot_area/mem_p->lip_area);
-               printf("Maximum number of lipids that will be removed is %d.\n",max_lip_rm);
-
-               printf("\nWill resize the protein by a factor of %.3f in the xy plane and %.3f in the z direction.\n"
-                               "This resizing will be done with respect to the geometrical center of all protein atoms\n"
-                               "that span the membrane region, i.e. z between %.3f and %.3f\n\n",xy_fac,z_fac,mem_p->zmin,mem_p->zmax);
-
-               /* resize the protein by xy and by z if necessary*/
-               snew(r_ins,ins_at->nr);
-               init_resize(ins_at,r_ins,pos_ins,mem_p,state->x,bALLOW_ASYMMETRY);
-               fac[0]=fac[1]=xy_fac;
-               fac[2]=z_fac;
-
-               xy_step =(xy_max-xy_fac)/(double)(it_xy);
-               z_step  =(z_max-z_fac)/(double)(it_z-1);
-
-               resize(ins_at,r_ins,state->x,pos_ins,fac);
-
-               /* remove overlapping lipids and water from the membrane box*/
-               /*mark molecules to be removed*/
-               snew(pbc,1);
-               set_pbc(pbc,inputrec->ePBC,state->box);
-
-               snew(rm_p,1);
-               lip_rm = gen_rm_list(rm_p,ins_at,rest_at,pbc,mtop,state->x, r_ins, mem_p,pos_ins,probe_rad,low_up_rm,bALLOW_ASYMMETRY);
-        lip_rm -= low_up_rm;
-
-               if(fplog)
-                       for(i=0;i<rm_p->nr;i++)
-                               fprintf(fplog,"rm mol %d\n",rm_p->mol[i]);
-
-               for(i=0;i<mtop->nmolblock;i++)
-               {
-                       ntype=0;
-                       for(j=0;j<rm_p->nr;j++)
-                               if(rm_p->block[j]==i)
-                                       ntype++;
-                       printf("Will remove %d %s molecules\n",ntype,*(mtop->moltype[mtop->molblock[i].type].name));
-               }
-
-               if(lip_rm>max_lip_rm)
-               {
-                       warn++;
-                       fprintf(stderr,"\nWarning %d:\nTrying to remove a larger lipid area than the estimated protein area\n"
-                                       "Try making the -xyinit resize factor smaller. If you are sure about this increase maxwarn.\n\n",warn);
-               }
-
-               /*remove all lipids and waters overlapping and update all important structures*/
-               rm_group(inputrec,groups,mtop,rm_p,state,ins_at,pos_ins);
-
-               rm_bonded_at = rm_bonded(ins_at,mtop);
-               if (rm_bonded_at != ins_at->nr)
-               {
-                       fprintf(stderr,"Warning: The number of atoms for which the bonded interactions are removed is %d, "
-                                       "while %d atoms are embedded. Make sure that the atoms to be embedded are not in the same"
-                                       "molecule type as atoms that are not to be embedded.\n",rm_bonded_at,ins_at->nr);
-               }
-
-               if(warn>maxwarn)
-                       gmx_fatal(FARGS,"Too many warnings.\nIf you are sure these warnings are harmless, you can increase -maxwarn");
-
-               if (MASTER(cr))
-               {
-                       if (ftp2bSet(efTOP,nfile,fnm))
-                               top_update(opt2fn("-p",nfile,fnm),ins,rm_p,mtop);
-               }
-
-               sfree(pbc);
-               sfree(rest_at);
-       }
-
-#ifdef GMX_FAHCORE
-    fcRegisterSteps(inputrec->nsteps,inputrec->init_step);
-#endif
-
-    /* NMR restraints must be initialized before load_checkpoint,
-     * since with time averaging the history is added to t_state.
-     * For proper consistency check we therefore need to extend
-     * t_state here.
-     * So the PME-only nodes (if present) will also initialize
-     * the distance restraints.
-     */
-    snew(fcd,1);
-
-    /* This needs to be called before read_checkpoint to extend the state */
-    init_disres(fplog,mtop,inputrec,cr,Flags & MD_PARTDEC,fcd,state);
-
-    if (gmx_mtop_ftype_count(mtop,F_ORIRES) > 0)
-    {
-        if (PAR(cr) && !(Flags & MD_PARTDEC))
-        {
-            gmx_fatal(FARGS,"Orientation restraints do not work (yet) with domain decomposition, use particle decomposition (mdrun option -pd)");
-        }
-        /* Orientation restraints */
-        if (MASTER(cr))
-        {
-            init_orires(fplog,mtop,state->x,inputrec,cr->ms,&(fcd->orires),
-                        state);
-        }
-    }
-
-    if (DEFORM(*inputrec))
-    {
-        /* Store the deform reference box before reading the checkpoint */
-        if (SIMMASTER(cr))
-        {
-            copy_mat(state->box,box);
-        }
-        if (PAR(cr))
-        {
-            gmx_bcast(sizeof(box),box,cr);
-        }
-        /* Because we do not have the update struct available yet
-         * in which the reference values should be stored,
-         * we store them temporarily in static variables.
-         * This should be thread safe, since they are only written once
-         * and with identical values.
-         */
-/*        deform_init_init_step_tpx = inputrec->init_step;*/
-/*        copy_mat(box,deform_init_box_tpx);*/
-    }
-
-    if (opt2bSet("-cpi",nfile,fnm))
-    {
-        /* Check if checkpoint file exists before doing continuation.
-         * This way we can use identical input options for the first and subsequent runs...
-         */
-        if( gmx_fexist_master(opt2fn_master("-cpi",nfile,fnm,cr),cr) )
-        {
-            load_checkpoint(opt2fn_master("-cpi",nfile,fnm,cr),&fplog,
-                            cr,Flags & MD_PARTDEC,ddxyz,
-                            inputrec,state,&bReadRNG,&bReadEkin,
-                            (Flags & MD_APPENDFILES));
-
-            if (bReadRNG)
-            {
-                Flags |= MD_READ_RNG;
-            }
-            if (bReadEkin)
-            {
-                Flags |= MD_READ_EKIN;
-            }
-        }
-    }
-
-    if ((MASTER(cr) || (Flags & MD_SEPPOT)) && (Flags & MD_APPENDFILES))
-    {
-        gmx_log_open(ftp2fn(efLOG,nfile,fnm),cr,!(Flags & MD_SEPPOT),
-                             Flags,&fplog);
-    }
-
-    if (SIMMASTER(cr))
-    {
-        copy_mat(state->box,box);
-    }
-
-    if (PAR(cr))
-    {
-        gmx_bcast(sizeof(box),box,cr);
-    }
-
-    if (bVerbose && SIMMASTER(cr))
-    {
-        fprintf(stderr,"Loaded with Money\n\n");
-    }
-
-    if (PAR(cr) && !((Flags & MD_PARTDEC) || EI_TPI(inputrec->eI)))
-    {
-        cr->dd = init_domain_decomposition(fplog,cr,Flags,ddxyz,rdd,rconstr,
-                                           dddlb_opt,dlb_scale,
-                                           ddcsx,ddcsy,ddcsz,
-                                           mtop,inputrec,
-                                           box,state->x,
-                                           &ddbox,&npme_major,&npme_minor);
-
-        make_dd_communicators(fplog,cr,dd_node_order);
-
-        /* Set overallocation to avoid frequent reallocation of arrays */
-        set_over_alloc_dd(TRUE);
-    }
-    else
-    {
-        /* PME, if used, is done on all nodes with 1D decomposition */
-        cr->npmenodes = 0;
-        cr->duty = (DUTY_PP | DUTY_PME);
-        npme_major = cr->nnodes;
-        npme_minor = 1;
-
-        if (inputrec->ePBC == epbcSCREW)
-        {
-            gmx_fatal(FARGS,
-                      "pbc=%s is only implemented with domain decomposition",
-                      epbc_names[inputrec->ePBC]);
-        }
-    }
-
-    if (PAR(cr))
-    {
-        /* After possible communicator splitting in make_dd_communicators.
-         * we can set up the intra/inter node communication.
-         */
-        gmx_setup_nodecomm(fplog,cr);
-    }
-
-    wcycle = wallcycle_init(fplog,resetstep,cr);
-    if (PAR(cr))
-    {
-        /* Master synchronizes its value of reset_counters with all nodes
-         * including PME only nodes */
-        reset_counters = wcycle_get_reset_counters(wcycle);
-        gmx_bcast_sim(sizeof(reset_counters),&reset_counters,cr);
-        wcycle_set_reset_counters(wcycle, reset_counters);
-    }
-
-
-    snew(nrnb,1);
-    if (cr->duty & DUTY_PP)
-    {
-        /* For domain decomposition we allocate dynamically
-         * in dd_partition_system.
-         */
-        if (DOMAINDECOMP(cr))
-        {
-            bcast_state_setup(cr,state);
-        }
-        else
-        {
-            if (PAR(cr))
-            {
-                if (!MASTER(cr))
-                {
-                    snew(state,1);
-                }
-                bcast_state(cr,state,TRUE);
-            }
-        }
-
-        /* Dihedral Restraints */
-        if (gmx_mtop_ftype_count(mtop,F_DIHRES) > 0)
-        {
-            init_dihres(fplog,mtop,inputrec,fcd);
-        }
-
-        /* Initiate forcerecord */
-        fr = mk_forcerec();
-        init_forcerec(fplog,oenv,fr,fcd,inputrec,mtop,cr,box,FALSE,
-                      opt2fn("-table",nfile,fnm),
-                      opt2fn("-tablep",nfile,fnm),
-                      opt2fn("-tableb",nfile,fnm),FALSE,pforce);
-
-        /* version for PCA_NOT_READ_NODE (see md.c) */
-        /*init_forcerec(fplog,fr,fcd,inputrec,mtop,cr,box,FALSE,
-          "nofile","nofile","nofile",FALSE,pforce);
-          */
-        fr->bSepDVDL = ((Flags & MD_SEPPOT) == MD_SEPPOT);
-
-        /* Initialize QM-MM */
-        if(fr->bQMMM)
-        {
-            init_QMMMrec(cr,box,mtop,inputrec,fr);
-        }
-
-        /* Initialize the mdatoms structure.
-         * mdatoms is not filled with atom data,
-         * as this can not be done now with domain decomposition.
-         */
-        mdatoms = init_mdatoms(fplog,mtop,inputrec->efep!=efepNO);
-
-        /* Initialize the virtual site communication */
-        vsite = init_vsite(mtop,cr);
-
-        calc_shifts(box,fr->shift_vec);
-
-        /* With periodic molecules the charge groups should be whole at start up
-         * and the virtual sites should not be far from their proper positions.
-         */
-        if (!inputrec->bContinuation && MASTER(cr) &&
-            !(inputrec->ePBC != epbcNONE && inputrec->bPeriodicMols))
-        {
-            /* Make molecules whole at start of run */
-            if (fr->ePBC != epbcNONE)
-            {
-                do_pbc_first_mtop(fplog,inputrec->ePBC,box,mtop,state->x);
-            }
-            if (vsite)
-            {
-                /* Correct initial vsite positions are required
-                 * for the initial distribution in the domain decomposition
-                 * and for the initial shell prediction.
-                 */
-                construct_vsites_mtop(fplog,vsite,mtop,state->x);
-            }
-        }
-
-        /* Initiate PPPM if necessary */
-        if (fr->eeltype == eelPPPM)
-        {
-            if (mdatoms->nChargePerturbed)
-            {
-                gmx_fatal(FARGS,"Free energy with %s is not implemented",
-                          eel_names[fr->eeltype]);
-            }
-            status = gmx_pppm_init(fplog,cr,oenv,FALSE,TRUE,box,
-                                   getenv("GMXGHAT"),inputrec, (Flags & MD_REPRODUCIBLE));
-            if (status != 0)
-            {
-                gmx_fatal(FARGS,"Error %d initializing PPPM",status);
-            }
-        }
-
-        if (EEL_PME(fr->eeltype))
-        {
-            ewaldcoeff = fr->ewaldcoeff;
-            pmedata = &fr->pmedata;
-        }
-        else
-        {
-            pmedata = NULL;
-        }
-    }
-    else
-    {
-        /* This is a PME only node */
-
-        /* We don't need the state */
-        done_state(state);
-
-        ewaldcoeff = calc_ewaldcoeff(inputrec->rcoulomb, inputrec->ewald_rtol);
-        snew(pmedata,1);
-    }
-
-    /* Initiate PME if necessary,
-     * either on all nodes or on dedicated PME nodes only. */
-    if (EEL_PME(inputrec->coulombtype))
-    {
-        if (mdatoms)
-        {
-            nChargePerturbed = mdatoms->nChargePerturbed;
-        }
-        if (cr->npmenodes > 0)
-        {
-            /* The PME only nodes need to know nChargePerturbed */
-            gmx_bcast_sim(sizeof(nChargePerturbed),&nChargePerturbed,cr);
-        }
-        if (cr->duty & DUTY_PME)
-        {
-            status = gmx_pme_init(pmedata,cr,npme_major,npme_minor,inputrec,
-                                  mtop ? mtop->natoms : 0,nChargePerturbed,
-                                  (Flags & MD_REPRODUCIBLE));
-            if (status != 0)
-            {
-                gmx_fatal(FARGS,"Error %d initializing PME",status);
-            }
-        }
-    }
-
-
-/*    if (integrator[inputrec->eI].func == do_md
-#ifdef GMX_OPENMM
-        ||
-        integrator[inputrec->eI].func == do_md_openmm
-#endif
-        )
-    {*/
-        /* Turn on signal handling on all nodes */
-        /*
-         * (A user signal from the PME nodes (if any)
-         * is communicated to the PP nodes.
-         */
-        signal_handler_install();
-/*    }*/
-
-    if (cr->duty & DUTY_PP)
-    {
-        if (inputrec->ePull != epullNO)
-        {
-            /* Initialize pull code */
-            init_pull(fplog,inputrec,nfile,fnm,mtop,cr,oenv,
-                      EI_DYNAMICS(inputrec->eI) && MASTER(cr),Flags);
-        }
-
-        constr = init_constraints(fplog,mtop,inputrec,ed,state,cr);
-
-        if (DOMAINDECOMP(cr))
-        {
-            dd_init_bondeds(fplog,cr->dd,mtop,vsite,constr,inputrec,
-                            Flags & MD_DDBONDCHECK,fr->cginfo_mb);
-
-            set_dd_parameters(fplog,cr->dd,dlb_scale,inputrec,fr,&ddbox);
-
-            setup_dd_grid(fplog,cr->dd);
-        }
-
-        /* Now do whatever the user wants us to do (how flexible...) */
-        do_md_membed(fplog,cr,nfile,fnm,
-                                      oenv,bVerbose,bCompact,
-                                      nstglobalcomm,
-                                      vsite,constr,
-                                      nstepout,inputrec,mtop,
-                                      fcd,state,
-                                      mdatoms,nrnb,wcycle,ed,fr,
-                                      repl_ex_nst,repl_ex_seed,
-                                      cpt_period,max_hours,
-                                      deviceOptions,
-                                      Flags,
-                                      &runtime,
-                                      fac, r_ins, pos_ins, ins_at,
-                                      xy_step, z_step, it_xy, it_z);
-
-        if (inputrec->ePull != epullNO)
-        {
-            finish_pull(fplog,inputrec->pull);
-        }
-    }
-    else
-    {
-        /* do PME only */
-        gmx_pmeonly(*pmedata,cr,nrnb,wcycle,ewaldcoeff,FALSE,inputrec);
-    }
-
-    if (EI_DYNAMICS(inputrec->eI) || EI_TPI(inputrec->eI))
-    {
-        /* Some timing stats */
-        if (MASTER(cr))
-        {
-            if (runtime.proc == 0)
-            {
-                runtime.proc = runtime.real;
-            }
-        }
-        else
-        {
-            runtime.real = 0;
-        }
-    }
-
-    wallcycle_stop(wcycle,ewcRUN);
-
-    /* Finish up, write some stuff
-     * if rerunMD, don't write last frame again
-     */
-    finish_run(fplog,cr,ftp2fn(efSTO,nfile,fnm),
-               inputrec,nrnb,wcycle,&runtime,
-               EI_DYNAMICS(inputrec->eI) && !MULTISIM(cr));
-
-    /* Does what it says */
-    print_date_and_time(fplog,cr->nodeid,"Finished mdrun",&runtime);
-
-    /* Close logfile already here if we were appending to it */
-    if (MASTER(cr) && (Flags & MD_APPENDFILES))
-    {
-        gmx_log_close(fplog);
-    }
-
-    if (pieces>1)
-    {
-       sfree(piecename);
-    }
-
-    rc=(int)gmx_get_stop_condition();
-
-    return rc;
-}
-
-
 int gmx_membed(int argc,char *argv[])
 {
        const char *desc[] = {
@@ -4320,6 +120,7 @@ int gmx_membed(int argc,char *argv[])
        int maxwarn=0;
        int pieces=1;
         gmx_bool bALLOW_ASYMMETRY=FALSE;
+        gmx_bool bStart=FALSE;
         int nstepout=100;
         gmx_bool bVerbose=FALSE;
         char *mdrun_path=NULL;
@@ -4352,6 +153,8 @@ int gmx_membed(int argc,char *argv[])
                                "Number of lipids that will additionally be removed from the lower (negative number) or upper (positive number) membrane leaflet." },
                        { "-maxwarn", FALSE, etINT, {&maxwarn},         
                                "Maximum number of warning allowed" },
+                        { "-start",   FALSE, etBOOL, {&bStart},
+                                "Call mdrun with membed options" },
                        { "-stepout", FALSE, etINT, {&nstepout},
                                "HIDDENFrequency of writing the remaining runtime" },
                        { "-v",       FALSE, etBOOL,{&bVerbose},
@@ -4401,7 +204,12 @@ int gmx_membed(int argc,char *argv[])
        }
 
         printf("%s\n",buf);
-        system(buf);
+        if (bStart)
+        {
+                system(buf);
+        } else {
+                printf("You can membed your protein now by:\n%s\n",buf);
+        }
 
         fprintf(stderr,"Please cite:\nWolf et al, J Comp Chem 31 (2010) 2169-2174.\n");
 
index 7f7dbeb3c6675984bc0935d41ec3d536c9178c19..0d59616405dbe769e9f5a0f40a7ae68447bc3c49 100644 (file)
@@ -122,8 +122,9 @@ int gmx_saltbr(int argc,char *argv[])
   const char *desc[] = {
     "g_saltbr plots the distance between all combination of charged groups",
     "as a function of time. The groups are combined in different ways.",
-    "A minimum distance can be given, (eg. the cut-off), then groups",
-    "that are never closer than that distance will not be plotted.[BR]",
+    "A truncation/cut-off distance can be supplied with -t, ",
+    "such that only groups interacting within this distance will be plotted in the ",
+    "output.[BR]",
     "Output will be in a number of fixed filenames, min-min.xvg, plus-min.xvg",
     "and plus-plus.xvg, or files for every individual ion-pair if the [TT]-sep[tt]",
     "option is selected. In this case files are named as [TT]sb-ResnameResnr-Atomnr[tt].",
index da974a4f792f67b86708dfe7b200d61e5bd53949..ed6e9bb407b59468b18ada313746108f29b50ab7 100644 (file)
 #include <config.h>
 #endif
 
+
+#include <time.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+
+
 #include "statutil.h"
 #include "typedefs.h"
 #include "smalloc.h"
index d656889836ac0192e31a2a965407611695bf9c62..8ea9ce9fd38583256cc2bc9cbe644797001d5a0d 100644 (file)
@@ -162,8 +162,9 @@ int gmx_velacc(int argc,char *argv[])
   parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE,
                    NFILE,fnm,npargs,ppa,asize(desc),desc,0,NULL,&oenv);
 
-  if (bMol)
-    bTPS = bM || ftp2bSet(efTPS,NFILE,fnm) || !ftp2bSet(efNDX,NFILE,fnm);
+  if (bMol || bM) {
+    bTPS = ftp2bSet(efTPS,NFILE,fnm) || !ftp2bSet(efNDX,NFILE,fnm);
+  }
 
   if (bTPS) {
     bTop=read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,NULL,NULL,box,
index ff7c7a39b098f2fd9053bbea8f4f5a6adfcf526a..fa0e58a8b121f070658c9ff44477cc3eba441c1d 100644 (file)
@@ -1,11 +1,12 @@
+/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*- */ 
 /*
- *
+ * 
  *                This source code is part of
- *
+ * 
  *                 G   R   O   M   A   C   S
- *
+ * 
  *          GROningen MAchine for Chemical Simulations
- *
+ * 
  *                        VERSION 3.2.0
  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  * of the License, or (at your option) any later version.
- *
+ * 
  * If you want to redistribute modifications, please consider that
  * scientific software is very special. Version control is crucial -
  * bugs must be traceable. We will be happy to consider code for
  * inclusion in the official distribution, but derived work must not
  * be called official GROMACS. Details are found in the README & COPYING
  * files - if they are missing, get the official version at www.gromacs.org.
- *
+ * 
  * To help us fund GROMACS development, we humbly ask that you cite
  * the papers on the package - you can find them in the top README file.
- *
+ * 
  * For more info, check our website at http://www.gromacs.org
- *
+ * 
  * And Hey:
  * Green Red Orange Magenta Azure Cyan Skyblue
  */
@@ -36,8 +37,6 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
-
-
 #include <stdio.h>
 
 #include "statutil.h"
@@ -48,9 +47,9 @@
 #include "statutil.h"
 #include "tpxio.h"
 #include "names.h"
+#include "gmx_random.h"
 #include "gmx_ana.h"
 
-
 #ifndef HAVE_STRDUP
 #define HAVE_STRDUP
 #endif
 #include "xvgr.h"
 
 
+#define WHAM_MAXFILELEN 2048
+
 /* enum for energy units */
 enum { enSel, en_kJ, en_kCal, en_kT, enNr };
 /* enum for type of input files (pdos, tpr, or pullf) */
 enum { whamin_unknown, whamin_tpr, whamin_pullxf, whamin_pdo };
-/* enum for methods to make profile cyclic/periodic */
-enum { enCycl, enCycl_no, enCycl_yes, enCycl_weighted, enCycl_nr};
+/* enum for bootstrapping method (
+   - bootstrap complete histograms with continuous weights (Bayesian bootstrap)
+   - bootstrap complete histograms
+   - bootstrap trajectories from given umbrella histograms
+   - bootstrap trajectories from Gaussian with mu/sigam computed from 
+   the respective histogram
+   
+   ********************************************************************
+   FOR MORE DETAILS ON THE BOOTSTRAP METHODS (INCLUDING EXAMPLES), SEE
+   JS Hub, BL de Groot, D van der Spoel
+   g_wham - A free weighted histogram analysis implementation including 
+   robust error and autocorrelation estimates, 
+   J Chem Theory Comput, accepted (2010)
+   ********************************************************************
+ */
+enum { bsMethod_unknown, bsMethod_BayesianHist, bsMethod_hist, 
+       bsMethod_traj, bsMethod_trajGauss };
+
 
-typedef struct
+typedef struct 
 {
-    /* umbrella with pull code of gromacs 4 */
+    /* umbrella with pull code of gromacs 4.x */
     int npullgrps;      /* nr of pull groups in tpr file         */
     int pull_geometry;  /* such as distance, position            */
     ivec pull_dim;      /* pull dimension with geometry distance */
     int  pull_ndim;     /* nr of pull_dim != 0                   */
     real *k;            /* force constants in tpr file           */
     rvec *init_dist;    /* reference displacements               */
-    real *umbInitDist;  /* referebce displacement in umbrella direction */
-
+    real *umbInitDist;  /* reference displacement in umbrella direction */
+    
     /* From here, old pdo stuff */
-    int nSkip;
+    int nSkip;             
     char Reference[256];
     int nPull;
     int nDim;
@@ -85,59 +102,185 @@ typedef struct
     char PullName[4][256];
     double UmbPos[4][3];
     double UmbCons[4][3];
-    gmx_bool Flipped[4];
 } t_UmbrellaHeader;
 
-typedef struct
+typedef struct 
 {
-    int nPull;
-    int nBin;
-    double **Histo,**cum;
-    double *k;
-    double *pos;
-    double *z;
-    double * N, *Ntot;
-    gmx_bool * Flipped;
-    double dt;
-    gmx_bool **bContrib;
+    int nPull;            /* nr of pull groups in this pdo or pullf/x file */
+    double **Histo,**cum; /* nPull histograms and nPull cumulative distr. funct */
+    int nBin;             /* nr of bins. identical to opt->bins */
+    double *k;            /* force constants for the nPull groups */
+    double *pos;          /* umbrella positions for the nPull groups */
+    double *z;            /* z=(-Fi/kT) for the nPull groups. These values are
+                             iteratively computed during wham */
+    double *N, *Ntot;     /* nr of data points in nPull histograms. N and Ntot
+                             only differ if bHistEq==TRUE */
+    
+    double *g,*tau,*tausmooth;  /* g = 1 + 2*tau[int]/dt where tau is the integrated
+                                   autocorrelation time. Compare, e.g. 
+                                   Ferrenberg/Swendsen, PRL 63:1195 (1989)
+                                   Kumar et al, J Comp Chem 13, 1011-1021 (1992), eq. 28 */
+
+    double dt;                 /* timestep in the input data. Can be adapted with 
+                                  g_wham option -dt */
+    gmx_bool **bContrib;       /* TRUE, if any data point of the histogram is within min 
+                                  and max, otherwise FALSE. */
+    real **ztime;              /* input data z(t) as a function of time. Required to 
+                                  compute ACTs */
+    real *forceAv;             /* average force estimated from average displacement, fAv=dzAv*k
+                                  Used for integration to guess the potential. */
+    real *aver,*sigma;         /* average and stddev of histograms */
+    double *bsWeight;          /* for bootstrapping complete histograms with continuous weights */ 
 } t_UmbrellaWindow;
 
-typedef struct
+
+typedef struct 
 {
-    const char *fnTpr,*fnPullf,*fnPdo,*fnPullx;
-    gmx_bool bTpr,bPullf,bPdo,bPullx;
-    int bins,cycl;
-    gmx_bool verbose,bShift,bAuto,bBoundsOnly;
-    gmx_bool bFlipProf;
-    real tmin, tmax, dt;
-    real Temperature,Tolerance;
-    int nBootStrap,histBootStrapBlockLength;
-    real dtBootStrap,zProfZero,alpha;
-    int bsSeed,stepchange;
-    gmx_bool bHistBootStrap,bWeightedCycl,bHistOutOnly;
-    gmx_bool bAutobounds,bNoprof;
+    /* INPUT STUFF */
+    const char *fnTpr,*fnPullf;
+    const char *fnPdo,*fnPullx;      /* file names of input */
+    gmx_bool bTpr,bPullf,bPdo,bPullx;/* input file types given? */
+    real tmin, tmax, dt;             /* only read input within tmin and tmax with dt */
+    
+    gmx_bool bInitPotByIntegration;  /* before WHAM, guess potential by force integration. Yields
+                                        1.5 to 2 times faster convergence */
+    int stepUpdateContrib;           /* update contribution table every ... iterations. Accelerates
+                                        WHAM. */
+    
+    /* BASIC WHAM OPTIONS */
+    int bins;                        /* nr of bins, min, max, and dz of profile */
     real min,max,dz;
-    gmx_bool bLog;
-    int unit;
-    real zProf0;
-    gmx_bool bProf0Set,bs_verbose;
-    gmx_bool bHistEq, bTab;
+    real Temperature,Tolerance;      /* temperature, converged when probability changes less
+                                        than Tolerance */
+    gmx_bool bCycl;                  /* generate cyclic (periodic) PMF */
+    
+    /* OUTPUT CONTROL */
+    gmx_bool bLog;                   /* energy output (instead of probability) for profile */
+    int unit;                        /* unit for PMF output kJ/mol or kT or kCal/mol */
+    gmx_bool bSym;                   /* symmetrize PMF around z=0 after WHAM, useful for 
+                                        membranes etc. */
+    real zProf0;                     /* after wham, set prof to zero at this z-position 
+                                        When bootstrapping, set zProf0 to a "stable" reference
+                                        position. */
+    gmx_bool bProf0Set;              /* setting profile to 0 at zProf0? */
+    
+    gmx_bool bBoundsOnly,bHistOnly;  /* determine min and max, or write histograms and exit */
+    gmx_bool bAuto;                  /* determine min and max automatically but do not exit */
+    
+    gmx_bool verbose;               /* more noisy wham mode */
+    int stepchange;                 /* print maximum change in prof after how many interations */
+    output_env_t oenv;              /* xvgr options */
+    
+    /* AUTOCORRELATION STUFF */
+    gmx_bool bTauIntGiven,bCalcTauInt;/* IACT given or should be calculated? */
+    real sigSmoothIact;              /* sigma of Gaussian to smooth ACTs */
+    gmx_bool bAllowReduceIact;           /* Allow to reduce ACTs during smoothing. Otherwise
+                                            ACT are only increased during smoothing */
+    real acTrestart;                 /* when computing ACT, time between restarting points */
+    gmx_bool bHistEq;                /* Enforce the same weight for each umbella window, that is
+                                        calculate with the same number of data points for
+                                        each window. That can be reasonable, if the histograms
+                                        have different length, but due to autocorrelation, 
+                                        a longer simulation should not have larger weightin wham. */
+    
+    /* BOOTSTRAPPING STUFF */
+    int nBootStrap;                /* nr of bootstraps (50 is usually enough) */
+    int bsMethod;                  /* if == bsMethod_hist, consider complete histograms as independent 
+                                      data points and, hence, only mix complete histograms.
+                                      if == bsMethod_BayesianHist, consider complete histograms
+                                      as independent data points, but assign random weights
+                                      to the histograms during the bootstrapping ("Bayesian bootstrap")
+                                      In case of long correlations (e.g., inside a channel), these
+                                      will yield a more realistic error.
+                                      if == bsMethod_traj(Gauss), generate synthetic histograms 
+                                      for each given
+                                      histogram by generating an autocorrelated random sequence
+                                      that is distributed according to the respective given
+                                      histogram. With bsMethod_trajGauss, bootstrap from a Gaussian
+                                      (instead of from the umbrella histogram) to generate a new
+                                      histogram 
+                                   */
+    real tauBootStrap;             /* autocorrelation time (ACT) used to generate synthetic
+                                      histograms. If ==0, use calculated ACF */
+    int histBootStrapBlockLength;  /* when mixing histograms, mix only histograms withing blocks
+                                      long the reaction coordinate xi. Avoids gaps along xi. */
+    int bsSeed;                    /* random seed for bootstrapping */
+    gmx_bool bs_verbose;               /* Write cumulative distribution functions (CDFs) of histograms
+                                          and write the generated histograms for each bootstrap */
+    
+    /* tabulated umbrella potential stuff */
+    gmx_bool bTab;                      
     double *tabX,*tabY,tabMin,tabMax,tabDz;
     int tabNbins;
+    
+    gmx_rng_t rng;                  /* gromacs random number generator */
 } t_UmbrellaOptions;
 
 
+t_UmbrellaWindow * initUmbrellaWindows(int nwin)
+{
+    t_UmbrellaWindow *win;
+    int i;
+    snew(win,nwin);
+    for (i=0; i<nwin; i++)
+    {
+        win[i].Histo = win[i].cum  = 0;
+        win[i].k     = win[i].pos  = win[i].z =0;
+        win[i].N     = win[i].Ntot = 0;
+        win[i].g     = win[i].tau  = win[i].tausmooth = 0;
+        win[i].bContrib=0;
+        win[i].ztime=0;
+        win[i].forceAv=0;
+        win[i].aver = win[i].sigma = 0;
+        win[i].bsWeight = 0;
+    }
+    return win;
+}
+
+void freeUmbrellaWindows(t_UmbrellaWindow *win, int nwin)
+{
+    int i,j;
+    for (i=0; i<nwin; i++)
+    {
+        if (win[i].Histo)
+            for (j=0;j<win[i].nPull;j++)
+                sfree(win[i].Histo[j]);
+        if (win[i].cum)
+            for (j=0;j<win[i].nPull;j++)
+                sfree(win[i].cum[j]);
+        if (win[i].bContrib)
+            for (j=0;j<win[i].nPull;j++)
+                sfree(win[i].bContrib[j]);
+        sfree(win[i].Histo);
+        sfree(win[i].cum);
+        sfree(win[i].k);
+        sfree(win[i].pos);
+        sfree(win[i].z);
+        sfree(win[i].N);
+        sfree(win[i].Ntot);
+        sfree(win[i].g);
+        sfree(win[i].tau);
+        sfree(win[i].tausmooth);
+        sfree(win[i].bContrib);
+        sfree(win[i].ztime);
+        sfree(win[i].forceAv);
+        sfree(win[i].aver);
+        sfree(win[i].sigma);
+        sfree(win[i].bsWeight);
+    }
+    sfree(win);
+}
+
 /* Return j such that xx[j] <= x < xx[j+1] */
 void searchOrderedTable(double xx[], int n, double x, int *j)
 {
     int ju,jm,jl;
     int ascending;
-
-
+    
     jl=-1;
     ju=n;
     ascending=(xx[n-1] > xx[0]);
-    while (ju-jl > 1)
+    while (ju-jl > 1) 
     {
         jm=(ju+jl) >> 1;
         if ((x >= xx[jm]) == ascending)
@@ -150,14 +293,12 @@ void searchOrderedTable(double xx[], int n, double x, int *j)
     else *j=jl;
 }
 
-
 /* Read and setup tabulated umbrella potential */
 void setup_tab(const char *fn,t_UmbrellaOptions *opt)
 {
     int i,ny,nl;
     double **y;
-
-
+    
     printf("Setting up tabulated potential from file %s\n",fn);
     nl=read_xvg(fn,&y,&ny);
     opt->tabNbins=nl;
@@ -168,113 +309,83 @@ void setup_tab(const char *fn,t_UmbrellaOptions *opt)
     opt->tabDz=(opt->tabMax-opt->tabMin)/(nl-1);
     if (opt->tabDz<=0)
         gmx_fatal(FARGS,"The tabulated potential in %s must be provided in \n"
-                "ascending z-direction",fn);
+                  "ascending z-direction",fn);
     for (i=0;i<nl-1;i++)
         if  (fabs(y[0][i+1]-y[0][i]-opt->tabDz) > opt->tabDz/1e6)
             gmx_fatal(FARGS,"z-values in %s are not equally spaced.\n",ny,fn);
     snew(opt->tabY,nl);
     snew(opt->tabX,nl);
-    for (i=0;i<nl;i++){
+    for (i=0;i<nl;i++)
+    {
         opt->tabX[i]=y[0][i];
         opt->tabY[i]=y[1][i];
     }
     printf("Found equally spaced tabulated potential from %g to %g, spacing %g\n",
-            opt->tabMin,opt->tabMax,opt->tabDz);
+           opt->tabMin,opt->tabMax,opt->tabDz);
 }
 
-
-void read_pdo_header(FILE * file,t_UmbrellaHeader * header, 
-                     t_UmbrellaOptions *opt)
+void read_pdo_header(FILE * file,t_UmbrellaHeader * header, t_UmbrellaOptions *opt)
 {
-    char Buffer0[256];
-    char Buffer1[256];
-    char Buffer2[256];
-    char Buffer3[256];
-    char Buffer4[256];
-    int i,j;
-
-
+    char line[2048];
+    char Buffer0[256], Buffer1[256], Buffer2[256], Buffer3[256], Buffer4[256];
+    int i;
+    
     /*  line 1 */
-    if(3 != fscanf(file,"%s%s%s",Buffer0,Buffer1,Buffer2))
-    {
-       gmx_fatal(FARGS,"Error reading header from pdo file");
-    }
-    if(strcmp(Buffer1,"UMBRELLA"))
-        gmx_fatal(FARGS,"This does not appear to be a valid pdo file. Found %s, expected %s",
-                Buffer1, "UMBRELLA");
+    if (fgets(line,2048,file) == NULL)
+        gmx_fatal(FARGS,"Error reading header from pdo file\n");
+    sscanf(line,"%s%s%s",Buffer0,Buffer1,Buffer2);
+    if(strcmp(Buffer1,"UMBRELLA")) 
+        gmx_fatal(FARGS,"This does not appear to be a valid pdo file. Found %s, expected %s\n"
+                  "(Found in first line: `%s')\n",
+                  Buffer1, "UMBRELLA",line);
     if(strcmp(Buffer2,"3.0"))
         gmx_fatal(FARGS,"This does not appear to be a version 3.0 pdo file");
-
+    
     /*  line 2 */
-    if(6 != fscanf(file,"%s%s%s%d%d%d",Buffer0,Buffer1,Buffer2,
-                  &(header->Dims[0]),&(header->Dims[1]),&(header->Dims[2])))
-    { 
-       gmx_fatal(FARGS,"Error reading dimensions in header from pdo file");
-    }
-
+    if (fgets(line,2048,file) == NULL)
+        gmx_fatal(FARGS,"Error reading header from pdo file\n");
+    sscanf(line,"%s%s%s%d%d%d",Buffer0,Buffer1,Buffer2,
+           &(header->Dims[0]),&(header->Dims[1]),&(header->Dims[2]));
+    
     /* printf("%d %d %d\n", header->Dims[0],header->Dims[1],header->Dims[2]); */
-
+    
     header->nDim = header->Dims[0] + header->Dims[1] + header->Dims[2];
     if(header->nDim!=1)
         gmx_fatal(FARGS,"Currently only supports one dimension");
-
+    
     /* line3 */
-    if(3 != fscanf(file,"%s%s%d",Buffer0,Buffer1,&(header->nSkip)))
-    { 
-       gmx_fatal(FARGS,"Error reading header from pdo file");
-    }
-
-    /* line 4 */
-    if(4 != fscanf(file,"%s%s%s%s",Buffer0,Buffer1,Buffer2,header->Reference))
-    { 
-       gmx_fatal(FARGS,"Error reading header from pdo file");
-    }
-
+    if (fgets(line,2048,file) == NULL)
+        gmx_fatal(FARGS,"Error reading header from pdo file\n");
+    sscanf(line,"%s%s%d",Buffer0,Buffer1,&(header->nSkip));
+    
+    /* line 4 */ 
+    if (fgets(line,2048,file) == NULL)
+        gmx_fatal(FARGS,"Error reading header from pdo file\n");
+    sscanf(line,"%s%s%s%s",Buffer0,Buffer1,Buffer2,header->Reference);
+    
     /* line 5 */
-    if(6 != fscanf(file,"%s%s%s%s%s%d",Buffer0,Buffer1,Buffer2,Buffer3,Buffer4,&(header->nPull)))
-    { 
-       gmx_fatal(FARGS,"Error reading header from pdo file");
-    }
-
+    if (fgets(line,2048,file) == NULL)
+        gmx_fatal(FARGS,"Error reading header from pdo file\n");
+    sscanf(line,"%s%s%s%s%s%d",Buffer0,Buffer1,Buffer2,Buffer3,Buffer4,&(header->nPull));
+       
     if (opt->verbose)
-        printf("Found nPull=%d , nSkip=%d, ref=%s\n",header->nPull,header->nSkip,
-                header->Reference);
-
-    for(i=0;i<header->nPull;++i)
+        printf("\tFound nPull=%d , nSkip=%d, ref=%s\n",header->nPull,header->nSkip,
+               header->Reference);
+    
+    for(i=0;i<header->nPull;++i) 
     {
-      if(4 != fscanf(file,"%s%s%s%s",Buffer0,Buffer1,Buffer2,header->PullName[i]))
-      { 
-         gmx_fatal(FARGS,"Error reading header from pdo file");
-      }
+        if (fgets(line,2048,file) == NULL)
+            gmx_fatal(FARGS,"Error reading header from pdo file\n");
+        sscanf(line,"%*s%*s%*s%s%*s%*s%lf%*s%*s%lf",header->PullName[i]
+               ,&(header->UmbPos[i][0]),&(header->UmbCons[i][0]));
         if (opt->verbose)
-            printf("pullgroup %d, pullname = %s\n",i,header->PullName[i]);
-        for(j=0;j<header->nDim;++j)
-        {
-         if(6 != fscanf(file,"%s%s%lf%s%s%lf",Buffer0,Buffer1,&(header->UmbPos[i][j]),
-                        Buffer2,Buffer3,&(header->UmbCons[i][j])))
-          { 
-             gmx_fatal(FARGS,"Error reading header from pdo file");
-         }
-
-            if (opt->bFlipProf)
-            {
-                /* We want to combine both halves of a profile into one */
-                if(header->UmbPos[i][j]<0)
-                {
-                    header->UmbPos[i][j]= -header->UmbPos[i][j];
-                    header->Flipped[i]=TRUE;
-                }
-            }
-            else header->Flipped[i]=FALSE;
-            /*printf("%f\t%f\n",header->UmbPos[i][j],header->UmbCons[i][j]);*/
-        }
-    }
-
-    if(1 != fscanf(file,"%s",Buffer3))
-    { 
-       gmx_fatal(FARGS,"Error reading header from pdo file");
+            printf("\tpullgroup %d, pullname = %s, UmbPos = %g, UmbConst = %g\n",
+                   i,header->PullName[i],header->UmbPos[i][0],header->UmbCons[i][0]);
     }
-
+    
+    if (fgets(line,2048,file) == NULL)
+        gmx_fatal(FARGS,"Cannot read from file\n");
+    sscanf(line,"%s",Buffer3);
     if (strcmp(Buffer3,"#####") != 0)
         gmx_fatal(FARGS,"Expected '#####', found %s. Hick.\n",Buffer3);
 }
@@ -284,12 +395,11 @@ static char *fgets3(FILE *fp,char ptr[],int *len)
 {
     char *p;
     int  slen;
-
-
+    
     if (fgets(ptr,*len-1,fp) == NULL)
         return NULL;
     p = ptr;
-    while ((strchr(ptr,'\n') == NULL) && (!feof(fp)))
+    while ((strchr(ptr,'\n') == NULL) && (!feof(fp))) 
     {
         /* This line is longer than len characters, let's increase len! */
         *len += STRLEN;
@@ -301,57 +411,68 @@ static char *fgets3(FILE *fp,char ptr[],int *len)
     slen = strlen(ptr);
     if (ptr[slen-1] == '\n')
         ptr[slen-1] = '\0';
-
+    
     return ptr;
 }
 
-
 void read_pdo_data(FILE * file, t_UmbrellaHeader * header,
-        int fileno, t_UmbrellaWindow * win,
-        t_UmbrellaOptions *opt,
-        gmx_bool bGetMinMax,real *mintmp,real *maxtmp)
+                   int fileno, t_UmbrellaWindow * win,
+                   t_UmbrellaOptions *opt,
+                   gmx_bool bGetMinMax,real *mintmp,real *maxtmp)
 {
-    int i,inttemp,bins,count;
-    real min,max,minfound,maxfound;
+    int i,inttemp,bins,count,ntot;
+    real min,max,minfound=1e20,maxfound=-1e20;
     double temp,time,time0=0,dt;
-    char *ptr;
+    char *ptr=0;
     t_UmbrellaWindow * window=0;
     gmx_bool timeok,dt_ok=1;
-    char  *tmpbuf,fmt[256],fmtign[256];
-    int    len=STRLEN,dstep=1;
-
-       minfound=1e20;
-       maxfound=-1e20;
-       
+    char  *tmpbuf=0,fmt[256],fmtign[256];
+    int    len=STRLEN,dstep=1;  
+    const int blocklen=4096;
+    int *lennow=0;
+    
     if (!bGetMinMax)
     {
         bins=opt->bins;
         min=opt->min;
         max=opt->max;
-
+        
         window=win+fileno;
         /* Need to alocate memory and set up structure */
         window->nPull=header->nPull;
         window->nBin=bins;
-
+        
         snew(window->Histo,window->nPull);
         snew(window->z,window->nPull);
         snew(window->k,window->nPull);
         snew(window->pos,window->nPull);
-        snew(window->Flipped,window->nPull);
         snew(window->N, window->nPull);
         snew(window->Ntot, window->nPull);
-
-        for(i=0;i<window->nPull;++i)
+        snew(window->g, window->nPull);
+        snew(window->bsWeight, window->nPull);
+        
+        window->bContrib=0;
+        
+        if (opt->bCalcTauInt)
+            snew(window->ztime, window->nPull);
+        else
+            window->ztime=0;
+        snew(lennow,window->nPull);
+        
+        for(i=0;i<window->nPull;++i) 
         {
             window->z[i]=1;
+            window->bsWeight[i]=1.;
             snew(window->Histo[i],bins);
             window->k[i]=header->UmbCons[i][0];
             window->pos[i]=header->UmbPos[i][0];
-            window->Flipped[i]=header->Flipped[i];
             window->N[i]=0;
             window->Ntot[i]=0;
+            window->g[i]=1.;
+            if (opt->bCalcTauInt)
+                window->ztime[i]=0;      
         }
+        
         /* Done with setup */
     }
     else
@@ -360,24 +481,24 @@ void read_pdo_data(FILE * file, t_UmbrellaHeader * header,
         maxfound=-1e20;
         min=max=bins=0; /* Get rid of warnings */
     }
-
+    
     count=0;
     snew(tmpbuf,len);
     while ( (ptr=fgets3(file,tmpbuf,&len)) != NULL)
     {
         trim(ptr);
-
+        
         if (ptr[0] == '#' || strlen(ptr)<2)
             continue;
-
+        
         /* Initiate format string */
         fmtign[0] = '\0';
         strcat(fmtign,"%*s");
-
+        
         sscanf(ptr,"%lf",&time); /* printf("Time %f\n",time); */
         /* Round time to fs */
         time=1.0/1000*( (int) (time*1000+0.5) );
-
+        
         /* get time step of pdo file */
         if (count==0)
             time0=time;
@@ -386,7 +507,7 @@ void read_pdo_data(FILE * file, t_UmbrellaHeader * header,
             dt=time-time0;
             if (opt->dt>0.0)
             {
-             dstep=(int)(opt->dt/dt+0.5);
+                dstep=(int)(opt->dt/dt+0.5);
                 if (dstep==0)
                     dstep=1;
             }
@@ -394,58 +515,65 @@ void read_pdo_data(FILE * file, t_UmbrellaHeader * header,
                 window->dt=dt*dstep;
         }
         count++;
-
+        
         dt_ok=((count-1)%dstep == 0);
         timeok=(dt_ok && time >= opt->tmin && time <= opt->tmax);
         /* if (opt->verbose)
-      printf(" time = %f, (tmin,tmax)=(%e,%e), dt_ok=%d timeok=%d\n",
-      time,opt->tmin, opt->tmax, dt_ok,timeok); */
-
+           printf(" time = %f, (tmin,tmax)=(%e,%e), dt_ok=%d timeok=%d\n", 
+           time,opt->tmin, opt->tmax, dt_ok,timeok); */
+        
         if (timeok)
         {
-            for(i=0;i<header->nPull;++i)
+            for(i=0;i<header->nPull;++i) 
             {
                 strcpy(fmt,fmtign);
                 strcat(fmt,"%lf");      /* Creating a format stings such as "%*s...%*s%lf" */
                 strcat(fmtign,"%*s");   /* ignoring one more entry in the next loop */
-                if(sscanf(ptr,fmt,&temp))
+                if(sscanf(ptr,fmt,&temp)) 
                 {
-                    if(opt->bFlipProf)
-                    {
-                        if(header->Flipped[i]) temp=-temp;
-                    }
-
                     temp+=header->UmbPos[i][0];
-                    if (bGetMinMax){
+                    if (bGetMinMax)
+                    {
                         if (temp<minfound)
                             minfound=temp;
                         if (temp>maxfound)
                             maxfound=temp;
                     }
-                    else
-                    {
+                    else{
+                        if (opt->bCalcTauInt)
+                        {
+                            /* save time series for autocorrelation analysis */
+                            ntot=window->Ntot[i];
+                            if (ntot>=lennow[i])
+                            {
+                                lennow[i]+=blocklen;
+                                srenew(window->ztime[i],lennow[i]);
+                            }
+                            window->ztime[i][ntot]=temp;
+                        }
+                        
                         temp-=min;
                         temp/=(max-min);
                         temp*=bins;
                         temp=floor(temp);
-
+                        
                         inttemp = (int)temp;
-                        if (opt->cycl==enCycl_yes)
+                        if (opt->bCycl)
                         {
                             if (inttemp < 0)
                                 inttemp+=bins;
                             else if (inttemp >= bins)
                                 inttemp-=bins;
                         }
-
-                        if(inttemp >= 0 && inttemp < bins)
+                        
+                        if(inttemp >= 0 && inttemp < bins) 
                         {
-                            window->Histo[i][inttemp]+=1;
+                            window->Histo[i][inttemp]+=1.;
                             window->N[i]++;
                         }
                         window->Ntot[i]++;
                     }
-                }
+                }        
             }
         }
         if (time>opt->tmax)
@@ -455,49 +583,54 @@ void read_pdo_data(FILE * file, t_UmbrellaHeader * header,
             break;
         }
     }
-
+    
     if (bGetMinMax)
     {
         *mintmp=minfound;
         *maxtmp=maxfound;
     }
+    
+    sfree(lennow);
+    sfree(tmpbuf);
 }
 
-
 void enforceEqualWeights(t_UmbrellaWindow * window,int nWindows)
 {
     int i,k,j,NEnforced;
     double ratio;
-
-
+    
     NEnforced=window[0].Ntot[0];
     printf("\nFound -hist-eq. Enforcing equal weights for all histograms, \ni.e. doing a "
-            "non-weighted histogram analysis method. Ndata = %d\n",NEnforced);
+           "non-weighted histogram analysis method. Ndata = %d\n",NEnforced);
     /* enforce all histograms to have the same weight as the very first histogram */
-
+    
     for(j=0;j<nWindows;++j)
-        for(k=0;k<window[j].nPull;++k)
+    {
+        for(k=0;k<window[j].nPull;++k) 
         {
             ratio=1.0*NEnforced/window[j].Ntot[k];
             for(i=0;i<window[0].nBin;++i)
+            {
                 window[j].Histo[k][i]*=ratio;
-            window[j].N[k]=(int)(ratio*window[j].N[k]+0.5);
+            }
+            window[j].N[k]=(int)(ratio*window[j].N[k] + 0.5);
         }
+    }
 }
 
-
 /* Simple linear interpolation between two given tabulated points */
 double tabulated_pot(double dist, t_UmbrellaOptions *opt)
 {
     int jl,ju;
     double pl,pu,dz,dp;
 
-
     jl=floor((dist-opt->tabMin)/opt->tabDz);
     ju=jl+1;
     if (jl<0 || ju>=opt->tabNbins)
+    {
         gmx_fatal(FARGS,"Distance %f out of bounds of tabulated potential (jl=%d, ju=%d).\n"
-                "Provide an extended table.",dist,jl,ju);
+                  "Provide an extended table.",dist,jl,ju);
+    }
     pl=opt->tabY[jl];
     pu=opt->tabY[ju];
     dz=dist-opt->tabX[jl];
@@ -507,95 +640,127 @@ double tabulated_pot(double dist, t_UmbrellaOptions *opt)
 
 
 /* Don't worry, that routine does not mean we compute the PMF in limited precision.
-   After rapid convergence (using only substiantal contributions), we always switch to
+   After rapid convergence (using only substiantal contributions), we always switch to 
    full precision. */
-#define WHAM_CONTRIB_LIM 1e-10
-void setup_acc_wham(t_UmbrellaWindow * window,int nWindows, t_UmbrellaOptions *opt)
+void setup_acc_wham(double *profile,t_UmbrellaWindow * window,int nWindows, 
+                    t_UmbrellaOptions *opt)
 {
-    int i,j,k;
-    double U,min=opt->min,dz=opt->dz,temp,ztot_half,distance,ztot,contrib;
+    int i,j,k,nGrptot=0,nContrib=0,nTot=0;
+    double U,min=opt->min,dz=opt->dz,temp,ztot_half,distance,ztot,contrib1,contrib2;
     gmx_bool bAnyContrib;
-
-
+    static int bFirst=1;
+    static double wham_contrib_lim;
+    
+    if (bFirst)
+    {
+        for(i=0;i<nWindows;++i)
+        {
+            nGrptot+=window[i].nPull;
+        }
+        wham_contrib_lim=opt->Tolerance/nGrptot;
+    }
+    
     ztot=opt->max-opt->min;
     ztot_half=ztot/2;
-
-    for(i=0;i<nWindows;++i)
+       
+    for(i=0;i<nWindows;++i) 
     {
-        snew(window[i].bContrib,window[i].nPull);
-        for(j=0;j<window[i].nPull;++j)
+        if ( ! window[i].bContrib)
+        {
+            snew(window[i].bContrib,window[i].nPull);
+        }
+        for(j=0;j<window[i].nPull;++j) 
         {
-            snew(window[i].bContrib[j],opt->bins);
+            if ( ! window[i].bContrib[j])
+                snew(window[i].bContrib[j],opt->bins);
             bAnyContrib=FALSE;
-            for(k=0;k<opt->bins;++k)
+            for(k=0;k<opt->bins;++k) 
             {
                 temp=(1.0*k+0.5)*dz+min;
                 distance = temp - window[i].pos[j];   /* distance to umbrella center */
-                if (opt->cycl==enCycl_yes)
+                if (opt->bCycl)
                 {                                     /* in cyclic wham:             */
                     if (distance > ztot_half)           /*    |distance| < ztot_half   */
                         distance-=ztot;
                     else if (distance < -ztot_half)
                         distance+=ztot;
                 }
+                /* Note: there are two contributions to bin k in the wham equations:
+                   i)  N[j]*exp(- U/(8.314e-3*opt->Temperature) + window[i].z[j])
+                   ii) exp(- U/(8.314e-3*opt->Temperature))
+                   where U is the umbrella potential
+                   If any of these number is larger wham_contrib_lim, I set contrib=TRUE
+                */
+                
                 if (!opt->bTab)
                     U=0.5*window[i].k[j]*sqr(distance);       /* harmonic potential assumed. */
                 else
                     U=tabulated_pot(distance,opt);            /* Use tabulated potential     */
-
-                contrib=exp(- U/(8.314e-3*opt->Temperature));
-                window[i].bContrib[j][k] = (contrib > WHAM_CONTRIB_LIM);
+                
+                contrib1=profile[k]*exp(- U/(8.314e-3*opt->Temperature));
+                contrib2=window[i].N[j]*exp(- U/(8.314e-3*opt->Temperature) + window[i].z[j]);
+                window[i].bContrib[j][k] = (contrib1 > wham_contrib_lim || contrib2 > wham_contrib_lim);
                 bAnyContrib = (bAnyContrib | window[i].bContrib[j][k]);
+                if (window[i].bContrib[j][k])
+                    nContrib++;
+                nTot++;
             }
             /* If this histo is far outside min and max all bContrib may be FALSE,
-             * causing a floating point exception later on. To avoid that, switch
-             * them all to true.*/
+               causing a floating point exception later on. To avoid that, switch 
+               them all to true.*/
             if (!bAnyContrib)
                 for(k=0;k<opt->bins;++k)
                     window[i].bContrib[j][k]=TRUE;
         }
     }
-    printf("Initialized rapid wham stuff.\n");
+    if (bFirst)
+        printf("Initialized rapid wham stuff (contrib tolerance %g)\n"
+               "Evaluating only %d of %d expressions.\n\n",wham_contrib_lim,nContrib, nTot);
+    
+    if (opt->verbose)
+        printf("Updated rapid wham stuff. (evaluating only %d of %d contributions)\n",
+               nContrib,nTot);
+    bFirst=0;    
 }
 
 
-void calc_profile(double *profile,t_UmbrellaWindow * window, int nWindows, t_UmbrellaOptions *opt,
-        gmx_bool bExact)
+void calc_profile(double *profile,t_UmbrellaWindow * window, int nWindows, 
+                  t_UmbrellaOptions *opt, gmx_bool bExact)
 {
     int i,k,j;
     double num,ztot_half,ztot,distance,min=opt->min,dz=opt->dz;
-    double denom,U=0,temp=0;
-
-
+    double denom,U=0,temp=0,invg;
+    
     ztot=opt->max-opt->min;
-    ztot_half=ztot/2;
-
-
-    for(i=0;i<opt->bins;++i)
+    ztot_half=ztot/2;   
+    
+    for(i=0;i<opt->bins;++i) 
     {
-        num=denom=0;
-        for(j=0;j<nWindows;++j)
+        num=denom=0.;
+        for(j=0;j<nWindows;++j) 
         {
-            for(k=0;k<window[j].nPull;++k)
+            for(k=0;k<window[j].nPull;++k) 
             {
-                temp=(1.0*i+0.5)*dz+min;
-                num+=window[j].Histo[k][i];
-
+                invg = 1.0/window[j].g[k] * window[j].bsWeight[k];
+                temp = (1.0*i+0.5)*dz+min;
+                num += invg*window[j].Histo[k][i];
+                
                 if (! (bExact || window[j].bContrib[k][i]))
                     continue;
                 distance = temp - window[j].pos[k];   /* distance to umbrella center */
-                if (opt->cycl==enCycl_yes){           /* in cyclic wham:             */
+                if (opt->bCycl)
+                {                                     /* in cyclic wham:             */
                     if (distance > ztot_half)           /*    |distance| < ztot_half   */
                         distance-=ztot;
                     else if (distance < -ztot_half)
                         distance+=ztot;
                 }
-
+                
                 if (!opt->bTab)
                     U=0.5*window[j].k[k]*sqr(distance);       /* harmonic potential assumed. */
                 else
                     U=tabulated_pot(distance,opt);            /* Use tabulated potential     */
-                denom+=window[j].N[k]*exp(- U/(8.314e-3*opt->Temperature) + window[j].z[k]);
+                denom+=invg*window[j].N[k]*exp(- U/(8.314e-3*opt->Temperature) + window[j].z[k]);
             }
         }
         profile[i]=num/denom;
@@ -603,138 +768,108 @@ void calc_profile(double *profile,t_UmbrellaWindow * window, int nWindows, t_Umb
 }
 
 
-double calc_z(double * profile,t_UmbrellaWindow * window, int nWindows, t_UmbrellaOptions *opt,
-        gmx_bool bExact)
+double calc_z(double * profile,t_UmbrellaWindow * window, int nWindows, 
+              t_UmbrellaOptions *opt, gmx_bool bExact)
 {
-    int i,j,k;
-    double U=0,min=opt->min,dz=opt->dz,temp,ztot_half,distance,ztot;
+    int i,j,k,binMax=-1;
+    double U=0,min=opt->min,dz=opt->dz,temp,ztot_half,distance,ztot,totalMax;
     double MAX=-1e20, total=0;
-
-
+    
     ztot=opt->max-opt->min;
     ztot_half=ztot/2;
-
-    for(i=0;i<nWindows;++i)
+       
+    for(i=0;i<nWindows;++i) 
     {
-        for(j=0;j<window[i].nPull;++j)
+        for(j=0;j<window[i].nPull;++j) 
         {
             total=0;
-            for(k=0;k<window[i].nBin;++k)
+            for(k=0;k<window[i].nBin;++k) 
             {
                 if (! (bExact || window[i].bContrib[j][k]))
                     continue;
                 temp=(1.0*k+0.5)*dz+min;
                 distance = temp - window[i].pos[j];   /* distance to umbrella center */
-                if (opt->cycl==enCycl_yes)
+                if (opt->bCycl)
                 {                                     /* in cyclic wham:             */
                     if (distance > ztot_half)           /*    |distance| < ztot_half   */
                         distance-=ztot;
                     else if (distance < -ztot_half)
                         distance+=ztot;
                 }
-
+                
                 if (!opt->bTab)
                     U=0.5*window[i].k[j]*sqr(distance);       /* harmonic potential assumed. */
                 else
                     U=tabulated_pot(distance,opt);            /* Use tabulated potential     */
-
+                
                 total+=profile[k]*exp(-U/(8.314e-3*opt->Temperature));
             }
-            if (total > 0.0)
+            /* Avoid floating point exception if window is far outside min and max */
+            if (total != 0.0)
                 total = -log(total);
             else
                 total = 1000.0;
             temp = fabs(total - window[i].z[j]);
-            if(temp > MAX) MAX=temp;
+            if(temp > MAX){
+                MAX=temp;
+                binMax=k;
+                totalMax=total;
+            }
             window[i].z[j] = total;
         }
     }
     return MAX;
 }
 
-
-void cyclicProfByWeightedCorr(double *profile,t_UmbrellaWindow *window,
-                              int nWindows, t_UmbrellaOptions * opt,
-                              gmx_bool bAppendCorr2File, const char *fn, 
-                              const output_env_t oenv)
+void symmetrizeProfile(double* profile,t_UmbrellaOptions *opt)
 {
-    int i,j,k,bins=opt->bins;
-    static int first=1;
-    double *weight,sum=0.,diff,*histsum,*corr,sumCorr=0.,dCorr;
-    FILE *fp;
-    char buf[256];
-
-    if (first)
-    {
-        printf("\nEnforcing a periodic profile by a sampling wheighted correction.");
-        please_cite(stdout,"Hub2008");
-    }
-
-    snew(weight,bins-1);
-    snew(histsum,bins);
-    snew(corr,bins-1);
-
-    /* generate weights proportional to 1/(n(i)*n(i+1))^alpha
-     where n(i) is the total nur of data points in bin i from all histograms */
-    for(i=0;i<nWindows;++i)
-        for(j=0;j<window[i].nPull;++j)
-            for(k=0;k<bins;++k)
-                histsum[k]+=window[i].Histo[j][k];
-
-    for(k=0,sum=0.;k<bins-1;++k)
-    {
-        weight[k]=1./pow(histsum[k]*histsum[k+1],opt->alpha);
-        sum+=weight[k];
-    }
-    for(k=0;k<bins-1;++k)
-        weight[k]/=sum;
-
-    /* difference between last and first bin */
-    diff=profile[bins-1]-profile[0];
-    printf("Distributing %f between adjacent bins to enforce a cyclic profile\n",diff);
-
-    for (i=0;i<bins-1;i++)
-    {
-        dCorr=weight[i]*diff;
-        sumCorr+=dCorr;
-        corr[i]=sumCorr;
-    }
-
-    for (i=0;i<bins-1;i++)
-        profile[i+1]-=corr[i];
-
-    if (bAppendCorr2File)
+    int i,j;
+    double *prof2,bins=opt->bins,min=opt->min,max=opt->max,dz=opt->dz,zsym,deltaz,profsym;
+    double z,z1;
+    
+    if (min>0. || max<0.)
+        gmx_fatal(FARGS,"Cannot symmetrize profile around z=0 with min=%f and max=%f\n",
+                  opt->min,opt->max);
+    
+    snew(prof2,bins);
+    
+    for (i=0;i<bins;i++)
     {
-        fp=xvgropen(fn,"Corrections to enforce periodicity","z",
-                    "\\f{12}D\\f{}G(z)",oenv);
-        sprintf(buf,"corrections propotional to 1/(n\\si\\Nn\\si+1\\N)\\S%.2f",
-                opt->alpha);
-        xvgr_subtitle(fp,buf,oenv);
-        for (i=0;i<bins-1;i++)
-            fprintf(fp,"%g %g\n",opt->min+opt->dz*(i+1),-corr[i]);
-        ffclose(fp);
+        z=min+(i+0.5)*dz;
+        zsym=-z;
+        /* bin left of zsym */
+        j=floor((zsym-min)/dz-0.5);
+        if (j>=0 && (j+1)<bins)
+        {
+            /* interpolate profile linearly between bins j and j+1 */
+            z1=min+(j+0.5)*dz;
+            deltaz=zsym-z1;
+            profsym=profile[j] + (profile[j+1]-profile[j])/dz*deltaz;
+            /* average between left and right */
+            prof2[i]=0.5*(profsym+profile[i]);
+        }
+        else
+        {
+            prof2[i]=profile[i];
+        }
     }
-
-    sfree(histsum);
-    sfree(corr);
-    sfree(weight);
-    first=0;
+    
+    memcpy(profile,prof2,bins*sizeof(double));
+    sfree(prof2);
 }
 
-
 void prof_normalization_and_unit(double * profile, t_UmbrellaOptions *opt)
 {
     int i,bins,imin;
     double unit_factor=1., R_MolarGasConst, diff;
-
-
+    
     R_MolarGasConst=8.314472e-3; /* in kJ/(mol*K) */
     bins=opt->bins;
-
-    /* No log? Nothing to do! */
+    
+    /* Not log? Nothing to do! */
     if (!opt->bLog)
         return;
-
+    
     /* Get profile in units of kT, kJ/mol, or kCal/mol */
     if (opt->unit == en_kT)
         unit_factor=1.0;
@@ -743,59 +878,61 @@ void prof_normalization_and_unit(double * profile, t_UmbrellaOptions *opt)
     else if (opt->unit == en_kCal)
         unit_factor=R_MolarGasConst*opt->Temperature/4.1868;
     else
-        gmx_fatal(FARGS,"Sorry I don't know this energy unit.");
-
+        gmx_fatal(FARGS,"Sorry, I don't know this energy unit.");
+    
     for (i=0;i<bins;i++)
         if (profile[i]>0.0)
             profile[i]=-log(profile[i])*unit_factor;
-
+    
     /* shift to zero at z=opt->zProf0 */
     if (!opt->bProf0Set)
+    {
         diff=profile[0];
-    else{
-        /* Get bin with shortest distance to opt->zProf0 */
-      imin=(int)((opt->zProf0-opt->min)/opt->dz);
+    }
+    else
+    {
+        /* Get bin with shortest distance to opt->zProf0 
+           (-0.5 from bin position and +0.5 from rounding cancel) */
+        imin=(int)((opt->zProf0-opt->min)/opt->dz);
         if (imin<0)
             imin=0;
         else if (imin>=bins)
             imin=bins-1;
         diff=profile[imin];
     }
-
+  
     /* Shift to zero */
     for (i=0;i<bins;i++)
         profile[i]-=diff;
 }
 
-
-void getRandomIntArray(int nPull,int blockLength,int* randomArray)
+void getRandomIntArray(int nPull,int blockLength,int* randomArray,gmx_rng_t rng)
 {
     int ipull,blockBase,nr,ipullRandom;
-
-
+    
     if (blockLength==0)
         blockLength=nPull;
-
+    
     for (ipull=0; ipull<nPull; ipull++)
     {
         blockBase=(ipull/blockLength)*blockLength;
-        do{      /* make sure nothing bad happens in the last block */
-            nr=(int)((1.0*rand()/RAND_MAX)*blockLength);
+        do
+        {      /* make sure nothing bad happens in the last block */
+            nr=(int)(gmx_rng_uniform_real(rng)*blockLength);
             ipullRandom = blockBase + nr;
         } while (ipullRandom >= nPull);
         if (ipullRandom<0 || ipullRandom>=nPull)
             gmx_fatal(FARGS,"Ups, random iWin = %d, nPull = %d, nr = %d, "
-                    "blockLength = %d, blockBase = %d\n",
-                    ipullRandom,nPull,nr,blockLength,blockBase);
+                      "blockLength = %d, blockBase = %d\n",
+                      ipullRandom,nPull,nr,blockLength,blockBase);
         randomArray[ipull]=ipullRandom;
     }
     /*for (ipull=0; ipull<nPull; ipull++)
-    printf("%d ",randomArray[ipull]); printf("\n"); */
+      printf("%d ",randomArray[ipull]); printf("\n"); */
 }
 
-
 void copy_pullgrp_to_synthwindow(t_UmbrellaWindow *synthWindow,
-        t_UmbrellaWindow *thisWindow,int pullid)
+                                 t_UmbrellaWindow *thisWindow,int pullid)
 {
     synthWindow->N       [0]=thisWindow->N        [pullid];
     synthWindow->Histo   [0]=thisWindow->Histo    [pullid];
@@ -803,31 +940,30 @@ void copy_pullgrp_to_synthwindow(t_UmbrellaWindow *synthWindow,
     synthWindow->z       [0]=thisWindow->z        [pullid];
     synthWindow->k       [0]=thisWindow->k        [pullid];
     synthWindow->bContrib[0]=thisWindow->bContrib [pullid];
+    synthWindow->g       [0]=thisWindow->g        [pullid];
+    synthWindow->bsWeight[0]=thisWindow->bsWeight [pullid];
 }
 
-
-/* Calculate cummulative of all histograms. They allow to create random numbers
+/* Calculate cumulative distribution function of of all histograms. They 
+   allow to create random number sequences
    which are distributed according to the histograms. Required to generate
    the "synthetic" histograms for the Bootstrap method */
-void calc_cummulants(t_UmbrellaWindow *window,int nWindows,
-                     t_UmbrellaOptions *opt,const char *fnhist, 
-                     const output_env_t oenv)
+void calc_cumulatives(t_UmbrellaWindow *window,int nWindows,
+                      t_UmbrellaOptions *opt,const char *fnhist)
 {
     int i,j,k,nbin;
     double last;
     char *fn=0,*buf=0;
     FILE *fp=0;
-
-
+    
     if (opt->bs_verbose)
     {
         snew(fn,strlen(fnhist)+10);
         snew(buf,strlen(fnhist)+10);
         sprintf(fn,"%s_cumul.xvg",strncpy(buf,fnhist,strlen(fnhist)-4));
-        fp=xvgropen(fn,"Cummulants of umbrella histograms","z","cummulant",
-                    oenv);
+        fp=xvgropen(fn,"CDFs of umbrella windows","z","CDF",opt->oenv);
     }
-
+    
     nbin=opt->bins;
     for (i=0; i<nWindows; i++)
     {
@@ -838,15 +974,15 @@ void calc_cummulants(t_UmbrellaWindow *window,int nWindows,
             window[i].cum[j][0]=0.;
             for (k=1; k<=nbin; k++)
                 window[i].cum[j][k] = window[i].cum[j][k-1]+window[i].Histo[j][k-1];
-
-            /* normalize cummulant. Ensure cum[nbin]==1 */
+            
+            /* normalize CDFs. Ensure cum[nbin]==1 */
             last = window[i].cum[j][nbin];
             for (k=0; k<=nbin; k++)
                 window[i].cum[j][k] /= last;
         }
     }
-
-    printf("Cumulants of all histograms created.\n");
+    
+    printf("Cumulative distriubtion functions of all histograms created.\n");
     if (opt->bs_verbose)
     {
         for (k=0; k<=nbin; k++)
@@ -857,7 +993,7 @@ void calc_cummulants(t_UmbrellaWindow *window,int nWindows,
                     fprintf(fp,"%g\t",window[i].cum[j][k]);
             fprintf(fp,"\n");
         }
-        printf("Wrote cumulants to %s\n",fn);
+        printf("Wrote cumulative distribution functions to %s\n",fn);
         ffclose(fp);
         sfree(fn);
         sfree(buf);
@@ -866,14 +1002,13 @@ void calc_cummulants(t_UmbrellaWindow *window,int nWindows,
 
 
 /* Return j such that xx[j] <= x < xx[j+1] */
-void searchCummulant(double xx[], int n, double x, int *j)
+void searchCumulative(double xx[], int n, double x, int *j)
 {
     int ju,jm,jl;
-
-
+    
     jl=-1;
     ju=n;
-    while (ju-jl > 1)
+    while (ju-jl > 1) 
     {
         jm=(ju+jl) >> 1;
         if (x >= xx[jm])
@@ -889,64 +1024,140 @@ void searchCummulant(double xx[], int n, double x, int *j)
         *j=jl;
 }
 
-
-void create_synthetic_histo(t_UmbrellaWindow *synthWindow, 
-                            t_UmbrellaWindow *thisWindow,
+void create_synthetic_histo(t_UmbrellaWindow *synthWindow, t_UmbrellaWindow *thisWindow,
                             int pullid,t_UmbrellaOptions *opt)
 {
-    int nsynth,N,i,nbins,r_index;
-    double r;
-    static gmx_bool bWarnout=0;
-
-
+    int N,i,nbins,r_index,ibin;
+    double r,tausteps=0.0,a,ap,dt,x,invsqrt2,g,y,sig=0.,z,mu=0.;
+    char errstr[1024];
+    
     N=thisWindow->N[pullid];
+    dt=thisWindow->dt;
     nbins=thisWindow->nBin;
-
-    /* nsynth = nr of data points in synthetic histo */
-    if (opt->dtBootStrap==0.0)
-        nsynth=N;
-    else
+    
+    /* tau = autocorrelation time */
+    if (opt->tauBootStrap>0.0)
+        tausteps=opt->tauBootStrap/dt;
+    else if (opt->bTauIntGiven || opt->bCalcTauInt)
     {
-      nsynth=(int)(thisWindow->N[pullid]*thisWindow->dt/opt->dtBootStrap+0.5);
-        if (nsynth>N)
-            nsynth=N;
+        /* calc tausteps from g=1+2tausteps */
+        g=thisWindow->g[pullid];
+        tausteps=(g-1)/2;
     }
-
-    if (!bWarnout && nsynth<10)
+    else
     {
-        printf("\n++++ WARNING ++++\n\tOnly %d data points per synthetic histogram!\n"
-                "\tYou may want to consider option -bs-dt.\n\n",nsynth);
-        bWarnout=1;
+        sprintf(errstr,
+                "When generating hypothetical trajctories from given umbrella histograms,\n"
+                "autocorrelation times (ACTs) are required. Otherwise the statistical error\n"
+                "cannot be predicted. You have 3 options:\n"
+                "1) Make g_wham estimate the ACTs (options -ac and -acsig).\n"
+                "2) Calculate the ACTs by yourself (e.g. with g_analyze) and provide them\n");
+        strcat(errstr,
+               "   with option -iiact for all umbrella windows.\n"
+               "3) If all ACTs are identical and know, you can define them with -bs-tau.\n"
+               "   Use option (3) only if you are sure what you're doing, you may severely\n"
+               "   underestimate the error if a too small ACT is given.\n");
+        gmx_fatal(FARGS,errstr);
     }
 
-    synthWindow->N       [0]=nsynth;
+    synthWindow->N       [0]=N;
     synthWindow->pos     [0]=thisWindow->pos[pullid];
     synthWindow->z       [0]=thisWindow->z[pullid];
     synthWindow->k       [0]=thisWindow->k[pullid];
     synthWindow->bContrib[0]=thisWindow->bContrib[pullid];
-
+    synthWindow->g       [0]=thisWindow->g       [pullid];
+    synthWindow->bsWeight[0]=thisWindow->bsWeight[pullid];
+    
     for (i=0;i<nbins;i++)
         synthWindow->Histo[0][i]=0.;
-
-    for (i=0;i<nsynth;i++)
+    
+    if (opt->bsMethod==bsMethod_trajGauss)
+    {
+        sig = thisWindow->sigma [pullid];
+        mu  = thisWindow->aver  [pullid];
+    }
+    
+    /* Genrate autocorrelated Gaussian random variable with autocorrelation time tau 
+       Use the following:
+       If x and y are random numbers from N(0,1) (Gaussian with average 0 and sigma=1),
+       then
+       z = a*x + sqrt(1-a^2)*y
+       is also from N(0,1), and cov(z,x) = a. Thus, by gerenating a sequence
+       x' = a*x + sqrt(1-a^2)*y, the sequnce x(t) is from N(0,1) and has an autocorrelation 
+       function
+       C(t) = exp(-t/tau) with tau=-1/ln(a)
+
+       Then, use error function to turn the Gaussian random variable into a uniformly
+       distributed one in [0,1]. Eventually, use cumulative distribution function of
+       histogram to get random variables distributed according to histogram.
+       Note: The ACT of the flat distribution and of the generated histogram is not
+       100% exactly tau, but near tau (my test was 3.8 instead of 4).
+    */
+    a=exp(-1.0/tausteps);
+    ap=sqrt(1-a*a);
+    invsqrt2=1./sqrt(2.0);
+    
+    /* init random sequence */
+    x=gmx_rng_gaussian_table(opt->rng); 
+    
+    if (opt->bsMethod==bsMethod_traj)
+    {
+        /* bootstrap points from the umbrella histograms */
+        for (i=0;i<N;i++)
+        {
+            y=gmx_rng_gaussian_table(opt->rng);
+            x=a*x+ap*y;
+            /* get flat distribution in [0,1] using cumulative distribution function of Gauusian
+               Note: CDF(Gaussian) = 0.5*{1+erf[x/sqrt(2)]}
+            */           
+            r=0.5*(1+gmx_erf(x*invsqrt2));
+            searchCumulative(thisWindow->cum[pullid],nbins+1 ,r,&r_index);
+            synthWindow->Histo[0][r_index]+=1.;    
+        }
+    }
+    else if (opt->bsMethod==bsMethod_trajGauss)
+    {
+        /* bootstrap points from a Gaussian with the same average and sigma
+           as the respective umbrella histogram. The idea was, that -given
+           limited sampling- the bootstrapped histograms are otherwise biased 
+           from the limited sampling of the US histos. However, bootstrapping from
+           the Gaussian seems to yield a similar estimate. */
+        i=0;
+        while (i<N)
+        {
+            y=gmx_rng_gaussian_table(opt->rng);
+            x=a*x+ap*y;
+            z = x*sig+mu;
+            ibin=floor((z-opt->min)/opt->dz);
+            if (opt->bCycl)
+            {
+                if (ibin<0)
+                    while ( (ibin+=nbins) < 0);
+                else if (ibin>=nbins)
+                    while ( (ibin-=nbins) >= nbins);
+            }
+            
+            if (ibin>=0 && ibin<nbins)
+            {
+                synthWindow->Histo[0][ibin]+=1.;
+                i++;
+            }
+        }
+    }
+    else
     {
-        r=1.0*rand()/RAND_MAX;
-        searchCummulant(thisWindow->cum[pullid],nbins+1 ,r,&r_index);
-        synthWindow->Histo[0][r_index]+=1.;
+        gmx_fatal(FARGS,"Unknown bsMethod (id %d). That should not happen.\n",opt->bsMethod);
     }
 }
 
 
-void print_histograms(const char *fnhist, t_UmbrellaWindow * window, 
-                      int nWindows, int bs_index,t_UmbrellaOptions *opt, 
-                      const output_env_t oenv)
+void print_histograms(const char *fnhist, t_UmbrellaWindow * window, int nWindows,
+                      int bs_index,t_UmbrellaOptions *opt)
 {
-    char *fn;
-    char *buf=0,title[256];
+    char *fn=0,*buf=0,title[256];
     FILE *fp;
     int bins,l,i,j;
-
-
+    
     if (bs_index<0)
     {
         fn=strdup(fnhist);
@@ -954,29 +1165,29 @@ void print_histograms(const char *fnhist, t_UmbrellaWindow * window,
     }
     else
     {
-        snew(fn,strlen(fnhist)+6);
+        snew(fn,strlen(fnhist)+10);
         snew(buf,strlen(fnhist)+1);
         sprintf(fn,"%s_bs%d.xvg",strncpy(buf,fnhist,strlen(fnhist)-4),bs_index);
         sprintf(title,"Umbrella histograms. Bootstrap #%d",bs_index);
     }
-
-    fp=xvgropen(fn,title,"z","count",oenv);
+    
+    fp=xvgropen(fn,title,"z","count",opt->oenv);
     bins=opt->bins;
-
+    
     /* Write histograms */
-    for(l=0;l<bins;++l)
+    for(l=0;l<bins;++l) 
     {
         fprintf(fp,"%e\t",(double)(l+0.5)*opt->dz+opt->min);
-        for(i=0;i<nWindows;++i)
+        for(i=0;i<nWindows;++i) 
         {
-            for(j=0;j<window[i].nPull;++j)
+            for(j=0;j<window[i].nPull;++j) 
             {
                 fprintf(fp,"%e\t",window[i].Histo[j][l]);
             }
         }
         fprintf(fp,"\n");
     }
-
+    
     ffclose(fp);
     printf("Wrote %s\n",fn);
     if (buf)
@@ -986,11 +1197,52 @@ void print_histograms(const char *fnhist, t_UmbrellaWindow * window,
     }
 }
 
+int func_wham_is_larger(const void *a, const void *b)
+{
+    double *aa,*bb;
+    aa=(double*)a;
+    bb=(double*)b;
+    if (*aa < *bb)
+        return -1;
+    else if (*aa > *bb)
+        return 1;
+    else
+        return 0;
+}
+
+
+void setRandomBsWeights(t_UmbrellaWindow *synthwin,int nAllPull, t_UmbrellaOptions *opt)
+{
+    int i;
+    double *r;
+    
+    snew(r,nAllPull);
+    
+    /* generate ordered random numbers between 0 and nAllPull  */
+    for (i=0; i<nAllPull-1; i++)
+    {
+        r[i] = gmx_rng_uniform_real(opt->rng) * nAllPull;
+    }
+    qsort((void *)r,nAllPull-1, sizeof(double), &func_wham_is_larger);
+    r[nAllPull-1]=1.0*nAllPull;
+    
+    synthwin[0].bsWeight[0]=r[0];
+    for (i=1; i<nAllPull; i++)
+    {
+        synthwin[i].bsWeight[0]=r[i]-r[i-1];
+    }
+    
+    /* avoid to have zero weight by adding a tiny value */
+    for (i=0; i<nAllPull; i++)
+        if (synthwin[i].bsWeight[0] < 1e-5)   
+            synthwin[i].bsWeight[0] = 1e-5;
+
+    sfree(r);
+}
 
-void do_bootstrapping(const char *fnres, const char* fnprof, 
-                      const char *fnhist, char* ylabel, double *profile,
-                      t_UmbrellaWindow * window, int nWindows, 
-                      t_UmbrellaOptions *opt, const output_env_t oenv)
+void do_bootstrapping(const char *fnres, const char* fnprof, const char *fnhist,
+                      char* ylabel, double *profile,
+                      t_UmbrellaWindow * window, int nWindows, t_UmbrellaOptions *opt)
 {
     t_UmbrellaWindow * synthWindow;
     double *bsProfile,*bsProfiles_av, *bsProfiles_av2,maxchange=1e20,tmp,stddev;
@@ -998,21 +1250,20 @@ void do_bootstrapping(const char *fnres, const char* fnprof,
     int iAllPull,nAllPull,*allPull_winId,*allPull_pullId;
     FILE *fp;
     gmx_bool bExact=FALSE;
-
-
-    /* init random */
+    
+    /* init random generator */
     if (opt->bsSeed==-1)
-        srand(time(NULL));
+        opt->rng=gmx_rng_init(gmx_rng_make_seed());
     else
-        srand(opt->bsSeed);
-
+        opt->rng=gmx_rng_init(opt->bsSeed);
+    
     snew(bsProfile,     opt->bins);
     snew(bsProfiles_av, opt->bins);
     snew(bsProfiles_av2,opt->bins);
-
+    
     /* Create array of all pull groups. Note that different windows
-     may have different nr of pull groups
-     First: Get total nr of pull groups */
+       may have different nr of pull groups
+       First: Get total nr of pull groups */
     nAllPull=0;
     for (i=0;i<nWindows;i++)
         nAllPull+=window[i].nPull;
@@ -1021,13 +1272,15 @@ void do_bootstrapping(const char *fnres, const char* fnprof,
     iAllPull=0;
     /* Setup one array of all pull groups */
     for (i=0;i<nWindows;i++)
+    {
         for (j=0;j<window[i].nPull;j++)
         {
             allPull_winId[iAllPull]=i;
             allPull_pullId[iAllPull]=j;
             iAllPull++;
         }
-
+    }
+    
     /* setup stuff for synthetic windows */
     snew(synthWindow,nAllPull);
     for (i=0;i<nAllPull;i++)
@@ -1035,66 +1288,90 @@ void do_bootstrapping(const char *fnres, const char* fnprof,
         synthWindow[i].nPull=1;
         synthWindow[i].nBin=opt->bins;
         snew(synthWindow[i].Histo,1);
-        if (!opt->bHistBootStrap)
+        if (opt->bsMethod == bsMethod_traj || opt->bsMethod == bsMethod_trajGauss)
             snew(synthWindow[i].Histo[0],opt->bins);
         snew(synthWindow[i].N,1);
         snew(synthWindow[i].pos,1);
         snew(synthWindow[i].z,1);
         snew(synthWindow[i].k,1);
         snew(synthWindow[i].bContrib,1);
+        snew(synthWindow[i].g,1);
+        snew(synthWindow[i].bsWeight,1);
     }
-
-    if (opt->bHistBootStrap)
+    
+    switch(opt->bsMethod)
     {
+    case bsMethod_hist:
         snew(randomArray,nAllPull);
         printf("\n\nWhen computing statistical errors by bootstrapping entire histograms:\n");
         please_cite(stdout,"Hub2006");
+        break;
+    case bsMethod_BayesianHist :
+        /* just copy all histogams into synthWindow array */
+        for (i=0;i<nAllPull;i++)
+        {
+            winid =allPull_winId [i];
+            pullid=allPull_pullId[i];
+            copy_pullgrp_to_synthwindow(synthWindow+i,window+winid,pullid);
+        }
+        break;
+    case bsMethod_traj:
+    case bsMethod_trajGauss:   
+        calc_cumulatives(window,nWindows,opt,fnhist);
+        break;
+    default:
+        gmx_fatal(FARGS,"Unknown bootstrap method. That should not have happened.\n");
     }
-    else
-    {
-        calc_cummulants(window,nWindows,opt,fnhist,oenv);
-    }
-
+  
     /* do bootstrapping */
-    fp=xvgropen(fnprof,"Boot strap profiles","z",ylabel,oenv);
+    fp=xvgropen(fnprof,"Boot strap profiles","z",ylabel,opt->oenv);
     for (ib=0;ib<opt->nBootStrap;ib++)
     {
         printf("  *******************************************\n"
-                "  ******** Start bootstrap nr %d ************\n"
-                "  *******************************************\n",ib+1);
-
-        if (opt->bHistBootStrap)
+               "  ******** Start bootstrap nr %d ************\n"
+               "  *******************************************\n",ib+1);
+        
+        switch(opt->bsMethod)
         {
-            /* only mix given histos */
-            getRandomIntArray(nAllPull,opt->histBootStrapBlockLength,randomArray);
-            for (i=0;i<nAllPull;i++)
-            {
+        case bsMethod_hist:  
+            /* bootstrap complete histograms from given histograms */
+            getRandomIntArray(nAllPull,opt->histBootStrapBlockLength,randomArray,opt->rng);
+            for (i=0;i<nAllPull;i++){
                 winid =allPull_winId [randomArray[i]];
                 pullid=allPull_pullId[randomArray[i]];
                 copy_pullgrp_to_synthwindow(synthWindow+i,window+winid,pullid);
             }
-        }
-        else
-        {
-            /* create new histos from given histos */
+            break;
+        case bsMethod_BayesianHist:  
+            /* keep histos, but assign random weights ("Bayesian bootstrap") */
+            setRandomBsWeights(synthWindow,nAllPull,opt);
+            break;
+        case bsMethod_traj:
+        case bsMethod_trajGauss:       
+            /* create new histos from given histos, that is generate new hypothetical
+               trajectories */
             for (i=0;i<nAllPull;i++)
             {
                 winid=allPull_winId[i];
-                pullid=allPull_pullId[i];
+                pullid=allPull_pullId[i];        
                 create_synthetic_histo(synthWindow+i,window+winid,pullid,opt);
             }
+            break;
         }
-
-        /* print histos in case of verbose output */
+        
+        /* write histos in case of verbose output */
         if (opt->bs_verbose)
-            print_histograms(fnhist,synthWindow,nAllPull,ib,opt,oenv);
-
+            print_histograms(fnhist,synthWindow,nAllPull,ib,opt);
+        
         /* do wham */
         i=0;
         bExact=FALSE;
         maxchange=1e20;
         memcpy(bsProfile,profile,opt->bins*sizeof(double)); /* use profile as guess */
-        do {
+        do 
+        {
+            if ( (i%opt->stepUpdateContrib) == 0)
+                setup_acc_wham(bsProfile,synthWindow,nAllPull,opt);
             if (maxchange<opt->Tolerance)
                 bExact=TRUE;
             if (((i%opt->stepchange) == 0 || i==1) && !i==0)
@@ -1103,14 +1380,14 @@ void do_bootstrapping(const char *fnres, const char* fnprof,
             i++;
         } while( (maxchange=calc_z(bsProfile, synthWindow, nAllPull, opt,bExact)) > opt->Tolerance || !bExact);
         printf("\tConverged in %d iterations. Final maximum change %g\n",i,maxchange);
-
+        
         if (opt->bLog)
             prof_normalization_and_unit(bsProfile,opt);
-        /* Force cyclic profile by wheighted correction */
-        if (opt->cycl==enCycl_weighted)
-            cyclicProfByWeightedCorr(bsProfile,synthWindow,nAllPull,opt, 
-                                     FALSE, 0,oenv);
-
+        
+        /* symmetrize profile around z=0 */
+        if (opt->bSym)
+            symmetrizeProfile(bsProfile,opt);
+        
         /* save stuff to get average and stddev */
         for (i=0;i<opt->bins;i++)
         {
@@ -1122,12 +1399,9 @@ void do_bootstrapping(const char *fnres, const char* fnprof,
         fprintf(fp,"&\n");
     }
     ffclose(fp);
-
+  
     /* write average and stddev */
-    fp=ffopen(fnres,"w");
-    fprintf(fp,"@    title \"%s\"\n","Average and stddev from bootstrapping");
-    fprintf(fp,"@    xaxis  label \"%s\"\n","z");
-    fprintf(fp,"@    yaxis  label \"%s\"\n",ylabel);
+    fp=xvgropen(fnres,"Average and stddev from bootstrapping","z",ylabel,opt->oenv);
     fprintf(fp,"@TYPE xydy\n");
     for (i=0;i<opt->bins;i++)
     {
@@ -1141,8 +1415,7 @@ void do_bootstrapping(const char *fnres, const char* fnprof,
     printf("Wrote boot strap result to %s\n",fnres);
 }
 
-
-int whaminFileType(const char *fn)
+int whaminFileType(char *fn)
 {
     int len;
     len=strlen(fn);
@@ -1157,85 +1430,122 @@ int whaminFileType(const char *fn)
     return whamin_unknown;
 }
 
-
 void read_wham_in(const char *fn,char ***filenamesRet, int *nfilesRet,
                   t_UmbrellaOptions *opt)
 {
-    char **filename,tmp[STRLEN];
-    int nread,sizenow,i,block=10;
+    char **filename=0,tmp[STRLEN];
+    int nread,sizenow,i,block=1;
     FILE *fp;
-#define MAXFILELEN 512
-
-
+    
     fp=ffopen(fn,"r");
-    sizenow=block;
-    snew(filename,sizenow);
-    for (i=0;i<sizenow;i++)
-        snew(filename[i],MAXFILELEN);
     nread=0;
+    sizenow=0;
     while (fscanf(fp,"%s",tmp) != EOF)
     {
-        if (strlen(tmp)>=MAXFILELEN)
-            gmx_fatal(FARGS,"Filename too long. Only %d characters allowed\n",MAXFILELEN);
-        strcpy(filename[nread],tmp);
-        if (opt->verbose)
-            printf("Found file %s in %s\n",filename[nread],fn);
-        nread++;
+        if (strlen(tmp)>=WHAM_MAXFILELEN)
+            gmx_fatal(FARGS,"Filename too long. Only %d characters allowed\n",WHAM_MAXFILELEN);
         if (nread>=sizenow)
         {
             sizenow+=block;
             srenew(filename,sizenow);
             for (i=sizenow-block;i<sizenow;i++)
-                snew(filename[i],MAXFILELEN);
+                snew(filename[i],WHAM_MAXFILELEN);
         }
+        strcpy(filename[nread],tmp);
+        if (opt->verbose)
+            printf("Found file %s in %s\n",filename[nread],fn);
+        nread++;
     }
     *filenamesRet=filename;
     *nfilesRet=nread;
 }
 
 
-FILE *pdo_open_file(const char *fn)
+FILE *open_pdo_pipe(const char *fn, t_UmbrellaOptions *opt,gmx_bool *bPipeOpen)
 {
     char Buffer[1024],gunzip[1024],*Path=0;
-    FILE *fp;
-
-    if (!gmx_fexist(fn))
-       {
-        gmx_fatal(FARGS,"File %s does not exist.\n",fn);
-       }
-       
+    FILE *pipe=0;
+    static gmx_bool bFirst=1;  
+    
     /* gzipped pdo file? */
-    if (strcmp(fn+strlen(fn)-3,".gz")==0)
+    if ((strcmp(fn+strlen(fn)-3,".gz")==0))
     {
-#ifdef HAVE_PIPES
+        /* search gunzip executable */
         if(!(Path=getenv("GMX_PATH_GZIP")))
-            sprintf(gunzip,"%s","/bin/gunzip");
+        {
+            if (gmx_fexist("/bin/gunzip"))
+                sprintf(gunzip,"%s","/bin/gunzip");
+            else if (gmx_fexist("/usr/bin/gunzip"))
+                sprintf(gunzip,"%s","/usr/bin/gunzip");
+            else
+                gmx_fatal(FARGS,"Cannot find executable gunzip in /bin or /usr/bin.\n"
+                          "You may want to define the path to gunzip "
+                          "with the environment variable GMX_PATH_GZIP.",gunzip);
+        }
         else
+        {
             sprintf(gunzip,"%s/gunzip",Path);
-        if (!gmx_fexist(gunzip))
-            gmx_fatal(FARGS,"Cannot find executable %s. You may want to define the path to gunzip "
-                    "with the environment variable GMX_PATH_GZIP.",gunzip);
-        sprintf(Buffer,"%s -c < %s",gunzip,fn);
-               if((fp=popen(Buffer,"r"))==NULL)
-               {
-                       gmx_fatal(FARGS,"Unable to open pipe to `%s'\n",Buffer);
-               }
+            if (!gmx_fexist(gunzip))
+                gmx_fatal(FARGS,"Cannot find executable %s. Please define the path to gunzip"
+                          " in the environmental varialbe GMX_PATH_GZIP.",gunzip);
+        }    
+        if (bFirst)
+        {
+            printf("Using gunzig executable %s\n",gunzip);
+            bFirst=0;
+        }
+        if (!gmx_fexist(fn))
+        {
+            gmx_fatal(FARGS,"File %s does not exist.\n",fn);
+        }
+        sprintf(Buffer,"%s -c < %s",gunzip,fn);    
+        if (opt->verbose)
+            printf("Executing command '%s'\n",Buffer);
+#ifdef HAVE_PIPES
+        if((pipe=popen(Buffer,"r"))==NULL)
+        {
+            gmx_fatal(FARGS,"Unable to open pipe to `%s'\n",Buffer);
+        }
 #else
-               gmx_fatal(FARGS,"Cannot open a compressed file on platform without pipe support");
+        gmx_fatal(FARGS,"Cannot open a compressed file on platform without pipe support");
 #endif
+        *bPipeOpen=TRUE;
+    }
+    else{
+        pipe=ffopen(fn,"r");
+        *bPipeOpen=FALSE;
+    }
+    
+    return pipe;
+}
+
+
+FILE *open_pdo_pipe_gmx(const char *fn)
+{
+    char *fnNoGz=0;
+    FILE *pipe;
+
+    /* gzipped pdo file? */
+    if (strcmp(fn+strlen(fn)-3,".gz")==0)
+    {
+        snew(fnNoGz,strlen(fn));
+        strncpy(fnNoGz,fn,strlen(fn)-3);
+        fnNoGz[strlen(fn)-3]='\0';
+        if (gmx_fexist(fnNoGz) && gmx_fexist(fn))
+            gmx_fatal(FARGS,"Found file %s and %s. That confuses me. Please remove one of them\n",
+                      fnNoGz,fn);
+        pipe=ffopen(fnNoGz,"r");  
+        sfree(fnNoGz);
     }
     else
-       {
-               if((fp=ffopen(fn,"r"))==NULL)
-               {
-                       gmx_fatal(FARGS,"Unable to open file %s\n",fn);
-               }               
-       }
-       return fp;
+    {
+        pipe=ffopen(fn,"r");
+    }
+  
+    return pipe;
 }
 
-void
-pdo_close_file(FILE *fp)
+void pdo_close_file(FILE *fp)
 {
 #ifdef HAVE_PIPES
        pclose(fp);
@@ -1244,28 +1554,33 @@ pdo_close_file(FILE *fp)
 #endif
 }
 
+
 /* Reading pdo files */
 void read_pdo_files(char **fn, int nfiles, t_UmbrellaHeader* header,
-        t_UmbrellaWindow **window, t_UmbrellaOptions *opt)
+                    t_UmbrellaWindow *window, t_UmbrellaOptions *opt)
 {
-    FILE  * file;
-    real mintmp,maxtmp;
+    FILE  *file;
+    real mintmp,maxtmp,done=0.;
     int i;
-
-
+    gmx_bool bPipeOpen;
+    /* char Buffer0[1000]; */
+    
     if(nfiles<1)
         gmx_fatal(FARGS,"No files found. Hick.");
-
+    
     /* if min and max are not given, get min and max from the input files */
     if (opt->bAuto)
     {
         printf("Automatic determination of boundaries from %d pdo files...\n",nfiles);
         opt->min=1e20;
         opt->max=-1e20;
-        for(i=0;i<nfiles;++i)
+        for(i=0;i<nfiles;++i) 
         {
-            file=pdo_open_file(fn[i]);
-            printf("\rOpening %s ...",fn[i]); fflush(stdout);
+            file=open_pdo_pipe(fn[i],opt,&bPipeOpen);
+            /*fgets(Buffer0,999,file);
+              fprintf(stderr,"First line '%s'\n",Buffer0); */
+            done=100.0*(i+1)/nfiles;
+            printf("\rOpening %s ... [%2.0f%%]",fn[i],done); fflush(stdout);
             if (opt->verbose)
                 printf("\n");
             read_pdo_header(file,header,opt);
@@ -1275,7 +1590,10 @@ void read_pdo_files(char **fn, int nfiles, t_UmbrellaHeader* header,
                 opt->max=maxtmp;
             if (mintmp<opt->min)
                 opt->min=mintmp;
-            pdo_close_file(file);
+            if (bPipeOpen)
+                pdo_close_file(file);
+            else
+                ffclose(file);
         }
         printf("\n");
         printf("\nDetermined boundaries to %f and %f\n\n",opt->min,opt->max);
@@ -1287,73 +1605,87 @@ void read_pdo_files(char **fn, int nfiles, t_UmbrellaHeader* header,
     }
     /* store stepsize in profile */
     opt->dz=(opt->max-opt->min)/opt->bins;
-
-    snew(*window,nfiles);
-
+    
     /* Having min and max, we read in all files */
     /* Loop over all files */
-    for(i=0;i<nfiles;++i)
+    for(i=0;i<nfiles;++i) 
     {
-        printf("\rOpening %s ...",fn[i]); fflush(stdout);
+        done=100.0*(i+1)/nfiles;
+        printf("\rOpening %s ... [%2.0f%%]",fn[i],done); fflush(stdout);
         if (opt->verbose)
             printf("\n");
-        file=pdo_open_file(fn[i]);
-        /* read in the headers */
+        file=open_pdo_pipe(fn[i],opt,&bPipeOpen);
         read_pdo_header(file,header,opt);
         /* load data into window */
-        read_pdo_data(file,header,i,*window,opt,FALSE,NULL,NULL);
-        pdo_close_file(file);
+        read_pdo_data(file,header,i,window,opt,FALSE,NULL,NULL);
+        if ((window+i)->Ntot[0] == 0.0)
+            fprintf(stderr,"\nWARNING, no data points read from file %s (check -b option)\n", fn[i]);
+        if (bPipeOpen)
+            pdo_close_file(file);
+        else
+            ffclose(file);
     }
     printf("\n");
+    for(i=0;i<nfiles;++i)
+        sfree(fn[i]);
+    sfree(fn);
 }
 
-
 #define int2YN(a) (((a)==0)?("N"):("Y"))
 
-void read_tpr_header(const char *fn,t_UmbrellaHeader* header,
-                     t_UmbrellaOptions *opt)
+void read_tpr_header(const char *fn,t_UmbrellaHeader* header,t_UmbrellaOptions *opt)
 {
     t_inputrec  ir;
-    int         i,ngrp,d;
+    int i,ngrp,d;
     t_state     state;
     static int first=1;
-
-
+    
     /* printf("Reading %s \n",fn); */
     read_tpx_state(fn,&ir,&state,NULL,NULL);
-
+    
     if (ir.ePull != epullUMBRELLA)
-        gmx_fatal(FARGS,"This is not a tpr of an umbrella simulation. Found ir.ePull = %s\n",
-                epull_names[ir.ePull]);
-
+        gmx_fatal(FARGS,"This is not a tpr of an umbrella simulation. Found pull type \"%s\" "
+                  " (ir.ePull = %d)\n", epull_names[ir.ePull],ir.ePull);
+    
     /* nr of pull groups */
     ngrp=ir.pull->ngrp;
     if (ngrp < 1)
         gmx_fatal(FARGS,"This is not a tpr of umbrella simulation. Found only %d pull groups\n",ngrp);
-
+    
     header->npullgrps=ir.pull->ngrp;
     header->pull_geometry=ir.pull->eGeom;
     copy_ivec(ir.pull->dim,header->pull_dim);
     header->pull_ndim=header->pull_dim[0]+header->pull_dim[1]+header->pull_dim[2];
     if (header->pull_geometry==epullgPOS && header->pull_ndim>1)
+    {
         gmx_fatal(FARGS,"Found pull geometry 'position' and more than 1 pull dimension (%d).\n"
-                "Hence, the pull potential does not correspond to a one-dimensional umbrella potential.\n"
-                "If you have some special umbrella setup you may want to write your own pdo files\n"
-                "and feed them into g_wham. Check g_wham -h !\n",header->pull_ndim);
+                  "Hence, the pull potential does not correspond to a one-dimensional umbrella potential.\n"
+                  "If you have some special umbrella setup you may want to write your own pdo files\n"
+                  "and feed them into g_wham. Check g_wham -h !\n",header->pull_ndim);
+    }
     snew(header->k,ngrp);
     snew(header->init_dist,ngrp);
     snew(header->umbInitDist,ngrp);
+    
+    /* only z-direction with epullgCYL? */
+    if (header->pull_geometry == epullgCYL)
+    {
+        if (header->pull_dim[XX] || header->pull_dim[YY] || (!header->pull_dim[ZZ]))
+            gmx_fatal(FARGS,"With pull geometry 'cylinder', expected pulling in Z direction only.\n"
+                      "However, found dimensions [%s %s %s]\n",
+                      int2YN(header->pull_dim[XX]),int2YN(header->pull_dim[YY]),
+                      int2YN(header->pull_dim[ZZ]));
+    }
 
     for (i=0;i<ngrp;i++)
     {
         header->k[i]=ir.pull->grp[i+1].k;
         if (header->k[i]==0.0)
             gmx_fatal(FARGS,"Pull group %d has force constant of of 0.0 in %s.\n"
-                    "That doesn't seem to be an Umbrella tpr.\n",
-                    i,fn);
+                      "That doesn't seem to be an Umbrella tpr.\n",
+                      i,fn);
         copy_rvec(ir.pull->grp[i+1].init,header->init_dist[i]);
-        header->Flipped[i]=opt->bFlipProf;
-
+        
         /* initial distance to reference */
         switch(header->pull_geometry)
         {
@@ -1362,23 +1694,30 @@ void read_tpr_header(const char *fn,t_UmbrellaHeader* header,
                 if (header->pull_dim[d])
                     header->umbInitDist[i]=header->init_dist[i][d];
             break;
+        case epullgCYL:
+            /* umbrella distance stored in init_dist[i][0] for geometry cylinder (not in ...[i][ZZ]) */
         case epullgDIST:
+        case epullgDIR:
+        case epullgDIRPBC:
             header->umbInitDist[i]=header->init_dist[i][0];
             break;
         default:
             gmx_fatal(FARGS,"Pull geometry %s not supported\n",epullg_names[header->pull_geometry]);
         }
     }
-
+    
     if (opt->verbose || first)
     {
         printf("File %s, %d groups, geometry \"%s\", dimensions [%s %s %s], (%d dimensions)\n",
-                fn,header->npullgrps,epullg_names[header->pull_geometry],
-                int2YN(header->pull_dim[0]),int2YN(header->pull_dim[1]),int2YN(header->pull_dim[2]),
-                header->pull_ndim);
+               fn,header->npullgrps,epullg_names[header->pull_geometry],
+               int2YN(header->pull_dim[0]),int2YN(header->pull_dim[1]),int2YN(header->pull_dim[2]),
+               header->pull_ndim);
         for (i=0;i<ngrp;i++)
-            printf("\tgrp %d) k = %.3f  inittial distance = %g\n",i,header->k[i],header->umbInitDist[i]);
+            printf("\tgrp %d) k = %-5g  position = %g\n",i,header->k[i],header->umbInitDist[i]);    
     }
+    if (!opt->verbose && first)
+        printf("\tUse option -v to see this output for all input tpr files\n");
+    
     first=0;
 }
 
@@ -1387,103 +1726,154 @@ double dist_ndim(double **dx,int ndim,int line)
 {
     int i;
     double r2=0.;
-
-
     for (i=0;i<ndim;i++)
         r2+=sqr(dx[i][line]);
-
     return sqrt(r2);
 }
 
-
-void read_pull_xf(const char *fn, const char *fntpr, 
-                  t_UmbrellaHeader * header, t_UmbrellaWindow * window,
-                  t_UmbrellaOptions *opt, gmx_bool bGetMinMax,real *mintmp,
-                  real *maxtmp)
+void read_pull_xf(const char *fn, const char *fntpr, t_UmbrellaHeader * header,
+                  t_UmbrellaWindow * window,
+                  t_UmbrellaOptions *opt,
+                  gmx_bool bGetMinMax,real *mintmp,real *maxtmp)
 {
-    double **y,pos=0.,t,force,time0=0.,dt;
-    int ny,nt,bins,ibin,i,g,dstep=1,nColPerGrp,nColRef,nColExpect;
-    real min,max,minfound,maxfound;
+    double **y=0,pos=0.,t,force,time0=0.,dt;
+    int ny,nt,bins,ibin,i,g,dstep=1,nColPerGrp,nColRefOnce,nColRefEachGrp,nColExpect,ntot;
+    real min,max,minfound=1e20,maxfound=-1e20;
     gmx_bool dt_ok,timeok,bHaveForce;
     const char *quantity;
+    const int blocklen=4096;
+    int *lennow=0;
+    
+    /* 
+       in force    output pullf.xvg: 
+       No   reference, one  column  per pull group
+       in position output pullx.xvg (not cylinder)
+       ndim reference, ndim columns per pull group
+       in position output pullx.xvg (in geometry cylinder): 
+       ndim*2 columns per pull group (ndim for ref, ndim for group)
+    */
 
-       minfound=1e20;
-       maxfound=-1e20;
-
-    /*
-     in force    output pullf.xvg: No   reference, one  column  per pull group
-     in position output pullx.xvg: ndim reference, ndim columns per pull group
-     */
     nColPerGrp = opt->bPullx ? header->pull_ndim : 1;
-    nColRef    = opt->bPullx ? header->pull_ndim : 0;
     quantity   = opt->bPullx ? "position" : "force";
-    nColExpect = 1 + nColRef + header->npullgrps*nColPerGrp;
+    
+    if (opt->bPullx)
+    {
+        if (header->pull_geometry == epullgCYL)
+        {
+            /* Geometry cylinder -> reference group before each pull group */
+            nColRefEachGrp=header->pull_ndim;
+            nColRefOnce=0;
+        }
+        else
+        {
+            /* Geometry NOT cylinder -> reference group only once after time column */
+            nColRefEachGrp=0;
+            nColRefOnce=header->pull_ndim;
+        }
+    }
+    else /* read forces, no reference groups */
+    {
+       nColRefEachGrp=0;
+        nColRefOnce=0;
+    }
+    nColExpect = 1 + nColRefOnce + header->npullgrps*(nColRefEachGrp+nColPerGrp);
     bHaveForce = opt->bPullf;
-
+    
+    /* With geometry "distance" or "distance_periodic", only force reading is supported so far. 
+       That avoids the somewhat tedious extraction of the right columns from the pullx files
+       to compute the distances projection on the vector. Sorry for the laziness. */
+    if  ( (header->pull_geometry==epullgDIR || header->pull_geometry==epullgDIRPBC) 
+          && opt->bPullx)
+    {
+        gmx_fatal(FARGS,"With pull geometries \"direction\" and \"direction_periodic\", only pull force "
+                  "reading \n(option -if) is supported at present, "
+                  "not pull position reading (options -ix).\nMake sure mdrun writes the pull "
+                  "forces (pullf.xvg files)\nand provide them to g_wham with option -if.", 
+                  epullg_names[header->pull_geometry]);
+    }
+    
     nt=read_xvg(fn,&y,&ny);
 
     /* Check consistency */
     if (nt<1)
+    {
         gmx_fatal(FARGS,"Empty pull %s file %s\n",quantity,fn);
+    }
     if (ny != nColExpect)
+    {
         gmx_fatal(FARGS,"Found %d pull groups in %s,\n but %d data columns in %s (expected %d)\n",
-                header->npullgrps,fntpr,ny-1,fn,nColExpect-1);
-
+                  header->npullgrps,fntpr,ny-1,fn,nColExpect-1);
+    }
+    
     if (opt->verbose)
         printf("Found %d times and %d %s sets %s\n",nt,(ny-1)/nColPerGrp,quantity,fn);
-
+  
     if (!bGetMinMax)
     {
         bins=opt->bins;
         min=opt->min;
         max=opt->max;
         if (nt>1)
+        {
             window->dt=y[0][1]-y[0][0];
-        else if (opt->nBootStrap && opt->dtBootStrap!=0.0)
+        }
+        else if (opt->nBootStrap && opt->tauBootStrap!=0.0)
+        {
             fprintf(stderr,"\n *** WARNING, Could not determine time step in %s\n",fn);
-
+        }
+        
         /* Need to alocate memory and set up structure */
         window->nPull=header->npullgrps;
         window->nBin=bins;
-
+        
         snew(window->Histo,window->nPull);
         snew(window->z,window->nPull);
         snew(window->k,window->nPull);
         snew(window->pos,window->nPull);
-        snew(window->Flipped,window->nPull);
         snew(window->N, window->nPull);
         snew(window->Ntot, window->nPull);
+        snew(window->g, window->nPull);
+        snew(window->bsWeight, window->nPull);    
+        window->bContrib=0;
 
-        for(g=0;g<window->nPull;++g)
+        if (opt->bCalcTauInt)
+            snew(window->ztime,window->nPull);
+        else
+            window->ztime=NULL;
+        snew(lennow,window->nPull);
+
+        for(g=0;g<window->nPull;++g) 
         {
             window->z[g]=1;
+            window->bsWeight[g]=1.;
             snew(window->Histo[g],bins);
             window->k[g]=header->k[g];
-            window->Flipped[g]=header->Flipped[g];
             window->N[g]=0;
             window->Ntot[g]=0;
+            window->g[g]=1.;
             window->pos[g]=header->umbInitDist[g];
+            if (opt->bCalcTauInt)
+                window->ztime[g]=NULL;
         }
+
     }
     else
-    {
-        /* only determine min and max */
+    { /* only determine min and max */
         minfound=1e20;
         maxfound=-1e20;
         min=max=bins=0; /* Get rid of warnings */
     }
 
-    if(header->Flipped[0])
-        gmx_fatal(FARGS,"Sorry, flipping not supported for gmx4 output\n");
-
     for (i=0;i<nt;i++)
     {
         /* Do you want that time frame? */
-      t=1.0/1000*((int)(0.5+y[0][i]*1000)); /* round time to fs */
-
+        t=1.0/1000*( (int) ((y[0][i]*1000) + 0.5)); /* round time to fs */
+        
         /* get time step of pdo file and get dstep from opt->dt */
         if (i==0)
+        {
             time0=t;
+        }
         else if (i==1)
         {
             dt=t-time0;
@@ -1496,16 +1886,16 @@ void read_pull_xf(const char *fn, const char *fntpr,
             if (!bGetMinMax)
                 window->dt=dt*dstep;
         }
-
+        
         dt_ok=(i%dstep == 0);
         timeok=(dt_ok && t >= opt->tmin && t <= opt->tmax);
         /*if (opt->verbose)
-      printf(" time = %f, (tmin,tmax)=(%e,%e), dt_ok=%d timeok=%d\n",
-      t,opt->tmin, opt->tmax, dt_ok,timeok); */
-
+          printf(" time = %f, (tmin,tmax)=(%e,%e), dt_ok=%d timeok=%d\n", 
+          t,opt->tmin, opt->tmax, dt_ok,timeok); */
+        
         if (timeok)
         {
-            for(g=0;g<header->npullgrps;++g)
+            for(g=0;g<header->npullgrps;++g) 
             {
                 if (bHaveForce)
                 {
@@ -1518,20 +1908,25 @@ void read_pull_xf(const char *fn, const char *fntpr,
                     switch (header->pull_geometry)
                     {
                     case epullgDIST:
-                        /* y has 1 time column y[0] and nColPerGrps columns per pull group;
-                              Distance to reference: */
-                        pos=dist_ndim(y+1+nColRef+g*nColPerGrp,header->pull_ndim,i);
+                        /* y has 1 time column y[0] and nColPerGrps columns per pull group; 
+                           Distance to reference:                                           */
+                        /* pos=dist_ndim(y+1+nColRef+g*nColPerGrp,header->pull_ndim,i); gmx 4.0 */
+                        pos=dist_ndim(y + 1 + nColRefOnce + g*nColPerGrp,header->pull_ndim,i);
                         break;
                     case epullgPOS:
-                        /* with geometry==position, we have always one column per group;
-                              Distance to reference: */
-                        pos=y[1+nColRef+g][i];
+                    case epullgCYL:
+                        /* with geometry==position, we have the reference once (nColRefOnce==ndim), but
+                           no extra reference group columns before each group (nColRefEachGrp==0)
+                           with geometry==cylinder, we have no initial ref group column (nColRefOnce==0), 
+                           but ndim ref group colums before every group (nColRefEachGrp==ndim)
+                           Distance to reference: */
+                        pos=y[1 + nColRefOnce + g*(nColRefEachGrp+nColPerGrp)][i];
                         break;
                     default:
                         gmx_fatal(FARGS,"Bad error, this error should have been catched before. Ups.\n");
                     }
                 }
-
+                
                 /* printf("grp %d dpos %f poseq %f pos %f \n",g,dpos,poseq,pos); */
                 if (bGetMinMax)
                 {
@@ -1542,15 +1937,28 @@ void read_pull_xf(const char *fn, const char *fntpr,
                 }
                 else
                 {
+                    if (opt->bCalcTauInt && !bGetMinMax)
+                    {
+                        /* save time series for autocorrelation analysis */
+                        ntot=window->Ntot[g];
+                        /* printf("i %d, ntot %d, lennow[g] = %d\n",i,ntot,lennow[g]); */
+                        if (ntot>=lennow[g])
+                        {
+                            lennow[g]+=blocklen;
+                            srenew(window->ztime[g],lennow[g]);
+                        }
+                        window->ztime[g][ntot]=pos;
+                    }
+                    
                     ibin=(int) floor((pos-min)/(max-min)*bins);
-                    if (opt->cycl==enCycl_yes)
+                    if (opt->bCycl)
                     {
                         if (ibin<0)
                             while ( (ibin+=bins) < 0);
                         else if (ibin>=bins)
                             while ( (ibin-=bins) >= bins);
-                    }
-                    if(ibin >= 0 && ibin < bins)
+                    }    
+                    if(ibin >= 0 && ibin < bins) 
                     {
                         window->Histo[g][ibin]+=1.;
                         window->N[g]++;
@@ -1566,25 +1974,26 @@ void read_pull_xf(const char *fn, const char *fntpr,
             break;
         }
     }
-
+  
     if (bGetMinMax)
     {
         *mintmp=minfound;
         *maxtmp=maxfound;
     }
+    sfree(lennow);
+    for (i=0;i<ny;i++)
+        sfree(y[i]);
 }
 
-
-void read_tpr_pullxf_files(char **fnTprs,char **fnPull,
-                           int nfiles, t_UmbrellaHeader* header,
-                           t_UmbrellaWindow **window, t_UmbrellaOptions *opt)
+void read_tpr_pullxf_files(char **fnTprs,char **fnPull,int nfiles,
+                           t_UmbrellaHeader* header, 
+                           t_UmbrellaWindow *window, t_UmbrellaOptions *opt)
 {
     int i;
     real mintmp,maxtmp;
-
-
-    printf("Reading %d tpr and pullf files\n",nfiles);
-
+    
+    printf("Reading %d tpr and pullf files\n",nfiles/2);
+    
     /* min and max not given? */
     if (opt->bAuto)
     {
@@ -1598,14 +2007,15 @@ void read_tpr_pullxf_files(char **fnTprs,char **fnPull,
             read_tpr_header(fnTprs[i],header,opt);
             if (whaminFileType(fnPull[i]) != whamin_pullxf)
                 gmx_fatal(FARGS,"Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n",i);
-            read_pull_xf(fnPull[i],fnTprs[i],header,NULL,opt,TRUE,&mintmp,&maxtmp);
+            read_pull_xf(fnPull[i],fnTprs[i],header,NULL,opt,TRUE,&mintmp,&maxtmp);      
             if (maxtmp>opt->max)
                 opt->max=maxtmp;
             if (mintmp<opt->min)
                 opt->min=mintmp;
         }
         printf("\nDetermined boundaries to %f and %f\n\n",opt->min,opt->max);
-        if (opt->bBoundsOnly){
+        if (opt->bBoundsOnly)
+        {
             printf("Found option -boundsonly, now exiting.\n");
             exit (0);
         }
@@ -1613,7 +2023,6 @@ void read_tpr_pullxf_files(char **fnTprs,char **fnPull,
     /* store stepsize in profile */
     opt->dz=(opt->max-opt->min)/opt->bins;
 
-    snew(*window,nfiles);
     for (i=0;i<nfiles; i++)
     {
         if (whaminFileType(fnTprs[i]) != whamin_tpr)
@@ -1621,176 +2030,655 @@ void read_tpr_pullxf_files(char **fnTprs,char **fnPull,
         read_tpr_header(fnTprs[i],header,opt);
         if (whaminFileType(fnPull[i]) != whamin_pullxf)
             gmx_fatal(FARGS,"Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n",i);
-        read_pull_xf(fnPull[i],fnTprs[i],header,*window+i,opt,FALSE,NULL,NULL);
+        read_pull_xf(fnPull[i],fnTprs[i],header,window+i,opt,FALSE,NULL,NULL);
+        if (window[i].Ntot[0] == 0.0)
+            fprintf(stderr,"\nWARNING, no data points read from file %s (check -b option)\n", fnPull[i]);
+    }
+
+    for (i=0;i<nfiles; i++)
+    {
+        sfree(fnTprs[i]);
+        sfree(fnPull[i]);
+    }
+    sfree(fnTprs);
+    sfree(fnPull);
+}
+
+/* Note: Here we consider tau[int] := int_0^inf ACF(t) as the integrated autocorrelation time. 
+   The factor `g := 1 + 2*tau[int]` subsequently enters the uncertainty.
+*/
+void readIntegratedAutocorrelationTimes(t_UmbrellaWindow *window,int nwins,t_UmbrellaOptions *opt,
+                                        const char* fn)
+{
+    int nlines,ny,i,ig;
+    double **iact;
+
+    printf("Readging Integrated autocorrelation times from %s ...\n",fn);
+    nlines=read_xvg(fn,&iact,&ny);
+    if (nlines!=nwins)
+        gmx_fatal(FARGS,"Found %d lines with integrated autocorrelation times in %s.\nExpected %d",
+                  nlines,fn,nwins);
+    for (i=0;i<nlines;i++){
+        if (window[i].nPull != ny)
+            gmx_fatal(FARGS,"You are providing autocorrelation times with option -iiact and the\n"
+                      "number of pull groups is different in different simulations. That is not\n"
+                      "supported yet. Sorry.\n");
+        for (ig=0;ig<window[i].nPull;ig++){
+            /* compare Kumar et al, J Comp Chem 13, 1011-1021 (1992) */
+            window[i].g[ig]=1+2*iact[ig][i]/window[i].dt;  
+      
+            if (iact[ig][i] <= 0.0)
+                fprintf(stderr,"\nWARNING, IACT = %f (window %d, group %d)\n", iact[ig][i],i,ig);
+        }
     }
 }
 
 
+/* Smooth autocorreltion times along the reaction coordinate. This is useful
+   if the ACT is subject to high uncertainty in case if limited sampling. Note
+   that -in case of limited sampling- the ACT may be severely underestimated. 
+   Note: the g=1+2tau are overwritten.
+   if opt->bAllowReduceIact==FALSE, the ACTs are never reduced, only increased
+   by the smoothing
+*/
+void smoothIact(t_UmbrellaWindow *window,int nwins,t_UmbrellaOptions *opt)
+{
+    int i,ig,j,jg;
+    double pos,dpos2,siglim,siglim2,gaufact,invtwosig2,w,weight,tausm;
+  
+    /* only evaluate within +- 3sigma of the Gausian */
+    siglim=3.0*opt->sigSmoothIact;
+    siglim2=dsqr(siglim);
+    /* pre-factor of Gaussian */
+    gaufact=1.0/(sqrt(2*M_PI)*opt->sigSmoothIact);
+    invtwosig2=0.5/dsqr(opt->sigSmoothIact);
+  
+    for (i=0;i<nwins;i++)
+    {
+        snew(window[i].tausmooth,window[i].nPull);
+        for (ig=0;ig<window[i].nPull;ig++)
+        {
+            tausm=0.;
+            weight=0;
+            pos=window[i].pos[ig];
+            for (j=0;j<nwins;j++)
+            {
+                for (jg=0;jg<window[j].nPull;jg++)
+                {
+                    dpos2=dsqr(window[j].pos[jg]-pos);   
+                    if (dpos2<siglim2){
+                        w=gaufact*exp(-dpos2*invtwosig2);
+                        weight+=w;
+                        tausm+=w*window[j].tau[jg];
+                        /*printf("Weight %g dpos2=%g pos=%g gaufact=%g invtwosig2=%g\n",
+                          w,dpos2,pos,gaufact,invtwosig2); */
+                    }
+                }
+            }
+            tausm/=weight;
+            if (opt->bAllowReduceIact || tausm>window[i].tau[ig])
+                window[i].tausmooth[ig]=tausm;
+            else
+                window[i].tausmooth[ig]=window[i].tau[ig];
+            window[i].g[ig] = 1+2*tausm/window[i].dt;
+        }
+    }
+}
+
+/* try to compute the autocorrelation time for each umbrealla window */
+#define WHAM_AC_ZERO_LIMIT 0.05
+void calcIntegratedAutocorrelationTimes(t_UmbrellaWindow *window,int nwins,
+                                        t_UmbrellaOptions *opt,        const char *fn)
+{
+    int i,ig,ncorr,ntot,j,k,*count,restart;
+    real *corr,c0,dt,timemax,tmp;
+    real *ztime,av,tausteps;
+    FILE *fp,*fpcorr=0;
+  
+    if (opt->verbose)
+        fpcorr=xvgropen("hist_autocorr.xvg","Autocorrelation functions of umbrella windows",
+                        "time [ps]","autocorrelation function",opt->oenv);
+  
+    printf("\n");
+    for (i=0;i<nwins;i++)
+    {
+        printf("\rEstimating integrated autocorreltion times ... [%2.0f%%] ...",100.*(i+1)/nwins);
+        fflush(stdout);
+        ntot=window[i].Ntot[0];
+
+        /* using half the maximum time as length of autocorrelation function */
+        ncorr=ntot/2;
+        if (ntot<10)
+            gmx_fatal(FARGS,"Tryig to estimtate autocorrelation time from only %d"
+                      " points. Provide more pull data!",ntot);
+        snew(corr,ncorr);
+        /* snew(corrSq,ncorr); */
+        snew(count,ncorr);
+        dt=window[i].dt;
+        timemax=dt*ncorr;
+        snew(window[i].tau,window[i].nPull);
+        restart=(int)(opt->acTrestart/dt+0.5);
+        if (restart==0)
+            restart=1;
+
+        for (ig=0;ig<window[i].nPull;ig++)
+        {            
+            if (ntot != window[i].Ntot[ig])
+                gmx_fatal(FARGS,"Encountered different nr of frames in different pull groups.\n"
+                          "That should not happen. (%d and %d)\n", ntot,window[i].Ntot[ig]);
+            ztime=window[i].ztime[ig];
+            
+            /* calc autocorrelation function C(t) = < [z(tau)-<z>]*[z(tau+t)-<z>]> */
+            for(j=0, av=0; (j<ntot); j++)
+                av+=ztime[j];
+            av/=ntot;
+            for(k=0; (k<ncorr); k++)
+            {
+                corr[k]=0.;
+                count[k]=0;
+            }
+            for(j=0; (j<ntot); j+=restart) 
+                for(k=0; (k<ncorr) && (j+k < ntot); k++)
+                {
+                    tmp=(ztime[j]-av)*(ztime[j+k]-av); 
+                    corr  [k] += tmp;
+                    /* corrSq[k] += tmp*tmp; */
+                    count[k]++;
+                }
+            /* divide by nr of frames for each time displacement */
+            for(k=0; (k<ncorr); k++) 
+            {
+                /* count probably = (ncorr-k+(restart-1))/restart; */
+                corr[k] = corr[k]/count[k];
+                /* variance of autocorrelation function */
+                /* corrSq[k]=corrSq[k]/count[k]; */
+            }
+            /* normalize such that corr[0] == 0 */
+            c0=1./corr[0];
+            for(k=0; (k<ncorr); k++)
+            {
+                corr[k]*=c0;
+                /* corrSq[k]*=c0*c0; */
+            }
+
+            /* write ACFs in verbose mode */
+            if (fpcorr)
+            {
+                for(k=0; (k<ncorr); k++)
+                    fprintf(fpcorr,"%g  %g\n",k*dt,corr[k]);
+                fprintf(fpcorr,"&\n");
+            }
+      
+            /* esimate integrated correlation time, fitting is too unstable */
+            tausteps = 0.5*corr[0];
+            /* consider corr below WHAM_AC_ZERO_LIMIT as noise */
+            for(j=1; (j<ncorr) && (corr[j]>WHAM_AC_ZERO_LIMIT); j++)
+                tausteps += corr[j];
+         
+            /* g = 1+2*tau, see. Ferrenberg/Swendsen, PRL 63:1195 (1989) or
+               Kumar et al, eq. 28 ff. */
+            window[i].tau[ig] = tausteps*dt;
+            window[i].g[ig] = 1+2*tausteps;
+            /* printf("win %d, group %d, estimated correlation time = %g ps\n",i,ig,window[i].tau[ig]); */
+        } /* ig loop */
+        sfree(corr);
+        sfree(count);
+    }
+    printf(" done\n");
+    if (fpcorr)
+        ffclose(fpcorr);
+  
+    /* plot IACT along reaction coordinate */
+    fp=xvgropen(fn,"Integrated autocorrelation times","z","IACT [ps]",opt->oenv);
+    fprintf(fp,"@    s0 symbol 1\n@    s0 symbol size 0.5\n@    s0 line linestyle 0\n");
+    fprintf(fp,"#  WIN   tau(gr1)  tau(gr2) ...\n");
+    for (i=0;i<nwins;i++)
+    {
+        fprintf(fp,"# %3d   ",i);
+        for (ig=0;ig<window[i].nPull;ig++)
+            fprintf(fp," %11g",window[i].tau[ig]);
+        fprintf(fp,"\n");
+    }
+    for (i=0;i<nwins;i++)
+        for (ig=0;ig<window[i].nPull;ig++)
+            fprintf(fp,"%8g %8g\n",window[i].pos[ig],window[i].tau[ig]);
+    if (opt->sigSmoothIact > 0.0)
+    {
+        printf("Smoothing autocorrelation times along reaction coordinate with Gaussian of sig = %g\n",
+               opt->sigSmoothIact);
+        /* smooth IACT along reaction coordinate and overwrite g=1+2tau */
+        smoothIact(window,nwins,opt);
+        fprintf(fp,"&\n@    s1 symbol 1\n@    s1 symbol size 0.5\n@    s1 line linestyle 0\n");
+        fprintf(fp,"@    s1 symbol color 2\n");
+        for (i=0;i<nwins;i++)
+            for (ig=0;ig<window[i].nPull;ig++)
+                fprintf(fp,"%8g %8g\n",window[i].pos[ig],window[i].tausmooth[ig]);
+    }   
+    ffclose(fp);
+    printf("Wrote %s\n",fn);
+}
+
+/* compute average and sigma of each umbrella window */
+void averageSigma(t_UmbrellaWindow *window,int nwins,t_UmbrellaOptions *opt)
+{
+    int i,ig,ntot,k;
+    real av,sum2,sig,diff,*ztime,nSamplesIndep;
+
+    for (i=0;i<nwins;i++)
+    {
+        snew(window[i].aver, window[i].nPull);
+        snew(window[i].sigma,window[i].nPull);
+
+        ntot=window[i].Ntot[0];
+        for (ig=0;ig<window[i].nPull;ig++)
+        {
+            ztime=window[i].ztime[ig];
+            for (k=0, av=0.; k<ntot; k++)
+                av+=ztime[k];
+            av/=ntot;
+            for (k=0, sum2=0.; k<ntot; k++)
+            {
+                diff=ztime[k]-av;
+                sum2+=diff*diff;
+            }
+            sig=sqrt(sum2/ntot);
+            window[i].aver[ig]=av;
+
+            /* Note: This estimate for sigma is biased from the limited sampling.
+               Correct sigma by n/(n-1) where n = number of independent
+               samples. Only possible if IACT is known.
+            */
+            if (window[i].tau)
+            {
+                nSamplesIndep=window[i].N[ig]/(window[i].tau[ig]/window[i].dt);
+                window[i].sigma[ig]=sig * nSamplesIndep/(nSamplesIndep-1);
+            }
+            else
+                window[i].sigma[ig]=sig;
+            printf("win %d, aver = %f  sig = %f\n",i,av,window[i].sigma[ig]);
+        }
+    }      
+}
+
+
+/* Use histograms to  compute average force on pull group.
+   In addition, compute the sigma of the histogram.
+*/
+void computeAverageForce(t_UmbrellaWindow *window,int nWindows,t_UmbrellaOptions *opt)
+{
+    int i,j,bins=opt->bins,k;
+    double dz,min=opt->min,max=opt->max,displAv,displAv2,temp,distance,ztot,ztot_half,w,weight;
+    double posmirrored;
+
+    dz=(max-min)/bins;
+    ztot=opt->max-min;
+    ztot_half=ztot/2;
+
+    /* Compute average displacement from histograms */
+    for(j=0;j<nWindows;++j) 
+    {
+        snew(window[j].forceAv,window[j].nPull);
+        for(k=0;k<window[j].nPull;++k) 
+        {
+            displAv = 0.0;
+            displAv2 = 0.0;
+            weight  = 0.0;
+            for(i=0;i<opt->bins;++i) 
+            {    
+                temp=(1.0*i+0.5)*dz+min;
+                distance = temp - window[j].pos[k];
+                if (opt->bCycl)
+                {                                       /* in cyclic wham:             */
+                    if (distance > ztot_half)           /*    |distance| < ztot_half   */
+                        distance-=ztot;
+                    else if (distance < -ztot_half)
+                        distance+=ztot;
+                }
+                w=window[j].Histo[k][i]/window[j].g[k];
+                displAv  += w*distance;
+                displAv2 += w*sqr(distance);
+                weight+=w;
+                /* Are we near min or max? We are getting wron forces from the histgrams since
+                   the histigrams are zero outside [min,max). Therefore, assume that the position 
+                   on the other side of the histomgram center is equally likely. */
+                if (!opt->bCycl)
+                {
+                    posmirrored=window[j].pos[k]-distance;
+                    if (posmirrored>=max || posmirrored<min)
+                    {
+                        displAv  += -w*distance;
+                        displAv2 += w*sqr(-distance);      
+                        weight+=w;
+                    }
+                }
+            }
+            displAv  /= weight;
+            displAv2 /= weight;
+
+            /* average force from average displacement */
+            window[j].forceAv[k] = displAv*window[j].k[k];
+            /* sigma from average square displacement */
+            /* window[j].sigma  [k] = sqrt(displAv2); */
+            /* printf("Win %d, sigma = %f\n",j,sqrt(displAv2));  */
+        }
+    }
+}
+
+/* Check if the complete reaction coordinate is covered by the histograms */
+void  checkReactionCoordinateCovered(t_UmbrellaWindow *window,int nwins,
+                                     t_UmbrellaOptions *opt)
+{
+    int i,ig,j,bins=opt->bins,bBoundary;
+    real avcount=0,z,relcount,*count;
+    snew(count,opt->bins);
+
+    for(j=0;j<opt->bins;++j) 
+    {        
+        for (i=0;i<nwins;i++){
+            for (ig=0;ig<window[i].nPull;ig++)
+                count[j]+=window[i].Histo[ig][j];
+        }
+        avcount+=1.0*count[j];
+    }
+    avcount/=bins;
+    for(j=0;j<bins;++j) 
+    {
+        relcount=count[j]/avcount;
+        z=(j+0.5)*opt->dz+opt->min;
+        bBoundary=( j<bins/20 || (bins-j)>bins/20 );
+        /* check for bins with no data */
+        if (count[j] == 0)
+            fprintf(stderr, "\nWARNING, no data point in bin %d (z=%g) !\n"
+                    "You may not get a reasonable profile. Check your histograms!\n",j,z);
+        /* and check for poor sampling */
+        else if (relcount<0.005 && !bBoundary)
+            fprintf(stderr, "Warning, poor sampling bin %d (z=%g). Check your histograms!\n",j,z);
+    }
+    sfree(count);
+}
+
+
+void guessPotByIntegration(t_UmbrellaWindow *window,int nWindows,t_UmbrellaOptions *opt,
+                           char *fn)
+{
+    int i,j,ig,bins=opt->bins,nHist,winmin,groupmin;
+    double dz,min=opt->min,*pot,pos,hispos,dist,diff,fAv,distmin,*f;
+    FILE *fp;
+
+    dz=(opt->max-min)/bins;
+
+    printf("Getting initial potential by integration.\n");
+
+    /* Compute average displacement from histograms */
+    computeAverageForce(window,nWindows,opt);
+
+    /* Get force for each bin from all histograms in this bin, or, alternatively,
+       if no histograms are inside this bin, from the closest histogram */
+    snew(pot,bins);
+    snew(f,bins);
+    for(j=0;j<opt->bins;++j) 
+    {
+        pos=(1.0*j+0.5)*dz+min;
+        nHist=0;
+        fAv=0.;
+        distmin=1e20;
+        groupmin=winmin=0;
+        for (i=0;i<nWindows;i++)
+        {
+            for (ig=0;ig<window[i].nPull;ig++)
+            {
+                hispos=window[i].pos[ig];
+                dist=fabs(hispos-pos);
+                /* average force within bin */
+                if (dist < dz/2)
+                {
+                    nHist++;
+                    fAv+=window[i].forceAv[ig];
+                }
+                /* at the same time, rememer closest histogram */
+                if (dist<distmin){
+                    winmin=i;
+                    groupmin=ig;
+                    distmin=dist;
+                }
+            }
+        }
+        /* if no histogram found in this bin, use closest histogram */
+        if (nHist>0)
+            fAv=fAv/nHist;
+        else{
+            fAv=window[winmin].forceAv[groupmin];
+        }
+        f[j]=fAv;
+    }
+    for(j=1;j<opt->bins;++j)
+        pot[j] = pot[j-1] - 0.5*dz*(f[j-1]+f[j]);
+
+    /* cyclic wham: linearly correct possible offset */
+    if (opt->bCycl)
+    {
+        diff=(pot[bins-1]-pot[0])/(bins-1);
+        for(j=1;j<opt->bins;++j)
+            pot[j]-=j*diff;
+    }
+    if (opt->verbose)
+    {
+        fp=xvgropen("pmfintegrated.xvg","PMF from force integration","z","PMF [kJ/mol]",opt->oenv);
+        for(j=0;j<opt->bins;++j)
+            fprintf(fp,"%g  %g\n",(j+0.5)*dz+opt->min,pot[j]);
+        ffclose(fp);
+        printf("verbose mode: wrote %s with PMF from interated forces\n","pmfintegrated.xvg");
+    }
+
+    /* get initial z=exp(-F[i]/kT) from integrated potential, where F[i] denote the free
+       energy offsets which are usually determined by wham 
+       First: turn pot into probabilities:
+    */
+    for(j=0;j<opt->bins;++j)
+        pot[j]=exp(-pot[j]/(8.314e-3*opt->Temperature));
+    calc_z(pot,window,nWindows,opt,TRUE);
+    
+    sfree(pot);
+    sfree(f);
+}
+
+
 int gmx_wham(int argc,char *argv[])
 {
     const char *desc[] = {
-            "This is an analysis program that implements the Weighted",
-            "Histogram Analysis Method (WHAM). It is intended to analyze",
-            "output files generated by umbrella sampling simulations to ",
-            "compute a potential of mean force (PMF). [PAR]",
-            "At present, three input modes are supported:[BR]",
-            "[TT]*[tt] With option [TT]-it[tt], the user provides a file which contains the",
-            "  filenames of the umbrella simulation run-input files (tpr files),",
-            "  AND, with option -ix, a file which contains filenames of",
-            "  the pullx mdrun output files. The tpr and pullx files must",
-            "  be in corresponding order, i.e. the first tpr created the",
-            "  first pullx, etc.[BR]",
-            "[TT]*[tt] Same as the previous input mode, except that the the user",
-            "  provides the pull force ouput file names (pullf.xvg) with option -if.",
-            "  From the pull force the position in the ubrella potential is",
-            "  computed. This does not work with tabulated umbrella potentials.",
-            "[TT]*[tt] With option [TT]-ip[tt], the user provides filenames of (gzipped) pdo files, i.e.",
-            "  the gromacs 3.3 umbrella output files. If you have some unusual",
-            "  reaction coordinate you may also generate your own pdo files and",
-            "  feed them with the -ip option into to g_wham. The pdo file header",
-            "  must be similar to the folowing:[BR]",
-            "[TT]# UMBRELLA      3.0[BR]",
-            "# Component selection: 0 0 1[BR]",
-            "# nSkip 1[BR]",
-            "# Ref. Group 'TestAtom'[BR]",
-            "# Nr. of pull groups 2[BR]",
-            "# Group 1 'GR1'  Umb. Pos. 5.0 Umb. Cons. 1000.0[BR]",
-            "# Group 2 'GR2'  Umb. Pos. 2.0 Umb. Cons. 500.0[BR]",
-            "#####[tt][BR]",
-            "  Nr of pull groups, umbrella positions, force constants, and names",
-            "  may (of course) differ. Following the header, a time column and",
-            "  a data columns for each pull group follow (i.e. the displacement",
-            "  with respect to the umbrella center). Up to four pull groups are possible",
-            "  at present.[PAR]",
-            "By default, the output files are[BR]",
-            "  [TT]-o[tt]      PMF output file[BR]",
-            "  [TT]-hist[tt]   histograms output file[PAR]",
-            "The umbrella potential is assumed to be harmonic and the force constants are ",
-            "read from the tpr or pdo files. If a non-harmonic umbrella force was applied ",
-            "a tabulated potential can be provied with -tab.[PAR]",
-            "WHAM OPTIONS[PAR]",
-            "  [TT]-bins[tt]   Nr of bins used in analysis[BR]",
-            "  [TT]-temp[tt]   Temperature in the simulations[BR]",
-            "  [TT]-tol[tt]    Stop iteration if profile (probability) changed less than tolerance[BR]",
-            "  [TT]-auto[tt]   Automatic determination of boudndaries[BR]",
-            "  [TT]-min,-max[tt]   Boundaries of the profile [BR]",
-            "The data points which are used ",
-            "to compute the profile can be restricted with options -b, -e, and -dt. ",
-            "Play particularly with -b to ensure sufficient equilibration in each ",
-            "umbrella window![PAR]",
-            "With -log (default) the profile is written in energy units, otherwise (-nolog) as ",
-            "probability. The unit can be specified with -unit. With energy output, ",
-            "the energy in the first bin is defined to be zero. If you want the free energy at a different ",
-            "position to be zero, choose with -zprof0 (useful with bootstrapping, see below).[PAR]",
-            "For cyclic (or periodic) reaction coordinates (dihedral angle, channel PMF",
-            "without osmotic gradient), -cycl is useful.[BR]",
-            "[TT]-cycl yes[tt]        min and max are assumed to",
-            "be neighboring points and histogram points outside min and max are mapped into ",
-            "the interval [min,max] (compare histogram output). [BR]",
-            "[TT]-cycl weighted[tt]   First, a non-cyclic profile is computed. Subsequently, ",
-            "periodicity is enforced by adding corrections dG(i) between neighboring bins",
-            "i and i+1. The correction is chosen proportional to 1/[n(i)*n(i+1)]^alpha, where",
-            "n(i) denotes the total nr of data points in bin i as collected from all histograms.",
-            "alpha is defined with -alpha. The corrections are written to the file defined by -wcorr.",
-            " (Compare Hub and de Groot, PNAS 105:1198 (2008))[PAR]",
-            "ERROR ANALYSIS[BR]",
-            "Statistical errors may be estimated with bootstrap analysis. Use it with care, ",
-            "otherwise the statistical error may be substantially undererstimated !![BR]",
-            "[TT]-nBootstrap[tt] defines the nr of bootstraps. Two bootstrapping modes are supported.[BR]",
-            "[TT]-histbs[tt]    Complete histograms are considered as independent data points (default). For each",
-            "bootstrap, N histograms are randomly chosen from the N given histograms (allowing duplication).",
-            "To avoid gaps without data along the reaction coordinate blocks of histograms (-histbs-block)",
-            "may be defined. In that case, the given histograms are divided into blocks and ",
-            "only histograms within each block are mixed. Note that the histograms",
-            "within each block must be representative for all possible histograms, otherwise the",
-            "statistical error is undererstimated![BR]",
-            "[TT]-nohistbs[tt]  The given histograms are used to generate new random histograms,",
-            "such that the generated data points are distributed according the given histograms. The number",
-            "of points generated for each bootstrap histogram can be controlled with -bs-dt.",
-            "Note that one data point should be generated for each *independent* point in the given",
-            "histograms. With the long autocorrelations in MD simulations, this procedure may ",
-            "easily understimate the error![BR]",
-            "Bootstrapping output:[BR]",
-            "[TT]-bsres[tt]   Average profile and standard deviations[BR]",
-            "[TT]-bsprof[tt]  All bootstrapping profiles[BR]",
-            "With [TT]-vbs[tt] (verbose bootstrapping), the histograms of each bootstrap are written, and, ",
-            "with [TT]-nohistBS[tt], the cummulants of the histogram.",
+        "This is an analysis program that implements the Weighted",
+        "Histogram Analysis Method (WHAM). It is intended to analyze",
+        "output files generated by umbrella sampling simulations to ",
+        "compute a potential of mean force (PMF). [PAR] ",
+        "At present, three input modes are supported.[BR]",
+        "[TT]*[tt] With option [TT]-it[tt], the user provides a file which contains the[BR]",
+        "  file names of the umbrella simulation run-input files (tpr files),[BR]",
+        "  AND, with option [TT]-ix[tt], a file which contains file names of [BR]",
+        "  the pullx mdrun output files. The tpr and pullx files must [BR]",
+        "  be in corresponding order, i.e. the first tpr created the [BR]",
+        "  first pullx, etc.[BR]",
+        "[TT]*[tt] Same as the previous input mode, except that the the user [BR]",
+        "  provides the pull force output file names (pullf.xvg) with option [TT]-if[tt].[BR]",
+        "  From the pull force the position in the umbrella potential is [BR]",
+        "  computed. This does not work with tabulated umbrella potentials.[BR]"
+        "[TT]*[tt] With option [TT]-ip[tt], the user provides file names of (gzipped) pdo files, i.e.[BR]",
+        "  the gromacs 3.3 umbrella output files. If you have some unusual[BR]"
+        "  reaction coordinate you may also generate your own pdo files and [BR]",
+        "  feed them with the [TT]-ip[tt] option into to g_wham. The pdo file header [BR]",
+        "  must be similar to the following:[BR]",
+        "[TT]# UMBRELLA      3.0[BR]",
+        "# Component selection: 0 0 1[BR]",
+        "# nSkip 1[BR]",
+        "# Ref. Group 'TestAtom'[BR]",
+        "# Nr. of pull groups 2[BR]",
+        "# Group 1 'GR1'  Umb. Pos. 5.0 Umb. Cons. 1000.0[BR]",
+        "# Group 2 'GR2'  Umb. Pos. 2.0 Umb. Cons. 500.0[BR]",
+        "#####[tt][BR]",
+        "Nr of pull groups, umbrella positions, force constants, and names ",
+        "may (of course) differ. Following the header, a time column and ",
+        "a data columns for each pull group follows (i.e. the displacement",
+        "with respect to the umbrella center). Up to four pull groups are possible ",
+        "per pdo file at present.[PAR]",
+        "By default, the output files are[BR]",
+        "  [TT]-o[tt]      PMF output file[BR]",
+        "  [TT]-hist[tt]   histograms output file[BR]",
+        "Always check whether the histograms sufficiently overlap![PAR]",
+        "The umbrella potential is assumed to be harmonic and the force constants are ",
+        "read from the tpr or pdo files. If a non-harmonic umbrella force was applied ",
+        "a tabulated potential can be provided with [TT]-tab[tt].[PAR]",
+        "WHAM OPTIONS[BR]------------[BR]",
+        "  [TT]-bins[tt]   Nr of bins used in analysis[BR]",
+        "  [TT]-temp[tt]   Temperature in the simulations[BR]",
+        "  [TT]-tol[tt]    Stop iteration if profile (probability) changed less than tolerance[BR]",
+        "  [TT]-auto[tt]   Automatic determination of boundaries[BR]",
+        "  [TT]-min,-max[tt]   Boundaries of the profile [BR]",
+        "The data points which are used ",
+        "to compute the profile can be restricted with options [TT]-b[tt], [TT]-e[tt], and [TT]-dt[tt]. ",
+        "Play particularly with [TT]-b[tt] to ensure sufficient equilibration in each ",
+        "umbrella window![PAR]",
+        "With [TT]-log[tt] (default) the profile is written in energy units, otherwise ([TT]-nolog[tt]) as ",
+        "probability. The unit can be specified with [TT]-unit[tt]. With energy output, ",
+        "the energy in the first bin is defined to be zero. If you want the free energy at a different ",
+        "position to be zero, choose with [TT]-zprof0[tt] (useful with bootstrapping, see below).[PAR]",
+        "For cyclic (or periodic) reaction coordinates (dihedral angle, channel PMF",
+        "without osmotic gradient), the option [TT]-cycl[tt] is useful. g_wham will make use of the ",
+        "periodicity of the system and generate a periodic PMF. The first and the last bin of the",
+        "reaction coordinate will assumed be be neighbors[PAR]",
+        "Option [TT]-sym[tt] symmetrizes the profile around z=0 before output (useful for membrane etc.)[PAR]",
+        "AUTOCORRELATIONS[BR]----------------[BR]",
+        "With [TT]-ac[tt], g_wham estimates the integrated autocorrelation time (IACT) tau for each ",
+        "umbrella window and weights the respective window with 1/[1+2*tau/dt]. The IACTs are written ",
+        "to the file defined with [TT]-oiact[tt]. In verbose mode, all autocorrelation functions (ACFs) are",
+        "written to hist_autocorr.xvg. Because the IACTs can be severely underestimated in case of ",
+        "limited sampling, option [TT]-acsig[tt] allows to smooth the IACTs along the reaction coordinate ",
+        "with a Gaussian (sigma provided with [TT]-acsig[tt], see output in iact.xvg). Note that the ",
+        "IACTs are estimated by simple integration of the ACFs while the ACFs are larger 0.05.",
+        "If you prefer to compute the IACTs by a more sophisticated (but possibly less robust) method ",
+        "such as fitting to a double exponential, you can compute the IACTs with g_analyze and provide",
+        "them to g_wham with the file iact-in.dat (option [TT]-iiact[tt]). iact-in.dat should contain ",
+        "one line per input file (pdo or pullx/f file) and one column per pull group in the respective file.[PAR]"
+        "ERROR ANALYSIS[BR]--------------[BR]",
+        "Statistical errors may be estimated with bootstrap analysis. Use it with care, ",
+        "otherwise the statistical error may be substantially underestimated !![BR]",
+        "More background and examples for the bootstrap technique can be found in ",
+        "Hub, de Groot and Van der Spoel, JCTC (2010)[BR]",
+        "-nBootstrap defines the nr of bootstraps (use, e.g., 100). Four bootstrapping methods are supported and ",
+        "selected with [TT]-bs-method[tt].[BR]",
+        "  (1) [TT]b-hist[tt]   Default: complete histograms are considered as independent data points, and ",
+        " the bootstrap is carried out by assigning random weights to the histograms (\"Bayesian bootstrap\").",
+        " Note that each point along the reaction coordinate",
+        "must be covered by multiple independent histograms (e.g. 10 histograms), otherwise the ",
+        "statistical error is underestimated![BR]",
+        "  (2) [TT]hist[tt]    Complete histograms are considered as independent data points. For each",
+        "bootstrap, N histograms are randomly chosen from the N given histograms (allowing duplication, i.e. ",
+        "sampling with replacement).",
+        "To avoid gaps without data along the reaction coordinate blocks of histograms ([TT]-histbs-block[tt])",
+        "may be defined. In that case, the given histograms are divided into blocks and ",
+        "only histograms within each block are mixed. Note that the histograms",
+        "within each block must be representative for all possible histograms, otherwise the",
+        "statistical error is underestimated![BR]",
+        "  (3) [TT]traj[tt]  The given histograms are used to generate new random trajectories,",
+        "such that the generated data points are distributed according the given histograms ",
+        "and properly autocorrelated. The ",
+        "autocorrelation time (ACT) for each window must be known, so use [TT]-ac[tt] or provide the ACT",
+        "with [TT]-iiact[TT]. If the ACT of all windows are identical (and known), you can also ",
+        "provide them with [TT]-bs-tau[tt]. Note that this method may severely underestimate the error ",
+        "in case of limited sampling, that is if individual histograms do not represent the complete",
+        "phase space at the respective positions.[BR]",
+        "  (4) [TT]traj-gauss[tt]  The same as Method [TT]traj[tt], but the trajectories are not bootstrapped ",
+        "from the umbrella histograms but from Gaussians with the average and width of the umbrella ",
+        "histograms. That method yields similar error estimates like method [TT]traj[tt].[BR]"
+        "Bootstrapping output:[BR]",
+        "  [TT]-bsres[tt]   Average profile and standard deviations[BR]",
+        "  [TT]-bsprof[tt]  All bootstrapping profiles[BR]",
+        "With [TT]-vbs[tt] (verbose bootstrapping), the histograms of each bootstrap are written, and, ",
+        "with bootstrap method [TT]traj[tt], the cumulative distribution functions of the histograms.",
     };
 
-    static t_UmbrellaOptions opt;
-    static gmx_bool bHistOnly=FALSE;
-
     const char *en_unit[]={NULL,"kJ","kCal","kT",NULL};
-    const char *en_unit_label[]={"","E (kJ mol\\S-1\\N)","E (kcal mol\\S-1\\N)","E (kT)",};
-    const char *en_cycl[]={NULL,"no","yes","weighted",NULL};
-
+    const char *en_unit_label[]={"","E (kJ mol\\S-1\\N)","E (kcal mol\\S-1\\N)","E (kT)",NULL};
+    const char *en_bsMethod[]={ NULL,"b-hist", "hist", "traj", "traj-gauss", NULL };
+  
+    static t_UmbrellaOptions opt;
+  
     t_pargs pa[] = {
-            { "-min", FALSE, etREAL, {&opt.min},
-              "Minimum coordinate in profile"},
-            { "-max", FALSE, etREAL, {&opt.max},
-              "Maximum coordinate in profile"},
-            { "-auto", FALSE, etBOOL, {&opt.bAuto},
-              "determine min and max automatically"},
-            { "-bins",FALSE, etINT, {&opt.bins},
-              "Number of bins in profile"},
-            { "-temp", FALSE, etREAL, {&opt.Temperature},
-              "Temperature"},
-            { "-tol", FALSE, etREAL, {&opt.Tolerance},
-              "Tolerance"},
-            { "-v", FALSE, etBOOL, {&opt.verbose},
-              "verbose mode"},
-            { "-b", FALSE, etREAL, {&opt.tmin},
-              "first time to analyse (ps)"},
-            { "-e", FALSE, etREAL, {&opt.tmax},
-              "last time to analyse (ps)"},
-            { "-dt", FALSE, etREAL, {&opt.dt},
-              "Analyse only every dt ps"},
-            { "-histonly", FALSE, etBOOL, {&bHistOnly},
-              "Write histograms and exit"},
-            { "-boundsonly", FALSE, etBOOL, {&opt.bBoundsOnly},
-              "Determine min and max and exit (with -auto)"},
-            { "-log", FALSE, etBOOL, {&opt.bLog},
-              "Calculate the log of the profile before printing"},
-            { "-unit", FALSE,  etENUM, {en_unit},
-              "energy unit in case of log output" },
-            { "-zprof0", FALSE, etREAL, {&opt.zProf0},
-              "Define profile to 0.0 at this position (with -log)"},
-            { "-cycl", FALSE, etENUM, {en_cycl},
-              "Create cyclic/periodic profile. Assumes min and max are the same point."},
-            { "-alpha", FALSE, etREAL, {&opt.alpha},
-              "for '-cycl weighted', set parameter alpha"},
-            { "-flip", FALSE, etBOOL, {&opt.bFlipProf},
-              "Combine halves of profile (not supported)"},
-            { "-hist-eq", FALSE, etBOOL, {&opt.bHistEq},
-              "Enforce equal weight for all histograms. (Non-Weighed-HAM)"},
-            { "-nBootstrap", FALSE,  etINT, {&opt.nBootStrap},
-              "nr of bootstraps to estimate statistical uncertainty" },
-            { "-bs-dt", FALSE, etREAL, {&opt.dtBootStrap},
-              "timestep for synthetic bootstrap histograms (ps). Ensure independent data points!"},
-            { "-bs-seed", FALSE, etINT, {&opt.bsSeed},
-              "seed for bootstrapping. (-1 = use time)"},
-            { "-histbs", FALSE, etBOOL, {&opt.bHistBootStrap},
-              "In bootstrapping, consider complete histograms as one data point. "
-              "Accounts better for long autocorrelations."},
-            { "-histbs-block", FALSE, etINT, {&opt.histBootStrapBlockLength},
-              "when mixin histograms only mix within blocks of -histBS_block."},
-            { "-vbs", FALSE, etBOOL, {&opt.bs_verbose},
-                "verbose bootstrapping. Print the cummulants and a histogram file for each bootstrap."},
+        { "-min", FALSE, etREAL, {&opt.min},
+          "Minimum coordinate in profile"},
+        { "-max", FALSE, etREAL, {&opt.max},
+          "Maximum coordinate in profile"},
+        { "-auto", FALSE, etBOOL, {&opt.bAuto},
+          "determine min and max automatically"},
+        { "-bins",FALSE, etINT, {&opt.bins},
+          "Number of bins in profile"},
+        { "-temp", FALSE, etREAL, {&opt.Temperature},
+          "Temperature"},
+        { "-tol", FALSE, etREAL, {&opt.Tolerance},
+          "Tolerance"},
+        { "-v", FALSE, etBOOL, {&opt.verbose},
+          "verbose mode"},
+        { "-b", FALSE, etREAL, {&opt.tmin}, 
+          "first time to analyse (ps)"},
+        { "-e", FALSE, etREAL, {&opt.tmax}, 
+          "last time to analyse (ps)"},
+        { "-dt", FALSE, etREAL, {&opt.dt},
+          "Analyse only every dt ps"},
+        { "-histonly", FALSE, etBOOL, {&opt.bHistOnly},
+          "Write histograms and exit"},
+        { "-boundsonly", FALSE, etBOOL, {&opt.bBoundsOnly},
+          "Determine min and max and exit (with -auto)"},
+        { "-log", FALSE, etBOOL, {&opt.bLog},
+          "Calculate the log of the profile before printing"},
+        { "-unit", FALSE,  etENUM, {en_unit},
+          "energy unit in case of log output" },
+        { "-zprof0", FALSE, etREAL, {&opt.zProf0},
+          "Define profile to 0.0 at this position (with -log)"},
+        { "-cycl", FALSE, etBOOL, {&opt.bCycl},
+          "Create cyclic/periodic profile. Assumes min and max are the same point."},
+        { "-sym", FALSE, etBOOL, {&opt.bSym},
+          "symmetrize profile around z=0"},   
+        { "-hist-eq", FALSE, etBOOL, {&opt.bHistEq},
+          "HIDDENEnforce equal weight for all histograms. (Non-Weighed-HAM)"},
+        { "-ac", FALSE, etBOOL, {&opt.bCalcTauInt},
+          "calculate integrated autocorrelation times and use in wham"},
+        { "-acsig", FALSE, etREAL, {&opt.sigSmoothIact},
+          "Smooth autocorrelation times along reaction coordinate with Gaussian of this sigma"},
+        { "-ac-trestart", FALSE, etREAL, {&opt.acTrestart},
+          "When computing autocorrelation functions, restart computing every .. (ps)"},
+        { "-acred", FALSE, etBOOL, {&opt.bAllowReduceIact},
+          "HIDDENWhen smoothing the ACTs, allow to reduce ACTs. Otherwise, only increase ACTs "
+          "during smoothing"},
+        { "-nBootstrap", FALSE,  etINT, {&opt.nBootStrap},
+          "nr of bootstraps to estimate statistical uncertainty (e.g., 200)" },
+        { "-bs-method", FALSE,  etENUM, {en_bsMethod},
+          "bootstrap method" },
+        { "-bs-tau", FALSE, etREAL, {&opt.tauBootStrap},
+          "Autocorrelation time (ACT) assumed for all histograms. Use option -ac if ACT is unknown."},
+        { "-bs-seed", FALSE, etINT, {&opt.bsSeed},
+          "seed for bootstrapping. (-1 = use time)"},
+        { "-histbs-block", FALSE, etINT, {&opt.histBootStrapBlockLength},
+          "when mixing histograms only mix within blocks of -histbs-block."},
+        { "-vbs", FALSE, etBOOL, {&opt.bs_verbose},
+          "verbose bootstrapping. Print the CDFs and a histogram file for each bootstrap."},
+        { "-stepout", FALSE, etINT, {&opt.stepchange},
+          "HIDDENWrite maximum change every ... (set to 1 with -v)"},
+        { "-updateContr", FALSE, etINT, {&opt.stepUpdateContrib},
+          "HIDDENUpdate table with significan contributions to WHAM every ... iterations"},
     };
-
+  
     t_filenm fnm[] = {
-            { efDAT, "-ix","pullx-files",ffOPTRD},     /* wham input: pullf.xvg's and tprs    */
-            { efDAT, "-if","pullf-files",ffOPTRD},     /* wham input: pullf.xvg's and tprs    */
-            { efDAT, "-it","tpr-files",ffOPTRD},       /* wham input: tprs                    */
-            { efDAT, "-ip","pdo-files",ffOPTRD},       /* wham input: pdo files (gmx3 style)  */
-            { efXVG, "-o", "profile", ffWRITE },       /* output file for profile */
-            { efXVG, "-hist","histo", ffWRITE},               /* output file for histograms */
-            { efXVG, "-bsres","bsResult", ffOPTWR},    /* average and errors of bootstrap analysis */
-            { efXVG, "-bsprof","bsProfs", ffOPTWR},    /* output file for bootstrap profiles       */
-            { efDAT, "-tab","umb-pot",ffOPTRD},        /* Tabulated umbrella potential (if not harmonic) */
-            { efXVG, "-wcorr","cycl-corr",ffOPTRD},    /* Corrections to profile in case -cycl weighted */
+        { efDAT, "-ix","pullx-files",ffOPTRD},  /* wham input: pullf.xvg's and tprs           */
+        { efDAT, "-if","pullf-files",ffOPTRD},  /* wham input: pullf.xvg's and tprs           */
+        { efDAT, "-it","tpr-files",ffOPTRD},    /* wham input: tprs                           */
+        { efDAT, "-ip","pdo-files",ffOPTRD},    /* wham input: pdo files (gmx3 style)         */
+        { efXVG, "-o", "profile", ffWRITE },    /* output file for profile                     */
+        { efXVG, "-hist","histo", ffWRITE},        /* output file for histograms                  */
+        { efXVG, "-oiact","iact",ffOPTWR},      /* writing integrated autocorrelation times    */
+        { efDAT, "-iiact","iact-in",ffOPTRD},   /* reading integrated autocorrelation times   */    
+        { efXVG, "-bsres","bsResult", ffOPTWR}, /* average and errors of bootstrap analysis    */
+        { efXVG, "-bsprof","bsProfs", ffOPTWR}, /* output file for bootstrap profiles          */
+        { efDAT, "-tab","umb-pot",ffOPTRD},     /* Tabulated umbrella potential (if not harmonic) */    
     };
-
+  
     int i,j,l,nfiles,nwins,nfiles2;
     t_UmbrellaHeader header;
     t_UmbrellaWindow * window=NULL;
@@ -1799,69 +2687,71 @@ int gmx_wham(int argc,char *argv[])
     char **fninTpr,**fninPull,**fninPdo;
     const char *fnPull;
     FILE *histout,*profout;
-    char ylabel[256],title[256];
-    output_env_t oenv;
+    char ylabel[256],title[256];  
+
+#define NFILE asize(fnm)
+
+    CopyRight(stderr,argv[0]);
 
     opt.bins=200;
     opt.verbose=FALSE;
-    opt.cycl=enCycl_no;
+    opt.bHistOnly=FALSE;
+    opt.bCycl=FALSE;
     opt.tmin=50;
     opt.tmax=1e20;
     opt.dt=0.0;
-    opt.bShift=TRUE;
-    opt.nBootStrap=0;
-    opt.dtBootStrap=0.0;
-    opt.bsSeed=-1;
-    opt.bHistBootStrap=TRUE;
-    opt.histBootStrapBlockLength=12;
-    opt.zProfZero=0.0;
-    opt.bWeightedCycl=FALSE;
-    opt.alpha=2;
-    opt.bHistOutOnly=FALSE;
     opt.min=0;
     opt.max=0;
-    opt.bLog=TRUE;
-    opt.unit=en_kJ;
-    opt.zProf0=0.0;
+    opt.bAuto=TRUE;
+
+    /* bootstrapping stuff */
     opt.nBootStrap=0;
+    opt.bsMethod=bsMethod_hist;
+    opt.tauBootStrap=0.0;
     opt.bsSeed=-1;
-    opt.bHistBootStrap=TRUE;
     opt.histBootStrapBlockLength=8;
     opt.bs_verbose=FALSE;
+
+    opt.bLog=TRUE;
+    opt.unit=en_kJ;
+    opt.zProf0=0.;
     opt.Temperature=298;
-    opt.bFlipProf=FALSE;
     opt.Tolerance=1e-6;
-    opt.bAuto=TRUE;
     opt.bBoundsOnly=FALSE;
+    opt.bSym=FALSE;
+    opt.bCalcTauInt=FALSE;
+    opt.sigSmoothIact=0.0;
+    opt.bAllowReduceIact=TRUE;
+    opt.bInitPotByIntegration=TRUE;
+    opt.acTrestart=1.0;
+    opt.stepchange=100;
+    opt.stepUpdateContrib=100;
 
-
-#define NFILE asize(fnm)
-
-    CopyRight(stderr,argv[0]);
     parse_common_args(&argc,argv,PCA_BE_NICE,
-            NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv);
-
+                      NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&opt.oenv);
+  
     opt.unit=nenum(en_unit);
-    opt.cycl=nenum(en_cycl);
+    opt.bsMethod=nenum(en_bsMethod);
 
     opt.bProf0Set=opt2parg_bSet("-zprof0",  asize(pa), pa);
-
+  
     opt.bTab=opt2bSet("-tab",NFILE,fnm);
     opt.bPdo=opt2bSet("-ip",NFILE,fnm);
     opt.bTpr=opt2bSet("-it",NFILE,fnm);
     opt.bPullx=opt2bSet("-ix",NFILE,fnm);
     opt.bPullf=opt2bSet("-if",NFILE,fnm);
+    opt.bTauIntGiven=opt2bSet("-iiact",NFILE,fnm);
     if  (opt.bTab && opt.bPullf)
         gmx_fatal(FARGS,"Force input does not work with tabulated potentials. "
-                "Provide pullx.xvg or pdo files!");
+                  "Provide pullx.xvg or pdo files!");
 
-#define BOOLXOR(a,b) ( ((!(a))&&(b)) || ((a)&&(!(b))))
-    if (!opt.bPdo && !BOOLXOR(opt.bPullx,opt.bPullf))
+#define WHAMBOOLXOR(a,b) ( ((!(a))&&(b)) || ((a)&&(!(b))))
+    if (!opt.bPdo && !WHAMBOOLXOR(opt.bPullx,opt.bPullf))
         gmx_fatal(FARGS,"Give either pullx (-ix) OR pullf (-if) data. Not both.");
     if ( !opt.bPdo && !(opt.bTpr || opt.bPullf || opt.bPullx))
         gmx_fatal(FARGS,"g_wham supports three input modes, pullx, pullf, or pdo file input."
-                "\n\n Check g_wham -h !");
-
+                  "\n\n Check g_wham -h !");
+  
     opt.fnPdo=opt2fn("-ip",NFILE,fnm);
     opt.fnTpr=opt2fn("-it",NFILE,fnm);
     opt.fnPullf=opt2fn("-if",NFILE,fnm);
@@ -1882,28 +2772,41 @@ int gmx_wham(int argc,char *argv[])
         opt.bAuto=FALSE;
     }
 
+    if (opt.bTauIntGiven && opt.bCalcTauInt)
+        gmx_fatal(FARGS,"Either read (option -iiact) or calculate (option -ac) the\n"
+                  "the autocorrelation times. Not both.");
+
+    if (opt.tauBootStrap>0.0 && opt2parg_bSet("-ac",asize(pa), pa))
+        gmx_fatal(FARGS,"Either compute autocorrelation times (ACTs) (option -ac) or "
+                  "provide it with -bs-tau for bootstrapping. Not Both.\n");
+    if (opt.tauBootStrap>0.0 && opt2bSet("-iiact",NFILE,fnm))
+        gmx_fatal(FARGS,"Either provide autocorrelation times (ACTs) with file iact-in.dat "
+                  "(option -iiact) or define all ACTs with -bs-tau for bootstrapping\n. Not Both.");
+  
+
     /* Reading gmx4 pull output and tpr files */
     if (opt.bTpr || opt.bPullf || opt.bPullx)
     {
         read_wham_in(opt.fnTpr,&fninTpr,&nfiles,&opt);
-
+    
         fnPull=opt.bPullf ? opt.fnPullf : opt.fnPullx;
         read_wham_in(fnPull,&fninPull,&nfiles2,&opt);
         printf("Found %d tpr and %d pull %s files in %s and %s, respectively\n",
-                nfiles,nfiles2,opt.bPullf ? "force" : "position",opt.fnTpr,fnPull);
+               nfiles,nfiles2,opt.bPullf ? "force" : "position",opt.fnTpr,fnPull);
         if (nfiles!=nfiles2)
             gmx_fatal(FARGS,"Found %d file names in %s, but %d in %s\n",nfiles,
-                    opt.fnTpr,nfiles2,fnPull);
-        read_tpr_pullxf_files(fninTpr,fninPull,nfiles, &header, &window, &opt);
+                      opt.fnTpr,nfiles2,fnPull);
+        window=initUmbrellaWindows(nfiles);
+        read_tpr_pullxf_files(fninTpr,fninPull,nfiles, &header, window, &opt);
     }
     else
-    {
-        /* reading pdo files */
+    { /* reading pdo files */
         read_wham_in(opt.fnPdo,&fninPdo,&nfiles,&opt);
         printf("Found %d pdo files in %s\n",nfiles,opt.fnPdo);
-        read_pdo_files(fninPdo,nfiles, &header, &window, &opt);
+        window=initUmbrellaWindows(nfiles);
+        read_pdo_files(fninPdo,nfiles, &header, window, &opt);
     }
-    nwins=nfiles;
+    nwins=nfiles;  
 
     /* enforce equal weight for all histograms? */
     if (opt.bHistEq)
@@ -1911,13 +2814,13 @@ int gmx_wham(int argc,char *argv[])
 
     /* write histograms */
     histout=xvgropen(opt2fn("-hist",NFILE,fnm),"Umbrella histograms",
-            "z","count",oenv);
-    for(l=0;l<opt.bins;++l)
+                     "z","count",opt.oenv);
+    for(l=0;l<opt.bins;++l) 
     {
         fprintf(histout,"%e\t",(double)(l+0.5)/opt.bins*(opt.max-opt.min)+opt.min);
-        for(i=0;i<nwins;++i)
-        {
-            for(j=0;j<window[i].nPull;++j)
+        for(i=0;i<nwins;++i) 
+        {      
+            for(j=0;j<window[i].nPull;++j) 
             {
                 fprintf(histout,"%e\t",window[i].Histo[j][l]);
             }
@@ -1925,7 +2828,8 @@ int gmx_wham(int argc,char *argv[])
         fprintf(histout,"\n");
     }
     ffclose(histout);
-    if (bHistOnly)
+    printf("Wrote %s\n",opt2fn("-hist",NFILE,fnm));
+    if (opt.bHistOnly)
     {
         printf("Wrote histograms to %s, now exiting.\n",opt2fn("-hist",NFILE,fnm));
         return 0;
@@ -1934,14 +2838,36 @@ int gmx_wham(int argc,char *argv[])
     /* Using tabulated umbrella potential */
     if (opt.bTab)
         setup_tab(opt2fn("-tab",NFILE,fnm),&opt);
-
-    setup_acc_wham(window,nwins,&opt);
+  
+    /* Integrated autocorrelation times provided ? */
+    if (opt.bTauIntGiven)
+        readIntegratedAutocorrelationTimes(window,nwins,&opt,opt2fn("-iiact",NFILE,fnm));
+
+    /* Compute integrated autocorrelation times */
+    if (opt.bCalcTauInt)
+        calcIntegratedAutocorrelationTimes(window,nwins,&opt,opt2fn("-oiact",NFILE,fnm));
+
+    /* calc average and sigma for each histogram 
+       (maybe required for bootstrapping. If not, this is fast anyhow) */
+    if (opt.nBootStrap && opt.bsMethod==bsMethod_trajGauss)
+        averageSigma(window,nwins,&opt);
+  
+    /* Get initial potential by simple integration */
+    if (opt.bInitPotByIntegration)
+        guessPotByIntegration(window,nwins,&opt,0);  
+
+    /* Check if complete reaction coordinate is covered */
+    checkReactionCoordinateCovered(window,nwins,&opt);
 
     /* Calculate profile */
-    snew(profile,opt.bins);
-    opt.stepchange=(opt.verbose)? 1 : 100;
+    snew(profile,opt.bins);  
+    if (opt.verbose)
+        opt.stepchange=1;
     i=0;
-    do {
+    do 
+    {
+        if ( (i%opt.stepUpdateContrib) == 0)
+            setup_acc_wham(profile,window,nwins,&opt);
         if (maxchange<opt.Tolerance)
         {
             bExact=TRUE;
@@ -1952,9 +2878,14 @@ int gmx_wham(int argc,char *argv[])
         if (((i%opt.stepchange) == 0 || i==1) && !i==0)
             printf("\t%4d) Maximum change %e\n",i,maxchange);
         i++;
-    } while( (maxchange=calc_z(profile, window, nwins, &opt,bExact)) > opt.Tolerance || !bExact);
+    } while ( (maxchange=calc_z(profile, window, nwins, &opt,bExact)) > opt.Tolerance || !bExact);
     printf("Converged in %d iterations. Final maximum change %g\n",i,maxchange);
 
+    /* calc error from Kumar's formula */
+    /* Unclear how the error propagates along reaction coordinate, therefore
+       commented out  */
+    /* calc_error_kumar(profile,window, nwins,&opt); */
+
     /* Write profile in energy units? */
     if (opt.bLog)
     {
@@ -1967,23 +2898,29 @@ int gmx_wham(int argc,char *argv[])
         strcpy(ylabel,"Density of states");
         strcpy(title,"Density of states");
     }
-    /* Force cyclic profile by wheighted correction? */
-    if (opt.cycl==enCycl_weighted)
-        cyclicProfByWeightedCorr(profile,window,nwins,&opt,TRUE,
-                                 opt2fn("-wcorr",NFILE,fnm),oenv);
+    
+    /* symmetrize profile around z=0? */
+    if (opt.bSym)
+        symmetrizeProfile(profile,&opt);
 
-    profout=xvgropen(opt2fn("-o",NFILE,fnm),title,"z",ylabel,oenv);
+    /* write profile or density of states */
+    profout=xvgropen(opt2fn("-o",NFILE,fnm),title,"z",ylabel,opt.oenv);
     for(i=0;i<opt.bins;++i)
-        fprintf(profout,"%e\t%e\n",
-                (double)(i+0.5)/opt.bins*(opt.max-opt.min)+opt.min,profile[i]);
+        fprintf(profout,"%e\t%e\n",(double)(i+0.5)/opt.bins*(opt.max-opt.min)+opt.min,profile[i]);
     ffclose(profout);
     printf("Wrote %s\n",opt2fn("-o",NFILE,fnm));
-
+  
     /* Bootstrap Method */
     if (opt.nBootStrap)
-        do_bootstrapping(opt2fn("-bsres",NFILE,fnm),opt2fn("-bsprof",NFILE,fnm),
-                opt2fn("-hist",NFILE,fnm),
-                ylabel, profile, window, nwins, &opt,oenv);
+        do_bootstrapping(opt2fn("-bsres",NFILE,fnm),opt2fn("-bsprof",NFILE,fnm), 
+                         opt2fn("-hist",NFILE,fnm),
+                         ylabel, profile, window, nwins, &opt);
+
+    sfree(profile);
+    freeUmbrellaWindows(window,nfiles);
+
+    printf("\nIn case you use results from g_wham for a publication, please cite:\n");
+    please_cite(stdout,"Hub2010");
 
     thanx(stderr);
     return 0;
index d0b832a525355089732803aef3993a4522d46c7b..5736ab85916bf9876bde0656d75bb92f70c1afe0 100644 (file)
@@ -73,7 +73,7 @@ extern gmx_bool has_dihedral(int Dih,t_dlist *dl);
 extern t_dlist *mk_dlist(FILE *log, 
                         t_atoms *atoms, int *nlist,
                         gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, int maxchi,
-                        int r0,int naa,char **aa);
+                        int r0, gmx_residuetype_t rt);
                         
 extern void pr_dlist(FILE *fp,int nl,t_dlist dl[],real dt,  int printtype,
 gmx_bool bPhi, gmx_bool bPsi,gmx_bool bChi,gmx_bool bOmega, int maxchi);