diff --git a/.github/workflows/merge-gate.yml b/.github/workflows/merge-gate.yml index cd0eb2be0c..54e51a8117 100644 --- a/.github/workflows/merge-gate.yml +++ b/.github/workflows/merge-gate.yml @@ -63,16 +63,6 @@ jobs: mkdir -p include && mv AmberTools/src/sander/sander.h include mv lib include $HOME - curl -OL ftp://ftp.unidata.ucar.edu/pub/netcdf/netcdf-4.6.1.tar.gz - tar -zxf netcdf-4.6.1.tar.gz - cd netcdf-4.6.1 - ./configure --disable-netcdf-4 --disable-dap --disable-doxygen --prefix=$HOME - make -j2 - make install - cd .. - export PATH=$HOME/bin:$PATH - export LD_LIBRARY_PATH=$HOME/lib:${LD_LIBRARY_PATH} - if [ $USE_OPENMP = "yes" ]; then export OPT="openmp" export OMP_NUM_THREADS=4 @@ -105,6 +95,16 @@ jobs: fi if [ "$USE_CMAKE" = "1" ]; then + curl -OL ftp://ftp.unidata.ucar.edu/pub/netcdf/netcdf-4.6.1.tar.gz + tar -zxf netcdf-4.6.1.tar.gz + cd netcdf-4.6.1 + ./configure --disable-netcdf-4 --disable-dap --disable-doxygen --prefix=$HOME + make -j2 + make install + cd .. + export PATH=$HOME/bin:$PATH + export LD_LIBRARY_PATH=$HOME/lib:${LD_LIBRARY_PATH} + mkdir build install installdir=$(pwd) cd build @@ -117,7 +117,8 @@ jobs: export PATH=$installdir/bin:$PATH else export LD_LIBRARY_PATH=$HOME/lib:${LD_LIBRARY_PATH} - ./configure --with-netcdf=$HOME ${BUILD_FLAGS} ${COMPILER} + ./configure --buildlibs ${BUILD_FLAGS} ${COMPILER} + source cpptraj.sh make -j2 install fi cd test && make $TEST_TYPE diff --git a/appveyor.yml b/appveyor.yml index 314325d1ef..922b1182a1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,7 @@ platform: - x64 -image: Visual Studio 2019 +image: Previous Visual Studio 2019 clone_folder: c:\projects\cpptraj diff --git a/configure b/configure index 48b7217561..5ae28cb40a 100755 --- a/configure +++ b/configure @@ -134,6 +134,12 @@ NETCDF_SRCTAR='netcdf-4.6.1.tar.gz' NETCDF_SRCDIR='netcdf-4.6.1' NETCDF_URL="ftp://ftp.unidata.ucar.edu/pub/netcdf/$NETCDF_SRCTAR" NETCDF_OPTS=" --disable-netcdf-4 --disable-dap $windows_hostflag --disable-shared --disable-doxygen" +NETCDF4_OPTS=" --disable-dap $windows_hostflag --disable-shared --disable-doxygen" + +HDF5_SRCTAR='hdf5-1_10_9.tar.gz' +HDF5_SRCDIR='hdf5-hdf5-1_10_9' +HDF5_URL="https://github.com/HDFGroup/hdf5/archive/refs/tags/$HDF5_SRCTAR" +HDF5_OPTS='' BZIP2_SRCTAR='bzip2-latest.tar.gz' BZIP2_SRCDIR='' @@ -222,13 +228,14 @@ LBLAS=7 LFFTW3=8 LREADLINE=9 LXDRFILE=10 -LSANDER=11 -LTIMER=12 -LCUDA=13 -LHIP=14 -LOPENMM=15 +LTIMER=11 +LCUDA=12 +LHIP=13 +LOPENMM=14 +LHDF5=15 +LSANDER=16 # Make sure this comes last to avoid pulling in unnecessary symbols # Total number of external libraries -NLIB=16 +NLIB=17 # LIB_STAT = Library status: # off : Do not use library. @@ -336,7 +343,7 @@ LIB_FLAG[$LSANDER]='-lsander' LIB_STTC[$LSANDER]='' LIB_D_ON[$LSANDER]='-DUSE_SANDERLIB' LIB_DOFF[$LSANDER]='' -LIB_TYPE[$LSANDER]='cpp' +LIB_TYPE[$LSANDER]='ld' LIB_STAT[$LTIMER]='off' LIB_CKEY[$LTIMER]='timer' @@ -372,6 +379,16 @@ LIB_D_ON[$LTNGFILE]='-DHAS_TNGFILE' LIB_DOFF[$LTNGFILE]='' LIB_TYPE[$LTNGFILE]='cpp' +LIB_STAT[$LHDF5]='enabled' +LIB_CKEY[$LHDF5]='hdf5' +LIB_HOME[$LHDF5]='' +LIB_FLAG[$LHDF5]='' +LIB_STTC[$LHDF5]='libhdf5.a' +LIB_D_ON[$LHDF5]='-DHAS_HDF5' +LIB_DOFF[$LHDF5]='' +LIB_LINK[$LHDF5]='dynamic' +LIB_TYPE[$LHDF5]='ld' + LIB_STAT[$LOPENMM]='off' LIB_CKEY[$LOPENMM]='openmm' LIB_HOME[$LOPENMM]='' @@ -531,6 +548,8 @@ TestProgram() { else COMPILE_ERROR_LINE=$COMPILELINE COMPILE_ERROR_MESSAGE=`cat $COMPERR` + #echo "DEBUG: Error: $COMPILE_ERROR_LINE" + #echo "DEBUG: Error: $COMPILE_ERROR_MESSAGE" rm $COMPERR $COMPOUT return 1 fi @@ -641,6 +660,82 @@ EOF fi } +TestHdf5() { + # First, check if NetCDF has HDF5 support baked in. + cat > testp.cpp < +#include "netcdf.h" +void unused() { + int ncid, varid; + int dims[1]; + // Create a netcdf4 file + nc_create("foo.nc", NC_NETCDF4, &ncid); + // Create a dimension + dims[1] = 10; + nc_def_var(ncid, "MyVar", NC_DOUBLE, 1, dims, &varid); + // Set deflate + int err = nc_def_var_deflate(ncid, varid, NC_SHUFFLE, 1, 1); +} +int main() { printf("Testing\n"); printf("%s\n",nc_strerror(0)); return 0; } +EOF + TestProgram silent " Checking NetCDF4/HDF5" "$CXX" "$CXXFLAGS ${LIB_INCL[$LNETCDF]}" testp.cpp "${LIB_FLAG[$LNETCDF]}" + if [ $? -eq 0 ] ; then + # HDF5 support is present. + # If we are going to build our own netcdf, it needs to know how to link + # HDF5. + if [ "${LIB_MAKE[$LNETCDF]}" = 'yes' ] ; then + LIB_FLAG[$LHDF5]="-lhdf5_hl -lhdf5 -ldl ${LIB_FLAG[$LZIP]}" + fi + return 0 + fi + # If netcdf was specified, this means netcdf was built without hdf5 support + if [ "${LIB_STAT[$LNETCDF]}" = 'specified' ] ; then + ErrMsg "NetCDF in '${LIB_HOME[$LNETCDF]}' does not have HDF5 support." + ErrMsg "To use this NetCDF, disable HDF5 support with '-nohdf5'." + exit 1 + fi + # Check for separate HDF5 + cat > testp.cpp < +#include "hdf5.h" +void unused() { + hid_t file; + file = H5Fcreate("tmp", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + herr_t status = H5Fclose(file); +} +int main() { + printf("Testing\n"); + return 0; +} +EOF + TestProgram silent " Checking HDF5" "$CXX" "$CXXFLAGS ${LIB_INCL[$LHDF5]}" testp.cpp "${LIB_FLAG[$LHDF5]}" + if [ $? -ne 0 ] ; then + if [ "${LIB_STAT[$LHDF5]}" = 'enabled' ] ; then + # See if there is already a version of HDF5 in CPPTRAJHOME + LIB_STAT[$LHDF5]='specified' + LIB_HOME[$LHDF5]=$CPPTRAJHOME + LIB_FLAG[$LHDF5]="$CPPTRAJHOME/lib/libhdf5_hl.a $CPPTRAJHOME/lib/${LIB_STTC[$LHDF5]} -ldl ${LIB_FLAG[$LZIP]}" + LIB_INCL[$LHDF5]="-I$CPPTRAJHOME/include" + TestProgram $BUILDTESTOPT " Checking for bundled HDF5" "$CXX" "$CXXFLAGS ${LIB_INCL[$LHDF5]}" testp.cpp "${LIB_FLAG[$LHDF5]}" + if [ $? -ne 0 ] ; then + CheckRebuild "HDF5" "${LIB_FLAG[$LHDF5]}" + # See if user would like to get HDF5 + PREFIX=$CPPTRAJHOME CC=$CC CFLAGS=$CFLAGS LIBNAME='hdf5' \ + SRCDIR=$HDF5_SRCDIR SRCTAR=$HDF5_SRCTAR URL=$HDF5_URL ./get_library.sh $REBUILDOPT $HDF5_OPTS + if [ $? -ne 0 ] ; then + ErrMsg "Building HDF5 failed." + exit 1 + fi + # Test the built HDF5 + TestProgram " Checking built HDF5" "$CXX" "$CXXFLAGS ${LIB_INCL[$LHDF5]}" testp.cpp "${LIB_FLAG[$LHDF5]}" + fi + else + # HDF5 specified but failed. + TestProgErr "HDF5" + fi + fi +} + TestNetcdf() { cat > testp.cpp < @@ -663,14 +758,35 @@ EOF LIB_HOME[$LNETCDF]=$CPPTRAJHOME LIB_FLAG[$LNETCDF]=$CPPTRAJHOME/lib/${LIB_STTC[$LNETCDF]} LIB_INCL[$LNETCDF]="-I$CPPTRAJHOME/include" + if [ "${LIB_STAT[$LHDF5]}" != 'off' ] ; then + # Netcdf needs to know where hdf5 is + LIB_FLAG[$LNETCDF]="${LIB_FLAG[$LNETCDF]} ${LIB_FLAG[$LHDF5]}" + LIB_INCL[$LNETCDF]="${LIB_INCL[$LNETCDF]} ${LIB_INCL[$LHDF5]}" + fi TestProgram $BUILDTESTOPT " Checking for bundled NetCDF" "$CXX" "$CXXFLAGS ${LIB_INCL[$LNETCDF]}" testp.cpp "${LIB_FLAG[$LNETCDF]}" if [ $? -ne 0 ] ; then # Check if lib present but needs to be rebuilt CheckRebuild "NetCDF" "${LIB_FLAG[$LNETCDF]}" - # See if user would like to get netcdf - PREFIX=$CPPTRAJHOME CC=$CC CFLAGS=$CFLAGS LIBNAME='netcdf' \ - SRCDIR=$NETCDF_SRCDIR SRCTAR=$NETCDF_SRCTAR URL=$NETCDF_URL ./get_library.sh $rebuild_netcdf $NETCDF_OPTS - if [ $? -ne 0 ] ; then + if [ "${LIB_STAT[$LHDF5]}" != 'off' ] ; then + # Get/compile netcdf4 with HDF5 + # Some of the HDF5-related portions of NetCDF4 have race conditions, + # so override MAKE_COMMAND + if [ -z "$MAKE_COMMAND" ] ; then + echo "Setting MAKE_COMMAND to 'make -j1' to avoid NetCDF4/HDF5 race conditions." + else + echo "Overriding MAKE_COMMAND with 'make -j1' to avoid NetCDF4/HDF5 race conditions." + fi + PREFIX=$CPPTRAJHOME CC=$CC CFLAGS=$CFLAGS LIBNAME='netcdf' MAKE_COMMAND='make -j1' \ + CPPFLAGS=${LIB_INCL[$LHDF5]} LDFLAGS="-L$CPPTRAJHOME/lib" \ + SRCDIR=$NETCDF_SRCDIR SRCTAR=$NETCDF_SRCTAR URL=$NETCDF_URL ./get_library.sh $rebuild_netcdf $NETCDF4_OPTS + netcdferr=$? + else + # Get/compile netcdf3 + PREFIX=$CPPTRAJHOME CC=$CC CFLAGS=$CFLAGS LIBNAME='netcdf' \ + SRCDIR=$NETCDF_SRCDIR SRCTAR=$NETCDF_SRCTAR URL=$NETCDF_URL ./get_library.sh $rebuild_netcdf $NETCDF_OPTS + netcdferr=$? + fi + if [ $netcdferr -ne 0 ] ; then ErrMsg "Building NetCDF failed." exit 1 fi @@ -692,7 +808,16 @@ void unused() {int ncid; ncmpi_open(MPI_COMM_WORLD, "foo.nc", NC_NOWRITE, MPI_IN int main() { printf("Testing\n"); printf("%s\n",ncmpi_strerror(0)); return 0; } EOF TestProgram silent " Checking Parallel NetCDF" "$CXX" "$CXXFLAGS ${LIB_INCL[$LPARANC]}" testp.cpp "${LIB_FLAG[$LPARANC]}" - if [ $? -ne 0 ] ; then + pnetcdfstat=$? + # Check if pnetcdf just needs netcdf support + if [ $pnetcdfstat -ne 0 -a "${LIB_STAT[$LPARANC]}" = 'specified' ] ; then + TestProgram silent " Checking Parallel NetCDF (link to NetCDF)" "$CXX" "$CXXFLAGS ${LIB_INCL[$LPARANC]} ${LIB_INCL[$LNETCDF]}" testp.cpp "${LIB_FLAG[$LPARANC]} ${LIB_FLAG[$LNETCDF]}" + pnetcdfstat=$? + # If above check worked, pnetcdf should be linked OK with netcdf flags + return 0 + #echo "DEBUG: Returned $?" + fi + if [ $pnetcdfstat -ne 0 ] ; then if [ "${LIB_STAT[$LPARANC]}" = 'optional' ] ; then WrnMsg "Parallel NetCDF test failed. CPPTRAJ will be built without parallel NetCDF." LIB_STAT[$LPARANC]='off' @@ -1103,6 +1228,7 @@ TestLibraries() { fi if [ "${LIB_TEST[$LBZIP]}" = 'yes' ] ; then TestBzlib ; fi if [ "${LIB_TEST[$LZIP]}" = 'yes' ] ; then TestZlib ; fi + if [ "${LIB_TEST[$LHDF5]}" = 'yes' ] ; then TestHdf5 ; fi if [ "${LIB_TEST[$LNETCDF]}" = 'yes' ] ; then TestNetcdf ; fi if [ "${LIB_TEST[$LPARANC]}" = 'yes' ] ; then TestPnetcdf ; fi if [ "${LIB_TEST[$LBLAS]}" = 'yes' ] ; then TestMathlib ; fi @@ -1425,6 +1551,12 @@ SetupLibraries() { echo "Warning: TNG depends on libz; disabling TNG." LIB_STAT[$LTNGFILE]='off' fi + if [ "${LIB_STAT[$LNETCDF]}" = 'off' -a "${LIB_STAT[$LHDF5]}" != 'off' ] ; then + # HDF5 needs netcdf + echo "Warning: HDF5 depends on NetCDF; disabling HDF5." + LIB_STAT[$LHDF5]='off' + LIB_TEST[$LHDF5]='no' + fi } #------------------------------------------------------------------------------- @@ -1893,7 +2025,7 @@ SetupMKL() { LIB_FLAG[$LLAPACK]='' # If no FFTW, try using MKL if [ "$MKL_FFTW" != 'no' ] ; then - if [ "${LIB_STAT[$LFFTW3]}" = 'off' -o "${LIB_STAT[$LFFTW3]}" = 'optional' ] ; then + if [ "${LIB_STAT[$LFFTW3]}" = 'off' -o "${LIB_STAT[$LFFTW3]}" = 'optional' -o "${LIB_STAT[$LFFTW3]}" = 'enabled' ] ; then MKL_FFTW='yes' LIB_STAT[$LFFTW3]='enabled' LIB_FLAG[$LFFTW3]='' diff --git a/devtools/ci/appveyor/build.bat b/devtools/ci/appveyor/build.bat index d7f351b7d2..2a8053b823 100644 --- a/devtools/ci/appveyor/build.bat +++ b/devtools/ci/appveyor/build.bat @@ -30,7 +30,7 @@ if %BUILD_TYPE% equ cmake-mingw ( ) if %BUILD_TYPE% equ configure-mingw ( - sh -lc "./configure --with-netcdf=/mingw64/ --with-blas=/mingw64/ -openblas --with-bzlib=/mingw64/ --with-zlib=/mingw64 --with-arpack=/mingw64 --with-readline=/mingw64/ -nofftw3 -shared -windows gnu" || exit /b + sh -lc "./configure -nohdf5 --with-netcdf=/mingw64/ --with-blas=/mingw64/ -openblas --with-bzlib=/mingw64/ --with-zlib=/mingw64 --with-arpack=/mingw64 --with-readline=/mingw64/ -nofftw3 -shared -windows gnu" || exit /b make libcpptraj -j2 || exit /b make install -j2 || exit /b ) diff --git a/doc/cpptraj.bib b/doc/cpptraj.bib index d595801630..412af4f063 100644 --- a/doc/cpptraj.bib +++ b/doc/cpptraj.bib @@ -437,3 +437,10 @@ @article{Roe2022 issue = {13}, year = {2022} } + +@article{Roe2022a, +author = {Roe, Daniel R. and Brooks, Bernard R.}, +journal = {Protein Science}, +title = {{ Quantifying the Effects of Lossy Compression on Energies Calculated from Molecular Dynamics Trajectories}}, +year = {2022} +} diff --git a/doc/cpptraj.lyx b/doc/cpptraj.lyx index f71a76cf9e..13a6701796 100644 --- a/doc/cpptraj.lyx +++ b/doc/cpptraj.lyx @@ -2549,7 +2549,11 @@ set { | \begin_inset space ~ \end_inset -{atoms|residues|molecules|atomnums|resnums|oresnums|molnums} +{atoms|residues|molecules|atomnums|resnums +\end_layout + +\begin_layout Description +|oresnums|molnums} \begin_inset space ~ \end_inset @@ -2660,7 +2664,7 @@ The following input will put a range of residues selected by :LYS: \end_layout \begin_layout LyX-Code -> set SELECTED1 = resnums inmask :LYS +> set SELECTED1 = resnums inmask :1-183&:LYS \end_layout \begin_layout LyX-Code @@ -2668,8 +2672,7 @@ The following input will put a range of residues selected by :LYS: \end_layout \begin_layout LyX-Code - Variable 'SELECTED1' set to '7-8,18,26,44,49,71,79,128,135,151,163,183,193,204- -205,217-218' + Variable 'SELECTED1' set to '7-8,18,26,44,49,71,79,128,135,151,163,183' \end_layout \begin_layout Subsection @@ -2883,7 +2886,7 @@ status open \begin_layout Plain Layout \align center \begin_inset Tabular - + @@ -3280,6 +3283,53 @@ Energy information, Read Only \begin_inset Text +\begin_layout Plain Layout +Amber Energy File +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +.ene +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +amberene +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Read Only +\end_layout + +\end_inset + + + + +\begin_inset Text + \begin_layout Plain Layout Amber Evecs \end_layout @@ -3374,6 +3424,53 @@ pH data only \begin_inset Text +\begin_layout Plain Layout +Amber Energy file +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +.ene +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +amberene +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +1D +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Read Only +\end_layout + +\end_inset + + + + +\begin_inset Text + \begin_layout Plain Layout Density Peaks \end_layout @@ -6801,6 +6898,68 @@ loadcrd loadcrd [parm | parmindex<#>] [] [name ] \end_layout +\begin_layout LyX-Code + [prec {single|double} +\end_layout + +\begin_deeper +\begin_layout Description + Trajectory file to load. +\end_layout + +\begin_layout Description +[parm +\begin_inset space ~ +\end_inset + +] Topology filename/tag to associate with trajectory (default + first topology). +\end_layout + +\begin_layout Description +[parmindex +\begin_inset space ~ +\end_inset + +<#>] Index of Topology to associate with trajectory (default 0, first topology). +\end_layout + +\begin_layout Description +[] Additional 'trajin' args; see +\begin_inset CommandInset ref +LatexCommand vref +reference "subsec:cpptraj_trajin" +plural "false" +caps "false" +noprefix "false" + +\end_inset + +. +\end_layout + +\begin_layout Description +[name +\begin_inset space ~ +\end_inset + +] Name of the COORDS set. +\end_layout + +\begin_layout Description +[prec +\begin_inset space ~ +\end_inset + +{single|double}] Load as either a single-precision COORDS set (the default) + or a double-precision FRAMES set (which will use much more memory). +\end_layout + +\end_deeper \begin_layout Standard Immediately load trajectory as a COORDS data set named (default base name of ). @@ -6829,6 +6988,20 @@ loadtraj loadtraj name [] \end_layout +\begin_deeper +\begin_layout Description +name +\begin_inset space ~ +\end_inset + + Name of the TRAJ set. +\end_layout + +\begin_layout Description +[] If specified, trajectory to add to the TRAJ set. +\end_layout + +\end_deeper \begin_layout Standard This command functions in two ways. If is not provided, all currently loaded input trajectories @@ -9303,6 +9476,7 @@ cat ... Concatenate two or more data sets into a new data set (optionally named ). + Only works for scalar 1D and string sets. \end_layout \begin_layout Description @@ -13170,7 +13344,12 @@ change [parm | parmindex <#> | <#> | \end_layout \begin_layout LyX-Code - removebonds [] [out ] } + removebonds [] [out ] | +\end_layout + +\begin_layout LyX-Code + bondparm [] {setrk|scalerk|setreq|scalereq} + } \end_layout \begin_deeper @@ -13421,6 +13600,45 @@ removebonds name> '. \end_layout +\end_deeper +\begin_layout Description +bondparm +\begin_inset space ~ +\end_inset + + +\begin_inset space ~ +\end_inset + +[] +\begin_inset space ~ +\end_inset + +{setrk|scalerk|setreq|scalereq} +\begin_inset space ~ +\end_inset + + Modify bond parameters in bonds selected by (and + if specified) by specified . +\end_layout + +\begin_deeper +\begin_layout Description +setrk Set bond force constants to . +\end_layout + +\begin_layout Description +scalerk Scale bond force constants by . +\end_layout + +\begin_layout Description +setreq Set bond equilibrium lengths to . +\end_layout + +\begin_layout Description +scalereq Scale bond equilibirum lengths by . +\end_layout + \end_deeper \end_deeper \begin_layout Standard @@ -15052,7 +15270,7 @@ Cpptraj currently understands the following trajectory file formats: \begin_layout Standard \align center \begin_inset Tabular - + @@ -15873,7 +16091,7 @@ Read Only - + \begin_inset Text \begin_layout Plain Layout @@ -15882,7 +16100,7 @@ LMOD Conflib \end_inset - + \begin_inset Text \begin_layout Plain Layout @@ -15891,7 +16109,7 @@ conflib \end_inset - + \begin_inset Text \begin_layout Plain Layout @@ -15900,13 +16118,89 @@ conflib \end_inset - + \begin_inset Text \begin_layout Plain Layout Read Only, Detection by extension \end_layout +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +MDTraj H5 +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +h5 +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +.h5 +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Read Only +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +MDAnalysis H5MD +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +h5md +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +.h5md +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +Read Only +\end_layout + \end_inset @@ -17581,6 +17875,26 @@ mdfrc Write only force information in trajectory. mdcrd Write coordinates to trajectory (only required with mdvel/mdfrc). \end_layout +\begin_layout Description +hdf5 Create file as NetCDF4/HDF5 instead of NetCDF4 (classic). +\end_layout + +\begin_layout Description +compress Use compression in NetCDF4/HDF5 file. +\end_layout + +\begin_layout Description +icompress Use lossy compression in NetCDF4/HDF5 file via conversion to integers. +\begin_inset CommandInset citation +LatexCommand citep +key "Roe2022a" +literal "true" + +\end_inset + + +\end_layout + \end_deeper \begin_layout Subsubsection @@ -24694,11 +25008,12 @@ energy [] [] [out ] [nobondstoh] \end_layout \begin_layout LyX-Code - [bond] [angle] [dihedral] {[nb14] | [e14] | [v14]} + [bond] [angle] [dihedral] {[nb14]|[e14]|[v14]} {[nonbond]|[elec] [vdw]} + \end_layout \begin_layout LyX-Code - {[nonbond] | [elec] [vdw]} [kinetic [ketype {vel|vv}] [dt
]] + [{nokinetic|kinetic [ketype {vel|vv}] [dt
]}] \end_layout \begin_layout LyX-Code @@ -24803,6 +25118,51 @@ energy [] [] [out ] [nobondstoh] [vdw] Calculate van der Waals energy (Lennard-Jones 6-12 potential). \end_layout +\begin_layout Description +[nokinetic] Do not calculate kinetic energy even if velocity/force information + present. +\end_layout + +\begin_layout Description +[kinetic] Attempt to calculate kinetic energy. + Requires force and/or velocity information. +\end_layout + +\begin_deeper +\begin_layout Description +ketype +\begin_inset space ~ +\end_inset + +{vel|vv} Specify kinetic energy type. + If not specified, if velocity and force information use a velocity verlet-type + calculation ( +\series bold +vv +\series default +), i.e. + assume velocities are a half-step ahead of the forces. + If only velocity information is present, calculate from on-step velocities + ( +\series bold +vel +\series default +). +\end_layout + +\begin_layout Description +dt +\begin_inset space ~ +\end_inset + +
Time step for +\series bold +vv +\series default + calculation in ps. +\end_layout + +\end_deeper \begin_layout Description [etype \begin_inset space ~ @@ -25037,6 +25397,10 @@ DataSet Aspects: [elec] Electrostatic energy. \end_layout +\begin_layout Description +[kinetic] Kinetic energy. +\end_layout + \begin_layout Description [total] Total energy. \end_layout @@ -50118,7 +50482,7 @@ timecorr \end_layout \begin_layout LyX-Code -timecorr vec1 [vec2 ] out +timecorr vec1 [vec2 ] out [name ] \end_layout \begin_layout LyX-Code @@ -50169,6 +50533,14 @@ out Name of file to write output to. \end_layout +\begin_layout Description +[name +\begin_inset space ~ +\end_inset + +] Name of output vector data sets. +\end_layout + \begin_layout Description \series bold diff --git a/src/Action_Energy.cpp b/src/Action_Energy.cpp index 6e5d1da93d..d24f7038b1 100644 --- a/src/Action_Energy.cpp +++ b/src/Action_Energy.cpp @@ -24,8 +24,8 @@ Action_Energy::~Action_Energy() { void Action_Energy::Help() const { mprintf("\t[] [] [out ] [nobondstoh]\n" - "\t[bond] [angle] [dihedral] {[nb14] | [e14] | [v14]}\n" - "\t{[nonbond] | [elec] [vdw]} [kinetic [ketype {vel|vv}] [dt
]]\n" + "\t[bond] [angle] [dihedral] {[nb14]|[e14]|[v14]} {[nonbond] | [elec] [vdw]}\n" + "\t[{nokinetic|kinetic [ketype {vel|vv}] [dt
]}]\n" "\t[ etype { simple |\n" "\t directsum [npoints ] |\n" "\t ewald %s\n" @@ -98,6 +98,14 @@ Action::RetType Action_Energy::Init(ArgList& actionArgs, ActionInit& init, int d if (*it) ++nactive; // If no terms specified, enabled everything. TODO disable KE? if (nactive == 0) termEnabled.assign((int)TOTAL+1, true); + // Check if KE should be disabled + if (actionArgs.hasKey("nokinetic")) + termEnabled[KE] = false; + // Re-count the number of active terms if necessary. + if (nactive == 0) { + for (std::vector::const_iterator it = termEnabled.begin(); it != termEnabled.end(); ++it) + if (*it) ++nactive; + } // If more than one term enabled ensure total will be calculated. if (nactive > 1) termEnabled[TOTAL] = true; // If KE enabled get type, time step, etc diff --git a/src/BufferedFrame.cpp b/src/BufferedFrame.cpp index 44125485ae..83756ca22f 100644 --- a/src/BufferedFrame.cpp +++ b/src/BufferedFrame.cpp @@ -121,13 +121,14 @@ int BufferedFrame::AttemptReadFrame() { * \return false if read was successful. */ bool BufferedFrame::ReadFrame() { - return ( Read( buffer_, frameSize_ ) != (int)frameSize_ ); - /*int nread = Read(buffer_, frameSize_); + int nread = Read(buffer_, frameSize_); + //mprintf("DEBUG: %i bytes read.\n", nread); if (nread != (int)frameSize_) { - mprinterr("Error: Read %i bytes, expected %zu\n", nread, frameSize_); + if (nread < 0) + mprinterr("Error: Read %i bytes, expected %zu\n", nread, frameSize_); return true; } - return false;*/ + return false; } int BufferedFrame::WriteFrame() { diff --git a/src/BufferedLine.h b/src/BufferedLine.h index 3b271e239b..6d8eead52a 100644 --- a/src/BufferedLine.h +++ b/src/BufferedLine.h @@ -31,7 +31,7 @@ class BufferedLine : private CpptrajFile { return ResetBuffer(); } - /// \return current line number + /// \return current line number (starting from 1) int LineNumber() const { return nline_; } /// \return pointer to beginning of buffer. const char* Buffer() const { return buffer_; } diff --git a/src/Command.cpp b/src/Command.cpp index 1d9bc81972..850ddaf6c0 100644 --- a/src/Command.cpp +++ b/src/Command.cpp @@ -16,6 +16,7 @@ #include "Exec_Calc.h" #include "Exec_ClusterMap.h" #include "Exec_Commands.h" +#include "Exec_CompareEnergy.h" #include "Exec_CreateSet.h" #include "Exec_DataFile.h" #include "Exec_DataFilter.h" @@ -217,6 +218,7 @@ void Command::Init() { Command::AddCmd( new Exec_Clear(), Cmd::EXE, 1, "clear" ); Command::AddCmd( new Exec_ClusterMap(), Cmd::EXE, 1, "clustermap" ); // hidden Command::AddCmd( new Exec_CompareClusters(), Cmd::EXE, 1, "compareclusters" ); //hidden + Command::AddCmd( new Exec_CompareEnergy(), Cmd::EXE, 1, "compareenergy" ); //hidden Command::AddCmd( new Exec_CreateDataFile(), Cmd::EXE, 1, "create" ); Command::AddCmd( new Exec_CreateSet(), Cmd::EXE, 1, "createset" ); Command::AddCmd( new Exec_DataFileCmd(), Cmd::EXE, 1, "datafile" ); diff --git a/src/Constraints.cpp b/src/Constraints.cpp index 2028265c05..96cdb5fe37 100644 --- a/src/Constraints.cpp +++ b/src/Constraints.cpp @@ -17,6 +17,8 @@ Constraints::Constraints() : degrees_of_freedom_(0) {} +const int Constraints::maxIterations_ = 1000; + static const char* shakeString_[] = { "off", "bonds to H", "all bonds" }; @@ -123,6 +125,75 @@ int Constraints::SetupConstraints(AtomMask const& mask, Topology const& top) return 0; } +// Constraints::Rattle() +int Constraints::Rattle(Frame& frameIn, Frame const& oldFrame) +const +{ + static const double FAC = 1.2; // TODO make part of class + // Main loop + bool done = false; + int niterations = 0; + while (!done && (niterations < maxIterations_)) + { + niterations++; + done = true; + // Loop over selected constrained bonds + for (Carray::const_iterator bnd = Bonds_.begin(); bnd != Bonds_.end(); ++bnd) + { + // Get the bond equilibrium length + double req = bnd->req_; + // Calculate bond vector + Vec3 dR = Vec3(frameIn.XYZ( bnd->at2_)) - Vec3(frameIn.XYZ( bnd->at1_ )); + // Bond length^2 + double dist2 = dR.Magnitude2(); + // Delta (squared) + double delta = req * req - dist2; + + if ( fabs(delta) > EPS_ ) { + done = false; + Vec3 rOld = Vec3(oldFrame.XYZ( bnd->at2_)) - Vec3(oldFrame.XYZ( bnd->at1_ )); + + double dot = dR * rOld; + + double rma = 1.0 / frameIn.Mass( bnd->at1_ ); + double rmb = 1.0 / frameIn.Mass( bnd->at2_ ); + + double term = FAC * delta / (2.0 * (rma + rmb) * dot); + + Vec3 dTerm = rOld * term; + + // Update positions + double* xyzArray = frameIn.xAddress(); + int idx1 = bnd->at1_*3; + xyzArray[idx1 ] -= dTerm[0] * rma; + xyzArray[idx1+1] -= dTerm[1] * rma; + xyzArray[idx1+2] -= dTerm[2] * rma; + int idx2 = bnd->at2_*3; + xyzArray[idx2 ] += dTerm[0] * rmb; + xyzArray[idx2+1] += dTerm[1] * rmb; + xyzArray[idx2+2] += dTerm[2] * rmb; + // Update velocities + if (frameIn.HasVelocity()) { + rma = rma / dt_; + rmb = rmb / dt_; + double* vArray = frameIn.vAddress(); + vArray[idx1 ] -= dTerm[0] * rma; + vArray[idx1+1] -= dTerm[1] * rma; + vArray[idx1+2] -= dTerm[2] * rma; + vArray[idx2 ] += dTerm[0] * rmb; + vArray[idx2+1] += dTerm[1] * rmb; + vArray[idx2+2] += dTerm[2] * rmb; + } + } // END abs delta > epsilon + } // END loop over constrained bonds + } // END main rattle loop + if (niterations > maxIterations_) { + mprinterr("Error: RATTLE took more than %i iterations.\n", maxIterations_); + return 1; + } + return 0; +} + // Constraints::Rattle2() int Constraints::Rattle2(Frame& frameIn) const @@ -131,9 +202,8 @@ const // Main loop bool done = false; int niterations = 0; - static const int maxIterations = 1000; double* Vel = frameIn.vAddress(); - while (!done && (niterations < maxIterations)) + while (!done && (niterations < maxIterations_)) { niterations++; done = true; @@ -168,8 +238,8 @@ const } } // END loop over bonds } // END main rattle loop - if (niterations > maxIterations) { - mprinterr("Error: RATTLE took more than %i iterations.\n", maxIterations); + if (niterations > maxIterations_) { + mprinterr("Error: RATTLE2 took more than %i iterations.\n", maxIterations_); return 1; } return 0; diff --git a/src/Constraints.h b/src/Constraints.h index 1aa1304a46..8dfe92dca9 100644 --- a/src/Constraints.h +++ b/src/Constraints.h @@ -16,6 +16,9 @@ class Constraints { static const char* rattleArgs; int InitRattle(ArgList&); int SetupConstraints(AtomMask const&, Topology const&); + /// Version of rattle that adjusts positions and velocities + int Rattle(Frame&, Frame const&) const; + /// Version of rattle that adjusts velocities only int Rattle2(Frame&) const; ShakeType Type() const { return shakeType_; } int DegreesOfFreedom() const { return degrees_of_freedom_; } @@ -49,5 +52,7 @@ class Constraints { double EPS_; ///< Hold epsilon / dt ShakeType shakeType_; ///< What bonds constraints being applied to. int degrees_of_freedom_; ///< Unconstrained deg. of freedom. + + static const int maxIterations_; ///< Maximum iterations for rattle loop }; #endif diff --git a/src/Cpptraj.cpp b/src/Cpptraj.cpp index a740122c9a..b5714f20bd 100644 --- a/src/Cpptraj.cpp +++ b/src/Cpptraj.cpp @@ -214,6 +214,9 @@ std::string Cpptraj::Defines() { #endif #ifdef BINTRAJ defined_str.append(" -DBINTRAJ"); +# ifdef HAS_HDF5 + defined_str.append(" -DHAS_HDF5"); +# endif #endif #ifdef MPI defined_str.append(" -DMPI"); diff --git a/src/DataFile.cpp b/src/DataFile.cpp index 261e951d28..768560fbd7 100644 --- a/src/DataFile.cpp +++ b/src/DataFile.cpp @@ -29,6 +29,7 @@ #include "DataIO_Cmatrix_Binary.h" #include "DataIO_Cmatrix_NC.h" #include "DataIO_Peaks.h" +#include "DataIO_AmberEne.h" // CONSTRUCTOR DataFile::DataFile() : @@ -75,6 +76,7 @@ const FileTypes::AllocToken DataFile::DF_AllocArray[] = { { "Pairwise Cache (NetCDF)", 0, 0, 0 }, # endif { "Peaks", 0, 0, DataIO_Peaks::Alloc }, + { "Amber Energy File", 0, 0, DataIO_AmberEne::Alloc}, { "Unknown Data file", 0, 0, 0 } }; @@ -91,12 +93,13 @@ const FileTypes::KeyToken DataFile::DF_KeyArray[] = { { EVECS, "evecs", ".evecs" }, { XVG, "xvg", ".xvg" }, { CCP4, "ccp4", ".ccp4" }, - { CHARMMREPD, "charmmrepd",".exch" }, - { CHARMMOUT, "charmmout", ".charmmout"}, + { CHARMMREPD, "charmmrepd", ".exch" }, + { CHARMMOUT, "charmmout", ".charmmout"}, { CHARMMRTFPRM, "charmmrtfprm", ".rtfprm"}, - { CMATRIX_BINARY,"cmatrix",".cmatrix" }, - { CMATRIX_NETCDF,"nccmatrix", ".nccmatrix" }, - { PEAKS, "peaks", ".peaks" }, + { CMATRIX_BINARY,"cmatrix", ".cmatrix" }, + { CMATRIX_NETCDF,"nccmatrix", ".nccmatrix" }, + { PEAKS, "peaks", ".peaks" }, + { AMBERENE, "amberene", ".ene" }, { UNKNOWN_DATA, 0, 0 } }; diff --git a/src/DataFile.h b/src/DataFile.h index d3f20ab698..2f901aedcf 100644 --- a/src/DataFile.h +++ b/src/DataFile.h @@ -18,6 +18,7 @@ class DataFile { DATAFILE=0, XMGRACE, GNUPLOT, XPLOR, OPENDX, REMLOG, MDOUT, EVECS, VECTRAJ, XVG, CCP4, CHARMMREPD, CHARMMFASTREP, CHARMMOUT, CPOUT, CHARMMRTFPRM, CMATRIX_BINARY, CMATRIX_NETCDF, PEAKS, + AMBERENE, UNKNOWN_DATA }; DataFile(); diff --git a/src/DataIO_AmberEne.cpp b/src/DataIO_AmberEne.cpp new file mode 100644 index 0000000000..149c8ba64d --- /dev/null +++ b/src/DataIO_AmberEne.cpp @@ -0,0 +1,205 @@ +#include "DataIO_AmberEne.h" +#include "BufferedLine.h" +#include "CpptrajStdio.h" +#include // atoi, atof +#include // std::max + +/// CONSTRUCTOR +DataIO_AmberEne::DataIO_AmberEne() +{ + +} + +// DataIO_AmberEne::ID_DataFormat() +bool DataIO_AmberEne::ID_DataFormat(CpptrajFile& infile) +{ + if (infile.OpenFile()) return false; + bool isAmberEne = false; + std::string line = infile.GetLine(); + ArgList lineArgs( line, " " ); + if (lineArgs.Nargs() > 2) { + if (lineArgs[0] == "L0" && lineArgs[1] == "Nsteps") + isAmberEne = true; + } + return isAmberEne; +} + +// DataIO_AmberEne::ReadHelp() +void DataIO_AmberEne::ReadHelp() +{ + +} + +// DataIO_AmberEne::processReadArgs() +int DataIO_AmberEne::processReadArgs(ArgList& argIn) +{ + + return 0; +} + +// ----------------------------------------------- +/// Class to hold characteristics of an Amber energy file line +class AmberEneLine { + public: + /// CONSTRUCTOR + AmberEneLine() {} + /// Set up from given line + int Setup(const char* ptr, unsigned int lineNumber, DataSetList& dsl, + std::string const& dsname, DataSet::DataType fpType) + { + ArgList headerArgs( ptr, " \n\r" ); + if (headerArgs.Nargs() < 1) { + mprinterr("Error: No columns detected at line %u of Amber energy file.\n", + lineNumber); + return 1; + } + //fmt_.assign("%*s"); + // Output sets and sscanf read format + for (int iarg = 1; iarg < headerArgs.Nargs(); iarg++) { + // Determine expected type + DataSet::DataType setType; + if (headerArgs[iarg] == "Nsteps") + setType = DataSet::INTEGER; + else + setType = fpType; + MetaData md(dsname, headerArgs[iarg]); + DataSet* ds = dsl.CheckForSet( md ); + if (ds == 0) { + // Creating new set + ds = dsl.AddSet( setType, md ); + if (ds == 0) { + mprinterr("Error: Could not allocate set '%s[%s]'\n", + dsname.c_str(), headerArgs[iarg].c_str()); + return 1; + } + } else { + // Append to existing. Check type. + if (setType != ds->Type()) { + mprinterr("Error: Cannot append to set '%s'. Type is '%s', expected '%s'\n", + ds->legend(), DataSet::description(ds->Type()), + DataSet::description(setType)); + return 1; + } + } + outsets_.push_back( ds ); + //if (setType == DataSet::INTEGER) + // fmt_.append(" %i"); + //else + // fmt_.append(" %lf"); + } // END loop over header labels in this line + return 0; + } // END Setup() + /// Print details to stdout + void Print() const { + //mprintf("Format: '%s'\n", fmt_.c_str()); + mprintf("\tSets:"); + for (std::vector::const_iterator it = outsets_.begin(); + it != outsets_.end(); ++it) + mprintf(" %s", (*it)->legend()); + mprintf("\n"); + } + /// \return # of values this line contains + unsigned int Nvals() const { return outsets_.size(); } + /// \return iterator to beginning of sets + std::vector::const_iterator begin() const { return outsets_.begin(); } + /// \return iterator to end of sets + std::vector::const_iterator end() const { return outsets_.end(); } + private: + //std::string fmt_; ///< scanf format for reading this line + std::vector outsets_; ///< Output sets for this line +}; +// ----------------------------------------------- + +// DataIO_AmberEne::ReadData() +int DataIO_AmberEne::ReadData(FileName const& fname, DataSetList& dsl, std::string const& dsname) +{ + BufferedLine infile; + if (infile.OpenFileRead(fname)) return 1; + const char* ptr = infile.Line(); + // Should be at first line of the header + //mprintf("DEBUG: %i '%s'\n", infile.LineNumber(), ptr); + if (ptr[0] != 'L' || ptr[1] != '0') { + mprinterr("Error: 'L0' not found in Amber energy file '%s'\n", fname.full()); + return 1; + } + + typedef std::vector LineArray; + LineArray Lines; + + // Read the header + unsigned int maxVals = 0; + const DataSet::DataType fpType = DataSet::DOUBLE; + while (ptr != 0) { + if (infile.LineNumber() > 1 && ptr[0] == 'L' && ptr[1] == '0') { + // At first line of data + break; + } + Lines.push_back( AmberEneLine() ); + if (Lines.back().Setup(ptr, infile.LineNumber(), dsl, dsname, fpType)) + return 1; + Lines.back().Print(); + maxVals = std::max( maxVals, Lines.back().Nvals() ); + + ptr = infile.Line(); + } + + // Sanity check + if (Lines.empty()) { + mprinterr("Error: No headers read.\n"); + return 1; + } + + // Read data + int ndata = 0; + while (ptr != 0) { + for (LineArray::const_iterator it = Lines.begin(); it != Lines.end(); ++it) + { + int nvals = infile.TokenizeLine(" \n\r"); + // Subtract the LX column + nvals--; + if ( (nvals < 1) || ((unsigned int)nvals != it->Nvals()) ) { + mprinterr("Error: Line %i expected %u values, got %i\n", + infile.LineNumber(), it->Nvals(), nvals); + it->Print(); + return 1; + } + infile.NextToken(); + // Loop over remaining columns + for (std::vector::const_iterator ds = it->begin(); + ds != it->end(); ++ds) + { + if ((*ds)->Type() == DataSet::INTEGER) { + int ival = atoi( infile.NextToken() ); + (*ds)->Add( ndata, &ival ); + } else { + double dval = atof( infile.NextToken() ); + (*ds)->Add( ndata, &dval ); + } + } // END loop over remaining columns + ptr = infile.Line(); + } // END loop over lines + + ndata++; + } + return 0; +} + +// DataIO_AmberEne::WriteHelp() +void DataIO_AmberEne::WriteHelp() +{ + +} + +// DataIO_AmberEne::processWriteArgs() +int DataIO_AmberEne::processWriteArgs(ArgList& argIn) +{ + + return 0; +} + +// DataIO_AmberEne::WriteData() +int DataIO_AmberEne::WriteData(FileName const& fname, DataSetList const& dsl) +{ + + return 1; +} diff --git a/src/DataIO_AmberEne.h b/src/DataIO_AmberEne.h new file mode 100644 index 0000000000..0d6149be3b --- /dev/null +++ b/src/DataIO_AmberEne.h @@ -0,0 +1,17 @@ +#ifndef INC_DATAIO_AMBERENE_H +#define INC_DATAIO_AMBERENE_H +#include "DataIO.h" +/// Read Amber ASCII energy file +class DataIO_AmberEne : public DataIO { + public: + DataIO_AmberEne(); + static void ReadHelp(); + static void WriteHelp(); + static BaseIOtype* Alloc() { return (BaseIOtype*)new DataIO_AmberEne(); } + int processReadArgs(ArgList&); + int ReadData(FileName const&, DataSetList&, std::string const&); + int processWriteArgs(ArgList&); + int WriteData(FileName const&, DataSetList const&); + bool ID_DataFormat(CpptrajFile&); +}; +#endif diff --git a/src/DataSet.cpp b/src/DataSet.cpp index 31a1dbca14..cabaf04cbb 100644 --- a/src/DataSet.cpp +++ b/src/DataSet.cpp @@ -31,7 +31,8 @@ const char* DataSet::Descriptions_[] = { "tensor", // TENSOR "string variable", // STRINGVAR "vector with scalar", // VECTOR_SCALAR - "unsigned integer" // UNSIGNED_INTEGER + "unsigned integer", // UNSIGNED_INTEGER + "frames" // FRAMES }; // CONSTRUCTOR diff --git a/src/DataSet.h b/src/DataSet.h index 33223f4fdf..7671fae211 100644 --- a/src/DataSet.h +++ b/src/DataSet.h @@ -28,7 +28,8 @@ class DataSet { UNKNOWN_DATA=0, DOUBLE, FLOAT, INTEGER, STRING, MATRIX_DBL, MATRIX_FLT, COORDS, VECTOR, MODES, GRID_FLT, GRID_DBL, REMLOG, XYMESH, TRAJ, REF_FRAME, MAT3X3, TOPOLOGY, PH, PH_EXPL, PH_IMPL, - PARAMETERS, PMATRIX_MEM, PMATRIX_NC, TENSOR, STRINGVAR, VECTOR_SCALAR, UNSIGNED_INTEGER + PARAMETERS, PMATRIX_MEM, PMATRIX_NC, TENSOR, STRINGVAR, VECTOR_SCALAR, UNSIGNED_INTEGER, + FRAMES }; /// Group DataSet belongs to. enum DataGroup { diff --git a/src/DataSetList.cpp b/src/DataSetList.cpp index 9486970992..1fd12e93ec 100644 --- a/src/DataSetList.cpp +++ b/src/DataSetList.cpp @@ -34,6 +34,7 @@ #include "DataSet_StringVar.h" #include "DataSet_Vector_Scalar.h" #include "DataSet_unsignedInt.h" +#include "DataSet_Coords_FRM.h" bool DataSetList::useDiskCache_ = false; @@ -71,6 +72,7 @@ DataSet* DataSetList::NewSet(DataSet::DataType typeIn) { case DataSet::REMLOG : ds = DataSet_RemLog::Alloc(); break; case DataSet::XYMESH : ds = DataSet_Mesh::Alloc(); break; case DataSet::TRAJ : ds = DataSet_Coords_TRJ::Alloc(); break; + case DataSet::FRAMES : ds = DataSet_Coords_FRM::Alloc(); break; case DataSet::REF_FRAME : ds = DataSet_Coords_REF::Alloc(); break; case DataSet::MAT3X3 : ds = DataSet_Mat3x3::Alloc(); break; case DataSet::TOPOLOGY : ds = DataSet_Topology::Alloc(); break; diff --git a/src/DataSet_Coords_FRM.cpp b/src/DataSet_Coords_FRM.cpp new file mode 100644 index 0000000000..ec9edea873 --- /dev/null +++ b/src/DataSet_Coords_FRM.cpp @@ -0,0 +1,140 @@ +#include "DataSet_Coords_FRM.h" +#include "CpptrajStdio.h" + +/** CONSTRUCTOR */ +DataSet_Coords_FRM::DataSet_Coords_FRM() : + DataSet_Coords(FRAMES) +{} + +// ----------------------------------------------- +#ifdef MPI +/** Sync all frames to the master process. */ +int DataSet_Coords_FRM::Sync(size_t total, std::vector const& rank_frames, + Parallel::Comm const& commIn) +{ + if (commIn.Size()==1) return 0; + if (commIn.Master()) { + // Resize for total number of frames. + frames_.resize( total, AllocateFrame() ); + int cidx = rank_frames[0]; // Frame Index on master + // Receive data from each rank + for (int rank = 1; rank < commIn.Size(); rank++) { + for (int idx = 0; idx < rank_frames[rank]; idx++) { + //rprintf("DEBUG: MASTER RECEIVE from rank %i cidx=%i rank_frames=%i FrameSize=%u\n", + // rank, cidx, rank_frames[rank], frames_.FrameSize()); + frames_[cidx++].RecvFrame( rank, commIn ); + } + } + } else {// Send data to master + for (unsigned int idx = 0; idx < Size(); idx++) { + //rprintf("DEBUG: RANK %i SEND TO MASTER Size=%zu FrameSize=%u\n", + // commIn.Rank(), Size(), frames_.FrameSize()); + frames_[idx].SendFrame(0, commIn); + } + } + return 0; +} +#endif + +/** Add a single element. */ +void DataSet_Coords_FRM::Add(size_t idx, const void* ptrIn) { + Frame const* frmPtr = static_cast( ptrIn ); + if (frmPtr->Natom() != top_.Natom()) { + mprintf("Warning: DataSet_Coords_FRM::Add: Incoming frame has %i atoms but topology '%s' has %i\n", + frmPtr->Natom(), top_.c_str(), top_.Natom()); + } + if (idx > frames_.size()) + frames_.resize( idx ); + // Insert at end + frames_.push_back( *frmPtr ); +} + +/** Reserve space in frames_ array. */ +int DataSet_Coords_FRM::Allocate(SizeArray const& sizeIn) { + //rprintf("DEBUG: Calling Allocate: SizeArray[0]= %zu framesToReserve= %i\n", sizeIn[0], framesToReserve_); + if (!sizeIn.empty()) { + /*framesToReserve_ = (int)sizeIn[0]; + if (frames_.HasComponents()) + frames_.Resize( framesToReserve_ );*/ + frames_.reserve( sizeIn[0] ); + } + return 0; +} + +/** Allocate space in frames_ array. */ +int DataSet_Coords_FRM::MemAlloc( SizeArray const& sizeIn ) { + //rprintf("DEBUG: MemAlloc resize %s to %zu\n", legend(), sizeIn[0]); + if (!sizeIn.empty()) { + //framesToReserve_ = (int)sizeIn[0]; + //frames_.Resize( framesToReserve_ ); + frames_.resize( sizeIn[0] ); + } + return 0; +} + +/** \return Sum of bytes used by all frames in array. */ +size_t DataSet_Coords_FRM::MemUsageInBytes() const { + size_t total = 0; + for (FrmArrayType::const_iterator it = frames_.begin(); it != frames_.end(); ++it) + total += it->DataSize(); + return total; +} + +/** Copy block from incoming set of same type. + * \param startIdx Position in this set to copy to. + * \param dptrIn Set to copy from. + * \param pos Position in dptrIn to copy from. + * \param nelts Number of elements from dptrIn to copy. + */ +void DataSet_Coords_FRM::CopyBlock(size_t startIdx, DataSet const* dptrIn, size_t pos, size_t nelts) +{ + DataSet_Coords_FRM const& setIn = static_cast( *dptrIn ); + size_t tgtidx = startIdx; + size_t srcend = pos + nelts; + for (size_t srcidx = pos; srcidx != srcend; srcidx++, tgtidx++) + frames_[tgtidx] = setIn.frames_[srcidx]; +} + +// ----------------------------------------------- +/** Set up COORDS with given Topology and coordinate info. */ +int DataSet_Coords_FRM::CoordsSetup(Topology const& topIn, CoordinateInfo const& cInfoIn) { + top_ = topIn; + cInfo_ = cInfoIn; + + //if (frames_.SetupFrameArray(cInfo_, topIn.Natom(), framesToReserve_)) { + // mprinterr("Internal Error: Could not set up CompactFrameArray for '%s'\n", legend()); + // return 1; + //} + + return 0; +} + +/** Add frame to array. */ +void DataSet_Coords_FRM::AddFrame(Frame const& fIn) { + if (fIn.Natom() != top_.Natom()) { + mprintf("Warning: DataSet_Coords_FRM::AddFrame: Incoming frame has %i atoms but topology '%s' has %i\n", + fIn.Natom(), top_.c_str(), top_.Natom()); + } + frames_.push_back( fIn ); +} + +/** Copy frame to specified position in array. */ +void DataSet_Coords_FRM::SetCRD(int idx, Frame const& fIn) { + if (fIn.Natom() != top_.Natom()) { + mprintf("Warning: DataSet_Coords_FRM::SetCrd: Incoming frame has %i atoms but topology '%s' has %i\n", + fIn.Natom(), top_.c_str(), top_.Natom()); + } + if (idx > (int)frames_.size()) // TODO fix this sign issue + frames_.resize( idx ); + frames_[idx] = fIn; +} + +/** Get a frame from specified position in array. */ +void DataSet_Coords_FRM::GetFrame(int idx, Frame& fOut) { + fOut.SetFrame( frames_[idx] ); +} + +/** Get selected atoms from a frame from specified position in array. */ +void DataSet_Coords_FRM::GetFrame(int idx, Frame& fOut, AtomMask const& mask) { + fOut.SetFrame( frames_[idx], mask ); +} diff --git a/src/DataSet_Coords_FRM.h b/src/DataSet_Coords_FRM.h new file mode 100644 index 0000000000..53e89a67f1 --- /dev/null +++ b/src/DataSet_Coords_FRM.h @@ -0,0 +1,48 @@ +#ifndef INC_DATASET_COORDS_FRM_H +#define INC_DATASET_COORDS_FRM_H +#include "DataSet_Coords.h" +/// Hold full-precision array of Frames in memory. +class DataSet_Coords_FRM : public DataSet_Coords { + public: + /// CONSTRUCTOR + DataSet_Coords_FRM(); + /// Allocate DataSet + static DataSet* Alloc() { return (DataSet*)new DataSet_Coords_FRM(); } + // ----- DataSet functions ------------------- + /// \return Number of frames + size_t Size() const { return frames_.size(); } + /// \return array containing sizes for each dimension (frames) + SizeArray DimSizes() const { return SizeArray(1, Size()); } +# ifdef MPI + /// Synchronize all data to the master process + int Sync(size_t, std::vector const&, Parallel::Comm const&); +# endif + /// Print info to stdout + void Info() const { return; } + /// Add single element + void Add(size_t, const void*); + /// Reserve memory using given array of dimensions + int Allocate(SizeArray const&); + /// Allocate array using given array of dimensions + int MemAlloc(SizeArray const&); + /// \return Size of set in bytes + size_t MemUsageInBytes() const; + /// Copy a block of the DataSet + void CopyBlock(size_t, const DataSet*, size_t, size_t); + // ----- DataSet_Coords functions ------------ + /// Add a frame + void AddFrame(Frame const&); + /// Set frame at specified position + void SetCRD(int, Frame const&); + /// Get a frame at position. + void GetFrame(int, Frame&); + /// Get a frame at position corresponding to mask. + void GetFrame(int, Frame&, AtomMask const&); + /// Set topology and coordinate information + int CoordsSetup(Topology const&, CoordinateInfo const&); + // ------------------------------------------- + private: + typedef std::vector FrmArrayType; + FrmArrayType frames_; ///< Array of Frames +}; +#endif diff --git a/src/Energy.cpp b/src/Energy.cpp index ebcf35ea95..936414ecd0 100644 --- a/src/Energy.cpp +++ b/src/Energy.cpp @@ -8,6 +8,7 @@ #include "CharMask.h" #include "ExclusionArray.h" #include "Energy/Ene_Angle.h" +#include "Energy/Ene_Bond.h" const double Energy_Amber::QFAC = Constants::ELECTOAMBER * Constants::ELECTOAMBER; @@ -41,10 +42,7 @@ double Energy_Amber::CalcBondEnergy(Frame const& fIn, BondArray const& Bonds, continue; } BondParmType const& bp = BPA[bpidx]; - double r2 = DIST2_NoImage( fIn.XYZ(b->A1()), fIn.XYZ(b->A2()) ); - double r = sqrt(r2); - double rdiff = r - bp.Req(); - double ene = bp.Rk() * (rdiff * rdiff); + double ene = Cpptraj::Energy::Ene_Bond( fIn.XYZ(b->A1()), fIn.XYZ(b->A2()), bp.Req(), bp.Rk() ); Ebond += ene; // mprintf("EBOND %4li %4i -- %4i: k= %12.5f x0= %12.5f r= %12.5f E= %12.5f\n", // b - Bonds.begin(), b->A1()+1, b->A2()+1, bp.Rk(), bp.Req(), r, ene); diff --git a/src/Energy/Ene_Bond.h b/src/Energy/Ene_Bond.h new file mode 100644 index 0000000000..1100eb20ca --- /dev/null +++ b/src/Energy/Ene_Bond.h @@ -0,0 +1,20 @@ +#ifndef INC_ENERGY_ENE_BOND_H +#define INC_ENERGY_ENE_BOND_H +#include "Kernel_Harmonic.h" +namespace Cpptraj { +namespace Energy { +/// \return Energy of the bond between xyz1 and xyz2 +template +T Ene_Bond(T const* xyz1, T const* xyz2, T const& req, T const& rk) +{ + T x = xyz1[0] - xyz2[0]; + T y = xyz1[1] - xyz2[1]; + T z = xyz1[2] - xyz2[2]; + T r2 = (x*x + y*y + z*z); + T r = sqrt(r2); + T ene = Kernel_Harmonic( r, rk, req ); + return ene; +} +} +} +#endif diff --git a/src/Energy/Kernel_Fourier.h b/src/Energy/Kernel_Fourier.h new file mode 100644 index 0000000000..5d807815c2 --- /dev/null +++ b/src/Energy/Kernel_Fourier.h @@ -0,0 +1,11 @@ +#ifndef INC_ENERGYKERNEL_FOURIER_H +#define INC_ENERGYKERNEL_FOURIER_H +namespace Cpptraj { +namespace Energy { +template T Kernel_Fourier(T phi, T Pk, T Pn, T Phase) { + T ene = Pk * (1 + cos(Pn * phi - Phase)); + return ene; +} +} +} +#endif diff --git a/src/Energy/Kernel_Harmonic.h b/src/Energy/Kernel_Harmonic.h new file mode 100644 index 0000000000..649abeece8 --- /dev/null +++ b/src/Energy/Kernel_Harmonic.h @@ -0,0 +1,13 @@ +#ifndef INC_ENERGYKERNEL_HARMONIC_H +#define INC_ENERGYKERNEL_HARMONIC_H +namespace Cpptraj { +namespace Energy { +/// \return Hooke's law type energy +template T Kernel_Harmonic(T r, T Rk, T Req) { + T rdiff = r - Req; + T ene = Rk * (rdiff * rdiff); + return ene; +} +} +} +#endif diff --git a/src/Exec_Change.cpp b/src/Exec_Change.cpp index 78c1701deb..7da6f0956a 100644 --- a/src/Exec_Change.cpp +++ b/src/Exec_Change.cpp @@ -1,6 +1,8 @@ #include "Exec_Change.h" +#include "CharMask.h" #include "CpptrajStdio.h" #include "TypeNameHolder.h" +#include "ParameterTypes.h" // Exec_Change::Help() void Exec_Change::Help() const @@ -14,6 +16,7 @@ void Exec_Change::Help() const "\t atomname from to |\n" "\t addbond [req ] |\n" "\t removebonds [] [out ]}\n" + "\t bondparm [] {setrk|scalerk|setreq|scalereq} \n" " Change specified parts of topology or topology of a COORDS data set.\n", DataSetList::TopArgs); } @@ -23,7 +26,7 @@ Exec::RetType Exec_Change::Execute(CpptrajState& State, ArgList& argIn) { // Change type enum ChangeType { UNKNOWN = 0, RESNAME, CHAINID, ORESNUMS, ICODES, - ATOMNAME, ADDBOND, REMOVEBONDS, SPLITRES }; + ATOMNAME, ADDBOND, REMOVEBONDS, SPLITRES, BONDPARM }; ChangeType type = UNKNOWN; if (argIn.hasKey("resname")) type = RESNAME; @@ -39,6 +42,8 @@ Exec::RetType Exec_Change::Execute(CpptrajState& State, ArgList& argIn) type = ADDBOND; else if (argIn.hasKey("removebonds")) type = REMOVEBONDS; + else if (argIn.hasKey("bondparm")) + type = BONDPARM; else if (argIn.hasKey("splitres")) type = SPLITRES; if (type == UNKNOWN) { @@ -70,6 +75,7 @@ Exec::RetType Exec_Change::Execute(CpptrajState& State, ArgList& argIn) case ATOMNAME : err = ChangeAtomName(*parm, argIn); break; case ADDBOND : err = AddBond(*parm, argIn); break; case REMOVEBONDS : err = RemoveBonds(State, *parm, argIn); break; + case BONDPARM : err = ChangeBondParameters(*parm, argIn); break; case SPLITRES : err = ChangeSplitRes(*parm, argIn); break; case UNKNOWN : err = 1; // sanity check } @@ -433,7 +439,6 @@ int Exec_Change::RemoveBonds(CpptrajState& State, Topology& topIn, ArgList& argI return 0; } - // Exec_Change::AddBond() int Exec_Change::AddBond(Topology& topIn, ArgList& argIn) const { @@ -499,3 +504,91 @@ int Exec_Change::AddBond(Topology& topIn, ArgList& argIn) const { return 0; } + +/** Change/scale bond force constants. */ +int Exec_Change::ChangeBondParameters(Topology& topIn, ArgList& argIn) const { + CharMask mask1, mask2; + std::string str1 = argIn.GetMaskNext(); + if (str1.empty()) { + mprinterr("Error: Must specify at least 1 atom mask.\n"); + return 1; + } + if (mask1.SetMaskString( str1 )) return 1; + if (topIn.SetupCharMask( mask1 )) return 1; + if (mask1.None()) { + mprinterr("Error: %s selects no atoms.\n", str1.c_str()); + return 1; + } + std::string str2 = argIn.GetMaskNext(); + if (!str2.empty()) { + if (mask2.SetMaskString( str2 )) return 1; + if (topIn.SetupCharMask( mask2 )) return 1; + if (mask2.None()) { + mprinterr("Error: %s selects no atoms.\n", str2.c_str()); + return 1; + } + } + // Determine if we are setting or scaling + enum ModeType { SET_RK = 0, SET_REQ, SCALE_RK, SCALE_REQ }; + ModeType mode; + double dval = 0; + if (argIn.Contains("setrk")) { + mode = SET_RK; + dval = argIn.getKeyDouble("setrk", 0); + } else if (argIn.Contains("scalerk")) { + mode = SCALE_RK; + dval = argIn.getKeyDouble("scalerk", 0); + } else if (argIn.Contains("setreq")) { + mode = SET_REQ; + dval = argIn.getKeyDouble("setreq", 0); + } else if (argIn.Contains("scalereq")) { + mode = SCALE_REQ; + dval = argIn.getKeyDouble("scalereq", 0); + } else { + mprinterr("Error: Must specify one of 'setrk', 'scalerk', 'setreq', 'scalereq'.\n"); + return 1; + } + + static const char* ModeTypeStr[] = {"set RK to", "set REQ to", "scale RK by", "scale REQ by"}; + mprintf("\tWill %s %f\n", ModeTypeStr[mode], dval); + + // Get the list of bonds to modify + BondArray bondsToModify; + if (mask2.MaskStringSet()) { + // Atom 1 must be in mask1, atom 2 in mask2 + for (BondArray::const_iterator it = topIn.Bonds().begin(); it != topIn.Bonds().end(); ++it) + if (mask1.AtomInCharMask(it->A1()) && mask2.AtomInCharMask(it->A2())) + bondsToModify.push_back( *it ); + for (BondArray::const_iterator it = topIn.BondsH().begin(); it != topIn.BondsH().end(); ++it) + if (mask1.AtomInCharMask(it->A1()) && mask2.AtomInCharMask(it->A2())) + bondsToModify.push_back( *it ); + } else { + for (BondArray::const_iterator it = topIn.Bonds().begin(); it != topIn.Bonds().end(); ++it) + if (mask1.AtomInCharMask(it->A1()) && mask1.AtomInCharMask(it->A2())) + bondsToModify.push_back( *it ); + for (BondArray::const_iterator it = topIn.BondsH().begin(); it != topIn.BondsH().end(); ++it) + if (mask1.AtomInCharMask(it->A1()) && mask1.AtomInCharMask(it->A2())) + bondsToModify.push_back( *it ); + } + mprintf("\tBonds to modify (%zu):\n", bondsToModify.size()); + for (BondArray::const_iterator it = bondsToModify.begin(); it != bondsToModify.end(); ++it) + mprintf("\t\t%s to %s\n", + topIn.TruncResAtomName( it->A1() ).c_str(), + topIn.TruncResAtomName( it->A2() ).c_str()); + + // Remove, modify, add back. + for (BondArray::const_iterator it = bondsToModify.begin(); it != bondsToModify.end(); ++it) + { + BondParmType bp = topIn.BondParm()[it->Idx()]; + topIn.RemoveBond(it->A1(), it->A2()); + switch (mode) { + case SET_RK : bp.SetRk( dval ); break; + case SCALE_RK : bp.SetRk( bp.Rk() * dval ); break; + case SET_REQ : bp.SetReq( dval ); break; + case SCALE_REQ : bp.SetReq( bp.Req() * dval ); break; + } + topIn.AddBond(it->A1(), it->A2(), bp); + } + + return 0; +} diff --git a/src/Exec_Change.h b/src/Exec_Change.h index 5de0e3452c..3ab3b6dd61 100644 --- a/src/Exec_Change.h +++ b/src/Exec_Change.h @@ -20,5 +20,6 @@ class Exec_Change : public Exec { static inline int FindBondTypeIdx(Topology const&, BondArray const&, TypeNameHolder const&); int AddBond(Topology&, ArgList&) const; int RemoveBonds(CpptrajState&, Topology&, ArgList&) const; + int ChangeBondParameters(Topology&, ArgList&) const; }; #endif diff --git a/src/Exec_CompareEnergy.cpp b/src/Exec_CompareEnergy.cpp new file mode 100644 index 0000000000..5040fb092f --- /dev/null +++ b/src/Exec_CompareEnergy.cpp @@ -0,0 +1,542 @@ +#include +#include // sprintf +#include // std::max +#include "Exec_CompareEnergy.h" +#include "CpptrajStdio.h" +#include "DataSet_double.h" +#include "Energy/Kernel_Fourier.h" +#include "Energy/Kernel_Harmonic.h" +#include "TorsionRoutines.h" + +/** CONSRUCTOR */ +Exec_CompareEnergy::Exec_CompareEnergy() : + Exec(GENERAL), + bondout_(0), + bondDeltaE_(0), + bondDeltaR_(0), + angleout_(0), + angleDeltaE_(0), + angleDeltaR_(0) +{ + SetHidden(true); +} + +// Exec_CompareEnergy::Help() +void Exec_CompareEnergy::Help() const +{ + mprintf("\tcrd0 crd1 \n"); +} + +/** \return COORDINATES set corresponding to setname. */ +DataSet_Coords* Exec_CompareEnergy::GetCoordsSet(DataSetList const& DSL, + std::string const& setname) +{ + if (setname.empty()) { + mprinterr("Error: crdout: Specify COORDS dataset name.\n"); + return 0; + } + DataSet_Coords* CRD = (DataSet_Coords*)DSL.FindSetOfGroup( setname, DataSet::COORDINATES ); + if (CRD == 0) { + mprinterr("Error: crdout: No COORDS set with name %s found.\n", setname.c_str()); + return 0; + } + mprintf("\tUsing set '%s'\n", CRD->legend()); + return CRD; +} + +// ----------------------------------------------------------------------------- +/** Class to hold results from CalcEnergy */ +class Eresults { + public: + Eresults(DataSet_double* deltaE, DataSet_double* deltaR) : E0_(0), E1_(0), deltaE_(deltaE), deltaR_(deltaR) {} + + void Print(CpptrajFile* outfile, const char* header) { + double ermse = sqrt( avgEDelta2_.mean() ); + double rrmse = sqrt( avgRDelta2_.mean() ); + outfile->Printf("#%s E0 = %f\n", header, E0_); + outfile->Printf("#%s E1 = %f\n", header, E1_); + outfile->Printf("#%s = %f\n", header, avgEDelta_.mean()); + outfile->Printf("#%s ene RMSE = %f\n", header, ermse); + outfile->Printf("#%s = %f\n", header, avgRDelta_.mean()); + outfile->Printf("#%s len RMSE = %f\n", header, rrmse); + } + + double E0_; + double E1_; + Stats avgEDelta_; + Stats avgEDelta2_; + Stats avgRDelta_; + Stats avgRDelta2_; + DataSet_double* deltaE_; + DataSet_double* deltaR_; +}; + +/** Compare energies between two frames. */ +template void CalcEnergy( Eresults& result, + CpptrajFile* outfile, + Frame const& frame0, + std::vector const& tarray0, + std::vector

const& parray0, + Frame const& frame1, + std::vector const& tarray1, + std::vector

const& parray1, + std::vector const& names, + double (*fxn)(Frame const&, T const&, P const&, double&) ) +{ + for (unsigned int bidx = 0; bidx != tarray0.size(); bidx++) { + T const& t0 = tarray0[bidx]; + T const& t1 = tarray1[bidx]; + + double r0 = 0; + double r1 = 0; + double ene0 = fxn(frame0, tarray0[bidx], parray0[t0.Idx()], r0); + result.E0_ += ene0; + double ene1 = fxn(frame1, tarray1[bidx], parray1[t1.Idx()], r1); + result.E1_ += ene1; + double edelta = ene1 - ene0; + double rdelta = r1 - r0; + result.deltaE_->AddElement( edelta ); + result.deltaR_->AddElement( rdelta ); + outfile->Printf("%-s %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f\n", + names[bidx].c_str(), + ene0, ene1, edelta, r0, r1, rdelta); + result.avgEDelta_.accumulate( edelta ); + result.avgEDelta2_.accumulate( edelta*edelta ); + result.avgRDelta_.accumulate( rdelta ); + result.avgRDelta2_.accumulate( rdelta*rdelta ); + } +} + +// ----------------------------------------------------------------------------- +/// For calculating non-imaged distance^2 between two xyz points +template T Distance2Kernel(T const* a1, T const* a2) { + T x = a1[0] - a2[0]; + T y = a1[1] - a2[1]; + T z = a1[2] - a2[2]; + //double D = x*x + y*y + z*z; + //fprintf(stdout,"Mask1=%8.3f %8.3f %8.3f Mask2=%8.3f %8.3f %8.3f D=%8.3f\n", + // a1[0],a1[1],a1[2],a2[0],a2[1],a2[2],D); + return (x*x + y*y + z*z); +} + +/// \return Energy for given bond +static inline double EBONDFXN(Frame const& frame0, + BondType const& b0, + BondParmType const& bp0, + double& r0) +{ + if (b0.Idx() < 0) { + mprintf("Warning: Bond %i -- %i has no parameters.\n", b0.A1()+1, b0.A2()+1); + return 0; + } + double r20 = Distance2Kernel( frame0.XYZ(b0.A1()), + frame0.XYZ(b0.A2()) ); + r0 = sqrt(r20); + double ene = Cpptraj::Energy::Kernel_Harmonic( r0, bp0.Rk(), bp0.Req() ); + return ene; +} + +/** Do bond energy comparison. */ +void Exec_CompareEnergy::BondEnergy(Frame const& frame0, Topology const& top0, + Frame const& frame1, Topology const& top1) +const +{ + bondout_->Printf("%-12s %-12s %12s %12s %12s %12s %12s %12s\n", + "#Name0", "Name1", "Ene0", "Ene1", "Edelta", "R0", "R1", "Rdelta"); + + Eresults Ebond(bondDeltaE_, bondDeltaR_); + CalcEnergy(Ebond, bondout_, + frame0, commonBonds0_, top0.BondParm(), + frame1, commonBonds1_, top1.BondParm(), + bondNames_, EBONDFXN); + Ebond.Print( bondout_, "Bond" ); +} + +/** Set up array of selected bonds that top0 and top1 have in common. */ +int Exec_CompareEnergy::SetupBondArray(Topology const& top0, BondArray const& bonds0, BondArray const& bonds1) +{ + char buffer[64]; + if (bonds0.size() != bonds1.size()) { + mprintf("Warning: Different # of bonds (%zu vs %zu)\n", bonds0.size(), bonds1.size()); + return 1; + } + for (unsigned int bidx = 0; bidx != bonds0.size(); bidx++) { + BondType const& b0 = bonds0[bidx]; + BondType const& b1 = bonds1[bidx]; + if ( (b0.A1() != b1.A1()) || (b0.A2() != b1.A2()) ) { + mprintf("Warning: Bond atom # mismatch (%i-%i vs %i-%i)\n", + b0.A1()+1, b0.A2()+1, b1.A1()+1, b1.A2()+1); + continue; + } + if (b0.Idx() < 0) { + mprintf("Warning: No parameters for bond 0\n"); + continue; + } + if (b1.Idx() < 0) { + mprintf("Warning: No paramters for bond 1\n"); + continue; + } + + if ( (mask1_.AtomInCharMask(b0.A1()) && mask2_.AtomInCharMask(b0.A2())) || + (mask1_.AtomInCharMask(b0.A2()) && mask2_.AtomInCharMask(b0.A1())) ) + { + commonBonds0_.push_back( b0 ); + commonBonds1_.push_back( b1 ); + sprintf(buffer, "%-12s %-12s", + top0.TruncResAtomName(b0.A1()).c_str(), + top0.TruncResAtomName(b0.A2()).c_str()); + bondNames_.push_back( std::string(buffer) ); + } + } + + return 0; +} + +/** Set up arrays of selected bonds that top0 and top1 have in common. */ +int Exec_CompareEnergy::SetupBondArrays(Topology const& top0, Topology const& top1) { + commonBonds0_.clear(); + commonBonds1_.clear(); + bondNames_.clear(); + SetupBondArray(top0, top0.Bonds(), top1.Bonds()); + SetupBondArray(top0, top0.BondsH(), top1.BondsH()); + if (commonBonds0_.empty()) { + mprinterr("Error: No bonds in common.\n"); + return 1; + } + return 0; +} + +// ----------------------------------------------------------------------------- +/// \return Energy for given angle +static inline double EANGFXN(Frame const& frame0, + AngleType const& b0, + AngleParmType const& bp0, + double& r0) +{ + if (b0.Idx() < 0) { + mprintf("Warning: Angle %i -- %i -- %i has no parameters.\n", b0.A1()+1, b0.A2()+1, b0.A3()+1); + return 0; + } + double theta = CalcAngle( frame0.XYZ(b0.A1()), + frame0.XYZ(b0.A2()), + frame0.XYZ(b0.A3()) ); + double ene = Cpptraj::Energy::Kernel_Harmonic( theta, bp0.Tk(), bp0.Teq() ); + return ene; +} + +/** Do angle energy comparison. */ +void Exec_CompareEnergy::AngleEnergy(Frame const& frame0, Topology const& top0, + Frame const& frame1, Topology const& top1) +const +{ + angleout_->Printf("%-12s %-12s %-12s %12s %12s %12s %12s %12s %12s\n", + "#Name0", "Name1", "Name2", "Ene0", "Ene1", "Edelta", "R0", "R1", "Rdelta"); + + Eresults Eangle(angleDeltaE_, angleDeltaR_); + CalcEnergy(Eangle, angleout_, + frame0, commonAngles0_, top0.AngleParm(), + frame1, commonAngles1_, top1.AngleParm(), + angleNames_, EANGFXN); + Eangle.Print( angleout_, "Angle" ); +} + +/** Set up array of selected angles that top0 and top1 have in common. */ +int Exec_CompareEnergy::SetupAngleArray(Topology const& top0, AngleArray const& angles0, AngleArray const& angles1) +{ + char buffer[64]; + if (angles0.size() != angles1.size()) { + mprintf("Warning: Different # of angles (%zu vs %zu)\n", angles0.size(), angles1.size()); + return 1; + } + for (unsigned int bidx = 0; bidx != angles0.size(); bidx++) { + AngleType const& b0 = angles0[bidx]; + AngleType const& b1 = angles1[bidx]; + if ( (b0.A1() != b1.A1()) || (b0.A2() != b1.A2()) || (b0.A3() != b1.A3()) ) { + mprintf("Warning: Angle atom # mismatch (%i-%i-%i vs %i-%i-%i)\n", + b0.A1()+1, b0.A2()+1, b0.A3()+1, b1.A1()+1, b1.A2()+1, b1.A3()+1); + continue; + } + if (b0.Idx() < 0) { + mprintf("Warning: No parameters for angle 0\n"); + continue; + } + if (b1.Idx() < 0) { + mprintf("Warning: No paramters for angle 1\n"); + continue; + } + + if ( (mask1_.AtomInCharMask(b0.A1()) && mask2_.AtomInCharMask(b0.A2()) && mask3_.AtomInCharMask(b0.A3())) || + (mask1_.AtomInCharMask(b0.A3()) && mask2_.AtomInCharMask(b0.A2()) && mask3_.AtomInCharMask(b0.A1())) ) + { + commonAngles0_.push_back( b0 ); + commonAngles1_.push_back( b1 ); + sprintf(buffer, "%-12s %-12s %-12s", + top0.TruncResAtomName(b0.A1()).c_str(), + top0.TruncResAtomName(b0.A2()).c_str(), + top0.TruncResAtomName(b0.A3()).c_str()); + angleNames_.push_back( std::string(buffer) ); + } + } + + return 0; +} + +/** Set up arrays of selected angles that top0 and top1 have in common. */ +int Exec_CompareEnergy::SetupAngleArrays(Topology const& top0, Topology const& top1) { + commonAngles0_.clear(); + commonAngles1_.clear(); + angleNames_.clear(); + SetupAngleArray(top0, top0.Angles(), top1.Angles()); + SetupAngleArray(top0, top0.AnglesH(), top1.AnglesH()); + if (commonAngles0_.empty()) { + mprinterr("Error: No angles in common.\n"); + return 1; + } + return 0; +} + +// ----------------------------------------------------------------------------- +/// \return Energy for given dihedral +static inline double EDIHFXN(Frame const& frame0, + DihedralType const& b0, + DihedralParmType const& bp0, + double& r0) +{ + if (b0.Idx() < 0) { + mprintf("Warning: Dihedral %i -- %i -- %i -- %i has no parameters.\n", b0.A1()+1, b0.A2()+1, b0.A3()+1, b0.A4()+1); + return 0; + } + double theta = Torsion( frame0.XYZ(b0.A1()), + frame0.XYZ(b0.A2()), + frame0.XYZ(b0.A3()), + frame0.XYZ(b0.A4()) ); + double ene = Cpptraj::Energy::Kernel_Fourier( theta, bp0.Pk(), bp0.Pn(), bp0.Phase() ); + return ene; +} + +/** Do dihedral energy comparison. */ +void Exec_CompareEnergy::DihedralEnergy(Frame const& frame0, Topology const& top0, + Frame const& frame1, Topology const& top1) +const +{ + angleout_->Printf("%-12s %-12s %-12s %-12s %12s %12s %12s %12s %12s %12s\n", + "#Name0", "Name1", "Name2", "Name3", "Ene0", "Ene1", "Edelta", "R0", "R1", "Rdelta"); + + Eresults Edihedral(dihedralDeltaE_, dihedralDeltaR_); + CalcEnergy(Edihedral, dihedralout_, + frame0, commonDihedrals0_, top0.DihedralParm(), + frame1, commonDihedrals1_, top1.DihedralParm(), + dihedralNames_, EDIHFXN); + Edihedral.Print( dihedralout_, "Dihedral" ); +} + +/** Set up array of selected dihedrals that top0 and top1 have in common. */ +int Exec_CompareEnergy::SetupDihedralArray(Topology const& top0, DihedralArray const& dihedrals0, DihedralArray const& dihedrals1) +{ + char buffer[64]; + if (dihedrals0.size() != dihedrals1.size()) { + mprintf("Warning: Different # of dihedrals (%zu vs %zu)\n", dihedrals0.size(), dihedrals1.size()); + return 1; + } + for (unsigned int bidx = 0; bidx != dihedrals0.size(); bidx++) { + DihedralType const& b0 = dihedrals0[bidx]; + DihedralType const& b1 = dihedrals1[bidx]; + if ( (b0.A1() != b1.A1()) || (b0.A2() != b1.A2()) || (b0.A3() != b1.A3()) || (b0.A4() != b1.A4()) ) { + mprintf("Warning: Dihedral atom # mismatch (%i-%i-%i-%i vs %i-%i-%i-%i)\n", + b0.A1()+1, b0.A2()+1, b0.A3()+1, b0.A4()+1, + b1.A1()+1, b1.A2()+1, b1.A3()+1, b1.A4()+1); + continue; + } + if (b0.Idx() < 0) { + mprintf("Warning: No parameters for dihedral 0\n"); + continue; + } + if (b1.Idx() < 0) { + mprintf("Warning: No paramters for dihedral 1\n"); + continue; + } + + if ( (mask1_.AtomInCharMask(b0.A1()) && mask2_.AtomInCharMask(b0.A2()) && mask3_.AtomInCharMask(b0.A3()) && mask4_.AtomInCharMask(b0.A4())) || + (mask1_.AtomInCharMask(b0.A4()) && mask2_.AtomInCharMask(b0.A3()) && mask3_.AtomInCharMask(b0.A2()) && mask4_.AtomInCharMask(b0.A1())) ) + { + commonDihedrals0_.push_back( b0 ); + commonDihedrals1_.push_back( b1 ); + sprintf(buffer, "%-12s %-12s %-12s %-12s", + top0.TruncResAtomName(b0.A1()).c_str(), + top0.TruncResAtomName(b0.A2()).c_str(), + top0.TruncResAtomName(b0.A3()).c_str(), + top0.TruncResAtomName(b0.A4()).c_str()); + dihedralNames_.push_back( std::string(buffer) ); + } + } + + return 0; +} + +/** Set up arrays of selected dihedrals that top0 and top1 have in common. */ +int Exec_CompareEnergy::SetupDihedralArrays(Topology const& top0, Topology const& top1) { + commonDihedrals0_.clear(); + commonDihedrals1_.clear(); + dihedralNames_.clear(); + SetupDihedralArray(top0, top0.Dihedrals(), top1.Dihedrals()); + SetupDihedralArray(top0, top0.DihedralsH(), top1.DihedralsH()); + if (commonDihedrals0_.empty()) { + mprinterr("Error: No dihedrals in common.\n"); + return 1; + } + return 0; +} + + + +// ----------------------------------------------------------------------------- +/** Compare energies between two coords sets. */ +int Exec_CompareEnergy::GetEnergies(DataSet_Coords* crd0, DataSet_Coords* crd1) +const +{ + if (crd0->Size() < 1) { + mprinterr("Error: '%s' has no frames.\n", crd0->legend()); + return 1; + } + if (crd1->Size() < 1) { + mprinterr("Error: '%s' has no frames.\n", crd1->legend()); + return 1; + } + + Frame frame0 = crd0->AllocateFrame(); + Frame frame1 = crd1->AllocateFrame(); + Topology const& top0 = crd0->Top(); + Topology const& top1 = crd1->Top(); + + unsigned int maxframes = std::max( crd0->Size(), crd1->Size() ); + unsigned int idx0 = 0; + unsigned int idx1 = 0; + for (unsigned int idx = 0; idx != maxframes; idx++) { + crd0->GetFrame( idx0++, frame0 ); + crd1->GetFrame( idx1++, frame1 ); + + BondEnergy(frame0, top0, frame1, top1); + AngleEnergy(frame0, top0, frame1, top1); + DihedralEnergy(frame0, top0, frame1, top1); + + // Reset counters if needed + if (idx0 == crd0->Size()) + idx0 = 0; + if (idx1 == crd1->Size()) + idx1 = 0; + } + + return 0; +} + +// Exec_CompareEnergy::Execute() +Exec::RetType Exec_CompareEnergy::Execute(CpptrajState& State, ArgList& argIn) +{ + DataSet_Coords* crd0 = GetCoordsSet(State.DSL(), argIn.GetStringKey("crd0")); + if (crd0 == 0) return CpptrajState::ERR; + DataSet_Coords* crd1 = GetCoordsSet(State.DSL(), argIn.GetStringKey("crd1")); + if (crd1 == 0) return CpptrajState::ERR; + + bondout_ = State.DFL().AddCpptrajFile( argIn.GetStringKey("bondout"), + "bond comparison", + DataFileList::TEXT, + true ); + if (bondout_ == 0) { + mprinterr("Internal Error: Could not allocate bond comparison file.\n"); + return CpptrajState::ERR; + } + angleout_ = State.DFL().AddCpptrajFile( argIn.GetStringKey("angleout"), + "angle comparison", + DataFileList::TEXT, + true ); + if (angleout_ == 0) { + mprinterr("Internal Error: Could not allocate angle comparison file.\n"); + return CpptrajState::ERR; + } + dihedralout_ = State.DFL().AddCpptrajFile( argIn.GetStringKey("dihedralout"), + "dihedral comparison", + DataFileList::TEXT, + true ); + if (dihedralout_ == 0) { + mprinterr("Internal Error: Could not allocate dihedral comparison file.\n"); + return CpptrajState::ERR; + } + + std::string dsname = argIn.GetStringKey("name"); + if (dsname.empty()) + dsname = State.DSL().GenerateDefaultName("ECOMPARE"); + bondDeltaE_ = (DataSet_double*)State.DSL().AddSet(DataSet::DOUBLE, MetaData(dsname, "bondedelta")); + if (bondDeltaE_ == 0) return CpptrajState::ERR; + mprintf("\tBond energy delta set: %s\n", bondDeltaE_->legend()); + bondDeltaR_ = (DataSet_double*)State.DSL().AddSet(DataSet::DOUBLE, MetaData(dsname, "bondrdelta")); + if (bondDeltaR_ == 0) return CpptrajState::ERR; + mprintf("\tBond length delta set: %s\n", bondDeltaR_->legend()); + angleDeltaE_ = (DataSet_double*)State.DSL().AddSet(DataSet::DOUBLE, MetaData(dsname, "angleedelta")); + if (angleDeltaE_ == 0) return CpptrajState::ERR; + mprintf("\tAngle energy delta set: %s\n", angleDeltaE_->legend()); + angleDeltaR_ = (DataSet_double*)State.DSL().AddSet(DataSet::DOUBLE, MetaData(dsname, "anglerdelta")); + if (angleDeltaR_ == 0) return CpptrajState::ERR; + mprintf("\tAngle length delta set: %s\n", angleDeltaR_->legend()); + dihedralDeltaE_ = (DataSet_double*)State.DSL().AddSet(DataSet::DOUBLE, MetaData(dsname, "dihedraledelta")); + if (dihedralDeltaE_ == 0) return CpptrajState::ERR; + mprintf("\tDihedral energy delta set: %s\n", dihedralDeltaE_->legend()); + dihedralDeltaR_ = (DataSet_double*)State.DSL().AddSet(DataSet::DOUBLE, MetaData(dsname, "dihedralrdelta")); + if (dihedralDeltaR_ == 0) return CpptrajState::ERR; + mprintf("\tDihedral length delta set: %s\n", dihedralDeltaR_->legend()); + + mask1_.SetMaskString( argIn.GetStringKey("mask1") ); + mask2_.SetMaskString( argIn.GetStringKey("mask2") ); + mask3_.SetMaskString( argIn.GetStringKey("mask3") ); + mask4_.SetMaskString( argIn.GetStringKey("mask4") ); + + mprintf("\tMask 1: %s\n", mask1_.MaskString()); + mprintf("\tMask 2: %s\n", mask2_.MaskString()); + mprintf("\tMask 3: %s\n", mask3_.MaskString()); + mprintf("\tMask 4: %s\n", mask4_.MaskString()); + + if (crd0->Top().SetupCharMask( mask1_ )) { + mprinterr("Error: Setting up mask '%s' failed.\n", mask1_.MaskString()); + return CpptrajState::ERR; + } + if (mask1_.None()) { + mprinterr("Error: No atoms selected by '%s'\n", mask1_.MaskString()); + return CpptrajState::ERR; + } + if (crd0->Top().SetupCharMask( mask2_ )) { + mprinterr("Error: Setting up mask '%s' failed.\n", mask2_.MaskString()); + return CpptrajState::ERR; + } + if (mask2_.None()) { + mprinterr("Error: No atoms selected by '%s'\n", mask2_.MaskString()); + return CpptrajState::ERR; + } + if (crd0->Top().SetupCharMask( mask3_ )) { + mprinterr("Error: Setting up mask '%s' failed.\n", mask3_.MaskString()); + return CpptrajState::ERR; + } + if (mask3_.None()) { + mprinterr("Error: No atoms selected by '%s'\n", mask3_.MaskString()); + return CpptrajState::ERR; + } + if (crd0->Top().SetupCharMask( mask4_ )) { + mprinterr("Error: Setting up mask '%s' failed.\n", mask4_.MaskString()); + return CpptrajState::ERR; + } + if (mask4_.None()) { + mprinterr("Error: No atoms selected by '%s'\n", mask4_.MaskString()); + return CpptrajState::ERR; + } + + mask1_.MaskInfo(); + mask2_.MaskInfo(); + mask3_.MaskInfo(); + mask4_.MaskInfo(); + + if (SetupBondArrays(crd0->Top(), crd1->Top())) return CpptrajState::ERR; + if (SetupAngleArrays(crd0->Top(), crd1->Top())) return CpptrajState::ERR; + if (SetupDihedralArrays(crd0->Top(), crd1->Top())) return CpptrajState::ERR; + + if (GetEnergies(crd0, crd1)) return CpptrajState::ERR; + + return CpptrajState::OK; +} diff --git a/src/Exec_CompareEnergy.h b/src/Exec_CompareEnergy.h new file mode 100644 index 0000000000..332e9334e8 --- /dev/null +++ b/src/Exec_CompareEnergy.h @@ -0,0 +1,63 @@ +#ifndef INC_EXEC_COMPAREENERGY_H +#define INC_EXEC_COMPAREENERGY_H +#include "Exec.h" +#include "CharMask.h" +#include "OnlineVarT.h" +class DataSet_double; +/// +class Exec_CompareEnergy : public Exec { + public: + Exec_CompareEnergy(); + void Help() const; + DispatchObject* Alloc() const { return (DispatchObject*)new Exec_CompareEnergy(); } + RetType Execute(CpptrajState&, ArgList&); + private: + typedef std::vector Sarray; + + static DataSet_Coords* GetCoordsSet(DataSetList const&, std::string const&); + + void BondEnergy(Frame const&, Topology const&, + Frame const&, Topology const&) const; + int SetupBondArray(Topology const&, BondArray const&, BondArray const&); + int SetupBondArrays(Topology const&, Topology const&); + + void AngleEnergy(Frame const&, Topology const&, + Frame const&, Topology const&) const; + int SetupAngleArray(Topology const&, AngleArray const&, AngleArray const&); + int SetupAngleArrays(Topology const&, Topology const&); + + void DihedralEnergy(Frame const&, Topology const&, + Frame const&, Topology const&) const; + int SetupDihedralArray(Topology const&, DihedralArray const&, DihedralArray const&); + int SetupDihedralArrays(Topology const&, Topology const&); + + int GetEnergies(DataSet_Coords*, DataSet_Coords*) const; + + CharMask mask1_; + CharMask mask2_; + CharMask mask3_; + CharMask mask4_; + + CpptrajFile* bondout_; + DataSet_double* bondDeltaE_; + DataSet_double* bondDeltaR_; + BondArray commonBonds0_; + BondArray commonBonds1_; + Sarray bondNames_; + + CpptrajFile* angleout_; + DataSet_double* angleDeltaE_; + DataSet_double* angleDeltaR_; + AngleArray commonAngles0_; + AngleArray commonAngles1_; + Sarray angleNames_; + + CpptrajFile* dihedralout_; + DataSet_double* dihedralDeltaE_; + DataSet_double* dihedralDeltaR_; + DihedralArray commonDihedrals0_; + DihedralArray commonDihedrals1_; + Sarray dihedralNames_; + +}; +#endif diff --git a/src/Exec_DataSetCmd.cpp b/src/Exec_DataSetCmd.cpp index 8e29896c1d..28d559b36b 100644 --- a/src/Exec_DataSetCmd.cpp +++ b/src/Exec_DataSetCmd.cpp @@ -29,7 +29,7 @@ void Exec_DataSetCmd::Help(ArgList& argIn) const { " Extract X, Y, or Z component of vector data into new set.\n"); } else if (argIn.hasKey("cat")) { mprintf(" cat ... [name ] [nooffset]\n" - " Concatenate 2 or more data sets.\n"); + " Concatenate 2 or more data sets. Currently only scalar 1D and string sets are supported.\n"); } else if (argIn.hasKey("make2d")) { mprintf(" make2d <1D set> cols rows [name ]\n" " Create new 2D data set from 1D data set, assumes row-major ordering.\n"); @@ -701,37 +701,85 @@ Exec::RetType Exec_DataSetCmd::Filter(CpptrajState& State, ArgList& argIn) { Exec::RetType Exec_DataSetCmd::Concatenate(CpptrajState& State, ArgList& argIn) { std::string name = argIn.GetStringKey("name"); bool use_offset = !argIn.hasKey("nooffset"); - DataSet* ds3 = State.DSL().AddSet( DataSet::XYMESH, name, "CAT" ); - if (ds3 == 0) return CpptrajState::ERR; - DataSet_1D& out = static_cast( *ds3 ); - mprintf("\tConcatenating sets into '%s'\n", out.legend()); - if (use_offset) - mprintf("\tX values will be offset.\n"); - else - mprintf("\tX values will not be offset.\n"); + + std::vector setsToCat; + enum OutputSetTypeEnum { UNKNOWN = 0, SCALAR_1D, STRING }; + static const char* OutputSetTypeStr[] = { 0, "scalar 1D", "string" }; + OutputSetTypeEnum outputSetType = UNKNOWN; std::string dsarg = argIn.GetStringNext(); - double offset = 0.0; + while (!dsarg.empty()) { DataSetList dsl = State.DSL().GetMultipleSets( dsarg ); - double XY[2]; - for (DataSetList::const_iterator ds = dsl.begin(); ds != dsl.end(); ++ds) - { - if ( (*ds)->Group() != DataSet::SCALAR_1D ) - { - mprintf("Warning: '%s': Concatenation only supported for 1D scalar data sets.\n", - (*ds)->legend()); + for (DataSetList::const_iterator ds = dsl.begin(); ds != dsl.end(); ++ds) { + // Check the type + OutputSetTypeEnum currentType = UNKNOWN; + if ( (*ds)->Group() == DataSet::SCALAR_1D ) + currentType = SCALAR_1D; + else if ( (*ds)->Type() == DataSet::STRING ) + currentType = STRING; + if (outputSetType == UNKNOWN) { + if (currentType == UNKNOWN) { + mprinterr("Error: '%s' concatenation only supported for scalar 1D or string sets.\n", (*ds)->legend()); + return CpptrajState::ERR; + } + outputSetType = currentType; } else { - DataSet_1D const& set = static_cast( *(*ds) ); - mprintf("\t\t'%s'\n", set.legend()); - for (size_t i = 0; i != set.Size(); i++) { - XY[0] = set.Xcrd( i ) + offset; - XY[1] = set.Dval( i ); - out.Add( i, XY ); // NOTE: value of i does not matter for mesh + // Type must match + if (outputSetType != currentType) { + mprinterr("Error: '%s' all sets must be of the same type.\n", (*ds)->legend()); + return CpptrajState::ERR; } - if (use_offset) offset = XY[0]; } + setsToCat.push_back( *ds ); } dsarg = argIn.GetStringNext(); + } // END loop over data set arguments from argument list + + DataSet* ds3 = 0; + if (outputSetType == SCALAR_1D) + ds3 = State.DSL().AddSet( DataSet::XYMESH, name, "CAT" ); + else if (outputSetType == STRING) + ds3 = State.DSL().AddSet( DataSet::STRING, name, "CAT" ); + else { + mprinterr("Error: No valid sets to concatenate.\n"); + return CpptrajState::ERR; + } + if (ds3 == 0) return CpptrajState::ERR; + mprintf("\tConcatenating %zu sets into %s set '%s'\n", setsToCat.size(), OutputSetTypeStr[outputSetType], ds3->legend()); + + if (outputSetType == SCALAR_1D) { + DataSet_1D& out = static_cast( *ds3 ); + + if (use_offset) + mprintf("\tX values will be offset.\n"); + else + mprintf("\tX values will not be offset.\n"); + double offset = 0.0; + double XY[2]; + for (std::vector::const_iterator ds = setsToCat.begin(); ds != setsToCat.end(); ++ds) + { + DataSet_1D const& set = static_cast( *(*ds) ); + mprintf("\t\t'%s'\n", set.legend()); + for (size_t i = 0; i != set.Size(); i++) { + XY[0] = set.Xcrd( i ) + offset; + XY[1] = set.Dval( i ); + out.Add( i, XY ); // NOTE: value of i does not matter for mesh + } + if (use_offset) offset = XY[0]; + } // END loop over input 1D scalar sets + } else if (outputSetType == STRING) { + DataSet_string& out = static_cast( *ds3 ); + for (std::vector::const_iterator ds = setsToCat.begin(); ds != setsToCat.end(); ++ds) + { + DataSet_string const& set = static_cast( *(*ds) ); + mprintf("\t\t'%s'\n", set.legend()); + for (size_t i = 0; i != set.Size(); i++) + out.AddElement( set[i] ); + } // END loop over input string sets + } else { + // Sanity check + mprinterr("Internal Error: Unhandled set type in data set concatenation.\n"); + return CpptrajState::ERR; } return CpptrajState::OK; } diff --git a/src/Exec_LoadCrd.cpp b/src/Exec_LoadCrd.cpp index eb4193d77a..ba688c01de 100644 --- a/src/Exec_LoadCrd.cpp +++ b/src/Exec_LoadCrd.cpp @@ -4,7 +4,8 @@ void Exec_LoadCrd::Help() const { mprintf("\t [%s] [] [name ]\n", DataSetList::TopArgs); - mprintf(" Load trajectory as a COORDS data set named (default ).\n"); + mprintf("\t[prec {single|double}]\n"); + mprintf(" Load trajectory as a COORDS/FRAMES data set named (default ).\n"); } Exec::RetType Exec_LoadCrd::Execute(CpptrajState& State, ArgList& argIn) { @@ -14,6 +15,19 @@ Exec::RetType Exec_LoadCrd::Execute(CpptrajState& State, ArgList& argIn) { mprinterr("Error: loadcrd: No parm files loaded.\n"); return CpptrajState::ERR; } + // Get desired precision + DataSet::DataType setType = DataSet::COORDS; + std::string precArg = argIn.GetStringKey("prec"); + if (!precArg.empty()) { + if (precArg == "single") + setType = DataSet::COORDS; + else if (precArg == "double") + setType = DataSet::FRAMES; + else { + mprinterr("Error: Invalid arg for prec '%s'\n", precArg.c_str()); + return CpptrajState::ERR; + } + } // Load trajectory Trajin_Single trajin; trajin.SetDebug( State.Debug() ); @@ -31,33 +45,35 @@ Exec::RetType Exec_LoadCrd::Execute(CpptrajState& State, ArgList& argIn) { MetaData md( trajin.Traj().Filename(), setname, -1 ); // Check if set already present DataSet_Coords* coords = 0; - DataSet* ds = State.DSL().FindSetOfType( setname, DataSet::COORDS ); + DataSet* ds = State.DSL().FindSetOfGroup( setname, DataSet::COORDINATES ); if (ds == 0) { // Create Set - coords = (DataSet_Coords*)State.DSL().AddSet(DataSet::COORDS, md); + coords = (DataSet_Coords*)State.DSL().AddSet(setType, md); if (coords == 0) { - mprinterr("Error: loadcrd: Could not set up COORDS data set.\n"); + mprinterr("Error: loadcrd: Could not set up %s data set.\n", DataSet::description(setType)); return CpptrajState::ERR; } coords->CoordsSetup( *parm, trajin.TrajCoordInfo() ); mprintf("\tLoading trajectory '%s' as '%s'\n", trajin.Traj().Filename().full(), coords->legend()); } else { - // Check that set is actually coords. - if (ds->Type() != DataSet::COORDS) { - mprinterr("Error: Set %s present but is not of type COORDS.\n", ds->legend()); + // Check that set type matches. + if (ds->Type() != setType) { + mprinterr("Error: Set %s present but is not of type '%s'.\n", + ds->legend(), DataSet::description(setType)); return CpptrajState::ERR; } coords = (DataSet_Coords*)ds; // Check that topology matches. For now just check # atoms. if (parm->Natom() != coords->Top().Natom()) { - mprinterr("Error: Trajectory '%s' # atoms %i does not match COORDS data set '%s' (%i)\n", + mprinterr("Error: Trajectory '%s' # atoms %i does not match %s data set '%s' (%i)\n", trajin.Traj().Filename().full(), parm->Natom(), + DataSet::description(setType), coords->legend(), coords->Top().Natom()); return CpptrajState::ERR; } - mprintf("\tAppending trajectory '%s' to COORDS data set '%s'\n", - trajin.Traj().Filename().full(), coords->legend()); + mprintf("\tAppending trajectory '%s' to %s data set '%s'\n", + trajin.Traj().Filename().full(), DataSet::description(setType), coords->legend()); } // Read trajectory TODO progress bar trajin.BeginTraj(); diff --git a/src/FileIO_Gzip.cpp b/src/FileIO_Gzip.cpp index 3153445b1f..da10d1f245 100644 --- a/src/FileIO_Gzip.cpp +++ b/src/FileIO_Gzip.cpp @@ -19,7 +19,7 @@ FileIO_Gzip::~FileIO_Gzip() { int FileIO_Gzip::Open(const char *filename, const char *mode) { if (filename == 0) return 1; fp_ = gzopen(filename, mode); - if (fp_==NULL) return 1; + if (fp_ == NULL) return 1; // Set gzip buffer size //if ( gzbuffer(fp_, GZ_BUF_SIZE)!=0 ) return 1; return 0; @@ -27,8 +27,9 @@ int FileIO_Gzip::Open(const char *filename, const char *mode) { // FileIO_Gzip::Close() int FileIO_Gzip::Close() { - if (fp_!=NULL) gzclose(fp_); - fp_=NULL; + if (fp_ != NULL) + gzclose(fp_); + fp_ = NULL; return 0; } @@ -80,13 +81,24 @@ off_t FileIO_Gzip::Size(const char *filename) { // FileIO_Gzip::Read() // NOTE: gzread returns 0 on EOF, -1 on error int FileIO_Gzip::Read(void *buffer, size_t num_bytes) { - return (gzread(fp_, buffer, num_bytes)); + int n_bytes_read = gzread(fp_, buffer, num_bytes); + if (n_bytes_read < 1) { + int gzerr = 0; + const char* gzerrmsg = gzerror(fp_, &gzerr); + mprinterr("Internal Error: FileIO_Gzip::Read: %s\n", gzerrmsg); + } + return n_bytes_read; } // FileIO_Gzip::Write() int FileIO_Gzip::Write(const void *buffer, size_t num_bytes) { - if ( gzwrite(fp_, buffer, num_bytes)==0 ) return 1; - // NOTE: Check for errors here. + int n_bytes_written = gzwrite(fp_, buffer, num_bytes); + if ((size_t)n_bytes_written != num_bytes) { + int gzerr = 0; + const char* gzerrmsg = gzerror(fp_, &gzerr); + mprinterr("Internal Error: FileIO_Gzip::Write: %s\n", gzerrmsg); + return 1; + } return 0; } @@ -95,14 +107,22 @@ int FileIO_Gzip::Seek(off_t offset) { z_off_t zipOffset; //if (origin == SEEK_END) return 1; - zipOffset=(z_off_t) offset; - if ( gzseek(fp_, zipOffset, SEEK_SET) < 0) return 1; + zipOffset = (z_off_t)offset; + z_off_t uncompressed_pos = gzseek(fp_, zipOffset, SEEK_SET); + if (uncompressed_pos < 0) { + mprinterr("Internal Error: FileIO_Gzip::Seek failed, offset = %li\n", (long int)offset); + return 1; + } return 0; } // FileIO_Gzip::Rewind() int FileIO_Gzip::Rewind() { - gzrewind(fp_); + int err = gzrewind(fp_); + if (err < 0) { + mprinterr("Internal Error: FileIO_Gzip::Rewind failed.\n"); + return 1; + } return 0; } @@ -116,9 +136,16 @@ off_t FileIO_Gzip::Tell() { // FileIO_Gzip::Gets() int FileIO_Gzip::Gets(char *str, int num) { - if ( gzgets(fp_,str,num) == NULL ) + char* pos = gzgets(fp_, str, num); + // Null can mean EOF or error + if ( pos == Z_NULL ) { + int gzerr = 0; + const char* gzerrmsg = gzerror(fp_, &gzerr); + if (gzerr != 0) { + mprinterr("Internal Error: FileIO_Gzip::Gets: (%i) %s\n", gzerr, gzerrmsg); + } return 1; - else - return 0; + } + return 0; } #endif diff --git a/src/NC_Routines.cpp b/src/NC_Routines.cpp index fde9a918b9..27a33fd206 100644 --- a/src/NC_Routines.cpp +++ b/src/NC_Routines.cpp @@ -19,23 +19,53 @@ bool NC::CheckErr(int ncerr) { std::string NC::GetAttrText(int ncid, int vid, const char* attribute) { size_t attlen; std::string attrOut; - // Get attr length - if ( CheckErr(nc_inq_attlen(ncid, vid, attribute, &attlen)) ) { - mprintf("Warning: Getting length for attribute '%s'\n",attribute); + // Get attr length. Make this fail silently. + int ncerr = nc_inq_attlen(ncid, vid, attribute, &attlen); + if (ncerr != NC_NOERR) + return attrOut; + // Check attribute type + int xtypep = -1; + if ( CheckErr(nc_inq_atttype(ncid, vid, attribute, &xtypep)) ) { + mprintf("Warning: Problem getting attribute type for '%s'\n", attribute); return attrOut; } - // Allocate space for attr text, plus one for null char - char *attrText = new char[ (attlen + 1) ]; + //mprintf("DEBUG: Attribute %s type %i\n", attribute, xtypep); + // Get attr text - if ( CheckErr(nc_get_att_text(ncid, vid, attribute, attrText)) ) { - mprintf("Warning: Getting attribute text for '%s'\n",attribute); + if ( xtypep == NC_CHAR ) { + // Allocate space for attr text, plus one for null char + char *attrText = new char[ (attlen + 1) ]; + if ( CheckErr(nc_get_att_text(ncid, vid, attribute, attrText)) ) { + mprintf("Warning: Problem getting attribute text for '%s'\n", attribute); + delete[] attrText; + return attrOut; + } + // Append null char - NECESSARY? + attrText[attlen]='\0'; + attrOut.assign( attrText ); delete[] attrText; + } else if ( xtypep == NC_STRING ) { +# ifdef HAS_HDF5 + if (attlen > 1) { + mprinterr("Error: Variable attribute %s has %zu strings, expected only 1.\n", + attribute, attlen); + return attrOut; + } + char* attrString; + if ( CheckErr(nc_get_att_string(ncid, vid, attribute, &attrString)) ) { + mprintf("Warning: Problem getting attribute string for '%s'\n", attribute); + return attrOut; + } + attrOut.assign( attrString ); + nc_free_string(attlen, &attrString); +# else + mprinterr("Internal Error: Attribute type 'string' only supported with NetCDF4/HDF5.\n" + "Internal Error: Recompile with Netcdf4/HDF5 support.\n"); +# endif + } else { + mprinterr("Error: Attribute %s has unhandled type.\n", attribute); return attrOut; } - // Append null char - NECESSARY? - attrText[attlen]='\0'; - attrOut.assign( attrText ); - delete[] attrText; return attrOut; } @@ -96,6 +126,16 @@ void NC::Debug(int ncid) { ndimsp, nvarsp, ngattsp, unlimdimidp); else mprintf("NETCDF Error occurred.\n"); + // Print name of each dimension defined in netcdf file + mprintf("NC DIMS:\n"); + for (int i = 0; i < ndimsp; i++) { + err = nc_inq_dimname(ncid, i, varname); + mprintf(" Dim %i - ", i); + if (err == NC_NOERR) + mprintf("%s\n", varname); + else + mprintf("NETCDF Error occured.\n"); + } // Print name of each variable defined in netcdf file mprintf("NC VARIABLES:\n"); for (int i = 0; i < nvarsp; i++) { @@ -108,4 +148,40 @@ void NC::Debug(int ncid) { } mprintf("========== END NETCDF DEBUG ==========\n"); } -#endif + +// ----- NetCDF4/HDF5 routines ------------------------------------------------- +#ifdef HAS_HDF5 +/** \return Array containing group names. Also set array with corresponding ncids. */ +std::vector NC::GetGroupNames(int ncid, std::vector& NcidArray) { + std::vector GroupNames; + int numgrps; + nc_inq_grps( ncid, &numgrps, NULL ); + if (numgrps < 1) + return GroupNames; + + //mprintf("DEBUG: Netcdf file contains %i groups.\n", numgrps); + GroupNames.reserve( numgrps ); + NcidArray.assign( numgrps, -1 ); + int* ncids = &NcidArray[0]; + nc_inq_grps( ncid, NULL, ncids ); + for (int ii = 0; ii < numgrps; ii++) { + //mprintf("\tncid %i", ncids[ii]); + size_t gnamelen; + nc_inq_grpname_len( ncids[ii], &gnamelen ); + char* gname = new char[ gnamelen+1 ]; + nc_inq_grpname( ncids[ii], gname ); + //mprintf(" %s\n", gname); + GroupNames.push_back( gname ); + delete[] gname; + } + return GroupNames; +} + +/** \return Array containing group names. */ +std::vector NC::GetGroupNames(int ncid) { + std::vector NcidArray; + return GetGroupNames(ncid, NcidArray); +} +#endif /* HAS_HDF5 */ +// ----------------------------------------------------------------------------- +#endif /* BINTRAJ */ diff --git a/src/NC_Routines.h b/src/NC_Routines.h index 5987fa9fc3..1f9943451d 100644 --- a/src/NC_Routines.h +++ b/src/NC_Routines.h @@ -2,6 +2,7 @@ #define INC_NC_ROUTINES_H #ifdef BINTRAJ #include +#include namespace NC { /// \return true if given code is error and print message, false otherwise. bool CheckErr(int); @@ -15,6 +16,12 @@ namespace NC { int GetDimInfo(int, const char*, int&); /// Print debug info to STDOUT void Debug(int); +# ifdef HAS_HDF5 + /// \return Array of group names, set array with ncids + std::vector GetGroupNames(int, std::vector&); + /// \return Array of group names + std::vector GetGroupNames(int); +# endif } #endif /* BINTRAJ */ #endif diff --git a/src/NetcdfFile.cpp b/src/NetcdfFile.cpp index ac6ccdf47b..d26508c9c9 100644 --- a/src/NetcdfFile.cpp +++ b/src/NetcdfFile.cpp @@ -1,19 +1,60 @@ +#include // FILE, fopen, fclose +#include // round #include "NetcdfFile.h" +# include "CpptrajStdio.h" #ifdef BINTRAJ -# include -# include // strlen -# include "NC_Routines.h" -#endif -#ifdef MPI -# include "ParallelNetcdf.h" +# include +# include // strlen +# include "NC_Routines.h" +# include "Constants.h" +# include "Version.h" +# include "Frame.h" +# ifdef MPI +# include "ParallelNetcdf.h" +# endif +# ifdef HAS_HDF5 +# include // for integer compression +# endif #endif -#include "CpptrajStdio.h" -#include "Constants.h" -#include "Version.h" + +/** Strings corresponding to NC_FMT_TYPE */ +const char* NetcdfFile::NcFmtTypeStr_[] = { + "Not NetCDF", "NetCDF3", "NetCDF4/HDF5" +}; // NetcdfFile::GetNetcdfConventions() -NetcdfFile::NCTYPE NetcdfFile::GetNetcdfConventions(const char* fname) { +/** First check the base format type to determine NetCDF3 vs NetCDF/HDF5. + * Then check that the file has the proper conventions. + */ +NetcdfFile::NCTYPE NetcdfFile::GetNetcdfConventions(NC_FMT_TYPE& btype, const char* fname) +{ + btype = NC_NOTNC; NCTYPE nctype = NC_UNKNOWN; + // Determine base type via magic number + FILE* infile = fopen(fname, "rb"); + if (infile == 0) return nctype; + unsigned char buf[8]; + unsigned int nread = fread(buf, sizeof(char), 8, infile); + //mprintf("DEBUG: '%s' nread=%u %x %x %x %x %x %x %x %x\n", fname, nread, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); + fclose(infile); + if (nread > 3 && buf[0] == 'C' && buf[1] == 'D' && buf[2] == 'F') { +# ifdef BINTRAJ + btype = NC_V3; +# else + mprintf("Warning: File '%s' appears to be NetCDF3 but cpptraj was compiled without NetCDF support.\n", fname); + return nctype; +# endif + } else if (nread > 7 && buf[0] == 0x89 && buf[1] == 0x48 && buf[2] == 0x44 && buf[3] == 0x46 && + buf[4] == 0x0d && buf[5] == 0x0a && buf[6] == 0x1a && buf[7] == 0x0a) + { +# ifdef HAS_HDF5 + btype = NC_V4; +# else + mprintf("Warning: File '%s' appears to be NetCDF4/HDF5 but cpptraj was compiled without HDF5 support.\n", fname); + return nctype; +# endif + } + //mprintf("DEBUG: Type: %s\n", NcFmtTypeStr_[btype]); # ifdef BINTRAJ // NOTE: Do not use checkNCerr so this fails silently. Allows routine to // be used in file autodetection. @@ -28,6 +69,9 @@ NetcdfFile::NCTYPE NetcdfFile::GetNetcdfConventions(const char* fname) { return nctype; } +/** \return netcdf format type if the file magic number is recognized. + */ + #ifdef BINTRAJ // DEFINES #define NCENSEMBLE "ensemble" @@ -53,6 +97,10 @@ NetcdfFile::NCTYPE NetcdfFile::GetNetcdfConventions(const char* fname) { #define NCEPTOT "eptot" #define NCBINS "bins" #define NCREMDVALUES "remd_values" +#define NCCOMPPOS "compressedpos" +#define NCCOMPVEL "compressedvel" +#define NCCOMPFRC "compressedfrc" +#define NCICOMPFAC "icompressfac" // CONSTRUCTOR NetcdfFile::NetcdfFile() : @@ -70,6 +118,15 @@ NetcdfFile::NetcdfFile() : repidxVID_(-1), crdidxVID_(-1), ensembleSize_(0), + compressedPosVID_(-1), + compressedVelVID_(-1), + compressedFrcVID_(-1), + fchunkSize_(1), + ishuffle_(-1), +# ifdef HAS_HDF5 + deflateLevels_((unsigned int)NVID, 0), + intCompressFac_((unsigned int)NVID, 0), +# endif ncdebug_(0), frameDID_(-1), atomDID_(-1), @@ -104,23 +161,48 @@ NetcdfFile::NCTYPE NetcdfFile::GetNetcdfConventions(int ncidIn) { NCTYPE nctype = NC_UNKNOWN; std::string attrText = NC::GetAttrText(ncidIn, "Conventions"); if (attrText.empty()) { - mprinterr("Error: Could not get conventions from NetCDF file.\n"); - } else { - for (int i = 0; i < (int)NC_UNKNOWN; i++) { - if (attrText.compare( ConventionsStr_[i] ) == 0) { - nctype = (NCTYPE)i; - break; + // Check if this is an MDtraj h5 file + attrText = NC::GetAttrText(ncidIn, "conventions"); + if (attrText.empty()) { +# ifdef HAS_HDF5 + // Check if this is an MDAnalysis h5md file + bool is_h5md = false; + std::vector GroupNames = NC::GetGroupNames( ncidIn ); + if (!GroupNames.empty()) { + for (std::vector::const_iterator it = GroupNames.begin(); + it != GroupNames.end(); ++it) + { + if (*it == "h5md") { + mprintf("DEBUG: H5MD detected.\n"); + is_h5md = true; + break; + } + } } + if (!is_h5md) + mprinterr("Error: Could not get conventions from NetCDF file.\n"); +# endif + return NC_UNKNOWN; } - if (nctype == NC_UNKNOWN) { - mprinterr("Error: NetCDF file has unrecognized conventions \"%s\".\n", - attrText.c_str()); - mprinterr("Error: Expected one of"); - for (int i = 0; i < (int)NC_UNKNOWN; i++) - mprintf(" \"%s\"", ConventionsStr_[i]); - mprinterr("\n"); + //mprintf("DEBUG: This appears to be an HDF5 h5 file.\n"); + return NC_UNKNOWN; + } + // Identify the conventions string + for (int i = 0; i < (int)NC_UNKNOWN; i++) { + if (attrText.compare( ConventionsStr_[i] ) == 0) { + nctype = (NCTYPE)i; + break; } } + if (nctype == NC_UNKNOWN) { + mprinterr("Error: NetCDF file has unrecognized conventions \"%s\".\n", + attrText.c_str()); + mprinterr("Error: Expected one of"); + for (int i = 0; i < (int)NC_UNKNOWN; i++) + mprintf(" \"%s\"", ConventionsStr_[i]); + mprinterr("\n"); + } + return nctype; } @@ -131,6 +213,7 @@ void NetcdfFile::CheckConventionsVersion() { mprintf("Warning: NetCDF file has ConventionVersion that is not 1.0 (%s)\n", attrText.c_str()); } +// ----------------------------------------------------------------------------- /** \return true if temperature VID is defined or a replica dimension is temperature. */ bool NetcdfFile::HasTemperatures() const { @@ -191,24 +274,11 @@ int NetcdfFile::SetupCoordsVelo(bool useVelAsCoords, bool useFrcAsCoords) { mprinterr("Error: Cannot use both velocities and forces as coords - specify one only.\n"); return 1; } - // Get atoms info - atomDID_ = NC::GetDimInfo( ncid_, NCATOM, ncatom_ ); - if (atomDID_==-1) return 1; - ncatom3_ = ncatom_ * 3; - // Get coord info - coordVID_ = -1; - if ( nc_inq_varid(ncid_, NCCOORDS, &coordVID_) == NC_NOERR ) { - if (ncdebug_ > 0) mprintf("\tNetCDF file has coordinates.\n"); - std::string attrText = NC::GetAttrText(ncid_, coordVID_, "units"); - if (attrText!="angstrom") - mprintf("Warning: NetCDF file has length units of %s - expected angstrom.\n", - attrText.c_str()); - } // Get spatial info int spatial; spatialDID_ = NC::GetDimInfo( ncid_, NCSPATIAL, spatial ); - if (spatialDID_==-1) return 1; - if (spatial!=3) { + if (spatialDID_ == -1) return 1; + if (spatial != 3) { mprinterr("Error: Expected 3 spatial dimensions, got %i\n",spatial); return 1; } @@ -229,38 +299,137 @@ int NetcdfFile::SetupCoordsVelo(bool useVelAsCoords, bool useFrcAsCoords) { return 1; } } + + // Get atoms info + atomDID_ = NC::GetDimInfo( ncid_, NCATOM, ncatom_ ); + if (atomDID_==-1) return 1; + ncatom3_ = ncatom_ * 3; +# ifdef HAS_HDF5 + unsigned int needed_itmp_size = 0; +# endif + bool has_coordinates = false; + bool has_velocities = false; + bool has_forces = false; + // Get coord info + coordVID_ = -1; + if ( nc_inq_varid(ncid_, NCCOORDS, &coordVID_) == NC_NOERR ) { + if (ncdebug_ > 0) mprintf("\tNetCDF file has coordinates.\n"); + std::string attrText = NC::GetAttrText(ncid_, coordVID_, "units"); + if (attrText!="angstrom") + mprintf("Warning: NetCDF file has length units of %s - expected angstrom.\n", + attrText.c_str()); + has_coordinates = true; + } + // Get compressed coord info + compressedPosVID_ = -1; + if ( nc_inq_varid(ncid_, NCCOMPPOS, &compressedPosVID_) == NC_NOERR ) { + if (ncdebug_ > 0) mprintf("\tNetCDF file has integer-compressed coordinates.\n"); +# ifdef HAS_HDF5 + // Get integer compression factor + if (NC::CheckErr(nc_get_att_double(ncid_, compressedPosVID_, NCICOMPFAC, (&intCompressFac_[0])+V_COORDS))) { + mprinterr("Error: Could not get integer compression factor attribute for COORDS.\n"); + return 1; + } + mprintf("\tCoordinates are integer-compressed with factor: %g\n", intCompressFac_[V_COORDS]); + needed_itmp_size = Ncatom3(); + has_coordinates = true; +# else /* HAS_HDF5 */ + mprinterr("Error: Integer-compressed NetCDF trajectories requires cpptraj compiled with HDF5 support.\n"); + return 1; +# endif /* HAS_HDF5 */ + } + // Get velocity info velocityVID_ = -1; if ( nc_inq_varid(ncid_, NCVELO, &velocityVID_) == NC_NOERR ) { if (ncdebug_>0) mprintf("\tNetCDF file has velocities.\n"); + has_velocities = true; + } + // Get compressed velocity info + compressedVelVID_ = -1; + if ( nc_inq_varid(ncid_, NCCOMPVEL, &compressedVelVID_) == NC_NOERR ) { + if (ncdebug_ > 0) mprintf("\tNetCDF file has integer-compressed velocities.\n"); +# ifdef HAS_HDF5 + // Get integer compression factor + if (NC::CheckErr(nc_get_att_double(ncid_, compressedVelVID_, NCICOMPFAC, (&intCompressFac_[0])+V_VEL))) { + mprinterr("Error: Could not get integer compression factor attribute for VEL.\n"); + return 1; + } + mprintf("\tVelocities are integer-compressed with factor: %g\n", intCompressFac_[V_VEL]); + needed_itmp_size = Ncatom3(); + has_velocities = true; +# else /* HAS_HDF5 */ + mprinterr("Error: Integer-compressed NetCDF trajectories requires cpptraj compiled with HDF5 support.\n"); + return 1; +# endif /* HAS_HDF5 */ } + // Get force info frcVID_ = -1; if ( nc_inq_varid(ncid_, NCFRC, &frcVID_) == NC_NOERR ) { if (ncdebug_>0) mprintf("\tNetCDF file has forces.\n"); + has_forces = true; + } + // Get compressed force info + compressedFrcVID_ = -1; + if ( nc_inq_varid(ncid_, NCCOMPFRC, &compressedFrcVID_) == NC_NOERR ) { + if (ncdebug_ > 0) mprintf("\tNetCDF file has integer-compressed forces.\n"); +# ifdef HAS_HDF5 + // Get integer compression factor + if (NC::CheckErr(nc_get_att_double(ncid_, compressedFrcVID_, NCICOMPFAC, (&intCompressFac_[0])+V_FRC))) { + mprinterr("Error: Could not get integer compression factor attribute for FRC.\n"); + return 1; + } + mprintf("\tForces are integer-compressed with factor: %g\n", intCompressFac_[V_FRC]); + needed_itmp_size = Ncatom3(); + has_forces = true; +# else /* HAS_HDF5 */ + mprinterr("Error: Integer-compressed NetCDF trajectories requires cpptraj compiled with HDF5 support.\n"); + return 1; +# endif /* HAS_HDF5 */ } + +# ifdef HAS_HDF5 + // Allocate temporary space for integer array if needed + if (needed_itmp_size > 0) + itmp_.resize( needed_itmp_size ); +# endif // Return a error if no coords, velocities, or forces - if ( coordVID_ == -1 && velocityVID_ == -1 && frcVID_ == -1 ) { + if ( !has_coordinates && !has_velocities && !has_forces ) { mprinterr("Error: NetCDF file has no coordinates, velocities, or forces.\n"); return 1; } // If using velocities/forces as coordinates, swap them now. if (useVelAsCoords) { - if (velocityVID_ == -1) { + if (velocityVID_ != -1) { + coordVID_ = velocityVID_; + velocityVID_ = -1; +# ifdef HAS_HDF5 + } else if (compressedVelVID_ != -1) { + compressedPosVID_ = compressedVelVID_; + compressedVelVID_ = -1; + intCompressFac_[V_COORDS] = intCompressFac_[V_VEL]; +# endif + } else { mprinterr("Error: Cannot use velocities as coordinates; no velocities present.\n"); return 1; } mprintf("\tUsing velocities as coordinates.\n"); - coordVID_ = velocityVID_; - velocityVID_ = -1; } else if (useFrcAsCoords) { - if (frcVID_ == -1) { + if (frcVID_ != -1) { + coordVID_ = frcVID_; + frcVID_ = -1; +# ifdef HAS_HDF5 + } else if (compressedFrcVID_ != -1) { + compressedPosVID_ = compressedFrcVID_; + compressedFrcVID_ = -1; + intCompressFac_[V_COORDS] = intCompressFac_[V_FRC]; +# endif + } else { mprinterr("Error: Cannot use forces as coordinates; no forces present.\n"); return 1; } mprintf("\tUsing forces as coordinates.\n"); - coordVID_ = frcVID_; - frcVID_ = -1; } // Get overall replica and coordinate indices crdidxVID_ = -1; @@ -409,7 +578,6 @@ int NetcdfFile::SetupMultiD() { // NetcdfFile::SetupBox() /** \return 0 on success, 1 on error, -1 for no box coords. */ -// TODO: Use Box class int NetcdfFile::SetupBox() { nc_box_.SetNoBox(); if ( nc_inq_varid(ncid_, NCCELL_LENGTHS, &cellLengthVID_) == NC_NOERR ) { @@ -603,19 +771,6 @@ int NetcdfFile::NC_openWrite(std::string const& Name) { return 0; } -// NetcdfFile::NC_defineTemperature() -int NetcdfFile::NC_defineTemperature(int* dimensionID, int NDIM) { - if (NC::CheckErr(nc_def_var(ncid_,NCTEMPERATURE,NC_DOUBLE,NDIM,dimensionID,&TempVID_))) { - mprinterr("NetCDF error on defining temperature.\n"); - return 1; - } - if (NC::CheckErr(nc_put_att_text(ncid_,TempVID_,"units",6,"kelvin"))) { - mprinterr("NetCDF error on defining temperature units.\n"); - return 1; - } - return 0; -} - // NetcdfFile::NC_createReservoir() int NetcdfFile::NC_createReservoir(bool hasBins, double reservoirT, int iseed, int& eptotVID, int& binsVID) @@ -676,9 +831,372 @@ void NetcdfFile::SetRemDimDID(int remDimDID, int* dimensionID) const { } } -// NetcdfFile::NC_create() +/** Variable ID descriptions. */ +const char* NetcdfFile::vidDesc_[NVID] = { + "coordinates", // V_COORDS + "velocities", // V_VEL + "forces", // V_FRC + "temp0", // V_TEMP + "cell_lengths", // V_BOXL + "cell_angles", // V_BOXA + "time", // V_TIME + "remd_indices", // V_IND + "remd_repidx", // V_RIDX + "remd_crdidx", // V_CIDX + "remd_values" // V_REMDVALS +}; + +/** Dimension ID descriptions. */ +const char* NetcdfFile::didDesc_[NDID] = { + "frame", // D_FRAME + "atom", // D_ATOM + "spatial" // D_SPATIAL +}; + +// ----------------------------------------------------------------------------- +// This section contains HDF5-related functionality + +/** Set variable compression level (and integer shuffle) if supported. */ +int NetcdfFile::NC_setDeflate(VidType vtype, int varid, int ishuffleIn) const +{ +# ifdef HAS_HDF5 + if (deflateLevels_[vtype] > 0) { + if (ncdebug_ > 0) + mprintf("DEBUG: Setting deflate level for '%s' to %i (ishuffle=%i)\n", + vidDesc_[vtype], deflateLevels_[vtype], ishuffleIn); + if ( NC::CheckErr( nc_def_var_deflate(ncid_, varid, ishuffleIn, 1, deflateLevels_[vtype]) ) ) { + mprinterr("Error: Setting compression for '%s' variable.\n", vidDesc_[vtype]); + return 1; + } + } +# else + mprintf("Warning: Setting NetCDF variable compression requires compiling with HDF5 support.\n"); +# endif + return 0; +} + +/** Set variable compression level with integer shuffle off. */ +int NetcdfFile::NC_setDeflate(VidType vtype, int varid) const { + return NC_setDeflate(vtype, varid, 0); +} + +/** Increase frame chunk size for variable if supported. */ +int NetcdfFile::NC_setFrameChunkSize(VidType vtype, int varid) const +{ +# ifdef HAS_HDF5 + if (fchunkSize_ > 1) { + // Get number of dimensions + int ndims = 0; + if ( NC::CheckErr( nc_inq_varndims(ncid_, varid, &ndims) ) ) { + mprinterr("Error: getting # dims for '%s' variable.\n", vidDesc_[vtype]); + return 1; + } + if (ndims < 1) { + mprintf("Warning: NC_setFrameChunkSize: Variable '%s' has no dimensions.\n", + vidDesc_[vtype]); + return 0; + } + // Get dimension IDs + std::vector dimids(ndims); + if ( NC::CheckErr( nc_inq_var(ncid_, varid, 0, 0, 0, &dimids[0], 0) ) ) { + mprinterr("Error: getting dimension IDs for '%s' variable.\n", vidDesc_[vtype]); + return 1; + } + // Allocate space for chunk sizes + std::vector chunkSizes( ndims ); + // Set frame chunk size + int err = NC_setVarDimChunkSizes(vtype, varid, fchunkSize_, dimids, frameDID_, chunkSizes); + return err; + } +# else + mprintf("Warning: Setting NetCDF frame chunk size requires compiling with HDF5 support.\n"); +# endif + return 0; +} + +# ifdef HAS_HDF5 +/** Set desired compression level for specified variable if supported. */ +int NetcdfFile::setDesiredCompression(VidType vtype, int deflateLevelIn) { + if (ncdebug_ > 0) + mprintf("DEBUG: Setting desired compression for VIDTYPE %s to %i\n", vidDesc_[vtype], deflateLevelIn); + deflateLevels_[vtype] = deflateLevelIn; + return 0; +} + +/** Set desired compression level for all variables if supported. */ +int NetcdfFile::SetupCompression(int deflateLevelIn, int icompressIn, int ishuffleIn) { + mprintf("\tSetting NetCDF variable compression level to %i\n", deflateLevelIn); + int err = 0; + // Integer compression implies compression + int local_deflateLevel = deflateLevelIn; + if (local_deflateLevel == 0 && icompressIn > 0) { + local_deflateLevel = 1; + } + for (int i = 0; i != (int)NVID; i++) + err += setDesiredCompression( (VidType)i, local_deflateLevel ); + // Integer compression + ishuffle_ = 0; + if (icompressIn > 0) { + mprintf("\tSetting NetCDF integer compression for supported variables to %i\n", icompressIn); + // Warn about low precision powers + if (icompressIn < 4) { + mprintf("Warning: Using extremely low precision for integer compression.\n" + "Warning: Energy error will be on the order of 1E-%i kcal/mol/atom\n", icompressIn); + mprintf("Warning: Consider using integer power >= 4.\n"); + } else + mprintf("Warning: Using lossy compression.\n" + "Warning: Energy error will be on the order of 1E-%i kcal/mol/atom\n", icompressIn); + // Calculate integer compression factors for supported variables + err += (calcCompressFactor( intCompressFac_[V_COORDS], icompressIn, "coordinates" )); + err += (calcCompressFactor( intCompressFac_[V_VEL], icompressIn, "velocities" )); + err += (calcCompressFactor( intCompressFac_[V_FRC], icompressIn, "forces" )); + // Report ishuffle status + ishuffle_ = ishuffleIn; + if (ishuffle_ == 0) + mprintf("\tInteger shuffle is off.\n"); + else + mprintf("\tInteger shuffle is on.\n"); + } + return err; +} + +/* Set desired frame chunk size if supported. */ +int NetcdfFile::SetFrameChunkSize(int fchunkSizeIn) { + mprintf("\tSetting frame chunk size to %i\n", fchunkSizeIn); + fchunkSize_ = fchunkSizeIn; + return 0; +} + +/** If target dimID is -1 multiply existing chunk sizes for variable + * by chunkFac. Otherwise multiple chunk size matching target dimID + * only. + */ +int NetcdfFile::NC_setVarDimChunkSizes(VidType vtype, int varid, int chunkFac, + std::vector const& dimids, int tgtDimId, + std::vector& chunkSizes) +const +{ + // Sanity checks. + if (dimids.empty() || chunkSizes.empty()) { + mprinterr("Internal Error: NC_setVarDimChunkSizes called with empty arrays.\n"); + return 1; + } + // Get chunk sizes and storage type + int storagep = 0; + if ( NC::CheckErr( nc_inq_var_chunking(ncid_, varid, &storagep, &chunkSizes[0]) ) ) { + mprinterr("Error: getting existing chunk sizes for '%s' variable.\n", vidDesc_[vtype]); + return 1; + } + if (storagep != NC_CHUNKED) { + mprinterr("Internal Error: NC_setVarDimChunkSizes called for VID that is not chunked '%s'\n", + vidDesc_[vtype]); + return 1; + } + // Loop over dimension chunk sizes + for (unsigned int dim = 0; dim != dimids.size(); dim++) { + if (tgtDimId == -1 || tgtDimId == dimids[dim]) { + mprintf("DEBUG: '%s' dim %u chunk size = %zu new size= %zu\n", + vidDesc_[vtype], dim, chunkSizes[dim], chunkSizes[dim]*(size_t)chunkFac); + // Set new chunk size + chunkSizes[dim] *= chunkFac; + } + } + if ( NC::CheckErr( nc_def_var_chunking(ncid_, varid, NC_CHUNKED, &chunkSizes[0]) ) ) { + mprinterr("Error: Setting chunk sizes for '%s' variable.\n", vidDesc_[vtype]); + return 1; + } + return 0; +} + +/** Set compressedFac to given power of 10 (min 1). */ +int NetcdfFile::calcCompressFactor(double& compressedFac, int power, const char* desc) const { + compressedFac = 0; + if (power < 1) { + mprinterr("Internal Error: calcCompressFactor called with power of 10 < 1\n"); + return 1; + } + compressedFac = 10.0; + for (int i = 1; i < power; i++) + compressedFac *= 10.0; + if (ncdebug_ > 0) + mprintf("\tIf present, will convert %s to integer using factor: x%g\n", desc, compressedFac); + return 0; +} + +/** Write atom-based array using integer quantization and compression. */ +int NetcdfFile::NC_writeIntCompressed(const double* xyz, int vid, double compressedFacIn) +{ + // Convert to integer + static const long int maxval = (long int)std::numeric_limits::max(); + + for (int idx = 0; idx != Ncatom3(); idx++) + { + // Multiply by compression factor and round to the nearest integer + long int ii = (long int)(round(xyz[idx] * compressedFacIn)); + // Try some overflow protection + //long int ii = (long int)(frmOut[idx] * compressedFac_); + if (ii > maxval || ii < -maxval) { + mprinterr("Error: Value %i frame %i (%g) is too large to convert to int.\n", + idx+1, ncframe_+1, xyz[idx]); + mprinterr("Error: A smaller integer compression factor must be used.\n"); + return 1; + } + itmp_[idx] = (int)ii; + //itmp_[idx] = (int)(frmOut[idx] * compressedFac_); + } + //mprintf("DEBUG: atom 0 xyz={ %20.10f %20.10f %20.10f } ixyz= { %20i %20i %20i }\n", + // frmOut[0], frmOut[1], frmOut[2], itmp_[0], itmp_[1], itmp_[2]); + // Write array + start_[0] = Ncframe(); + start_[1] = 0; + start_[2] = 0; + count_[0] = 1; + count_[1] = Ncatom(); + count_[2] = 3; + + if (NC::CheckErr(nc_put_vara_int(ncid_, vid, start_, count_, &itmp_[0]))) { + mprinterr("Error: NetCDF writing compressed values frame %i\n", Ncframe()+1); + return 1; + } + return 0; +} + +/** Write integer-compressed coords. */ +int NetcdfFile::NC_writeIntCompressed(Frame const& frmOut) { + if (compressedPosVID_ != -1) { + if (NC_writeIntCompressed(frmOut.xAddress(), compressedPosVID_, intCompressFac_[V_COORDS])) { + mprinterr("Error: NetCDF writing compressed coordinates frame %i\n", ncframe_+1); + return 1; + } + } + if (compressedVelVID_ != -1) { + if (NC_writeIntCompressed(frmOut.vAddress(), compressedVelVID_, intCompressFac_[V_VEL])) { + mprinterr("Error: NetCDF writing compressed velocities frame %i\n", ncframe_+1); + return 1; + } + } + if (compressedFrcVID_ != -1) { + if (NC_writeIntCompressed(frmOut.fAddress(), compressedFrcVID_, intCompressFac_[V_FRC])) { + mprinterr("Error: NetCDF writing compressed forces frame %i\n", ncframe_+1); + return 1; + } + } + return 0; +} + +/** Read atom-based array that uses integer quantization and compression. */ +int NetcdfFile::NC_readIntCompressed(double* xyz, int vid, int set, double compressedFacIn) { + // Read array + start_[0] = set; + start_[1] = 0; + start_[2] = 0; + count_[0] = 1; + count_[1] = Ncatom(); + count_[2] = 3; + if (NC::CheckErr(nc_get_vara_int(ncid_, vid, start_, count_, &itmp_[0]))) { + mprinterr("Error: NetCDF reading compressed values frame %i\n", set+1); + return 1; + } + // Convert from integer + for (int idx = 0; idx != Ncatom3(); idx++) + xyz[idx] = (double)(itmp_[idx]) / compressedFacIn; // TODO convert to 1/fac first? + return 0; +} + +/** Read integer-compressed coords. */ +int NetcdfFile::NC_readIntCompressed(int set, Frame& frmIn) { + if (compressedPosVID_ != -1) { + if (NC_readIntCompressed( frmIn.xAddress(), compressedPosVID_, set, intCompressFac_[V_COORDS] )) { + mprinterr("Error: NetCDF reading compressed coordinates frame %i\n", set+1); + return 1; + } + } + if (compressedVelVID_ != -1) { + if (NC_readIntCompressed( frmIn.vAddress(), compressedVelVID_, set, intCompressFac_[V_VEL] )) { + mprinterr("Error: NetCDF reading compressed velocities frame %i\n", set+1); + return 1; + } + } + if (compressedFrcVID_ != -1) { + if (NC_readIntCompressed( frmIn.fAddress(), compressedFrcVID_, set, intCompressFac_[V_FRC] )) { + mprinterr("Error: NetCDF reading compressed forces frame %i\n", set+1); + return 1; + } + } + return 0; +} +// ----------------------------------------------------------------------------- +#endif /* HAS_HDF5 */ + +// NetcdfFile::NC_defineTemperature() +int NetcdfFile::NC_defineTemperature(int* dimensionID, int NDIM) { + if (NC::CheckErr(nc_def_var(ncid_,NCTEMPERATURE,NC_DOUBLE,NDIM,dimensionID,&TempVID_))) { + mprinterr("NetCDF error on defining temperature.\n"); + return 1; + } + if (NC::CheckErr(nc_put_att_text(ncid_,TempVID_,"units",6,"kelvin"))) { + mprinterr("NetCDF error on defining temperature units.\n"); + return 1; + } + if (NC_setDeflate(V_TEMP, TempVID_)) return 1; + return 0; +} + +/** Create default NetCDF version 3 file. */ int NetcdfFile::NC_create(std::string const& Name, NCTYPE typeIn, int natomIn, CoordinateInfo const& coordInfo, std::string const& title, int debugIn) +{ + return (NC_create(NC_V3, Name, typeIn, natomIn, coordInfo, title, debugIn)); +} + + +/** Set up given dimension array with dimension IDs appropriate for + * atom-based arrays for file type. + */ +int NetcdfFile::set_atom_dim_array(int* dimensionID) const { + // Setup dimensions for Coords/Velocity + // NOTE: THIS MUST BE MODIFIED IF NEW TYPES ADDED + switch (myType_) { + case NC_AMBERENSEMBLE: + dimensionID[0] = frameDID_; + dimensionID[1] = ensembleDID_; + dimensionID[2] = atomDID_; + dimensionID[3] = spatialDID_; + break; + case NC_AMBERTRAJ: + dimensionID[0] = frameDID_; + dimensionID[1] = atomDID_; + dimensionID[2] = spatialDID_; + break; + case NC_AMBERRESTART: + dimensionID[0] = atomDID_; + dimensionID[1] = spatialDID_; + break; + case NC_UNKNOWN: + mprinterr("Internal Error: Unknown type passed to set_atom_dim_array()\n"); + return 1; + } + return 0; +} + +/** Write - Set attributes for velocity variable. */ +int NetcdfFile::setVelAttributes(int vid) const { + if ( NC::CheckErr( nc_put_att_text( ncid_, vid, "units", 19, "angstrom/picosecond")) ) { + mprinterr("Error: Writing velocities variable units.\n"); + return 1; + } + if ( NC::CheckErr( nc_put_att_double( ncid_, vid, "scale_factor", NC_DOUBLE, 1, + &Constants::AMBERTIME_TO_PS)) ) + { + mprinterr("Error: Writing velocities scale factor.\n"); + return 1; + } + return 0; +} + +// NetcdfFile::NC_create() +int NetcdfFile::NC_create(NC_FMT_TYPE wtypeIn, std::string const& Name, NCTYPE typeIn, int natomIn, + CoordinateInfo const& coordInfo, std::string const& title, int debugIn) { if (Name.empty()) return 1; int dimensionID[NC_MAX_VAR_DIMS]; @@ -690,8 +1208,16 @@ int NetcdfFile::NC_create(std::string const& Name, NCTYPE typeIn, int natomIn, if (ncdebug_>1) mprintf("DEBUG: NC_create: '%s' natom=%i %s\n", Name.c_str(),natomIn, coordInfo.InfoString().c_str()); - - if ( NC::CheckErr( nc_create( Name.c_str(), NC_64BIT_OFFSET, &ncid_) ) ) + int cmode; + if (wtypeIn == NC_V3) + cmode = NC_64BIT_OFFSET; + else if (wtypeIn == NC_V4) + cmode = NC_NETCDF4; + else { + mprinterr("Internal Error: Unspecified base format type given in NC_create().\n"); + return 1; + } + if ( NC::CheckErr( nc_create( Name.c_str(), cmode, &ncid_) ) ) return 1; ncatom_ = natomIn; @@ -748,6 +1274,7 @@ int NetcdfFile::NC_create(std::string const& Name, NCTYPE typeIn, int natomIn, mprinterr("Error: Writing time VID units.\n"); return 1; } + if (NC_setDeflate(V_TIME, timeVID_)) return 1; } // Spatial dimension and variable if ( NC::CheckErr( nc_def_dim( ncid_, NCSPATIAL, 3, &spatialDID_)) ) { @@ -764,59 +1291,51 @@ int NetcdfFile::NC_create(std::string const& Name, NCTYPE typeIn, int natomIn, mprinterr("Error: Defining atom dimension.\n"); return 1; } + // Setup dimensions for Coords/Velocity - // NOTE: THIS MUST BE MODIFIED IF NEW TYPES ADDED - switch (myType_) { - case NC_AMBERENSEMBLE: - dimensionID[0] = frameDID_; - dimensionID[1] = ensembleDID_; - dimensionID[2] = atomDID_; - dimensionID[3] = spatialDID_; - break; - case NC_AMBERTRAJ: - dimensionID[0] = frameDID_; - dimensionID[1] = atomDID_; - dimensionID[2] = spatialDID_; - break; - case NC_AMBERRESTART: - dimensionID[0] = atomDID_; - dimensionID[1] = spatialDID_; - break; - case NC_UNKNOWN: - mprinterr("Internal Error: Unknown type passed to NC_create()\n"); - return 1; - } + if (set_atom_dim_array(dimensionID)) return 1; + // Coord variable - if (coordInfo.HasCrd()) { +# ifdef HAS_HDF5 + if (coordInfo.HasCrd() && intCompressFac_[V_COORDS] == 0) +# else + if (coordInfo.HasCrd()) +# endif + { + // Regular coords if ( NC::CheckErr( nc_def_var( ncid_, NCCOORDS, dataType, NDIM, dimensionID, &coordVID_)) ) { mprinterr("Error: Defining coordinates variable.\n"); return 1; } if ( NC::CheckErr( nc_put_att_text( ncid_, coordVID_, "units", 8, "angstrom")) ) { - mprinterr("Error: Writing coordinates variable units.\n"); + mprinterr("Error: Setting coordinates variable units attribute.\n"); return 1; } + if (NC_setDeflate(V_COORDS, coordVID_)) return 1; + if (NC_setFrameChunkSize(V_COORDS, coordVID_)) return 1; } // Velocity variable - if (coordInfo.HasVel()) { +# ifdef HAS_HDF5 + if (coordInfo.HasVel() && intCompressFac_[V_VEL] == 0) +# else + if (coordInfo.HasVel()) +# endif + { if ( NC::CheckErr( nc_def_var( ncid_, NCVELO, dataType, NDIM, dimensionID, &velocityVID_)) ) { mprinterr("Error: Defining velocities variable.\n"); return 1; } - if ( NC::CheckErr( nc_put_att_text( ncid_, velocityVID_, "units", 19, "angstrom/picosecond")) ) - { - mprinterr("Error: Writing velocities variable units.\n"); - return 1; - } - if ( NC::CheckErr( nc_put_att_double( ncid_, velocityVID_, "scale_factor", NC_DOUBLE, 1, - &Constants::AMBERTIME_TO_PS)) ) - { - mprinterr("Error: Writing velocities scale factor.\n"); - return 1; - } + if (setVelAttributes( velocityVID_ )) return 1; + if (NC_setDeflate(V_VEL, velocityVID_)) return 1; + if (NC_setFrameChunkSize(V_VEL, velocityVID_)) return 1; } // Force variable - if (coordInfo.HasForce()) { +# ifdef HAS_HDF5 + if (coordInfo.HasForce() && intCompressFac_[V_FRC] == 0) +# else + if (coordInfo.HasForce()) +# endif + { if ( NC::CheckErr( nc_def_var( ncid_, NCFRC, dataType, NDIM, dimensionID, &frcVID_)) ) { mprinterr("Error: Defining forces variable\n"); return 1; @@ -826,7 +1345,10 @@ int NetcdfFile::NC_create(std::string const& Name, NCTYPE typeIn, int natomIn, mprinterr("Error: Writing forces variable units.\n"); return 1; } + if (NC_setDeflate(V_FRC, frcVID_)) return 1; + if (NC_setFrameChunkSize(V_FRC, frcVID_)) return 1; } + // Replica Temperature if (coordInfo.HasTemp() && !coordInfo.UseRemdValues()) { // NOTE: Setting dimensionID should be OK for Restart, will not be used. @@ -841,6 +1363,8 @@ int NetcdfFile::NC_create(std::string const& Name, NCTYPE typeIn, int natomIn, mprinterr("Error: Defining replica idx variable ID.\n"); return 1; } + if (NC_setDeflate(V_RIDX, repidxVID_)) return 1; + //if (NC_setFrameChunkSize(V_RIDX, repidxVID_)) return 1; } // Overall coordinate index if (coordInfo.HasCrdIdx()) { @@ -850,6 +1374,8 @@ int NetcdfFile::NC_create(std::string const& Name, NCTYPE typeIn, int natomIn, mprinterr("Error: Defining coordinate idx variable ID.\n"); return 1; } + if (NC_setDeflate(V_CIDX, crdidxVID_)) return 1; + //if (NC_setFrameChunkSize(V_CIDX, crdidxVID_)) return 1; } // Replica indices int remDimTypeVID = -1; @@ -875,6 +1401,8 @@ int NetcdfFile::NC_create(std::string const& Name, NCTYPE typeIn, int natomIn, mprinterr("Error: Defining replica indices variable ID.\n"); return 1; } + if (NC_setDeflate(V_IND, indicesVID_)) return 1; + if (NC_setFrameChunkSize(V_IND, indicesVID_)) return 1; // TODO: Determine if groups are really necessary for restarts. If not, // remove from AmberNetcdf.F90. } @@ -904,7 +1432,9 @@ int NetcdfFile::NC_create(std::string const& Name, NCTYPE typeIn, int natomIn, // FIXME assuming temperature remValType_.AddRemdDimension( ReplicaDimArray::TEMPERATURE ); } - } + if (NC_setDeflate(V_REMDVALS, RemdValuesVID_)) return 1; + //if (NC_setFrameChunkSize(V_REMDVALS, RemdValuesVID_)) return 1; + } // Box Info if (coordInfo.HasBox()) { // Check x-aligned @@ -973,8 +1503,78 @@ int NetcdfFile::NC_create(std::string const& Name, NCTYPE typeIn, int natomIn, mprinterr("Error: Writing cell angle variable units.\n"); return 1; } + if (NC_setDeflate(V_BOXL, cellLengthVID_)) return 1; + if (NC_setFrameChunkSize(V_BOXL, cellLengthVID_)) return 1; + if (NC_setDeflate(V_BOXA, cellAngleVID_)) return 1; + if (NC_setFrameChunkSize(V_BOXA, cellAngleVID_)) return 1; } - +# ifdef HAS_HDF5 + unsigned int needed_itmp_size = 0; + // Integer-compressed coordinates + if (coordInfo.HasCrd() && intCompressFac_[V_COORDS] > 0) { + if (set_atom_dim_array(dimensionID)) return 1; + // Coords with integer compression + mprintf("\tCoordinates will use integer compression with factor %g\n", intCompressFac_[V_COORDS]); + if (NC::CheckErr( nc_def_var(ncid_, NCCOMPPOS, NC_INT, NDIM, dimensionID, &compressedPosVID_) )) { + mprinterr("Error: defining compressed positions VID.\n"); + return 1; + } + if (NC::CheckErr(nc_put_att_double(ncid_, compressedPosVID_, NCICOMPFAC, + NC_DOUBLE, 1, (&intCompressFac_[0])+V_COORDS))) { + mprinterr("Error: Assigning integer compressed coords compression factor attribute.\n"); + return 1; + } + needed_itmp_size = Ncatom3(); + if ( NC::CheckErr( nc_put_att_text( ncid_, compressedPosVID_, "units", 8, "angstrom")) ) { + mprinterr("Error: Assigning compressed coordinates variable units attribute.\n"); + return 1; + } + if (NC_setDeflate(V_COORDS, compressedPosVID_, ishuffle_)) return 1; + if (NC_setFrameChunkSize(V_COORDS, compressedPosVID_)) return 1; + } + // Integer-compressed velocities + if (coordInfo.HasVel() && intCompressFac_[V_VEL] > 0) { + if (set_atom_dim_array(dimensionID)) return 1; + // Velocities with integer compression + mprintf("\tVelocities will use integer compression with factor %g\n", intCompressFac_[V_VEL]); + if (NC::CheckErr( nc_def_var(ncid_, NCCOMPVEL, NC_INT, NDIM, dimensionID, &compressedVelVID_) )) { + mprinterr("Error: defining compressed velocities VID.\n"); + return 1; + } + if (NC::CheckErr(nc_put_att_double(ncid_, compressedVelVID_, NCICOMPFAC, + NC_DOUBLE, 1, (&intCompressFac_[0])+V_VEL))) { + mprinterr("Error: Assigning integer compressed velocities compression factor attribute.\n"); + return 1; + } + needed_itmp_size = Ncatom3(); + if (setVelAttributes( compressedVelVID_ )) return 1; + if (NC_setDeflate(V_VEL, compressedVelVID_, ishuffle_)) return 1; + if (NC_setFrameChunkSize(V_VEL, compressedVelVID_)) return 1; + } + // Integer-compressed forces + if (coordInfo.HasForce() && intCompressFac_[V_FRC] > 0) { + if (set_atom_dim_array(dimensionID)) return 1; + // Forces with integer compression + mprintf("\tForces will use integer compression with factor %g\n", intCompressFac_[V_FRC]); + if (NC::CheckErr( nc_def_var(ncid_, NCCOMPFRC, NC_INT, NDIM, dimensionID, &compressedFrcVID_) )) { + mprinterr("Error: defining compressed forces VID.\n"); + return 1; + } + if (NC::CheckErr(nc_put_att_double(ncid_, compressedFrcVID_, NCICOMPFAC, + NC_DOUBLE, 1, (&intCompressFac_[0])+V_FRC))) { + mprinterr("Error: Assigning integer compressed forces compression factor attribute.\n"); + return 1; + } + needed_itmp_size = Ncatom3(); + if ( NC::CheckErr( nc_put_att_text( ncid_, compressedFrcVID_, "units", 25, "kilocalorie/mole/angstrom")) ) + { + mprinterr("Error: Writing forces variable units.\n"); + return 1; + } + if (NC_setDeflate(V_FRC, compressedFrcVID_, ishuffle_)) return 1; + if (NC_setFrameChunkSize(V_FRC, compressedFrcVID_)) return 1; + } +# endif /* HAS_HDF5 */ // Attributes if (NC::CheckErr(nc_put_att_text(ncid_,NC_GLOBAL,"title",title.size(),title.c_str())) ) { mprinterr("Error: Writing title.\n"); @@ -1067,6 +1667,11 @@ int NetcdfFile::NC_create(std::string const& Name, NCTYPE typeIn, int natomIn, } } if (ncdebug_ > 1) NC::Debug(ncid_); + // Allocate temporary space for integer array +# ifdef HAS_HDF5 + if (needed_itmp_size > 0) + itmp_.resize( needed_itmp_size ); +# endif return 0; } @@ -1160,7 +1765,7 @@ void NetcdfFile::DebugVIDs() const { #ifdef MPI void NetcdfFile::Broadcast(Parallel::Comm const& commIn) { - static const unsigned int NCVARS_SIZE = 29; + static const unsigned int NCVARS_SIZE = 34; int nc_vars[NCVARS_SIZE]; if (commIn.Master()) { nc_vars[0] = ncframe_; @@ -1192,6 +1797,11 @@ void NetcdfFile::Broadcast(Parallel::Comm const& commIn) { nc_vars[26] = RemdValuesVID_; nc_vars[27] = remDimType_.Ndims(); nc_vars[28] = remValType_.Ndims(); + nc_vars[29] = compressedPosVID_; + nc_vars[30] = compressedVelVID_; + nc_vars[31] = compressedFrcVID_; + nc_vars[32] = fchunkSize_; + nc_vars[33] = ishuffle_; commIn.MasterBcast( nc_vars, NCVARS_SIZE, MPI_INT ); } else { // Non-master @@ -1226,11 +1836,21 @@ void NetcdfFile::Broadcast(Parallel::Comm const& commIn) { remDimType_.assign( nc_vars[27], ReplicaDimArray::UNKNOWN ); remValType_.assign( nc_vars[28], ReplicaDimArray::UNKNOWN ); RemdValues_.resize( nc_vars[28] ); + compressedPosVID_ = nc_vars[29]; + compressedVelVID_ = nc_vars[30]; + compressedFrcVID_ = nc_vars[31]; + fchunkSize_ = nc_vars[32]; + ishuffle_ = nc_vars[33]; } if (!remDimType_.empty()) commIn.MasterBcast( remDimType_.Ptr(), remDimType_.Ndims(), MPI_INT ); if (!remValType_.empty()) commIn.MasterBcast( remValType_.Ptr(), remValType_.Ndims(), MPI_INT ); +# ifdef HDF5 + commIn.MasterBcast( &deflateLevels_[0], deflateLevels_.size(), MPI_INT ); + commIn.MasterBcase( &intCompressFac_[0], intCompressFac_.size(), MPI_DOUBLE ); +# endif + } #endif /* MPI */ #endif /* BINTRAJ */ diff --git a/src/NetcdfFile.h b/src/NetcdfFile.h index 6fd98c209f..63cd245981 100644 --- a/src/NetcdfFile.h +++ b/src/NetcdfFile.h @@ -1,17 +1,21 @@ #ifndef INC_NETCDFFILE_H #define INC_NETCDFFILE_H #include -#include "Frame.h" +#include "CoordinateInfo.h" +class Frame; /// The base interface to NetCDF trajectory files. class NetcdfFile { public: /// For determining NetCDF trajectory file type enum NCTYPE { NC_AMBERTRAJ = 0, NC_AMBERRESTART, NC_AMBERENSEMBLE, NC_UNKNOWN }; - /// \return Type of given file. - NCTYPE GetNetcdfConventions(const char*); + /// For determining netcdf4/hdf5 vs netcdf3. Sync with NcFmtTypeStr_ + enum NC_FMT_TYPE { NC_NOTNC = 0, NC_V3, NC_V4 }; + /// \return Type of specified file. + static NCTYPE GetNetcdfConventions(NC_FMT_TYPE&, const char*); # ifndef BINTRAJ NetcdfFile() { } -# else +# else + /// CONSTRUCTOR NetcdfFile(); /// \return Coordinate info corresponding to current setup. TODO have in variable? CoordinateInfo NC_coordInfo() const; @@ -22,6 +26,9 @@ class NetcdfFile { /// Create NetCDF reservoir. int NC_createReservoir(bool, double, int, int&, int&); /// Create NetCDF trajectory file of given type. + int NC_create(NC_FMT_TYPE, std::string const&, NCTYPE, int, + CoordinateInfo const&, std::string const&, int); + /// Create NetCDF (v3) trajectory file of given type. int NC_create(std::string const&, NCTYPE, int, CoordinateInfo const&, std::string const&, int); /// Close NetCDF file, do not reset dimension/variable IDs. @@ -53,10 +60,28 @@ class NetcdfFile { inline int Ncatom3() const { return ncatom3_; } inline int Ncframe() const { return ncframe_; } inline int CoordVID() const { return coordVID_; } + /// \return Variable ID of integer-compressed coordinates + int CompressedPosVID() const { return compressedPosVID_; } protected: // TODO: Make all private + /// Enumerated type for variable IDs. MUST MATCH vidDesc_. + enum VidType { V_COORDS = 0, V_VEL, V_FRC, V_TEMP, V_BOXL, + V_BOXA, V_TIME, V_IND, V_RIDX, V_CIDX, + V_REMDVALS, + NVID }; +# ifdef HAS_HDF5 + /// Set all variables compression level and integer compression level (and shuffle). + int SetupCompression(int, int, int); + /// Set default frame chunk size + int SetFrameChunkSize(int); + /// Write an integer-compressed frame to the trajectory + int NC_writeIntCompressed(Frame const&); + /// Read an integer-compressed frame from the trajectory + int NC_readIntCompressed(int, Frame& frmIn); +# endif # ifdef MPI void Broadcast(Parallel::Comm const&); # endif + size_t start_[4]; ///< Array starting indices size_t count_[4]; ///< Array counts int ncid_; ///< NetCDF file ID @@ -79,16 +104,24 @@ class NetcdfFile { private: static const char* ConventionsStr_[]; + /// Descriptions of VidType. MUST MATCH VidType (except NVID). + static const char* vidDesc_[]; + /// Enumerated type for dimension IDs. MUST MATCH didDesc_. + enum DidType { D_FRAME = 0, D_ATOM, D_SPATIAL, + NDID }; // TODO everything else + /// Descriptions of DidType. MUST MATCH DidType (except NDID). + static const char* didDesc_[]; + /// \return NetCDF trajectory type based on conventions. - NCTYPE GetNetcdfConventions(int); + static NCTYPE GetNetcdfConventions(int); /// Check NetCDF file conventions version. void CheckConventionsVersion(); bool Has_pH() const; bool HasRedOx() const; - bool HasForces() const { return (frcVID_ != -1); } - bool HasVelocities() const { return (velocityVID_ != -1); } - bool HasCoords() const { return (coordVID_ != -1); } + bool HasForces() const { return (frcVID_ != -1 || compressedFrcVID_ != -1); } + bool HasVelocities() const { return (velocityVID_ != -1 || compressedVelVID_ != -1); } + bool HasCoords() const { return (coordVID_ != -1 || compressedPosVID_ != -1); } bool HasTemperatures() const; bool HasTimes() const { return (timeVID_ != -1); } @@ -107,8 +140,44 @@ class NetcdfFile { /// Read - Set up replica index info if present. int SetupMultiD(); + /// Set compression level and integer shuffle for variable ID (HDF5 only) + int NC_setDeflate(VidType, int, int) const; + /// Set compression level with integer shuffle off for variable ID (HDF5 only) + int NC_setDeflate(VidType, int) const; + /// Set frame chunk size for variable ID (HDF5 only) + int NC_setFrameChunkSize(VidType, int) const; +# ifdef HAS_HDF5 + /// Set desired compression level for variable ID. + int setDesiredCompression(VidType, int); + /// Calculate integer compression factor of 10 from given power + int calcCompressFactor(double&, int, const char*) const; + /// Increase variable chunk sizes + int NC_setVarDimChunkSizes(VidType, int, int, std::vector const&, int, std::vector&) const; + /// Write array[ncatom3] compressed + int NC_writeIntCompressed(const double*, int, double); + /// Read array[ncatom3] compressed + int NC_readIntCompressed(double*, int, int, double); +# endif + + /// Write - define the temperature variable int NC_defineTemperature(int*, int); + /// Write - set dimension array for remd vars inline void SetRemDimDID(int, int*) const; + /// Write - Set dimension IDs for atom-based array according to current file type + int set_atom_dim_array(int*) const; + /// Write - Set attributes for velocity variable + int setVelAttributes(int) const; + + int compressedPosVID_; ///< Coordinates integer VID + int compressedVelVID_; ///< Velocities integer VID + int compressedFrcVID_; ///< Velocities integer VID + int fchunkSize_; ///< Frame chunk size + int ishuffle_; ///< Control integer shuffle for integer-compressed vars +# ifdef HAS_HDF5 + std::vector deflateLevels_; ///< Compression levels for each VID + std::vector intCompressFac_; ///< Integer compression factor for each VID + std::vector itmp_; ///< Temp space for converting to int +# endif std::vector RemdValues_; ///< Hold remd values ReplicaDimArray remDimType_; ///< Type of each dimension (multi-D). @@ -129,8 +198,10 @@ class NetcdfFile { int spatialVID_; ///< Spatial (x, y, z) variable ID int cell_spatialVID_; ///< Box lengths variable ID int cell_angularVID_; ///< Box angles variable ID - int RemdValuesVID_; ///< Replica values variable ID. + int RemdValuesVID_; ///< Replica values variable ID. # endif /* BINTRAJ */ + /// Strings corresponding to NC_FMT_TYPE + static const char* NcFmtTypeStr_[]; }; #ifdef BINTRAJ // ----- Inline Functions ------------------------------------------------------ diff --git a/src/StringRoutines.cpp b/src/StringRoutines.cpp index d8d1649e74..8ef96147c0 100644 --- a/src/StringRoutines.cpp +++ b/src/StringRoutines.cpp @@ -400,17 +400,22 @@ std::string ArrayToRangeExpression(std::vector const& arrayIn, int offsetIn unsigned int idx = 0; while (idx < arrayIn.size()) { unsigned int kdx = idx + 1; - int delta = arrayIn[kdx] - arrayIn[kdx-1]; - while (delta == 1) { - kdx++; - if (kdx == arrayIn.size()) break; - delta = arrayIn[kdx] - arrayIn[kdx-1]; - } - //mprintf("DEBUG: idx= %u kdx= %u array[i]= %i array[k-1]= %i delta= %i\n", - // idx, kdx, arrayIn[idx], arrayIn[kdx-1], delta); - if (delta <= 0) { - mprinterr("Internal Error: ArrayToRangeExpression() requires arrays in increasing order.\n"); - return std::string(""); + if (kdx < arrayIn.size()) { + int delta = arrayIn[kdx] - arrayIn[kdx-1]; + while (delta == 1) { + kdx++; + if (kdx == arrayIn.size()) break; + delta = arrayIn[kdx] - arrayIn[kdx-1]; + } + //mprintf("DEBUG: idx= %u kdx= %u array[i]= %i array[k-1]= %i delta= %i\n", + // idx, kdx, arrayIn[idx], arrayIn[kdx-1], delta); + if (delta <= 0) { + mprinterr("Internal Error: ArrayToRangeExpression() requires arrays in increasing order.\n"); + mprinterr("Internal Error: idx = %u kdx = %u delta = %i\n", idx, kdx, delta); + for (unsigned int ii = 0; ii < arrayIn.size(); ii++) + mprinterr("Internal Error:\t\t[%8u] %8i\n", ii, arrayIn[ii]); + return std::string(""); + } } if (commaGroup > 0) out.append(","); diff --git a/src/Traj_AmberNetcdf.cpp b/src/Traj_AmberNetcdf.cpp index 3ba8b91298..88cbe416ef 100644 --- a/src/Traj_AmberNetcdf.cpp +++ b/src/Traj_AmberNetcdf.cpp @@ -24,7 +24,14 @@ Traj_AmberNetcdf::Traj_AmberNetcdf() : outputTemp_(false), write_mdcrd_(false), write_mdvel_(false), - write_mdfrc_(false) + write_mdfrc_(false), + compress_(0), + icompress_(0), +# ifdef HAS_HDF5 + fchunkSize_(0), + ishuffle_(1), +# endif + ftype_(NC_V3) // Default to NetCDF 3 {} // DESTRUCTOR @@ -36,7 +43,8 @@ Traj_AmberNetcdf::~Traj_AmberNetcdf() { } bool Traj_AmberNetcdf::ID_TrajFormat(CpptrajFile& fileIn) { - if ( GetNetcdfConventions( fileIn.Filename().full() ) == NC_AMBERTRAJ ) return true; + if ( GetNetcdfConventions( ftype_, fileIn.Filename().full() ) == NC_AMBERTRAJ ) + return true; return false; } @@ -94,10 +102,16 @@ int Traj_AmberNetcdf::setupTrajin(FileName const& fname, Topology* trajParm) } void Traj_AmberNetcdf::WriteHelp() { - mprintf("\tremdtraj: Write temperature to trajectory (makes REMD trajectory).\n" - "\tmdvel : Write only velocities to trajectory.\n" - "\tmdfrc : Write only forces to trajectory.\n" - "\tmdcrd : Write coordinates to trajectory (only required with mdvel/mdfrc).\n"); + mprintf("\tremdtraj : Write temperature to trajectory (makes REMD trajectory).\n" + "\tmdvel : Write only velocities to trajectory.\n" + "\tmdfrc : Write only forces to trajectory.\n" + "\tmdcrd : Write coordinates to trajectory (only required with mdvel/mdfrc).\n" +# ifdef HAS_HDF5 + "\thdf5 : Create file as NetCDF4/HDF5 instead of NetCDF4 (classic).\n" + "\tcompress : Use compression in HDF5 file.\n" + "\ticompress : Use lossy compression in HDF5 file via conversion to integers.\n" +# endif + ); } // Traj_AmberNetcdf::processWriteArgs() @@ -110,6 +124,50 @@ int Traj_AmberNetcdf::processWriteArgs(ArgList& argIn, DataSetList const& DSLin) mprintf("Warning: The 'force' keyword is no longer necessary and has been deprecated.\n"); write_mdvel_ = argIn.hasKey("mdvel"); write_mdfrc_ = argIn.hasKey("mdfrc"); + if (argIn.hasKey("hdf5")) { +# ifdef HAS_HDF5 + ftype_ = NC_V4; +# else + mprinterr("Error: HDF5 output requested but cpptraj compiled without HDF5 support.\n"); + return 1; +# endif + } +# ifdef HAS_HDF5 + // HDF5-specific options + if (ftype_ == NC_V4) { + // Regular compression + if (argIn.hasKey("compress")) + // Use recommended compression level + compress_ = 1; + else + compress_ = argIn.getKeyInt("deflatelvl", 0); // NOTE: Hidden option + if (compress_ < 0) { + mprinterr("Error: compress cannot be negative.\n"); + return 1; + } + // Integer compression + if (argIn.hasKey("icompress")) + // Use recommended integer compression power + icompress_ = 4; + else + icompress_ = argIn.getKeyInt("icompresspow", 0); // NOTE: Hidden option + if (icompress_ < 0) { + mprinterr("Error: icompress cannot be negative.\n"); + return 1; + } + // icompress implies compress + if (icompress_ > 0 && compress_ < 1) + compress_ = 1; + // integer shuffle + ishuffle_ = argIn.getKeyInt("ishuffle", 1); // NOTE: Hidden option + // Frame chunk size + fchunkSize_ = argIn.getKeyInt("fchunksize", 0); // NOTE: Hidden option + if (fchunkSize_ < 0) { + mprinterr("Error: fchunksize cannot be negative.\n"); + return 1; + } + } +# endif return 0; } @@ -151,10 +209,25 @@ int Traj_AmberNetcdf::setupTrajout(FileName const& fname, Topology* trajParm, // Set up title if (Title().empty()) SetTitle("Cpptraj Generated trajectory"); +# ifdef HAS_HDF5 + // Set compression levels + if (compress_ > 0 || icompress_ > 0) { + if (SetupCompression(compress_, icompress_, ishuffle_)) + return 1; + } + // Set frame chunk size + if (fchunkSize_ > 0) SetFrameChunkSize(fchunkSize_); +# endif // Create NetCDF file. - if (NC_create( filename_.Full(), NC_AMBERTRAJ, trajParm->Natom(), CoordInfo(), + if (NC_create( ftype_, filename_.Full(), NC_AMBERTRAJ, trajParm->Natom(), CoordInfo(), Title(), debug_ )) return 1; +//# ifdef HAS_HDF5 +// // Set up for integer compression if necessary +// if (icompress_ > 0) { +// if (NC_createIntCompressed(icompress_)) return 1; +// } +//# endif // Close Netcdf file. It will be reopened write. FIXME should NC_create leave it closed? NC_close(); // Allocate memory @@ -219,12 +292,19 @@ int Traj_AmberNetcdf::readFrame(int set, Frame& frameIn) { frameIn.SetTime( (double)time ); } - // Read Coords - if ( NC::CheckErr(nc_get_vara_float(ncid_, coordVID_, start_, count_, Coord_)) ) { - mprinterr("Error: Getting coordinates for frame %i\n", set+1); - return 1; + // Read Coords + # ifdef HAS_HDF5 + if (CompressedPosVID() != -1) { + if (NC_readIntCompressed(set, frameIn)) return 1; + } else +# endif + if (coordVID_ != -1) { + if ( NC::CheckErr(nc_get_vara_float(ncid_, coordVID_, start_, count_, Coord_)) ) { + mprinterr("Error: Getting coordinates for frame %i\n", set+1); + return 1; + } + FloatToDouble(frameIn.xAddress(), Coord_); } - FloatToDouble(frameIn.xAddress(), Coord_); // Read Velocities if (velocityVID_ != -1) { @@ -329,6 +409,11 @@ int Traj_AmberNetcdf::writeFrame(int set, Frame const& frameOut) { count_[2] = 3; // Write coords. +# ifdef HAS_HDF5 + if (CompressedPosVID() != -1) { + if (NC_writeIntCompressed(frameOut)) return 1; + } else +# endif if (coordVID_ != -1) { DoubleToFloat(Coord_, frameOut.xAddress()); if (NC::CheckErr(nc_put_vara_float(ncid_,coordVID_,start_,count_,Coord_)) ) { @@ -413,13 +498,17 @@ int Traj_AmberNetcdf::writeFrame(int set, Frame const& frameOut) { // Traj_AmberNetcdf::Info() void Traj_AmberNetcdf::Info() { - mprintf("is a NetCDF AMBER trajectory"); + static const char* fvstr[3] = { "?", "V3", "HDF5" }; + mprintf("is a NetCDF (%s) AMBER trajectory", fvstr[ftype_]); if (readAccess_) { mprintf(" with %s", CoordInfo().InfoString().c_str()); if (useVelAsCoords_) mprintf(" (using velocities as coordinates)"); if (useFrcAsCoords_) mprintf(" (using forces as coordinates)"); if (remd_dimension_ > 0) mprintf(", %i replica dimensions", remd_dimension_); - } + } else { + if (compress_ > 0) mprintf(", with compression"); + if (icompress_ > 0) mprintf(", with integer-compressed coordinates"); + } } #ifdef MPI #ifdef HAS_PNETCDF @@ -454,6 +543,12 @@ int Traj_AmberNetcdf::parallelSetupTrajout(FileName const& fname, Topology* traj Parallel::Comm const& commIn) { int err = 0; + if (ftype_ == NC_V4) { + if (commIn.Size() > 1) { + mprinterr("Error: NetCDF4/HDF5 write not yet supported for > 1 process.\n"); + return 1; + } + } if (commIn.Master()) { err = setupTrajout(fname, trajParm, cInfoIn, NframesToWrite, append); // NOTE: setupTrajout leaves file open. Should this change? diff --git a/src/Traj_AmberNetcdf.h b/src/Traj_AmberNetcdf.h index cf586072c1..8ffc618435 100644 --- a/src/Traj_AmberNetcdf.h +++ b/src/Traj_AmberNetcdf.h @@ -45,6 +45,13 @@ class Traj_AmberNetcdf : public TrajectoryIO, private NetcdfFile { bool write_mdcrd_; ///< If true write out coordinates bool write_mdvel_; ///< If true write out velocities bool write_mdfrc_; ///< If true write out forces + int compress_; ///< HDF5 compression level + int icompress_; ///< HDF5 integer compression level +# ifdef HAS_HDF5 + int fchunkSize_; ///< HDF5 frame chunk size + int ishuffle_; ///< HDF5 integer shuffle (1 = on, 0 = off) +# endif + NC_FMT_TYPE ftype_; ///< Base format type }; #endif #endif diff --git a/src/Traj_AmberRestartNC.cpp b/src/Traj_AmberRestartNC.cpp index 4003992a50..d7c0032478 100644 --- a/src/Traj_AmberRestartNC.cpp +++ b/src/Traj_AmberRestartNC.cpp @@ -23,7 +23,8 @@ Traj_AmberRestartNC::Traj_AmberRestartNC() : useFrcAsCoords_(false), outputTemp_(false), readAccess_(false), - prependExt_(false) + prependExt_(false), + ftype_(NC_V3) // Default to NetCDF 3 {} // DESTRUCTOR @@ -33,7 +34,8 @@ Traj_AmberRestartNC::~Traj_AmberRestartNC() { } bool Traj_AmberRestartNC::ID_TrajFormat(CpptrajFile& fileIn) { - if ( GetNetcdfConventions( fileIn.Filename().full() ) == NC_AMBERRESTART ) return true; + if ( GetNetcdfConventions( ftype_, fileIn.Filename().full() ) == NC_AMBERRESTART ) + return true; return false; } diff --git a/src/Traj_AmberRestartNC.h b/src/Traj_AmberRestartNC.h index 2916f597aa..303fe27823 100644 --- a/src/Traj_AmberRestartNC.h +++ b/src/Traj_AmberRestartNC.h @@ -46,6 +46,7 @@ class Traj_AmberRestartNC : public TrajectoryIO, private NetcdfFile { bool readAccess_; bool prependExt_; FileName filename_; + NC_FMT_TYPE ftype_; }; #endif #endif diff --git a/src/Traj_H5.cpp b/src/Traj_H5.cpp new file mode 100644 index 0000000000..d451d8c94b --- /dev/null +++ b/src/Traj_H5.cpp @@ -0,0 +1,508 @@ +#include "Traj_H5.h" +#include "Constants.h" +#include "CpptrajStdio.h" +#include "CpptrajFile.h" +#include "Topology.h" +#ifdef BINTRAJ +# include +# include "NC_Routines.h" +# include "Units.h" +#endif +//#ifdef HAS_HDF5 +//# include +// using namespace H5; +//#endif + +/// CONSTRUCTOR +Traj_H5::Traj_H5() +//#ifdef HAS_HDF5 +: +//file_(0) + ncid_(-1), + natom_(0), + coordVID_(-1), + cellLengthVID_(-1), + cellAngleVID_(-1), + timeVID_(-1), + convert_h5_to_cpptraj_box_(0), + convert_h5_to_cpptraj_coord_(0) +//#endif +{ + start_[0] = 0; + start_[1] = 0; + start_[2] = 0; + count_[0] = 0; + count_[1] = 0; + count_[2] = 0; +} + +/** DESTRUCTOR */ +Traj_H5::~Traj_H5() { + closeTraj(); +//# ifdef HAS_HDF5 +// if (file_ != 0) delete file_; +//# endif +} + +#ifdef HAS_HDF5 +bool Traj_H5::HasConventions(int ncid) { + std::string attrText = NC::GetAttrText(ncid, "conventions"); + if (attrText.empty()) + return false; + if (attrText != "Pande") { + mprinterr("Error: H5 file has conventions string that is not 'Pande'.\n"); + return false; + } + attrText = NC::GetAttrText(ncid, "conventionVersion"); + if ( attrText != "1.1") + mprintf("Warning: H5 file has conventionVersion that is not 1.1 (%s)\n", attrText.c_str()); + return true; +} +#endif + +/** Identify trajectory format. File should be setup for READ */ +bool Traj_H5::ID_TrajFormat(CpptrajFile& fileIn) { +# ifdef HAS_HDF5 + int myNcid; + if ( nc_open( fileIn.Filename().full(), NC_NOWRITE, &myNcid ) != NC_NOERR ) + return false; + if (HasConventions(myNcid)) return true; + nc_close( myNcid ); +# else + unsigned char buf[8]; + unsigned int nread = fileIn.Read(buf, 8); + if (nread > 7 && buf[0] == 0x89 && buf[1] == 0x48 && buf[2] == 0x44 && buf[3] == 0x46 && + buf[4] == 0x0d && buf[5] == 0x0a && buf[6] == 0x1a && buf[7] == 0x0a) + { + mprintf("Warning: File '%s' appears to be HDF5 but cpptraj was compiled without HDF5 support.\n", fileIn.Filename().full()); + } +# endif + return false; +} + +/** Print trajectory info to stdout. */ +void Traj_H5::Info() { + mprintf("is a MDtraj H5 (HDF5) trajectory"); +} + +/** Close file. */ +void Traj_H5::closeTraj() { +# ifdef HAS_HDF5 + if (ncid_ == -1) return; + bool err = NC::CheckErr( nc_close(ncid_) ); + if (err) { + mprinterr("Error closing ncid %i\n", ncid_); + } + //if (ncdebug_ > 0 && !err) + // mprintf("Successfully closed ncid %i\n",ncid_); + ncid_ = -1; +# endif +} + +// ----------------------------------------------------------------------------- +/** Open trajectory for reading. */ +int Traj_H5::openTrajin() { + + return 0; +} + +/** Read help */ +void Traj_H5::ReadHelp() { + +} + +/** Process read arguments. */ +int Traj_H5::processReadArgs(ArgList& argIn) { + + return 0; +} + +# ifdef HAS_HDF5 +/** Set up the coordinates variable ID, number of atoms, and number of frames. */ +int Traj_H5::setupCoordVID(int& frameDID, int& atomDID, int& spatialDID, int& nframes) +{ + // Get the 'coordinates' variable ID + if (NC::CheckErr(nc_inq_varid(ncid_, "coordinates", &coordVID_))) + return 1; + mprintf("DEBUG: Coordinates VID is %i\n", coordVID_); + // Set conversion factor for coords + std::string lengthUnits = NC::GetAttrText(ncid_, coordVID_, "units"); + if (Cpptraj::Units::SetConversionFactor( convert_h5_to_cpptraj_coord_, lengthUnits, "ang" )) { + mprinterr("Error: Could not determine Coordinates conversion factor.\n"); + return 1; + } + // Dimensions + frameDID = -1; + atomDID = -1; + spatialDID = -1; + natom_ = 0; + nframes = 0; + // Need to get the unlimited dimension ID, which should be the frame dim. + if (NC::CheckErr( nc_inq_unlimdim(ncid_, &frameDID) ) ) + return 1; + if (frameDID < 0) { + mprinterr("Error: No unlimited (frame) dimension present in H5 file.\n"); + return 1; + } + // Get dimensions for coordinates + int ndims = 0; + if (NC::CheckErr( nc_inq_varndims(ncid_, coordVID_, &ndims) ) ) + return 1; + if (ndims != 3) { + mprinterr("Error: Expected 3 dims for 'coordinates', got %i\n", ndims); + return 1; + } + int coord_dims[3]; + if (NC::CheckErr( nc_inq_vardimid(ncid_, coordVID_, coord_dims) ) ) + return 1; + mprintf("DEBUG: Coord dims: %i %i %i\n", coord_dims[0], coord_dims[1], coord_dims[2]); + // Check the dimensions. One should be frames (unlimited), one should be + // atoms, and the last should be spatial (XYZ) + + bool dim_used[3]; + for (int i = 0; i < 3; i++) dim_used[i] = false; + bool has_unlimited = false; + for (int nd = 0; nd < ndims; nd++) { + size_t dimsize = 0; + if (NC::CheckErr( nc_inq_dimlen(ncid_, coord_dims[nd], &dimsize))) + return 1; + mprintf("DEBUG: Dim %i size %zu\n", coord_dims[nd], dimsize); + if (coord_dims[nd] == frameDID) { + has_unlimited = true; + dim_used[nd] = true; + nframes = (int)dimsize; + } else if ( dimsize == 3 ) { + dim_used[nd] = true; + spatialDID = coord_dims[nd]; + } else { + // Should be natoms + dim_used[nd] = true; + natom_ = (int)dimsize; + atomDID = coord_dims[nd]; + } + } + + // Sanity checks + for (int nd = 0; nd < ndims; nd++) { + if (!dim_used[nd]) { + mprinterr("Error: Dimension %i remains unused for 'coordinates'.\n", coord_dims[nd]); + return 1; + } + } + if (!has_unlimited) { + mprinterr("Error: No unlimited dimension for 'coordinates'.\n"); + return 1; + } + // Expect dim order to be frame, atom, spatial + // TODO is this always the case for H5? + if (coord_dims[0] != frameDID) { + mprinterr("Error: Frame dimension is not first.\n"); + return 1; + } + if (coord_dims[1] != atomDID) { + mprinterr("Error: Atom dimension is not second.\n"); + return 1; + } + if (coord_dims[2] != spatialDID) { + mprinterr("Error: Spatial dimension is not third.\n"); + return 1; + } + return 0; +} + +/** Set up box variable IDs. + * \return 0 on success, 1 on error, -1 for no box coords. + */ +int Traj_H5::setupBoxVIDs(Box& ncbox, int frameDID, int spatialDID) { + ncbox.SetNoBox(); + // Get the 'cell_lengths' variable ID + int err = nc_inq_varid(ncid_, "cell_lengths", &cellLengthVID_); + if (err != NC_NOERR) return -1; + // Get the 'cell_angles' variable ID + if (NC::CheckErr(nc_inq_varid(ncid_, "cell_angles", &cellAngleVID_))) + return 1; + mprintf("DEBUG: Cell length vid= %i, cell angle vid= %i\n", + cellLengthVID_, cellAngleVID_); + // Ensure angles are in degrees + std::string angleUnits = NC::GetAttrText(ncid_, cellAngleVID_, "units"); + if (angleUnits != "degrees") { + mprinterr("Error: Cell angles have units that are not 'degrees' (%s)\n", angleUnits.c_str()); + return 1; + } + // Check units for lengths + std::string lengthUnits = NC::GetAttrText(ncid_, cellLengthVID_, "units"); + if (Cpptraj::Units::SetConversionFactor(convert_h5_to_cpptraj_box_, lengthUnits, "ang")) { + mprinterr("Error: Could not determine Cell Lengths conversion factor.\n"); + return 1; + } + // Get box lengths and angles to determine box type. + start_[0] = 0; + start_[1] = 0; + count_[0] = 1; // 1 frame + count_[1] = 3; // 3 coordinates (abg or xyz) + double boxCrd[6]; /// XYZ ABG + float* fptr = &ftmp_[0]; + if ( NC::CheckErr(nc_get_vara_float(ncid_, cellLengthVID_, start_, count_, fptr )) ) + { + mprinterr("Error: Getting cell lengths.\n"); + return 1; + } + if ( NC::CheckErr(nc_get_vara_float(ncid_, cellAngleVID_, start_, count_, fptr+3)) ) + { + mprinterr("Error: Getting cell angles.\n"); + return 1; + } + for (int i = 0; i < 6; i++) + boxCrd[i] = (double)ftmp_[i]; + // Convert + boxCrd[0] *= convert_h5_to_cpptraj_box_; + boxCrd[1] *= convert_h5_to_cpptraj_box_; + boxCrd[2] *= convert_h5_to_cpptraj_box_; + mprintf("DEBUG:\tH5 Box: XYZ={%f %f %f} ABG={%f %f %f}\n", + boxCrd[0], boxCrd[1], boxCrd[2], boxCrd[3], boxCrd[4], boxCrd[5]); + if (ncbox.SetupFromXyzAbg( boxCrd )) { + mprintf("Warning: H5 file unit cell variables appear to be empty; disabling box.\n"); + cellLengthVID_ = -1; + cellAngleVID_ = -1; + ncbox.SetNoBox(); + return -1; + } + // TODO check dim IDs + + return 0; +} + +#endif /* HAS_HDF5 */ + + +/** Set up trajectory for reading. + * \return Number of frames in trajectory. + */ +int Traj_H5::setupTrajin(FileName const& fname, Topology* trajParm) +{ +# ifdef HAS_HDF5 +/* if (file_ != 0) + delete file_; + file_ = new H5File( fname.full(), H5F_ACC_RDONLY ); + if (file_ == 0) { + mprinterr("Error: Could not allocate input trajectory file.\n"); + return TRAJIN_ERR; + } + return 0;*/ + if (ncid_ != -1) closeTraj(); + if ( NC::CheckErr( nc_open( fname.full(), NC_NOWRITE, &ncid_ ) ) ) + return TRAJIN_ERR; + NC::Debug(ncid_); + + // Set up coordinates + int frameDID, atomDID, spatialDID, nframes; + if (setupCoordVID(frameDID, atomDID, spatialDID, nframes)) { + mprinterr("Error: Could not set up coordinates variable.\n"); + return TRAJIN_ERR; + } + mprintf("DEBUG: Unlimited dimid is %i\n", frameDID); + mprintf("DEBUG: Atom dim is %i\n", atomDID); + mprintf("DEBUG: Spatial dim is %i\n", spatialDID); + + // Check # atoms + if ( natom_ != trajParm->Natom() ) { + mprinterr("Error: Atom mismatch between topology (%i) and trajectory (%i).\n", + trajParm->Natom(), natom_); + return TRAJIN_ERR; + } + + // Allocate temp space + ftmp_.assign( natom_*3, 0 ); + + // Check for box + Box ncbox; + int err = setupBoxVIDs(ncbox, frameDID, spatialDID); + if (err == 1) { + mprinterr("Error: Problem setting up box info.\n"); + return TRAJIN_ERR; + } + + // Check for time + err = nc_inq_varid(ncid_, "time", &timeVID_); + if (err != NC_NOERR) + timeVID_ = -1; + + // Get title + SetTitle( NC::GetAttrText(ncid_, "TITLE") ); + + // Setup coordinfo + SetCoordInfo( CoordinateInfo( ncbox, false, false, (timeVID_ != -1) ) ); + + return nframes; +# else + return TRAJIN_ERR; +# endif +} + +/** Read specified trajectory frame. */ +int Traj_H5::readFrame(int set, Frame& frameIn) { +# ifdef HAS_HDF5 + start_[0] = set; + start_[1] = 0; + start_[2] = 0; + count_[0] = 1; + count_[1] = natom_; + count_[2] = 3; + +/* // Get temperature + if (TempVID_!=-1) { + if ( NC::CheckErr(nc_get_vara_double(ncid_, TempVID_, start_, count_, frameIn.tAddress())) ) { + mprinterr("Error: Getting replica temperature for frame %i.\n", set+1); + return 1; + } + //fprintf(stderr,"DEBUG: Replica Temperature %lf\n",F->T); + }*/ + + // Get time + if (timeVID_!=-1) { + float time; + if (NC::CheckErr(nc_get_vara_float(ncid_, timeVID_, start_, count_, &time))) { + mprinterr("Error: Getting time for frame %i.\n", set + 1); + return 1; + } + frameIn.SetTime( (double)time ); + } + + float* fptr = &ftmp_[0]; + // Read Coords + if (coordVID_ != -1) { + if ( NC::CheckErr(nc_get_vara_float(ncid_, coordVID_, start_, count_, fptr)) ) { + mprinterr("Error: Getting coordinates for frame %i\n", set+1); + return 1; + } + for (unsigned int idx = 0; idx != ftmp_.size(); idx++) + frameIn.xAddress()[idx] = (double)ftmp_[idx] * convert_h5_to_cpptraj_coord_; + } + + // Read Velocities + /*if (velocityVID_ != -1) { + if ( NC::CheckErr(nc_get_vara_float(ncid_, velocityVID_, start_, count_, Coord_)) ) { + mprinterr("Error: Getting velocities for frame %i\n", set+1); + return 1; + } + FloatToDouble(frameIn.vAddress(), Coord_); + }*/ + + // Read Forces + /*if (frcVID_ != -1) { + if ( NC::CheckErr(nc_get_vara_float(ncid_, frcVID_, start_, count_, Coord_)) ) { + mprinterr("Error: Getting forces for frame %i\n", set+1); + return 1; + } + FloatToDouble(frameIn.fAddress(), Coord_); + }*/ + + // Read box info + if (cellLengthVID_ != -1) { + double xyzabg[6]; + count_[1] = 3; + count_[2] = 0; + if (NC::CheckErr(nc_get_vara_float(ncid_, cellLengthVID_, start_, count_, fptr))) + { + mprinterr("Error: Getting cell lengths for frame %i.\n", set+1); + return 1; + } + if (NC::CheckErr(nc_get_vara_float(ncid_, cellAngleVID_, start_, count_, fptr+3))) + { + mprinterr("Error: Getting cell angles for frame %i.\n", set+1); + return 1; + } + for (int i = 0; i < 6; i++) + xyzabg[i] = (double)ftmp_[i]; + // Convert + xyzabg[0] *= convert_h5_to_cpptraj_box_; + xyzabg[1] *= convert_h5_to_cpptraj_box_; + xyzabg[2] *= convert_h5_to_cpptraj_box_; + frameIn.ModifyBox().AssignFromXyzAbg( xyzabg ); + } + + return 0; +# else /* HAS_HDF5 */ + return 1; +# endif +} + +/** Read velocities from specified frame. */ +int Traj_H5::readVelocity(int set, Frame& frameIn) { + + return 0; +} + +/** Read forces from specified frame. */ +int Traj_H5::readForce(int set, Frame& frameIn) { + + return 0; +} + +// ----------------------------------------------------------------------------- +/** Write help. */ +void Traj_H5::WriteHelp() { + +} + +/** Process write arguments. */ +int Traj_H5::processWriteArgs(ArgList& argIn, DataSetList const& DSLin) { + + return 0; +} + +/** Set up trajectory for write. */ +int Traj_H5::setupTrajout(FileName const& fname, Topology* trajParm, + CoordinateInfo const& cInfoIn, + int NframesToWrite, bool append) +{ + mprinterr("Error: H5 write not yet supported.\n"); + return 1; +} + +/** Write specified trajectory frame. */ +int Traj_H5::writeFrame(int set, Frame const& frameOut) { + + mprinterr("Error: H5 write not yet supported.\n"); + return 0; +} + +// ============================================================================= +#ifdef MPI +/** Open trajectory for reading in parallel. */ +int Traj_H5::parallelOpenTrajin(Parallel::Comm const& commIn) { + return 1; +} + +/** Open trajectory for writing in parallel. */ +int Traj_H5::parallelOpenTrajout(Parallel::Comm const& commIn) { + return 1; +} + +/** Set up trajectory for write in parallel. */ +int Traj_H5::parallelSetupTrajout(FileName const& fname, Topology* trajParm, + CoordinateInfo const& cInfoIn, + int NframesToWrite, bool append, + Parallel::Comm const& commIn) +{ + + return 1; +} + +/** Read frame in parallel. */ +int Traj_H5::parallelReadFrame(int set, Frame& frameIn) { + + return 1; +} + +/** Write frame in parallel. */ +int Traj_H5::parallelWriteFrame(int set, Frame const& frameOut) { + + return 1; +} + +/** Close trajectory in parallel. */ +void Traj_H5::parallelCloseTraj() { + +} +#endif diff --git a/src/Traj_H5.h b/src/Traj_H5.h new file mode 100644 index 0000000000..7834e629bd --- /dev/null +++ b/src/Traj_H5.h @@ -0,0 +1,63 @@ +#ifndef INC_TRAJ_H5_H +#define INC_TRAJ_H5_H +#include "TrajectoryIO.h" +#include +//namespace H5 { +// class H5File; +//} +/// MDtraj H5 (HDF5) format +class Traj_H5 : public TrajectoryIO { + public: + Traj_H5(); + ~Traj_H5(); + static BaseIOtype* Alloc() { return (BaseIOtype*)new Traj_H5(); } + static void WriteHelp(); + static void ReadHelp(); + private: + // ----- Inherited functions ----------------- + bool ID_TrajFormat(CpptrajFile&); + int setupTrajin(FileName const&, Topology*); + int setupTrajout(FileName const&, Topology*, CoordinateInfo const&,int, bool); + int openTrajin(); + void closeTraj(); + int readFrame(int,Frame&); + int writeFrame(int,Frame const&); + void Info(); + int readVelocity(int, Frame&); + int readForce(int, Frame&); + int processWriteArgs(ArgList&, DataSetList const&); + int processReadArgs(ArgList&); + // ------------------------------------------- +# ifdef MPI + // ----- Parallel functions ------------------ + int parallelOpenTrajin(Parallel::Comm const&); + int parallelOpenTrajout(Parallel::Comm const&); + int parallelSetupTrajout(FileName const&, Topology*, CoordinateInfo const&, + int, bool, Parallel::Comm const&); + int parallelReadFrame(int, Frame&); + int parallelWriteFrame(int, Frame const&); + void parallelCloseTraj(); + // ------------------------------------------- +# endif +# ifdef HAS_HDF5 + static bool HasConventions(int); + /// Set up coordinates VID and related dim sizes + int setupCoordVID(int&, int&, int&, int&); + /// Set up box variable IDs and determine type + int setupBoxVIDs(Box&, int, int); +# endif + +// H5::H5File* file_; + int ncid_; ///< NetCDF ID + int natom_; ///< Number of atoms in each trajectory frame. + int coordVID_; ///< Coordinates variable ID + int cellLengthVID_; ///< Cell lengths variable ID + int cellAngleVID_; ///< Cell angles variable ID + int timeVID_; ///< Time variable ID + size_t start_[3]; ///< Start indices in each dimension + size_t count_[3]; ///< Count indices in each dimension + double convert_h5_to_cpptraj_box_; ///< For converting h5 box lengths to angstroms + double convert_h5_to_cpptraj_coord_; ///< For converting h5 coordinates to angstroms + std::vector ftmp_; ///< Temporary array to store floats +}; +#endif diff --git a/src/Traj_H5MD.cpp b/src/Traj_H5MD.cpp new file mode 100644 index 0000000000..809b3504bc --- /dev/null +++ b/src/Traj_H5MD.cpp @@ -0,0 +1,574 @@ +#include "Traj_H5MD.h" +#include "Constants.h" +#include "CpptrajStdio.h" +#include "CpptrajFile.h" +#include "Topology.h" +#ifdef BINTRAJ +# include +# include "NC_Routines.h" +# include "Units.h" +#endif +//#ifdef HAS_HDF5 +//# include +// using namespace H5; +//#endif + +/// CONSTRUCTOR +Traj_H5MD::Traj_H5MD() +//#ifdef HAS_HDF5 +: +//file_(0) + particle_gid_(-1), + position_gid_(-1), + edges_gid_(-1), + ncid_(-1), + natom_(0), + coordVID_(-1), + cellLengthVID_(-1), + cellAngleVID_(-1), + timeVID_(-1), + convert_h5_to_cpptraj_box_(0), + convert_h5_to_cpptraj_coord_(0) +//#endif +{ + start_[0] = 0; + start_[1] = 0; + start_[2] = 0; + count_[0] = 0; + count_[1] = 0; + count_[2] = 0; +} + +/** DESTRUCTOR */ +Traj_H5MD::~Traj_H5MD() { + closeTraj(); +//# ifdef HAS_HDF5 +// if (file_ != 0) delete file_; +//# endif +} + + +/** Identify trajectory format. File should be setup for READ */ +bool Traj_H5MD::ID_TrajFormat(CpptrajFile& fileIn) { +# ifdef HAS_HDF5 + int myNcid; + if ( nc_open( fileIn.Filename().full(), NC_NOWRITE, &myNcid ) != NC_NOERR ) + return false; + mainGroupNames_ = NC::GetGroupNames( myNcid, mainGroupIds_ ); + if (mainGroupNames_.empty()) return false; + // Check for h5md and particle groups + bool is_h5md = false; + particle_gid_ = -1; + for (unsigned int ii = 0; ii != mainGroupNames_.size(); ii++) { + if (mainGroupNames_[ii] == "h5md") { + is_h5md = true; + } else if (mainGroupNames_[ii] == "particles") { + particle_gid_ = mainGroupIds_[ii]; + } + } + nc_close( myNcid ); + if (is_h5md) { + if (particle_gid_ == -1) { + mprinterr("Error: H5MD file missing 'particle' group.\n"); + } else { + return true; + } + } +# else + unsigned char buf[8]; + unsigned int nread = fileIn.Read(buf, 8); + if (nread > 7 && buf[0] == 0x89 && buf[1] == 0x48 && buf[2] == 0x44 && buf[3] == 0x46 && + buf[4] == 0x0d && buf[5] == 0x0a && buf[6] == 0x1a && buf[7] == 0x0a) + { + mprintf("Warning: File '%s' appears to be HDF5 but cpptraj was compiled without HDF5 support.\n", fileIn.Filename().full()); + } +# endif + return false; +} + +/** Print trajectory info to stdout. */ +void Traj_H5MD::Info() { + mprintf("is a MDanalysis H5MD (HDF5) trajectory"); +} + +/** Close file. */ +void Traj_H5MD::closeTraj() { +# ifdef HAS_HDF5 + if (ncid_ == -1) return; + bool err = NC::CheckErr( nc_close(ncid_) ); + if (err) { + mprinterr("Error closing ncid %i\n", ncid_); + } + //if (ncdebug_ > 0 && !err) + // mprintf("Successfully closed ncid %i\n",ncid_); + ncid_ = -1; +# endif +} + +// ----------------------------------------------------------------------------- +/** Open trajectory for reading. */ +int Traj_H5MD::openTrajin() { + + return 0; +} + +/** Read help */ +void Traj_H5MD::ReadHelp() { + +} + +/** Process read arguments. */ +int Traj_H5MD::processReadArgs(ArgList& argIn) { + + return 0; +} + +# ifdef HAS_HDF5 +/** Set up the coordinates variable ID, number of atoms, and number of frames. */ +int Traj_H5MD::setupCoordVID(int& frameDID, int& atomDID, + int& spatialDID, int& nframes) +{ + // Get the 'coordinates' variable ID ('value') + if (NC::CheckErr(nc_inq_varid(position_gid_, "value", &coordVID_))) + return 1; + mprintf("DEBUG: Coordinates VID is %i\n", coordVID_); + // Set conversion factor for coords + std::string lengthUnits = NC::GetAttrText(position_gid_, coordVID_, "unit"); + mprintf("DEBUG: length units are: %s\n", lengthUnits.c_str()); + if (Cpptraj::Units::SetConversionFactor( convert_h5_to_cpptraj_coord_, lengthUnits, "ang" )) { + mprinterr("Error: Could not determine Coordinates conversion factor.\n"); + return 1; + } + + // Dimensions + frameDID = -1; + atomDID = -1; + spatialDID = -1; + natom_ = 0; + nframes = 0; + // Need to get the unlimited dimension ID, which should be the frame dim. + if (NC::CheckErr( nc_inq_unlimdim(position_gid_, &frameDID) ) ) + return 1; + if (frameDID < 0) { + mprinterr("Error: No unlimited (frame) dimension present in H5MD file.\n"); + return 1; + } + // Get dimensions for coordinates + int ndims = 0; + if (NC::CheckErr( nc_inq_varndims(position_gid_, coordVID_, &ndims) ) ) + return 1; + if (ndims != 3) { + mprinterr("Error: Expected 3 dims for 'coordinates', got %i\n", ndims); + return 1; + } + int coord_dims[3]; + if (NC::CheckErr( nc_inq_vardimid(position_gid_, coordVID_, coord_dims) ) ) + return 1; + mprintf("DEBUG: Coord dims: %i %i %i\n", coord_dims[0], coord_dims[1], coord_dims[2]); + // Check the dimensions. One should be frames (unlimited), one should be + // atoms, and the last should be spatial (XYZ) + + bool dim_used[3]; + for (int i = 0; i < 3; i++) dim_used[i] = false; + bool has_unlimited = false; + for (int nd = 0; nd < ndims; nd++) { + size_t dimsize = 0; + if (NC::CheckErr( nc_inq_dimlen(position_gid_, coord_dims[nd], &dimsize))) + return 1; + mprintf("DEBUG: Dim %i size %zu\n", coord_dims[nd], dimsize); + if (coord_dims[nd] == frameDID) { + has_unlimited = true; + dim_used[nd] = true; + nframes = (int)dimsize; + } else if ( dimsize == 3 ) { + dim_used[nd] = true; + spatialDID = coord_dims[nd]; + } else { + // Should be natoms + dim_used[nd] = true; + natom_ = (int)dimsize; + atomDID = coord_dims[nd]; + } + } + + // Sanity checks + for (int nd = 0; nd < ndims; nd++) { + if (!dim_used[nd]) { + mprinterr("Error: Dimension %i remains unused for 'coordinates'.\n", coord_dims[nd]); + return 1; + } + } + if (!has_unlimited) { + mprinterr("Error: No unlimited dimension for 'coordinates'.\n"); + return 1; + } + // Expect dim order to be frame, atom, spatial + // TODO is this always the case for H5MD? + if (coord_dims[0] != frameDID) { + mprinterr("Error: Frame dimension is not first.\n"); + return 1; + } + if (coord_dims[1] != atomDID) { + mprinterr("Error: Atom dimension is not second.\n"); + return 1; + } + if (coord_dims[2] != spatialDID) { + mprinterr("Error: Spatial dimension is not third.\n"); + return 1; + } + return 0; +} + +/** Set up box variable IDs. + * \return 0 on success, 1 on error, -1 for no box coords. + */ +int Traj_H5MD::setupBoxVIDs(int box_gid, Box& ncbox, int frameDID, int spatialDID) { + ncbox.SetNoBox(); + // Search for 'edges' group id + edges_gid_ = -1; + Iarray box_ids; + Sarray box_gnames = NC::GetGroupNames( box_gid, box_ids ); + for (unsigned int ii = 0; ii < box_gnames.size(); ii++) { + if (box_gnames[ii] == "edges") { + edges_gid_ = box_ids[ii]; + } + } + mprintf("DEBUG: edges group id %i\n", edges_gid_); + if (edges_gid_ < 0) { + mprinterr("Error: box group does not contain 'edges'\n"); + return 1; + } + // Get the cell_lengths 'value' variable ID + int err = nc_inq_varid(edges_gid_, "value", &cellLengthVID_); + if (err != NC_NOERR) return -1; +/* // Get the 'cell_angles' variable ID + if (NC::CheckErr(nc_inq_varid(edges_gid_, "cell_angles", &cellAngleVID_))) + return 1; + mprintf("DEBUG: Cell length vid= %i, cell angle vid= %i\n", + cellLengthVID_, cellAngleVID_); + // Ensure angles are in degrees + std::string angleUnits = NC::GetAttrText(edges_gid_, cellAngleVID_, "units"); + if (angleUnits != "degrees") { + mprinterr("Error: Cell angles have units that are not 'degrees' (%s)\n", angleUnits.c_str()); + return 1; + }*/ + // Check units for lengths + std::string lengthUnits = NC::GetAttrText(edges_gid_, cellLengthVID_, "unit"); + if (Cpptraj::Units::SetConversionFactor(convert_h5_to_cpptraj_box_, lengthUnits, "ang")) { + mprinterr("Error: Could not determine Cell Lengths conversion factor.\n"); + return 1; + } + // Check what kind of info is stored + int ndims = 0; + if (NC::CheckErr( nc_inq_varndims(edges_gid_, cellLengthVID_, &ndims) ) ) + return 1; + if (ndims != 3) { + mprinterr("Error: Expected 3 dims for 'edges', got %i\n", ndims); + return 1; + } + + // Get box lengths and angles to determine box type. + start_[0] = 0; + start_[1] = 0; + start_[2] = 0; + count_[0] = 1; // 1 frame + count_[1] = 3; // 3 unit cell vectors + count_[2] = 3; // 3 coordinates (XYZ) + double ucell[9]; /// Unit cell vectors in rows + float* fptr = &ftmp_[0]; + if ( NC::CheckErr(nc_get_vara_float(edges_gid_, cellLengthVID_, start_, count_, fptr )) ) + { + mprinterr("Error: Getting unit cell vectors.\n"); + return 1; + } + /*if ( NC::CheckErr(nc_get_vara_float(edges_gid_, cellAngleVID_, start_, count_, fptr+3)) ) + { + mprinterr("Error: Getting cell angles.\n"); + return 1; + }*/ + // Convert + for (int i = 0; i < 9; i++) + ucell[i] = (double)ftmp_[i] * convert_h5_to_cpptraj_box_; + // Convert +/* boxCrd[0] *= convert_h5_to_cpptraj_box_; + boxCrd[1] *= convert_h5_to_cpptraj_box_; + boxCrd[2] *= convert_h5_to_cpptraj_box_;*/ + mprintf("DEBUG:\tH5MD Box: X={%f %f %f}\n" + " \t Y={%f %f %f}\n" + " \t Z={%f %f %f}\n", + ucell[0], ucell[1], ucell[2], + ucell[3], ucell[4], ucell[5], + ucell[6], ucell[7], ucell[8]); + if (ncbox.SetupFromUcell( ucell )) { + mprintf("Warning: H5MD file unit cell variables appear to be empty; disabling box.\n"); + cellLengthVID_ = -1; + cellAngleVID_ = -1; + ncbox.SetNoBox(); + return -1; + } + // TODO check dim IDs + + return 0; +} + +#endif /* HAS_HDF5 */ + + +/** Set up trajectory for reading. + * \return Number of frames in trajectory. + */ +int Traj_H5MD::setupTrajin(FileName const& fname, Topology* trajParm) +{ +# ifdef HAS_HDF5 +/* if (file_ != 0) + delete file_; + file_ = new H5File( fname.full(), H5F_ACC_RDONLY ); + if (file_ == 0) { + mprinterr("Error: Could not allocate input trajectory file.\n"); + return TRAJIN_ERR; + } + return 0;*/ + if (ncid_ != -1) closeTraj(); + if ( NC::CheckErr( nc_open( fname.full(), NC_NOWRITE, &ncid_ ) ) ) + return TRAJIN_ERR; + NC::Debug(ncid_); + + // Get trajectory group in the particles group + int trajectory_gid = -1; + Iarray particle_ids; + Sarray particle_gnames = NC::GetGroupNames( particle_gid_, particle_ids ); + for (unsigned int ii = 0; ii < particle_gnames.size(); ii++) { + if (particle_gnames[ii] == "trajectory") + trajectory_gid = particle_ids[ii]; + } + if (trajectory_gid == -1) { + mprinterr("Error: 'trajectory' group not found.\n"); + return TRAJIN_ERR; + } + // Get box and position groups in the trajectory group + int box_gid = -1; + position_gid_ = -1; + Iarray trajectory_ids; + Sarray trajectory_gnames = NC::GetGroupNames( trajectory_gid, trajectory_ids ); + for (unsigned int ii = 0; ii < trajectory_gnames.size(); ii++) { + if (trajectory_gnames[ii] == "box") + box_gid = trajectory_ids[ii]; + else if (trajectory_gnames[ii] == "position") + position_gid_ = trajectory_ids[ii]; + } + mprintf("DEBUG: Box gid = %i, position gid = %i\n", box_gid, position_gid_); + + // Set up coordinates + int frameDID, atomDID, spatialDID, nframes; + if (setupCoordVID(frameDID, atomDID, spatialDID, nframes)) { + mprinterr("Error: Could not set up coordinates variable.\n"); + return TRAJIN_ERR; + } + mprintf("DEBUG: Unlimited dimid is %i\n", frameDID); + mprintf("DEBUG: Atom dim is %i\n", atomDID); + mprintf("DEBUG: Spatial dim is %i\n", spatialDID); + + // Check # atoms + if ( natom_ != trajParm->Natom() ) { + mprinterr("Error: Atom mismatch between topology (%i) and trajectory (%i).\n", + trajParm->Natom(), natom_); + return TRAJIN_ERR; + } + + // Allocate temp space + ftmp_.assign( natom_*3, 0 ); + + // Check for box + Box ncbox; + int err = setupBoxVIDs(box_gid, ncbox, frameDID, spatialDID); + if (err == 1) { + mprinterr("Error: Problem setting up box info.\n"); + return TRAJIN_ERR; + } + ncbox.PrintDebug("H5MD box"); + + // Check for time + err = nc_inq_varid(position_gid_, "time", &timeVID_); + if (err != NC_NOERR) + timeVID_ = -1; + mprintf("DEBUG: Time variable ID %i\n", timeVID_); + + // Get title + SetTitle( NC::GetAttrText(ncid_, "TITLE") ); + + // Setup coordinfo + SetCoordInfo( CoordinateInfo( ncbox, false, false, (timeVID_ != -1) ) ); + + return nframes; +# else + return TRAJIN_ERR; +# endif +} + +/** Read specified trajectory frame. */ +int Traj_H5MD::readFrame(int set, Frame& frameIn) { +# ifdef HAS_HDF5 + start_[0] = set; + start_[1] = 0; + start_[2] = 0; + count_[0] = 1; + count_[1] = natom_; + count_[2] = 3; + +/* // Get temperature + if (TempVID_!=-1) { + if ( NC::CheckErr(nc_get_vara_double(ncid_, TempVID_, start_, count_, frameIn.tAddress())) ) { + mprinterr("Error: Getting replica temperature for frame %i.\n", set+1); + return 1; + } + //fprintf(stderr,"DEBUG: Replica Temperature %lf\n",F->T); + }*/ + + // Get time + if (timeVID_!=-1) { + float time; + if (NC::CheckErr(nc_get_vara_float(position_gid_, timeVID_, start_, count_, &time))) { + mprinterr("Error: Getting time for frame %i.\n", set + 1); + return 1; + } + frameIn.SetTime( (double)time ); + } + + float* fptr = &ftmp_[0]; + // Read Coords + if (coordVID_ != -1) { + if ( NC::CheckErr(nc_get_vara_float(position_gid_, coordVID_, start_, count_, fptr)) ) { + mprinterr("Error: Getting coordinates for frame %i\n", set+1); + return 1; + } + for (unsigned int idx = 0; idx != ftmp_.size(); idx++) + frameIn.xAddress()[idx] = (double)ftmp_[idx] * convert_h5_to_cpptraj_coord_; + } + + // Read Velocities + /*if (velocityVID_ != -1) { + if ( NC::CheckErr(nc_get_vara_float(position_gid_, velocityVID_, start_, count_, Coord_)) ) { + mprinterr("Error: Getting velocities for frame %i\n", set+1); + return 1; + } + FloatToDouble(frameIn.vAddress(), Coord_); + }*/ + + // Read Forces + /*if (frcVID_ != -1) { + if ( NC::CheckErr(nc_get_vara_float(position_gid_, frcVID_, start_, count_, Coord_)) ) { + mprinterr("Error: Getting forces for frame %i\n", set+1); + return 1; + } + FloatToDouble(frameIn.fAddress(), Coord_); + }*/ + + // Read box info + if (cellLengthVID_ != -1) { + double ucell[9]; + count_[1] = 3; + count_[2] = 3; + if (NC::CheckErr(nc_get_vara_float(edges_gid_, cellLengthVID_, start_, count_, fptr))) + { + mprinterr("Error: Getting unit cell vectors for frame %i.\n", set+1); + return 1; + } +/* if (NC::CheckErr(nc_get_vara_float(edges_gid_, cellAngleVID_, start_, count_, fptr+3))) + { + mprinterr("Error: Getting cell angles for frame %i.\n", set+1); + return 1; + }*/ + // Convert + for (int i = 0; i < 9; i++) + ucell[i] = (double)ftmp_[i] * convert_h5_to_cpptraj_box_; + // Convert +/* xyzabg[0] *= convert_h5_to_cpptraj_box_; + xyzabg[1] *= convert_h5_to_cpptraj_box_; + xyzabg[2] *= convert_h5_to_cpptraj_box_;*/ + frameIn.ModifyBox().AssignFromUcell( ucell ); + } + return 0; +# else /* HAS_HDF5 */ + return 1; +# endif +} + +/** Read velocities from specified frame. */ +int Traj_H5MD::readVelocity(int set, Frame& frameIn) { + + return 0; +} + +/** Read forces from specified frame. */ +int Traj_H5MD::readForce(int set, Frame& frameIn) { + + return 0; +} + +// ----------------------------------------------------------------------------- +/** Write help. */ +void Traj_H5MD::WriteHelp() { + +} + +/** Process write arguments. */ +int Traj_H5MD::processWriteArgs(ArgList& argIn, DataSetList const& DSLin) { + + return 0; +} + +/** Set up trajectory for write. */ +int Traj_H5MD::setupTrajout(FileName const& fname, Topology* trajParm, + CoordinateInfo const& cInfoIn, + int NframesToWrite, bool append) +{ + mprinterr("Error: H5 write not yet supported.\n"); + return 1; +} + +/** Write specified trajectory frame. */ +int Traj_H5MD::writeFrame(int set, Frame const& frameOut) { + + mprinterr("Error: H5 write not yet supported.\n"); + return 0; +} + +// ============================================================================= +#ifdef MPI +/** Open trajectory for reading in parallel. */ +int Traj_H5MD::parallelOpenTrajin(Parallel::Comm const& commIn) { + return 1; +} + +/** Open trajectory for writing in parallel. */ +int Traj_H5MD::parallelOpenTrajout(Parallel::Comm const& commIn) { + return 1; +} + +/** Set up trajectory for write in parallel. */ +int Traj_H5MD::parallelSetupTrajout(FileName const& fname, Topology* trajParm, + CoordinateInfo const& cInfoIn, + int NframesToWrite, bool append, + Parallel::Comm const& commIn) +{ + + return 1; +} + +/** Read frame in parallel. */ +int Traj_H5MD::parallelReadFrame(int set, Frame& frameIn) { + + return 1; +} + +/** Write frame in parallel. */ +int Traj_H5MD::parallelWriteFrame(int set, Frame const& frameOut) { + + return 1; +} + +/** Close trajectory in parallel. */ +void Traj_H5MD::parallelCloseTraj() { + +} +#endif diff --git a/src/Traj_H5MD.h b/src/Traj_H5MD.h new file mode 100644 index 0000000000..a5047156d4 --- /dev/null +++ b/src/Traj_H5MD.h @@ -0,0 +1,72 @@ +#ifndef INC_TRAJ_H5MD_H +#define INC_TRAJ_H5MD_H +#include "TrajectoryIO.h" +#include +//namespace H5 { +// class H5File; +//} +/// MDanalysis H5MD (HDF5) format +class Traj_H5MD : public TrajectoryIO { + public: + Traj_H5MD(); + ~Traj_H5MD(); + static BaseIOtype* Alloc() { return (BaseIOtype*)new Traj_H5MD(); } + static void WriteHelp(); + static void ReadHelp(); + private: + // ----- Inherited functions ----------------- + bool ID_TrajFormat(CpptrajFile&); + int setupTrajin(FileName const&, Topology*); + int setupTrajout(FileName const&, Topology*, CoordinateInfo const&,int, bool); + int openTrajin(); + void closeTraj(); + int readFrame(int,Frame&); + int writeFrame(int,Frame const&); + void Info(); + int readVelocity(int, Frame&); + int readForce(int, Frame&); + int processWriteArgs(ArgList&, DataSetList const&); + int processReadArgs(ArgList&); + // ------------------------------------------- +# ifdef MPI + // ----- Parallel functions ------------------ + int parallelOpenTrajin(Parallel::Comm const&); + int parallelOpenTrajout(Parallel::Comm const&); + int parallelSetupTrajout(FileName const&, Topology*, CoordinateInfo const&, + int, bool, Parallel::Comm const&); + int parallelReadFrame(int, Frame&); + int parallelWriteFrame(int, Frame const&); + void parallelCloseTraj(); + // ------------------------------------------- +# endif +# ifdef HAS_HDF5 + /// Set up coordinates VID and related dim sizes + int setupCoordVID(int&, int&, int&, int&); + /// Set up box variable IDs and determine type + int setupBoxVIDs(int, Box&, int, int); +# endif + +// H5::H5File* file_; + typedef std::vector Sarray; + typedef std::vector Iarray; + + Sarray mainGroupNames_; + Iarray mainGroupIds_; + + int particle_gid_; ///< particles group ID + int position_gid_; ///< position group ID (particles->trajectory->position) + int edges_gid_; ///< edges group ID (particles->trajectory->box->edges) + + int ncid_; ///< NetCDF ID + int natom_; ///< Number of atoms in each trajectory frame. + int coordVID_; ///< Coordinates variable ID + int cellLengthVID_; ///< Cell lengths variable ID + int cellAngleVID_; ///< Cell angles variable ID TODO remove if unused + int timeVID_; ///< Time variable ID + size_t start_[3]; ///< Start indices in each dimension + size_t count_[3]; ///< Count indices in each dimension + double convert_h5_to_cpptraj_box_; ///< For converting h5 box lengths to angstroms + double convert_h5_to_cpptraj_coord_; ///< For converting h5 coordinates to angstroms + std::vector ftmp_; ///< Temporary array to store floats +}; +#endif diff --git a/src/Traj_NcEnsemble.cpp b/src/Traj_NcEnsemble.cpp index 006cf46fab..72c32c3645 100644 --- a/src/Traj_NcEnsemble.cpp +++ b/src/Traj_NcEnsemble.cpp @@ -23,7 +23,8 @@ Traj_NcEnsemble::Traj_NcEnsemble() : ensembleEnd_(0), readAccess_(false), useVelAsCoords_(false), - useFrcAsCoords_(false) + useFrcAsCoords_(false), + ftype_(NC_V3) // Default to NetCDF 3 {} // DESTRUCTOR @@ -57,7 +58,7 @@ int Traj_NcEnsemble::processReadArgs(ArgList& argIn) { // Traj_NcEnsemble::ID_TrajFormat() bool Traj_NcEnsemble::ID_TrajFormat(CpptrajFile& fileIn) { - return ( GetNetcdfConventions( fileIn.Filename().full() ) == NC_AMBERENSEMBLE ); + return ( GetNetcdfConventions( ftype_, fileIn.Filename().full() ) == NC_AMBERENSEMBLE ); } // Traj_NcEnsemble::openTrajin() diff --git a/src/Traj_NcEnsemble.h b/src/Traj_NcEnsemble.h index f2c8b758f0..dea7a317a6 100644 --- a/src/Traj_NcEnsemble.h +++ b/src/Traj_NcEnsemble.h @@ -37,6 +37,7 @@ class Traj_NcEnsemble : public TrajectoryIO, private NetcdfFile { bool readAccess_; bool useVelAsCoords_; bool useFrcAsCoords_; + NC_FMT_TYPE ftype_; }; #endif #endif diff --git a/src/TrajectoryFile.cpp b/src/TrajectoryFile.cpp index 21c80f8958..c221804e95 100644 --- a/src/TrajectoryFile.cpp +++ b/src/TrajectoryFile.cpp @@ -26,6 +26,8 @@ #include "Traj_GmxTng.h" #include "Traj_GmxDump.h" #include "Traj_DTR.h" +#include "Traj_H5.h" +#include "Traj_H5MD.h" // ----- STATIC VARS / ROUTINES ------------------------------------------------ // NOTE: Must be in same order as TrajFormatType @@ -76,6 +78,13 @@ const FileTypes::AllocToken TrajectoryFile::TF_AllocArray[] = { { "Desmond DTR", 0, 0, Traj_DTR::Alloc }, # else { "Desmond DTR", 0, 0, 0 }, +# endif +# ifdef HAS_HDF5 + { "MDtraj H5", 0, 0, Traj_H5::Alloc }, + { "MDanalysis H5MD", 0, 0, Traj_H5MD::Alloc }, +# else + { "MDtraj H5", 0, 0, 0 }, + { "MDanalysis H5MD", 0, 0, 0 }, # endif { "Unknown trajectory", 0, 0, 0 } }; @@ -111,6 +120,8 @@ const FileTypes::KeyToken TrajectoryFile::TF_KeyArray[] = { { SDF, "sdf", ".sdf" }, { XYZ, "xyz", ".xyz" }, { DTR, "dtr", ".dtr" }, + { H5, "h5", ".h5" }, + { H5MD, "h5md", ".h5md" }, { UNKNOWN_TRAJ, 0, 0 } }; diff --git a/src/TrajectoryFile.h b/src/TrajectoryFile.h index c4fcd4ce65..1ce66acc5e 100644 --- a/src/TrajectoryFile.h +++ b/src/TrajectoryFile.h @@ -28,7 +28,7 @@ class TrajectoryFile { CIF, CHARMMDCD, GMXTRX, GMXXTC, GMXTNG, BINPOS, AMBERRESTART, GRO, TINKER, CHARMMCOR, CHARMMREST, AMBERTRAJ, SQM, SDF, XYZ, - CONFLIB, GMXDUMP, DTR, + CONFLIB, GMXDUMP, DTR, H5, H5MD, UNKNOWN_TRAJ }; diff --git a/src/Units.cpp b/src/Units.cpp new file mode 100644 index 0000000000..c938851065 --- /dev/null +++ b/src/Units.cpp @@ -0,0 +1,50 @@ +#include "Units.h" +#include "Constants.h" +#include "CpptrajStdio.h" +#include // tolower + +/** \return Unit type from name. */ +Cpptraj::Units::Type Cpptraj::Units::TypeFromName(std::string const& nameIn) { + std::string name; + for (std::string::const_iterator it = nameIn.begin(); it != nameIn.end(); ++it) + name += tolower( *it ); + if (name == "angstroms" || name == "angstrom" || name == "ang") return ANG; + if (name == "nanometers" || name == "nanometer" || name == "nm") return NM; + mprintf("Warning: Unrecognized units: %s\n", nameIn.c_str()); + return UNKNOWN_UNITS; +} + +/** Set the conversion factor required to convert the first unit + * into the second unit via multiplication. + */ +int Cpptraj::Units::SetConversionFactor(double& fac, + std::string const& fromName, std::string const& toName) +{ + fac = 0; + Type fromUnits = TypeFromName(fromName); + if (fromUnits == UNKNOWN_UNITS) return 1; + Type toUnits = TypeFromName(toName); + if (toUnits == UNKNOWN_UNITS) return 1; + + // If units match no conversion factor needed + if (fromUnits == toUnits) { + fac = 1.0; + return 0; + } + + if (fromUnits == ANG) { + // from angstroms to X + if (toUnits == NM) { + fac = Constants::ANG_TO_NM; + return 0; + } + } else if (fromUnits == NM) { + // from nanometers to X + if (toUnits == ANG) { + fac = Constants::NM_TO_ANG; + return 0; + } + } + mprintf("Warning: No conversion from '%s' to '%s'\n", fromName.c_str(), toName.c_str()); + return 1; +} diff --git a/src/Units.h b/src/Units.h new file mode 100644 index 0000000000..79394749c2 --- /dev/null +++ b/src/Units.h @@ -0,0 +1,20 @@ +#ifndef INC_UNITS_H +#define INC_UNITS_H +#include +namespace Cpptraj { +namespace Units { + +enum Type { ANG = 0, ///< Angstroms + NM, ///< nanometers + UNKNOWN_UNITS + }; + +/// \return Unit type from name. +Type TypeFromName(std::string const&); + +/// Set multiplicative conversion factor from first unit to second unit +int SetConversionFactor(double&, std::string const&, std::string const&); + +} +} +#endif diff --git a/src/Version.h b/src/Version.h index 87b5fb72e0..748564599b 100644 --- a/src/Version.h +++ b/src/Version.h @@ -12,7 +12,7 @@ * Whenever a number that precedes is incremented, all subsequent * numbers should be reset to 0. */ -#define CPPTRAJ_INTERNAL_VERSION "V6.15.2" +#define CPPTRAJ_INTERNAL_VERSION "V6.16.0" /// PYTRAJ relies on this #define CPPTRAJ_VERSION_STRING CPPTRAJ_INTERNAL_VERSION #endif diff --git a/src/cpptrajdepend b/src/cpptrajdepend index 7c3fb6e79b..1570aabe4c 100644 --- a/src/cpptrajdepend +++ b/src/cpptrajdepend @@ -182,7 +182,7 @@ ClusterMap.o : ClusterMap.cpp AssociatedData.h ClusterMap.h Constants.h CpptrajF Cmd.o : Cmd.cpp Cmd.h DispatchObject.h CmdInput.o : CmdInput.cpp CmdInput.h StringRoutines.h CmdList.o : CmdList.cpp Cmd.h CmdList.h DispatchObject.h -Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h +Command.o : Command.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h ActionTopWriter.h Action_Align.h Action_Angle.h Action_AreaPerMol.h Action_AtomMap.h Action_AtomicCorr.h Action_AtomicFluct.h Action_AutoImage.h Action_Average.h Action_Bounds.h Action_Box.h Action_Center.h Action_Channel.h Action_CheckChirality.h Action_CheckStructure.h Action_Closest.h Action_ClusterDihedral.h Action_Contacts.h Action_CreateCrd.h Action_CreateReservoir.h Action_DNAionTracker.h Action_DSSP.h Action_Density.h Action_Diffusion.h Action_Dihedral.h Action_DihedralRMS.h Action_Dipole.h Action_DistRmsd.h Action_Distance.h Action_Energy.h Action_Esander.h Action_FilterByData.h Action_FixAtomOrder.h Action_FixImagedBonds.h Action_GIST.h Action_Grid.h Action_GridFreeEnergy.h Action_HydrogenBond.h Action_Image.h Action_InfraredSpectrum.h Action_Jcoupling.h Action_Keep.h Action_LESsplit.h Action_LIE.h Action_LipidOrder.h Action_MakeStructure.h Action_Mask.h Action_Matrix.h Action_MinImage.h Action_Molsurf.h Action_MultiDihedral.h Action_MultiPucker.h Action_MultiVector.h Action_NAstruct.h Action_NMRrst.h Action_NativeContacts.h Action_OrderParameter.h Action_Outtraj.h Action_PairDist.h Action_Pairwise.h Action_Principal.h Action_Projection.h Action_Pucker.h Action_Radgyr.h Action_Radial.h Action_RandomizeIons.h Action_Remap.h Action_ReplicateCell.h Action_Rmsd.h Action_Rotate.h Action_RunningAvg.h Action_STFC_Diffusion.h Action_Scale.h Action_SetVelocity.h Action_Spam.h Action_Strip.h Action_Surf.h Action_SymmetricRmsd.h Action_Temperature.h Action_Time.h Action_Translate.h Action_Unstrip.h Action_Unwrap.h Action_Vector.h Action_VelocityAutoCorr.h Action_Volmap.h Action_Volume.h Action_Watershell.h Action_XtalSymm.h Analysis.h AnalysisList.h AnalysisState.h Analysis_AmdBias.h Analysis_AutoCorr.h Analysis_Average.h Analysis_Clustering.h Analysis_ConstantPHStats.h Analysis_Corr.h Analysis_CrankShaft.h Analysis_CrdFluct.h Analysis_CrossCorr.h Analysis_CurveFit.h Analysis_Divergence.h Analysis_EvalPlateau.h Analysis_FFT.h Analysis_HausdorffDistance.h Analysis_Hist.h Analysis_IRED.h Analysis_Integrate.h Analysis_KDE.h Analysis_Lifetime.h Analysis_LowestCurve.h Analysis_Matrix.h Analysis_MeltCurve.h Analysis_Modes.h Analysis_MultiHist.h Analysis_Multicurve.h Analysis_Overlap.h Analysis_PhiPsi.h Analysis_Regression.h Analysis_RemLog.h Analysis_Rms2d.h Analysis_RmsAvgCorr.h Analysis_Rotdif.h Analysis_RunningAvg.h Analysis_Slope.h Analysis_Spline.h Analysis_State.h Analysis_Statistics.h Analysis_TI.h Analysis_Timecorr.h Analysis_VectorMath.h Analysis_Wavelet.h ArgList.h Array1D.h ArrayIterator.h AssociatedData.h Atom.h AtomMap.h AtomMask.h AtomType.h AxisType.h BaseIOtype.h Box.h BoxArgs.h BufferedLine.h CharMask.h Cluster/Algorithm.h Cluster/BestReps.h Cluster/CentroidArray.h Cluster/Cframes.h Cluster/Control.h Cluster/DrawGraph.h Cluster/List.h Cluster/Metric.h Cluster/MetricArray.h Cluster/Node.h Cluster/Sieve.h Cluster/Silhouette.h ClusterMap.h Cmd.h CmdInput.h CmdList.h Command.h CompactFrameArray.h ComplexArray.h Constants.h Constraints.h ControlBlock.h ControlBlock_For.h CoordinateInfo.h Corr.h Cph.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_GridFlt.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_RemLog.h DataSet_Vector.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h Deprecated.h DihedralSearch.h Dimension.h DispatchObject.h Energy.h Energy_Sander.h EnsembleIn.h EnsembleOutList.h Ewald.h EwaldOptions.h Ewald_ParticleMesh.h ExclusionArray.h Exec.h Exec_AddMissingRes.h Exec_Analyze.h Exec_Calc.h Exec_CatCrd.h Exec_Change.h Exec_ClusterMap.h Exec_CombineCoords.h Exec_Commands.h Exec_CompareClusters.h Exec_CompareEnergy.h Exec_CompareTop.h Exec_CrdAction.h Exec_CrdOut.h Exec_CreateSet.h Exec_DataFile.h Exec_DataFilter.h Exec_DataSetCmd.h Exec_Emin.h Exec_Flatten.h Exec_GenerateAmberRst.h Exec_Graft.h Exec_Help.h Exec_HmassRepartition.h Exec_LoadCrd.h Exec_LoadTraj.h Exec_ParallelAnalysis.h Exec_ParmBox.h Exec_ParmSolvent.h Exec_ParmStrip.h Exec_ParmWrite.h Exec_PermuteDihedrals.h Exec_Precision.h Exec_PrepareForLeap.h Exec_PrintData.h Exec_Random.h Exec_ReadData.h Exec_ReadEnsembleData.h Exec_ReadInput.h Exec_RotateDihedral.h Exec_RunAnalysis.h Exec_ScaleDihedralK.h Exec_SequenceAlign.h Exec_Set.h Exec_Show.h Exec_SortEnsembleData.h Exec_SplitCoords.h Exec_System.h Exec_Top.h Exec_Traj.h Exec_UpdateParameters.h Exec_ViewRst.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h GIST_PME.h Grid.h GridAction.h GridBin.h HistBin.h Hungarian.h ImageOption.h ImageTypes.h InputTrajCommon.h MapAtom.h MaskArray.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h NetcdfFile.h OnlineVarT.h OutputTrajCommon.h PDBfile.h PairList.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h PubFFT.h Pucker.h Pucker_PuckerMask.h Pucker_PuckerSearch.h Pucker_PuckerToken.h RPNcalc.h Random.h Range.h ReferenceAction.h ReferenceFrame.h RemdReservoirNC.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h Spline.h SplineFxnTable.h StructureCheck.h SymbolExporting.h SymmetricRmsdCalc.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h cuda_kernels/GistCudaSetup.cuh helpme_standalone.h molsurf.h CompactFrameArray.o : CompactFrameArray.cpp Box.h CompactFrameArray.h CoordinateInfo.h CpptrajStdio.h Matrix_3x3.h Parallel.h ReplicaDimArray.h Vec3.h ComplexArray.o : ComplexArray.cpp ArrayIterator.h ComplexArray.h Constraints.o : Constraints.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h Constraints.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -195,10 +195,11 @@ CpptrajFile.o : CpptrajFile.cpp CpptrajFile.h CpptrajStdio.h FileIO.h FileIO_Bzi CpptrajState.o : CpptrajState.cpp Action.h ActionList.h ActionState.h Action_CreateCrd.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CompactFrameArray.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_Coords_TRJ.h DataSet_Topology.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleNavigator.h EnsembleOutList.h FileIO.h FileName.h FileTypes.h Frame.h FrameArray.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ProgressBar.h Random.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajFrameIndex.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h CpptrajStdio.o : CpptrajStdio.cpp Parallel.h CurveFit.o : CurveFit.cpp CurveFit.h -DataFile.o : DataFile.cpp ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h BufferedLine.h Cluster/Cframes.h Cluster/Cmatrix_NC.h Constants.h CoordinateInfo.h Cph.h CpptrajFile.h CpptrajStdio.h DataFile.h DataIO.h DataIO_CCP4.h DataIO_CharmmFastRep.h DataIO_CharmmOutput.h DataIO_CharmmRepLog.h DataIO_CharmmRtfPrm.h DataIO_Cmatrix_Binary.h DataIO_Cmatrix_NC.h DataIO_Cpout.h DataIO_Evecs.h DataIO_Gnuplot.h DataIO_Grace.h DataIO_Mdout.h DataIO_OpenDx.h DataIO_Peaks.h DataIO_RemLog.h DataIO_Std.h DataIO_VecTraj.h DataIO_XVG.h DataIO_Xplor.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_PairwiseCache.h DataSet_PairwiseCache_MEM.h DataSet_RemLog.h Dimension.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h TypeNameHolder.h Unit.h Vec3.h +DataFile.o : DataFile.cpp ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h BufferedLine.h Cluster/Cframes.h Cluster/Cmatrix_NC.h Constants.h CoordinateInfo.h Cph.h CpptrajFile.h CpptrajStdio.h DataFile.h DataIO.h DataIO_AmberEne.h DataIO_CCP4.h DataIO_CharmmFastRep.h DataIO_CharmmOutput.h DataIO_CharmmRepLog.h DataIO_CharmmRtfPrm.h DataIO_Cmatrix_Binary.h DataIO_Cmatrix_NC.h DataIO_Cpout.h DataIO_Evecs.h DataIO_Gnuplot.h DataIO_Grace.h DataIO_Mdout.h DataIO_OpenDx.h DataIO_Peaks.h DataIO_RemLog.h DataIO_Std.h DataIO_VecTraj.h DataIO_XVG.h DataIO_Xplor.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_PairwiseCache.h DataSet_PairwiseCache_MEM.h DataSet_RemLog.h Dimension.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h TypeNameHolder.h Unit.h Vec3.h DataFileList.o : DataFileList.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PDBfile.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h DataFilter.o : DataFilter.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataFile.h DataFileList.h DataFilter.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_integer.h Dimension.h FileIO.h FileName.h FileTypes.h Frame.h GridBin.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h DataIO.o : DataIO.cpp ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataIO.h DataSet.h DataSetList.h DataSet_2D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_MatrixDbl.h Dimension.h FileIO.h FileName.h Frame.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h +DataIO_AmberEne.o : DataIO_AmberEne.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h BufferedLine.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataIO.h DataIO_AmberEne.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h FileIO.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h DataIO_CCP4.o : DataIO_CCP4.cpp ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h ByteRoutines.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataIO.h DataIO_CCP4.h DataSet.h DataSetList.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridFlt.h Dimension.h FileIO.h FileName.h Frame.h Grid.h GridBin.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h DataIO_CharmmFastRep.o : DataIO_CharmmFastRep.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h BufferedLine.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataIO.h DataIO_CharmmFastRep.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_RemLog.h Dimension.h FileIO.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h DataIO_CharmmOutput.o : DataIO_CharmmOutput.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h BufferedLine.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataIO.h DataIO_CharmmOutput.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_double.h Dimension.h FileIO.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h @@ -219,11 +220,12 @@ DataIO_VecTraj.o : DataIO_VecTraj.cpp ActionFrameCounter.h ArgList.h ArrayIterat DataIO_XVG.o : DataIO_XVG.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h BufferedLine.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataIO.h DataIO_XVG.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_double.h Dimension.h FileIO.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h DataIO_Xplor.o : DataIO_Xplor.cpp ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h BufferedLine.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataIO.h DataIO_Xplor.h DataSet.h DataSetList.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_GridFlt.h Dimension.h FileIO.h FileName.h Frame.h Grid.h GridBin.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ProgressBar.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TypeNameHolder.h Unit.h Vec3.h DataSet.o : DataSet.cpp AssociatedData.h CpptrajFile.h CpptrajStdio.h DataSet.h Dimension.h FileIO.h FileName.h MetaData.h Parallel.h Range.h TextFormat.h -DataSetList.o : DataSetList.cpp ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h Box.h Cluster/Cframes.h Cluster/Cmatrix_NC.h CompactFrameArray.h ComplexArray.h Constants.h CoordinateInfo.h Cph.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h DataSet_Coords_TRJ.h DataSet_GridDbl.h DataSet_GridFlt.h DataSet_Mat3x3.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_PHREMD.h DataSet_PHREMD_Explicit.h DataSet_PHREMD_Implicit.h DataSet_PairwiseCache.h DataSet_PairwiseCache_MEM.h DataSet_PairwiseCache_NC.h DataSet_Parameters.h DataSet_RemLog.h DataSet_StringVar.h DataSet_Tensor.h DataSet_Topology.h DataSet_Vector.h DataSet_Vector_Scalar.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_disk.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h DataSet_unsignedInt.h Dimension.h FileIO.h FileName.h Frame.h Grid.h GridBin.h InputTrajCommon.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h StringRoutines.h SymbolExporting.h SymmetricTensor.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajFrameIndex.h Trajin.h TypeNameHolder.h Unit.h Vec3.h +DataSetList.o : DataSetList.cpp ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h Box.h Cluster/Cframes.h Cluster/Cmatrix_NC.h CompactFrameArray.h ComplexArray.h Constants.h CoordinateInfo.h Cph.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSetList.h DataSet_1D.h DataSet_2D.h DataSet_3D.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_FRM.h DataSet_Coords_REF.h DataSet_Coords_TRJ.h DataSet_GridDbl.h DataSet_GridFlt.h DataSet_Mat3x3.h DataSet_MatrixDbl.h DataSet_MatrixFlt.h DataSet_Mesh.h DataSet_Modes.h DataSet_PHREMD.h DataSet_PHREMD_Explicit.h DataSet_PHREMD_Implicit.h DataSet_PairwiseCache.h DataSet_PairwiseCache_MEM.h DataSet_PairwiseCache_NC.h DataSet_Parameters.h DataSet_RemLog.h DataSet_StringVar.h DataSet_Tensor.h DataSet_Topology.h DataSet_Vector.h DataSet_Vector_Scalar.h DataSet_double.h DataSet_float.h DataSet_integer.h DataSet_integer_disk.h DataSet_integer_mem.h DataSet_pH.h DataSet_string.h DataSet_unsignedInt.h Dimension.h FileIO.h FileName.h Frame.h Grid.h GridBin.h InputTrajCommon.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h Spline.h StringRoutines.h SymbolExporting.h SymmetricTensor.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajFrameIndex.h Trajin.h TypeNameHolder.h Unit.h Vec3.h DataSet_1D.o : DataSet_1D.cpp ArrayIterator.h AssociatedData.h ComplexArray.h Constants.h Corr.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSet_1D.h Dimension.h FileIO.h FileName.h MetaData.h Parallel.h PubFFT.h Range.h TextFormat.h DataSet_3D.o : DataSet_3D.cpp AssociatedData.h Box.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSet_3D.h Dimension.h FileIO.h FileName.h GridBin.h Matrix_3x3.h MetaData.h Parallel.h Range.h TextFormat.h Vec3.h DataSet_Coords.o : DataSet_Coords.cpp AssociatedData.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSet_Coords.h Dimension.h FileIO.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Topology.h TypeNameHolder.h Unit.h Vec3.h DataSet_Coords_CRD.o : DataSet_Coords_CRD.cpp AssociatedData.h Atom.h AtomMask.h AtomType.h Box.h CompactFrameArray.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSet_Coords.h DataSet_Coords_CRD.h Dimension.h FileIO.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Topology.h TypeNameHolder.h Unit.h Vec3.h +DataSet_Coords_FRM.o : DataSet_Coords_FRM.cpp AssociatedData.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSet_Coords.h DataSet_Coords_FRM.h Dimension.h FileIO.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Topology.h TypeNameHolder.h Unit.h Vec3.h DataSet_Coords_REF.o : DataSet_Coords_REF.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h FileIO.h FileName.h Frame.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Topology.h TrajFrameCounter.h Trajin.h Trajin_Single.h TypeNameHolder.h Unit.h Vec3.h DataSet_Coords_TRJ.o : DataSet_Coords_TRJ.cpp AssociatedData.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSet_Coords.h DataSet_Coords_TRJ.h Dimension.h FileIO.h FileName.h Frame.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Topology.h TrajFrameCounter.h TrajFrameIndex.h Trajin.h Trajin_Single.h TypeNameHolder.h Unit.h Vec3.h DataSet_GridDbl.o : DataSet_GridDbl.cpp ArrayIterator.h AssociatedData.h Box.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSet_3D.h DataSet_GridDbl.h Dimension.h FileIO.h FileName.h Grid.h GridBin.h Matrix_3x3.h MetaData.h Parallel.h Range.h StringRoutines.h TextFormat.h Vec3.h @@ -255,7 +257,7 @@ DataSet_unsignedInt.o : DataSet_unsignedInt.cpp AssociatedData.h CpptrajFile.h D Deprecated.o : Deprecated.cpp CpptrajStdio.h Deprecated.h DispatchObject.h DihedralSearch.o : DihedralSearch.cpp ArgList.h Atom.h AtomMask.h AtomType.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h DihedralSearch.h FileName.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h DistRoutines.o : DistRoutines.cpp Box.h DistRoutines.h ImageOption.h Matrix_3x3.h Parallel.h Vec3.h -Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h +Energy.o : Energy.cpp Atom.h AtomMask.h AtomType.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajStdio.h DistRoutines.h Energy.h Energy/Ene_Angle.h Energy/Ene_Bond.h Energy/Kernel_Harmonic.h ExclusionArray.h FileName.h Frame.h ImageOption.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TorsionRoutines.h TypeNameHolder.h Unit.h Vec3.h EnergyArray.o : EnergyArray.cpp CpptrajFile.h CpptrajStdio.h EnergyArray.h FileIO.h FileName.h Parallel.h Energy_Sander.o : Energy_Sander.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h Energy_Sander.h FileName.h FileTypes.h File_TempName.h Frame.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ParmFile.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TypeNameHolder.h Unit.h Vec3.h EnsembleIn.o : EnsembleIn.cpp Atom.h AtomMask.h Box.h CoordinateInfo.h CpptrajStdio.h EnsembleIn.h FileName.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h Timer.h TrajFrameCounter.h Unit.h Vec3.h @@ -275,11 +277,12 @@ Exec_AddMissingRes.o : Exec_AddMissingRes.cpp Action.h ActionFrameCounter.h Acti Exec_Analyze.o : Exec_Analyze.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Cmd.h CmdList.h Command.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h Exec.h Exec_Analyze.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h Exec_Calc.o : Exec_Calc.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h Exec.h Exec_Calc.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h RPNcalc.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h Exec_CatCrd.o : Exec_CatCrd.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h Exec.h Exec_CatCrd.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h -Exec_Change.o : Exec_Change.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h Exec.h Exec_Change.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h +Exec_Change.o : Exec_Change.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h Exec.h Exec_Change.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h Exec_ClusterMap.o : Exec_ClusterMap.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h ArrayIterator.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h ClusterMap.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_2D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_MatrixFlt.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h Exec.h Exec_ClusterMap.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h Exec_CombineCoords.o : Exec_CombineCoords.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h Exec.h Exec_CombineCoords.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h Exec_Commands.o : Exec_Commands.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h Exec.h Exec_Commands.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h Exec_CompareClusters.o : Exec_CompareClusters.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h Exec.h Exec_CompareClusters.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h +Exec_CompareEnergy.o : Exec_CompareEnergy.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h CharMask.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_double.h Dimension.h DispatchObject.h Energy/Kernel_Fourier.h Energy/Kernel_Harmonic.h EnsembleIn.h EnsembleOutList.h Exec.h Exec_CompareEnergy.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OnlineVarT.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TorsionRoutines.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h Exec_CompareTop.o : Exec_CompareTop.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h Exec.h Exec_CompareTop.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h Exec_CrdAction.o : Exec_CrdAction.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Cmd.h CmdList.h Command.h CompactFrameArray.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_CRD.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h Exec.h Exec_CrdAction.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ProgressBar.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h Exec_CrdOut.o : Exec_CrdOut.cpp Action.h ActionFrameCounter.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajState.h CpptrajStdio.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h Exec.h Exec_CrdOut.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ProgressBar.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajectoryFile.h Trajin.h TrajinList.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h @@ -450,6 +453,8 @@ Traj_GmxTng.o : Traj_GmxTng.cpp Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Traj_GmxTrX.o : Traj_GmxTrX.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h ByteRoutines.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h FileIO.h FileName.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h Traj_GmxTrX.h TrajectoryIO.h TypeNameHolder.h Unit.h Vec3.h Traj_GmxXtc.o : Traj_GmxXtc.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h FileIO.h FileName.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h Traj_GmxXtc.h TrajectoryIO.h TypeNameHolder.h Unit.h Vec3.h Traj_Gro.o : Traj_Gro.cpp Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h BufferedLine.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h FileIO.h FileName.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h Traj_Gro.h TrajectoryIO.h TypeNameHolder.h Unit.h Vec3.h +Traj_H5.o : Traj_H5.cpp Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h FileIO.h FileName.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NC_Routines.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h Traj_H5.h TrajectoryIO.h TypeNameHolder.h Unit.h Units.h Vec3.h +Traj_H5MD.o : Traj_H5MD.cpp Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h FileIO.h FileName.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NC_Routines.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h Traj_H5MD.h TrajectoryIO.h TypeNameHolder.h Unit.h Units.h Vec3.h Traj_Mol2File.o : Traj_Mol2File.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h FileIO.h FileName.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Mol2File.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h Traj_Mol2File.h TrajectoryIO.h TypeNameHolder.h Unit.h Vec3.h Traj_NcEnsemble.o : Traj_NcEnsemble.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h FileIO.h FileName.h Frame.h FrameArray.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NC_Routines.h NameType.h NetcdfFile.h Parallel.h ParallelNetcdf.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h Traj_NcEnsemble.h TrajectoryIO.h TypeNameHolder.h Unit.h Vec3.h Traj_PDBfile.o : Traj_PDBfile.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSetList.h DataSet_1D.h DataSet_Coords.h DataSet_Coords_REF.h DataSet_Tensor.h Dimension.h DistRoutines.h FileIO.h FileName.h Frame.h FramePtrArray.h ImageOption.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h PDBfile.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h SymmetricTensor.h TextFormat.h Timer.h Topology.h Traj_PDBfile.h TrajectoryIO.h TypeNameHolder.h Unit.h Vec3.h @@ -457,13 +462,14 @@ Traj_SDF.o : Traj_SDF.cpp Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Consta Traj_SQM.o : Traj_SQM.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h FileIO.h FileName.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h Traj_SQM.h TrajectoryIO.h TypeNameHolder.h Unit.h Vec3.h Traj_Tinker.o : Traj_Tinker.cpp Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h BufferedLine.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h FileIO.h FileName.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TinkerFile.h Topology.h Traj_Tinker.h TrajectoryIO.h TypeNameHolder.h Unit.h Vec3.h Traj_XYZ.o : Traj_XYZ.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h BufferedLine.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h FileIO.h FileName.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Topology.h Traj_XYZ.h TrajectoryIO.h TypeNameHolder.h Unit.h Vec3.h -TrajectoryFile.o : TrajectoryFile.cpp Atom.h AtomMask.h BaseIOtype.h Box.h BufferedFrame.h BufferedLine.h CIFfile.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Mol2File.h Molecule.h NameType.h NetcdfFile.h PDBfile.h Parallel.h ReplicaDimArray.h Residue.h SDFfile.h Segment.h SymbolExporting.h TextFormat.h TinkerFile.h Traj_AmberCoord.h Traj_AmberNetcdf.h Traj_AmberRestart.h Traj_AmberRestartNC.h Traj_Binpos.h Traj_CIF.h Traj_CharmmCor.h Traj_CharmmDcd.h Traj_CharmmRestart.h Traj_Conflib.h Traj_DTR.h Traj_GmxDump.h Traj_GmxTng.h Traj_GmxTrX.h Traj_GmxXtc.h Traj_Gro.h Traj_Mol2File.h Traj_NcEnsemble.h Traj_PDBfile.h Traj_SDF.h Traj_SQM.h Traj_Tinker.h Traj_XYZ.h TrajectoryFile.h TrajectoryIO.h Unit.h Vec3.h +TrajectoryFile.o : TrajectoryFile.cpp Atom.h BaseIOtype.h Box.h BufferedFrame.h BufferedLine.h CIFfile.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h FileIO.h FileName.h FileTypes.h FramePtrArray.h Matrix_3x3.h Mol2File.h NameType.h NetcdfFile.h PDBfile.h Parallel.h ReplicaDimArray.h Residue.h SDFfile.h SymbolExporting.h TextFormat.h TinkerFile.h Traj_AmberCoord.h Traj_AmberNetcdf.h Traj_AmberRestart.h Traj_AmberRestartNC.h Traj_Binpos.h Traj_CIF.h Traj_CharmmCor.h Traj_CharmmDcd.h Traj_CharmmRestart.h Traj_Conflib.h Traj_DTR.h Traj_GmxDump.h Traj_GmxTng.h Traj_GmxTrX.h Traj_GmxXtc.h Traj_Gro.h Traj_H5.h Traj_H5MD.h Traj_Mol2File.h Traj_NcEnsemble.h Traj_PDBfile.h Traj_SDF.h Traj_SQM.h Traj_Tinker.h Traj_XYZ.h TrajectoryFile.h TrajectoryIO.h Vec3.h TrajectoryIO.o : TrajectoryIO.cpp BaseIOtype.h Box.h CoordinateInfo.h FramePtrArray.h Matrix_3x3.h Parallel.h ReplicaDimArray.h TrajectoryIO.h Vec3.h TrajinList.o : TrajinList.cpp ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSet_RemLog.h Dimension.h EnsembleIn.h EnsembleIn_Multi.h EnsembleIn_Single.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h StringRoutines.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h TrajIOarray.h TrajectoryFile.h TrajectoryIO.h Trajin.h TrajinList.h Trajin_Multi.h Trajin_Single.h TypeNameHolder.h Unit.h Vec3.h Trajin_Multi.o : Trajin_Multi.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h FileName.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TrajFrameCounter.h TrajIOarray.h TrajectoryIO.h Trajin.h Trajin_Multi.h TypeNameHolder.h Unit.h Vec3.h Trajin_Single.o : Trajin_Single.cpp ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h Topology.h TrajFrameCounter.h TrajectoryFile.h TrajectoryIO.h Trajin.h Trajin_Single.h TypeNameHolder.h Unit.h Vec3.h TrajoutList.o : TrajoutList.cpp ActionFrameCounter.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h TrajoutList.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h Trajout_Single.o : Trajout_Single.cpp ActionFrameCounter.h ArgList.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajStdio.h FileName.h FileTypes.h Frame.h FramePtrArray.h MaskToken.h Matrix_3x3.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReplicaDimArray.h Residue.h Segment.h StringRoutines.h SymbolExporting.h Topology.h TrajectoryFile.h TrajectoryIO.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h +Units.o : Units.cpp Constants.h CpptrajStdio.h Units.h Vec3.o : Vec3.cpp Constants.h CpptrajStdio.h Vec3.h ViewRst.o : ViewRst.cpp ActionFrameCounter.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h CpptrajFile.h CpptrajStdio.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h FileIO.h FileName.h FileTypes.h Frame.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h OutputTrajCommon.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h ParmFile.h Range.h ReferenceFrame.h ReplicaDimArray.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajectoryFile.h Trajout_Single.h TypeNameHolder.h Unit.h Vec3.h ViewRst.h main.o : main.cpp Action.h ActionList.h ActionState.h Analysis.h AnalysisList.h AnalysisState.h ArgList.h AssociatedData.h Atom.h AtomMask.h AtomType.h BaseIOtype.h Box.h Constants.h CoordinateInfo.h Cpptraj.h CpptrajFile.h CpptrajState.h DataFile.h DataFileList.h DataSet.h DataSetList.h DataSet_Coords.h DataSet_Coords_REF.h Dimension.h DispatchObject.h EnsembleIn.h EnsembleOutList.h FileIO.h FileName.h FileTypes.h Frame.h FramePtrArray.h InputTrajCommon.h MaskToken.h Matrix_3x3.h MetaData.h Molecule.h NameType.h Parallel.h ParameterHolders.h ParameterSet.h ParameterTypes.h Range.h ReferenceFrame.h ReplicaDimArray.h ReplicaInfo.h Residue.h Segment.h SymbolExporting.h TextFormat.h Timer.h Topology.h TrajFrameCounter.h Trajin.h TrajinList.h TrajoutList.h TypeNameHolder.h Unit.h Vec3.h diff --git a/src/cpptrajfiles b/src/cpptrajfiles index eafcc25f9f..1183c36925 100644 --- a/src/cpptrajfiles +++ b/src/cpptrajfiles @@ -170,6 +170,7 @@ COMMON_SOURCES= \ DataFileList.cpp \ DataFilter.cpp \ DataIO.cpp \ + DataIO_AmberEne.cpp \ DataIO_CCP4.cpp \ DataIO_CharmmFastRep.cpp \ DataIO_CharmmOutput.cpp \ @@ -195,6 +196,7 @@ COMMON_SOURCES= \ DataSet_3D.cpp \ DataSet_Coords.cpp \ DataSet_Coords_CRD.cpp \ + DataSet_Coords_FRM.cpp \ DataSet_Coords_REF.cpp \ DataSet_Coords_TRJ.cpp \ DataSet_GridDbl.cpp \ @@ -250,6 +252,7 @@ COMMON_SOURCES= \ Exec_CombineCoords.cpp \ Exec_Commands.cpp \ Exec_CompareClusters.cpp \ + Exec_CompareEnergy.cpp \ Exec_CompareTop.cpp \ Exec_CrdAction.cpp \ Exec_CrdOut.cpp \ @@ -408,6 +411,8 @@ COMMON_SOURCES= \ Traj_GmxTrX.cpp \ Traj_GmxXtc.cpp \ Traj_Gro.cpp \ + Traj_H5.cpp \ + Traj_H5MD.cpp \ Traj_Mol2File.cpp \ Traj_NcEnsemble.cpp \ Traj_PDBfile.cpp \ @@ -424,6 +429,7 @@ COMMON_SOURCES= \ TrajIOarray.cpp \ Trajout_Single.cpp \ TrajoutList.cpp \ + Units.cpp \ Vec3.cpp \ ViewRst.cpp \ vmdplugin/dtrplugin.cpp \ diff --git a/test/Makefile b/test/Makefile index ba6266e4ef..c6192864c2 100644 --- a/test/Makefile +++ b/test/Makefile @@ -506,6 +506,9 @@ test.keep: test.hremd: @-cd Test_Ensemble_HREMD && ./RunTest.sh $(OPT) +test.compareenergy: + @-cd Test_CompareEnergy && ./RunTest.sh $(OPT) + # Every test target should go here. COMPLETETESTS=test.general \ test.strip \ @@ -665,7 +668,8 @@ COMPLETETESTS=test.general \ test.ljc \ test.hmassrepartition \ test.prepareforleap \ - test.keep + test.keep \ + test.compareenergy test.all: $(MAKE) test.complete summary diff --git a/test/MasterTest.sh b/test/MasterTest.sh index 581feee1ae..15a42425a3 100644 --- a/test/MasterTest.sh +++ b/test/MasterTest.sh @@ -37,6 +37,7 @@ # CPPTRAJ_ZLIB : If set CPPTRAJ has zlib support. # CPPTRAJ_BZLIB : If set CPPTRAJ has bzip support. # CPPTRAJ_NETCDFLIB : If set CPPTRAJ has NetCDF support. +# CPPTRAJ_HDF5 : If set CPPTRAJ has NetCDF4/HDF5 support. # CPPTRAJ_C11_SUPPORT : If set CPPTRAJ has C++11 support. # CPPTRAJ_LIBPME : If set CPPTRAJ was compiled with libPME. # CPPTRAJ_MPILIB : If set CPPTRAJ has MPI support. @@ -813,6 +814,7 @@ CheckDefines() { '-DHASGZ' ) export CPPTRAJ_ZLIB=$DEFINE ;; '-DHASBZ2' ) export CPPTRAJ_BZLIB=$DEFINE ;; '-DBINTRAJ' ) export CPPTRAJ_NETCDFLIB=$DEFINE ;; + '-DHAS_HDF5' ) export CPPTRAJ_HDF5=$DEFINE ;; '-DC11_SUPPORT' ) export CPPTRAJ_C11_SUPPORT=$DEFINE ;; '-DLIBPME' ) export CPPTRAJ_LIBPME=$DEFINE ;; '-DMPI' ) export CPPTRAJ_MPILIB=$DEFINE ;; @@ -1032,6 +1034,7 @@ CheckEnv() { #echo "DEBUG: $DESCRIP: Checking requirement: $1" case "$1" in 'netcdf' ) TestLibrary "NetCDF" "$CPPTRAJ_NETCDFLIB" ;; + 'hdf5' ) TestLibrary "HDF5" "$CPPTRAJ_HDF5" ;; 'c++11' ) TestLibrary "C++11" "$CPPTRAJ_C11_SUPPORT" ;; 'libpme' ) TestLibrary "libPME" "$CPPTRAJ_LIBPME" ;; 'zlib' ) TestLibrary "Zlib" "$CPPTRAJ_ZLIB" ;; diff --git a/test/Test_CompareEnergy/RunTest.sh b/test/Test_CompareEnergy/RunTest.sh new file mode 100755 index 0000000000..c68d4cb616 --- /dev/null +++ b/test/Test_CompareEnergy/RunTest.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +. ../MasterTest.sh + +CleanFiles compare.in compare.bonds.dat compare.angles.dat compare.dih.dat + +TESTNAME='Compare energy tests' +Requires maxthreads 1 + +INPUT='-i compare.in' + +cat > compare.in < = -0.033383 +#Angle ene RMSE = 0.307728 +#Angle = 0.000000 +#Angle len RMSE = 0.000000 +#Name0 Name1 Name2 Name3 Ene0 Ene1 Edelta R0 R1 Rdelta diff --git a/test/Test_CompareEnergy/compare.bonds.dat.save b/test/Test_CompareEnergy/compare.bonds.dat.save new file mode 100644 index 0000000000..576b7658c9 --- /dev/null +++ b/test/Test_CompareEnergy/compare.bonds.dat.save @@ -0,0 +1,32 @@ +#Name0 Name1 Ene0 Ene1 Edelta R0 R1 Rdelta +TRP_2@C TRP_2@O 0.0001 0.0000 -0.0000 1.2286 1.2288 0.0002 +TRP_2@CE3 TRP_2@CD2 0.0001 0.0000 -0.0001 1.4045 1.4041 -0.0004 +TRP_2@CZ3 TRP_2@CE3 0.0000 0.0003 0.0003 1.3999 1.3992 -0.0007 +TRP_2@CH2 TRP_2@CZ3 0.0000 0.0003 0.0003 1.3999 1.4008 0.0009 +TRP_2@CZ2 TRP_2@CH2 0.0001 0.0000 -0.0001 1.3995 1.3999 0.0004 +TRP_2@CE2 TRP_2@CZ2 0.0000 0.0000 0.0000 1.4001 1.4003 0.0002 +TRP_2@CE2 TRP_2@CD2 0.0003 0.0000 -0.0002 1.4182 1.4191 0.0009 +TRP_2@NE1 TRP_2@CE2 0.0000 0.0000 -0.0000 1.3797 1.3801 0.0004 +TRP_2@CD1 TRP_2@NE1 0.0001 0.0000 -0.0001 1.3815 1.3809 -0.0006 +TRP_2@CG TRP_2@CD1 0.0002 0.0001 -0.0001 1.3514 1.3524 0.0011 +TRP_2@CG TRP_2@CD2 0.0002 0.0000 -0.0001 1.4596 1.4591 -0.0006 +TRP_2@CB TRP_2@CG 0.0001 0.0000 -0.0001 1.4945 1.4951 0.0006 +TRP_2@CA TRP_2@CB 0.0002 0.0000 -0.0002 1.5267 1.5258 -0.0009 +TRP_2@CA TRP_2@C 0.0000 0.0002 0.0002 1.5219 1.5228 0.0009 +TRP_2@N TRP_2@CA 0.0000 0.0000 0.0000 1.4489 1.4487 -0.0001 +TRP_2@CE3 TRP_2@HE3 0.0001 0.0001 -0.0000 1.0795 1.0795 0.0000 +TRP_2@CZ3 TRP_2@HZ3 0.0000 0.0001 0.0001 1.0801 1.0805 0.0005 +TRP_2@CH2 TRP_2@HH2 0.0000 0.0001 0.0001 1.0800 1.0794 -0.0006 +TRP_2@CZ2 TRP_2@HZ2 0.0000 0.0001 0.0000 1.0804 1.0796 -0.0008 +TRP_2@NE1 TRP_2@HE1 0.0002 0.0001 -0.0001 1.0106 1.0095 -0.0011 +TRP_2@CD1 TRP_2@HD1 0.0000 0.0001 0.0001 1.0800 1.0796 -0.0005 +TRP_2@CB TRP_2@HB2 0.0000 0.0001 0.0001 1.0901 1.0896 -0.0005 +TRP_2@CB TRP_2@HB3 0.0000 0.0000 0.0000 1.0903 1.0903 0.0001 +TRP_2@CA TRP_2@HA 0.0001 0.0000 -0.0001 1.0895 1.0901 0.0006 +TRP_2@N TRP_2@H 0.0001 0.0000 -0.0001 1.0106 1.0102 -0.0004 +#Bond E0 = 0.001927 +#Bond E1 = 0.001731 +#Bond = -0.000008 +#Bond ene RMSE = 0.000135 +#Bond = -0.000016 +#Bond len RMSE = 0.000630 diff --git a/test/Test_CompareEnergy/compare.dih.dat.save b/test/Test_CompareEnergy/compare.dih.dat.save new file mode 100644 index 0000000000..ca36cf9bac --- /dev/null +++ b/test/Test_CompareEnergy/compare.dih.dat.save @@ -0,0 +1,74 @@ +TRP_2@CH2 TRP_2@CZ2 TRP_2@CE2 TRP_2@CD2 0.0788 0.0262 -0.0526 0.0000 0.0000 0.0000 +TRP_2@CH2 TRP_2@CZ3 TRP_2@CE3 TRP_2@CD2 0.0018 0.2113 0.2095 0.0000 0.0000 0.0000 +TRP_2@CZ2 TRP_2@CE2 TRP_2@CD2 TRP_2@CE3 0.0341 0.0076 -0.0265 0.0000 0.0000 0.0000 +TRP_2@CZ2 TRP_2@CH2 TRP_2@CZ3 TRP_2@CE3 0.0162 0.0419 0.0257 0.0000 0.0000 0.0000 +TRP_2@CE2 TRP_2@CZ2 TRP_2@CH2 TRP_2@CZ3 0.0567 0.0118 -0.0449 0.0000 0.0000 0.0000 +TRP_2@CE2 TRP_2@CD2 TRP_2@CE3 TRP_2@CZ3 0.0057 0.1600 0.1543 0.0000 0.0000 0.0000 +TRP_2@NE1 TRP_2@CD1 TRP_2@CG TRP_2@CD2 0.4542 0.0048 -0.4494 0.0000 0.0000 0.0000 +TRP_2@NE1 TRP_2@CE2 TRP_2@CZ2 TRP_2@CH2 0.4369 0.0989 -0.3381 0.0000 0.0000 0.0000 +TRP_2@NE1 TRP_2@CE2 TRP_2@CD2 TRP_2@CE3 0.2705 0.0004 -0.2701 0.0000 0.0000 0.0000 +TRP_2@CD1 TRP_2@CG TRP_2@CD2 TRP_2@CE2 0.4048 0.0520 -0.3527 0.0000 0.0000 0.0000 +TRP_2@CD1 TRP_2@CG TRP_2@CD2 TRP_2@CE3 0.0570 0.0228 -0.0341 0.0000 0.0000 0.0000 +TRP_2@CD1 TRP_2@NE1 TRP_2@CE2 TRP_2@CZ2 0.0005 0.0438 0.0434 0.0000 0.0000 0.0000 +TRP_2@CD1 TRP_2@NE1 TRP_2@CE2 TRP_2@CD2 0.2572 0.0896 -0.1676 0.0000 0.0000 0.0000 +TRP_2@CG TRP_2@CB TRP_2@CA TRP_2@C 0.0000 0.0131 0.0131 0.0000 0.0000 0.0000 +TRP_2@CG TRP_2@CD1 TRP_2@NE1 TRP_2@CE2 0.0125 0.0278 0.0153 0.0000 0.0000 0.0000 +TRP_2@CG TRP_2@CD2 TRP_2@CE2 TRP_2@NE1 0.8224 0.2073 -0.6151 0.0000 0.0000 0.0000 +TRP_2@CG TRP_2@CD2 TRP_2@CE2 TRP_2@CZ2 0.0482 0.1221 0.0739 0.0000 0.0000 0.0000 +TRP_2@CG TRP_2@CD2 TRP_2@CE3 TRP_2@CZ3 0.3336 0.0418 -0.2919 0.0000 0.0000 0.0000 +TRP_2@CB TRP_2@CA TRP_2@C TRP_2@O 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +TRP_2@CB TRP_2@CG TRP_2@CD1 TRP_2@NE1 0.2998 0.0065 -0.2933 0.0000 0.0000 0.0000 +TRP_2@CB TRP_2@CG TRP_2@CD2 TRP_2@CE2 0.3273 0.0217 -0.3056 0.0000 0.0000 0.0000 +TRP_2@CB TRP_2@CG TRP_2@CD2 TRP_2@CE3 0.0293 0.0537 0.0244 0.0000 0.0000 0.0000 +TRP_2@CA TRP_2@CB TRP_2@CG TRP_2@CD1 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +TRP_2@CA TRP_2@CB TRP_2@CG TRP_2@CD2 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +TRP_2@N TRP_2@CA TRP_2@CB TRP_2@CG 0.0308 0.0004 -0.0304 0.0000 0.0000 0.0000 +TRP_2@N TRP_2@CA TRP_2@C TRP_2@O 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +TRP_2@CD1 TRP_2@CD2 TRP_2@CG TRP_2@CB 0.0030 0.0043 0.0013 0.0000 0.0000 0.0000 +TRP_2@HZ3 TRP_2@CZ3 TRP_2@CE3 TRP_2@HE3 0.4065 0.3204 -0.0861 0.0000 0.0000 0.0000 +TRP_2@HZ3 TRP_2@CZ3 TRP_2@CE3 TRP_2@CD2 0.3064 0.0955 -0.2109 0.0000 0.0000 0.0000 +TRP_2@HH2 TRP_2@CH2 TRP_2@CZ3 TRP_2@HZ3 0.2000 0.0009 -0.1991 0.0000 0.0000 0.0000 +TRP_2@HH2 TRP_2@CH2 TRP_2@CZ3 TRP_2@CE3 0.0005 0.0141 0.0135 0.0000 0.0000 0.0000 +TRP_2@CH2 TRP_2@CZ3 TRP_2@CE3 TRP_2@HE3 0.0167 0.1734 0.1567 0.0000 0.0000 0.0000 +TRP_2@HZ2 TRP_2@CZ2 TRP_2@CE2 TRP_2@CD2 0.0231 0.0002 -0.0230 0.0000 0.0000 0.0000 +TRP_2@HZ2 TRP_2@CZ2 TRP_2@CH2 TRP_2@HH2 0.0006 0.0004 -0.0002 0.0000 0.0000 0.0000 +TRP_2@HZ2 TRP_2@CZ2 TRP_2@CH2 TRP_2@CZ3 0.0146 0.0033 -0.0113 0.0000 0.0000 0.0000 +TRP_2@CZ2 TRP_2@CH2 TRP_2@CZ3 TRP_2@HZ3 0.3539 0.0031 -0.3507 0.0000 0.0000 0.0000 +TRP_2@CE2 TRP_2@CZ2 TRP_2@CH2 TRP_2@HH2 0.0087 0.0346 0.0259 0.0000 0.0000 0.0000 +TRP_2@CE2 TRP_2@CD2 TRP_2@CE3 TRP_2@HE3 0.0241 0.2733 0.2492 0.0000 0.0000 0.0000 +TRP_2@HE1 TRP_2@NE1 TRP_2@CE2 TRP_2@CZ2 0.0590 0.1199 0.0609 0.0000 0.0000 0.0000 +TRP_2@HE1 TRP_2@NE1 TRP_2@CE2 TRP_2@CD2 0.0846 0.1892 0.1046 0.0000 0.0000 0.0000 +TRP_2@NE1 TRP_2@CE2 TRP_2@CZ2 TRP_2@HZ2 0.6167 0.0279 -0.5888 0.0000 0.0000 0.0000 +TRP_2@HD1 TRP_2@CD1 TRP_2@CG TRP_2@CD2 0.1367 0.2051 0.0684 0.0000 0.0000 0.0000 +TRP_2@HD1 TRP_2@CD1 TRP_2@NE1 TRP_2@HE1 0.1572 0.0148 -0.1424 0.0000 0.0000 0.0000 +TRP_2@HD1 TRP_2@CD1 TRP_2@NE1 TRP_2@CE2 0.3601 0.0002 -0.3599 0.0000 0.0000 0.0000 +TRP_2@CG TRP_2@CD1 TRP_2@NE1 TRP_2@HE1 0.0102 0.0917 0.0815 0.0000 0.0000 0.0000 +TRP_2@CG TRP_2@CD2 TRP_2@CE3 TRP_2@HE3 0.2493 1.2059 0.9566 0.0000 0.0000 0.0000 +TRP_2@HB3 TRP_2@CB TRP_2@CA TRP_2@C 0.0007 0.0013 0.0006 0.0000 0.0000 0.0000 +TRP_2@HB3 TRP_2@CB TRP_2@CG TRP_2@CD1 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +TRP_2@HB3 TRP_2@CB TRP_2@CG TRP_2@CD2 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +TRP_2@HB2 TRP_2@CB TRP_2@CA TRP_2@C 0.0095 0.0113 0.0018 0.0000 0.0000 0.0000 +TRP_2@HB2 TRP_2@CB TRP_2@CG TRP_2@CD1 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +TRP_2@HB2 TRP_2@CB TRP_2@CG TRP_2@CD2 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +TRP_2@CB TRP_2@CG TRP_2@CD1 TRP_2@HD1 0.2470 0.0922 -0.1549 0.0000 0.0000 0.0000 +TRP_2@HA TRP_2@CA TRP_2@CB TRP_2@HB2 0.0103 0.0004 -0.0098 0.0000 0.0000 0.0000 +TRP_2@HA TRP_2@CA TRP_2@CB TRP_2@HB3 0.0485 0.0025 -0.0460 0.0000 0.0000 0.0000 +TRP_2@HA TRP_2@CA TRP_2@CB TRP_2@CG 0.0408 0.0008 -0.0399 0.0000 0.0000 0.0000 +TRP_2@HA TRP_2@CA TRP_2@C TRP_2@O 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +TRP_2@H TRP_2@N TRP_2@CA TRP_2@HA 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +TRP_2@H TRP_2@N TRP_2@CA TRP_2@CB 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +TRP_2@H TRP_2@N TRP_2@CA TRP_2@C 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +TRP_2@N TRP_2@CA TRP_2@CB TRP_2@HB2 0.0054 0.0008 -0.0046 0.0000 0.0000 0.0000 +TRP_2@N TRP_2@CA TRP_2@CB TRP_2@HB3 0.0377 0.0097 -0.0280 0.0000 0.0000 0.0000 +TRP_2@CZ3 TRP_2@CD2 TRP_2@CE3 TRP_2@HE3 0.0020 0.2596 0.2576 0.0000 0.0000 0.0000 +TRP_2@CH2 TRP_2@CE3 TRP_2@CZ3 TRP_2@HZ3 0.0794 0.0070 -0.0724 0.0000 0.0000 0.0000 +TRP_2@CZ2 TRP_2@CZ3 TRP_2@CH2 TRP_2@HH2 0.0069 0.0023 -0.0046 0.0000 0.0000 0.0000 +TRP_2@CE2 TRP_2@CH2 TRP_2@CZ2 TRP_2@HZ2 0.0042 0.0084 0.0042 0.0000 0.0000 0.0000 +TRP_2@CD1 TRP_2@CE2 TRP_2@NE1 TRP_2@HE1 0.0322 0.0126 -0.0196 0.0000 0.0000 0.0000 +TRP_2@CG TRP_2@NE1 TRP_2@CD1 TRP_2@HD1 0.1789 0.0243 -0.1546 0.0000 0.0000 0.0000 +#Dihedral E0 = 7.713854 +#Dihedral E1 = 4.477089 +#Dihedral = -0.047599 +#Dihedral ene RMSE = 0.214669 +#Dihedral = 0.000000 +#Dihedral len RMSE = 0.000000 diff --git a/test/Test_LoadCrd/RunTest.sh b/test/Test_LoadCrd/RunTest.sh index a4e830d8fd..3834940a2a 100755 --- a/test/Test_LoadCrd/RunTest.sh +++ b/test/Test_LoadCrd/RunTest.sh @@ -2,38 +2,41 @@ . ../MasterTest.sh -CleanFiles load.in d1-10.dat d1-12.dat +CleanFiles load.in d1-10.dat d1-12.dat frm.d1-10.dat trj.d1-10.dat \ + trajin.d1-10.dat frm.d1-12.dat + TESTNAME='COORDS data set tests' Requires netcdf INPUT="-i load.in" + # Generate comparison file Generate() { -cat > load.in < load.in < load.in < load.in < load.in < load.in < load.in < load.in < load.in < load.in < load.in < load.in < mdcrd" DoTest ../tz2.truncoct.crd trajectory_test.mdcrd +# ----- NetCDF4/HDF5 tests ----------------------- +UNITNAME='Convert mdcrd <-> NetCDF4/HDF5' +CheckFor hdf5 maxthreads 1 +if [ $? -eq 0 ] ; then + cat > $INPUT < NetCDF4/HDF5" + cat > $INPUT < mdcrd" + DoTest ../tz2.truncoct.crd trajectory_nc4.mdcrd +fi + +UNITNAME='Convert mdcrd <-> NetCDF4/HDF5 with compression' +CheckFor hdf5 maxthreads 1 +if [ $? -eq 0 ] ; then + cat > $INPUT < NetCDF4/HDF5 with compression" + cat > $INPUT < mdcrd" + DoTest ../tz2.truncoct.crd compress.mdcrd +fi + +UNITNAME='Convert mdcrd <-> NetCDF4/HDF5 with lossy compression' +CheckFor hdf5 maxthreads 1 +if [ $? -eq 0 ] ; then + cat > $INPUT < NetCDF4/HDF5 with lossy compression" + cat > $INPUT < mdcrd" + # NOTE: An absolute tolerance of 0.0001 (which is greater than the + # possible precision of MDCRD format) is used to allow for + # the fact that a -0.000 will be converted to 0.000 by the + # lossy compression. + DoTest ../tz2.truncoct.crd icompress.mdcrd -a 0.0001 +fi + +TOP='' +INPUT="-i ptraj_netcdf.in" +UNITNAME='Test compression of velocity/force info' +CheckFor hdf5 maxthreads 1 +if [ $? -eq 0 ] ; then + cat > ptraj_netcdf.in < ptraj_netcdf.in < ptraj_netcdf.in < ptraj_netcdf.in < vector.in < cpptraj.in <