From 82d1f1c43c3522b2a3814e530bf7b3fc3ec0d35f Mon Sep 17 00:00:00 2001 From: "Maarten L. Hekkelman" Date: Tue, 24 Nov 2020 09:48:37 +0100 Subject: [PATCH] Updated options, added manual --- GNUmakefile.in | 62 ++++---- README.md | 34 ++++- configure | 368 +++++++++++---------------------------------- configure.ac | 46 +++--- mkdssp.1 | 76 ++++++++++ src/config.hpp.in | 9 -- src/dssp.cpp | 371 ++++++++++++++-------------------------------- src/dssp.hpp | 36 ----- 8 files changed, 363 insertions(+), 639 deletions(-) create mode 100644 mkdssp.1 delete mode 100644 src/dssp.hpp diff --git a/GNUmakefile.in b/GNUmakefile.in index a376a48..23b8223 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -22,11 +22,13 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +SHELL := /bin/bash + firstTarget: all CXX = @CXX@ -CXXFLAGS = @CXXFLAGS@ @CPPFLAGS@ @BOOST_CPPFLAGS@ @PTHREAD_CFLAGS@ @CIFPP_CFLAGS@ -LDFLAGS = @LDFLAGS@ @BOOST_LDFLAGS@ @PTHREAD_CFLAGS@ +CXXFLAGS = @CXXFLAGS@ @CPPFLAGS@ @PTHREAD_CFLAGS@ @CIFPP_CFLAGS@ +LDFLAGS = @LDFLAGS@ @PTHREAD_CFLAGS@ LIBS = @LIBS@ \ @CIFPP_LIBS@ \ @BOOST_IOSTREAMS_LIB@ \ @@ -38,6 +40,7 @@ exec_prefix = @exec_prefix@ bindir = @bindir@ datarootdir = @datarootdir@ datadir = @datadir@ +mandir = @mandir@ GNUmakefile: config.status GNUmakefile.in $(SHELL) ./config.status @@ -53,6 +56,9 @@ configure: configure.ac endif # main build variables +VERSION = @PACKAGE_VERSION@.0 +DEFINES += VERSION='"$(VERSION)"' + CXXFLAGS += -Wall -Wno-multichar CIFPP_RSRC = @CIFPP_RSRC@ @@ -97,14 +103,18 @@ $(OBJDIR)/%.o: %.cpp | $(OBJDIR) @ echo ">>" $< @ $(CXX) -MD -c -o $@ $< $(CFLAGS) $(CXXFLAGS) -COMMON_OBJECTS = pr-main.o +# We have development releases and official releases, for each we +# maintain different versioning schemes. + +ifneq "x@UPDATE_REVISION@" "x" REVISION = $(shell git log --pretty=format:%h --max-count=1) REVISION_FILE = version-info-$(REVISION).txt $(REVISION_FILE): rm -f version-info-*.txt - git describe --match=build --dirty > $@ + @ echo dssp-version: $(VERSION) > $@ + @ git describe --match=build --dirty >> $@ @ git log --pretty=medium --date=iso8601 -1 >> $@ src/revision.hpp: $(REVISION_FILE) @@ -112,10 +122,17 @@ src/revision.hpp: $(REVISION_FILE) @ cat $? >> $@ @ echo ')";' >> $@ -$(OBJDIR)/pr-main.o: src/revision.hpp +else + +src/revision.hpp: + @ echo 'const char kRevision[] = R"(' > $@ + @ echo dssp-version: $(VERSION) >> $@ + @ echo Date: $$(date --iso-8601) >> $@ + @ echo ')";' >> $@ + +endif ifneq "$(USE_RSRC)" "0" -COMMON_RSRC = $(DATADIR)/dictionaries rsrc: @ mkdir -p $@ @@ -127,46 +144,39 @@ endif # The program rules -# disabled for now: centrifuge map-maker -PROGRAMS = dssp - -define PROGRAM_template = - -$(1)_OBJECTS += $(1).o $(COMMON_OBJECTS) +OBJECTS = \ + $(OBJDIR)/dssp.o ifneq "$(USE_RSRC)" "0" -$(1)_OBJECTS += $(1).o $(1)_rsrc.o +$OBJECTS += dssp_rsrc.o -$$(OBJDIR)/$(1)_rsrc.o: $$($(1)_RSRC) $$(COMMON_RSRC) +$(OBJDIR)/dssp_rsrc.o: $(DATADIR)/mmcif_pdbx_v50.dic $(MRC) -o $$@ $$^ endif -$(1): $$($(1)_OBJECTS:%=$(OBJDIR)/%) +$(OBJDIR)/dssp.o: src/revision.hpp -endef - -$(foreach program,$(PROGRAMS),$(eval $(call PROGRAM_template,$(program)))) - -$(PROGRAMS): +mkdssp: $(OBJECTS) @ echo '->' $@ @ $(CXX) -o $@ $^ $(CXXFLAGS) $(LDFLAGS) $(LIBS) -OBJECTS = $(sort $(foreach program,$(PROGRAMS),$($(program)_OBJECTS))) - $(OBJDIR)/%.d: $(OBJDIR)/%.o -include $(OBJECTS:%.o=$(OBJDIR)/%.d) .PHONY: clean all clean: - rm -rf $(PROGRAMS) $(OBJDIR)/* $(REVISION_FILE) + rm -rf mkdssp $(OBJDIR)/* src/revision.hpp -all: $(PROGRAMS) +all: mkdssp .PHONY: install -install: $(PROGRAMS) +install: mkdssp install -d $(bindir) - for p in $(PROGRAMS); do install $$p $(bindir)/$$p; done + install mkdssp $(bindir)/mkdssp + install -d $(mandir)/man1 + install -m 644 mkdssp.1 $(mandir)/man1/mkdssp.1; + gzip $(mandir)/man1/mkdssp.1; .PHONY: FORCE FORCE: diff --git a/README.md b/README.md index 7044988..01ab9ec 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,38 @@ -DSSP version 4 -============== +DSSP 4.0 +======== This is a rewrite of DSSP, now offering full mmCIF support. The difference with previous releases of DSSP is that it now writes out an annotated mmCIF file by default, storing the secondary structure information in the _struct_conf category. +The DSSP program was designed by Wolfgang Kabsch and Chris Sander to +standardize secondary structure assignment. DSSP is a database of secondary +structure assignments (and much more) for all protein entries in the Protein +Data Bank (PDB). DSSP is also the program that calculates DSSP entries from +PDB entries. DSSP does not predict secondary structure. + +Requirements +------------ + +The tools are based on [libcif++](/~https://github.com/PDB-REDO/libcifpp) +and the code is written in modern C++ so you need a compiler capable +of handling C++17 code. + Building -------- -To build this, first install [libcif++](/~https://github.com/PDB-REDO/libcifpp.git) -and then run `configure`, `make` and `make install`. + +Make sure you install libcif++ first before building. + +After that, building should be as easy as typing: + +``` +./configure +make +make install +``` + +Usage +----- + +See `man mkdssp` for more info. diff --git a/configure b/configure index 3d44548..60a4daf 100755 --- a/configure +++ b/configure @@ -625,10 +625,6 @@ ac_includes_default="\ ac_subst_vars='LTLIBOBJS LIBOBJS -LIBBZ2_LDFLAGS -LIBBZ2_CPPFLAGS -LIBZ_LDFLAGS -LIBZ_CPPFLAGS CIFPP_LDFLAGS CIFPP_CPPFLAGS AX_PACKAGE_REQUIRES_PRIVATE @@ -645,9 +641,6 @@ BOOST_IOSTREAMS_LIB BOOST_LDFLAGS BOOST_CPPFLAGS CXXCPP -USE_RSRC -MRC -DEBUG PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -667,6 +660,9 @@ build_os build_vendor build_cpu build +UPDATE_REVISION +MRC +DEBUG INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM @@ -720,7 +716,7 @@ SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking -enable_resources +enable_revision with_boost with_boost_libdir with_boost_iostreams @@ -737,11 +733,11 @@ LDFLAGS LIBS CPPFLAGS CCC +DEBUG +MRC CC CFLAGS CPP -DEBUG -MRC CXXCPP PKG_CONFIG PKG_CONFIG_PATH @@ -749,11 +745,7 @@ PKG_CONFIG_LIBDIR CIFPP_CFLAGS CIFPP_LIBS CIFPP_CPPFLAGS -CIFPP_LDFLAGS -LIBZ_CPPFLAGS -LIBZ_LDFLAGS -LIBBZ2_CPPFLAGS -LIBBZ2_LDFLAGS' +CIFPP_LDFLAGS' # Initialize some variables set by options. @@ -1378,7 +1370,7 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-resources Do not use mrc to store data in resources + --disable-revision Create a build number as revision Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -1417,11 +1409,11 @@ Some influential environment variables: LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory + DEBUG Build a debug version of the application + MRC Specify a location for the mrc executable CC C compiler command CFLAGS C compiler flags CPP C preprocessor - DEBUG Build a debug version of the application - MRC Specify a location for the mrc executable CXXCPP C++ preprocessor PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH @@ -1435,14 +1427,6 @@ Some influential environment variables: C preprocessor flags for CIFPP headers CIFPP_LDFLAGS linker flags for CIFPP libraries - LIBZ_CPPFLAGS - C preprocessor flags for LIBZ headers - LIBZ_LDFLAGS - linker flags for LIBZ libraries - LIBBZ2_CPPFLAGS - C preprocessor flags for LIBBZ2 headers - LIBBZ2_LDFLAGS - linker flags for LIBBZ2 libraries Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -3683,7 +3667,9 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags__Werror__fstandalone_debug" >&5 $as_echo "$ax_cv_check_cxxflags__Werror__fstandalone_debug" >&6; } if test "x$ax_cv_check_cxxflags__Werror__fstandalone_debug" = xyes; then : - CXXFLAGS="$CXXFLAGS -fstandalone-debug" + + CXXFLAGS="$CXXFLAGS -fstandalone-debug" + else : fi @@ -3719,7 +3705,6 @@ ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - ac_config_headers="$ac_config_headers src/config.hpp" @@ -3819,6 +3804,72 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + + + +if test "x$MRC" = "x"; then + # Extract the first word of "mrc", so it can be a program name with args. +set dummy mrc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MRC+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MRC in + [\\/]* | ?:[\\/]*) + ac_cv_path_MRC="$MRC" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_MRC="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +MRC=$ac_cv_path_MRC +if test -n "$MRC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MRC" >&5 +$as_echo "$MRC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi + +if test "x$MRC" = "x"; then + as_fn_error $? "mrc not found, the application will be built without resources" "$LINENO" 5 +fi + +# Check whether --enable-revision was given. +if test "${enable_revision+set}" = set; then : + enableval=$enable_revision; +fi + + +if test "x$enable_revision" != "xno" ; then : + + UPDATE_REVISION=1 + +fi + +UPDATE_REVISION=$UPDATE_REVISION + + # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 @@ -5409,81 +5460,6 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - - -USE_RSRC=0 - -if test "x$MRC" = "x"; then - # Extract the first word of "mrc", so it can be a program name with args. -set dummy mrc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_MRC+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $MRC in - [\\/]* | ?:[\\/]*) - ac_cv_path_MRC="$MRC" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_MRC="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -MRC=$ac_cv_path_MRC -if test -n "$MRC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MRC" >&5 -$as_echo "$MRC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi - -if test "x$MRC" = "x"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: The mrc application was not found, not using resources." >&5 -$as_echo "$as_me: WARNING: The mrc application was not found, not using resources." >&2;} -else - # Check whether --enable-resources was given. -if test "${enable_resources+set}" = set; then : - enableval=$enable_resources; -fi - - - if test "x$enable_resources" != "xno" ; then : - - USE_RSRC=1 - -fi -fi - -USE_RSRC=$USE_RSRC - - - -cat >>confdefs.h <<_ACEOF -#define USE_RSRC $USE_RSRC -_ACEOF - - ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -7017,7 +6993,7 @@ fi - AX_PACKAGE_REQUIRES="$AX_PACKAGE_REQUIRES libcif++" + AX_PACKAGE_REQUIRES="$AX_PACKAGE_REQUIRES libcifpp" AX_PACKAGE_REQUIRES_PRIVATE="$AX_PACKAGE_REQUIRES_PRIVATE " @@ -7029,12 +7005,12 @@ if test -n "$CIFPP_CFLAGS"; then pkg_cv_CIFPP_CFLAGS="$CIFPP_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcif++ \""; } >&5 - ($PKG_CONFIG --exists --print-errors "libcif++ ") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcifpp \""; } >&5 + ($PKG_CONFIG --exists --print-errors "libcifpp ") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_CIFPP_CFLAGS=`$PKG_CONFIG --cflags "libcif++ " 2>/dev/null` + pkg_cv_CIFPP_CFLAGS=`$PKG_CONFIG --cflags "libcifpp " 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -7046,12 +7022,12 @@ if test -n "$CIFPP_LIBS"; then pkg_cv_CIFPP_LIBS="$CIFPP_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcif++ \""; } >&5 - ($PKG_CONFIG --exists --print-errors "libcif++ ") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcifpp \""; } >&5 + ($PKG_CONFIG --exists --print-errors "libcifpp ") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_CIFPP_LIBS=`$PKG_CONFIG --libs "libcif++ " 2>/dev/null` + pkg_cv_CIFPP_LIBS=`$PKG_CONFIG --libs "libcifpp " 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -7072,18 +7048,18 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - CIFPP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libcif++ " 2>&1` + CIFPP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libcifpp " 2>&1` else - CIFPP_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libcif++ " 2>&1` + CIFPP_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libcifpp " 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$CIFPP_PKG_ERRORS" >&5 - as_fn_error $? "the required package libcif++ is not installed" "$LINENO" 5 + as_fn_error $? "the required package libcifpp is not installed" "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - as_fn_error $? "the required package libcif++ is not installed" "$LINENO" 5 + as_fn_error $? "the required package libcifpp is not installed" "$LINENO" 5 else CIFPP_CFLAGS=$pkg_cv_CIFPP_CFLAGS CIFPP_LIBS=$pkg_cv_CIFPP_LIBS @@ -7197,170 +7173,6 @@ fi fi - - - - - - if ${ax_cv_have_LIBZ+:} false; then : - $as_echo_n "(cached) " >&6 -else - save_CPPFLAGS="$CPPFLAGS" - save_LDFLAGS="$LDFLAGS" - save_LIBS="$LIBS" - - if test "x$LIBZ_CPPFLAGS" != "x"; then : - CPPFLAGS="$CPPFLAGS $LIBZ_CPPFLAGS" -fi - - if test "x$LIBZ_LDFLAGS" != "x"; then : - LDFLAGS="$LDFLAGS $LIBZ_LDFLAGS" -fi - - ac_fn_cxx_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" -if test "x$ac_cv_header_zlib_h" = xyes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lz" >&5 -$as_echo_n "checking for main in -lz... " >&6; } -if ${ac_cv_lib_z_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - ac_cv_lib_z_main=yes -else - ac_cv_lib_z_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_main" >&5 -$as_echo "$ac_cv_lib_z_main" >&6; } -if test "x$ac_cv_lib_z_main" = xyes; then : - ax_cv_have_LIBZ=yes -else - ax_cv_have_LIBZ=no -fi - - -else - ax_cv_have_LIBZ=no -fi - - - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - -fi - - - if test "$ax_cv_have_LIBZ" = "yes"; then : - -$as_echo "#define HAVE_LIBZ 1" >>confdefs.h - - LIBS="$LIBS -lz" -else - as_fn_error $? "libz not found - compressed files not supported" "$LINENO" 5 -fi - - - - - - if ${ax_cv_have_LIBBZ2+:} false; then : - $as_echo_n "(cached) " >&6 -else - save_CPPFLAGS="$CPPFLAGS" - save_LDFLAGS="$LDFLAGS" - save_LIBS="$LIBS" - - if test "x$LIBBZ2_CPPFLAGS" != "x"; then : - CPPFLAGS="$CPPFLAGS $LIBBZ2_CPPFLAGS" -fi - - if test "x$LIBBZ2_LDFLAGS" != "x"; then : - LDFLAGS="$LDFLAGS $LIBBZ2_LDFLAGS" -fi - - ac_fn_cxx_check_header_mongrel "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default" -if test "x$ac_cv_header_bzlib_h" = xyes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lbz2" >&5 -$as_echo_n "checking for main in -lbz2... " >&6; } -if ${ac_cv_lib_bz2_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lbz2 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - ac_cv_lib_bz2_main=yes -else - ac_cv_lib_bz2_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_main" >&5 -$as_echo "$ac_cv_lib_bz2_main" >&6; } -if test "x$ac_cv_lib_bz2_main" = xyes; then : - ax_cv_have_LIBBZ2=yes -else - ax_cv_have_LIBBZ2=no -fi - - -else - ax_cv_have_LIBBZ2=no -fi - - - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - -fi - - - if test "$ax_cv_have_LIBBZ2" = "yes"; then : - -$as_echo "#define HAVE_LIBBZ2 1" >>confdefs.h - - LIBS="$LIBS -lbz2" -else - as_fn_error $? "libbz2 not found - compressed files not supported" "$LINENO" 5 -fi - - ac_config_files="$ac_config_files GNUmakefile" cat >confcache <<\_ACEOF diff --git a/configure.ac b/configure.ac index af718e3..a89e8f9 100644 --- a/configure.ac +++ b/configure.ac @@ -2,48 +2,48 @@ AC_PREREQ([2.69]) AC_INIT([dssp], 4.0, [m.hekkelman@nki.nl]) -dnl Switch to a decent C++ compiler, and check if it works. +dnl Switch to a C++ compiler, and check if it works. AC_LANG(C++) AX_CXX_COMPILE_STDCXX_17([noext]) -AX_CHECK_COMPILE_FLAG([-fstandalone-debug], [ CXXFLAGS="$CXXFLAGS -fstandalone-debug" ], , [-Werror]) +AX_CHECK_COMPILE_FLAG([-fstandalone-debug], + [ + CXXFLAGS="$CXXFLAGS -fstandalone-debug" + ] , , [-Werror]) AC_CONFIG_SRCDIR([src/dssp.cpp]) AC_CONFIG_AUX_DIR(config) -AC_CONFIG_MACRO_DIR([config/m4]) AC_CONFIG_HEADERS([src/config.hpp]) AC_PREFIX_DEFAULT(/usr/local) AC_PROG_INSTALL -AX_PTHREAD - AC_ARG_VAR([DEBUG], [Build a debug version of the application]) AC_ARG_VAR([MRC], [Specify a location for the mrc executable]) -USE_RSRC=0 - +dnl We would like to use mrc if test "x$MRC" = "x"; then AC_PATH_PROG([MRC], [mrc]) fi if test "x$MRC" = "x"; then - AC_MSG_WARN([The mrc application was not found, not using resources.]) -else - AC_ARG_ENABLE( - resources, - [AS_HELP_STRING([--disable-resources], [Do not use mrc to store data in resources])]) - - AS_IF([test "x$enable_resources" != "xno" ], [ - USE_RSRC=1 - ]) + AC_MSG_ERROR([mrc not found, the application will be built without resources]) fi -AC_SUBST([USE_RSRC], [$USE_RSRC]) +dnl revision numbering is something used internally at the NKI +AC_ARG_ENABLE( + revision, + [AS_HELP_STRING([--disable-revision], [Create a build number as revision])]) + +AS_IF([test "x$enable_revision" != "xno" ], [ + UPDATE_REVISION=1 +]) + +AC_SUBST([UPDATE_REVISION], [$UPDATE_REVISION]) -AC_DEFINE_UNQUOTED([USE_RSRC], [$USE_RSRC], [Use mrc to store resources]) +AX_PTHREAD AC_CHECK_HEADER([filesystem], [], [AC_MSG_ERROR([The file is missing, perhaps you should install a more recent libstdc++ implementation.])]) @@ -98,7 +98,7 @@ AS_IF([test "x$CIFPP_LIBS" = "x"], [ AC_PATH_PROG([PKG_CONFIG], [pkg-config]) if test -x "$PKG_CONFIG" then - AX_PKG_CHECK_MODULES([CIFPP], [libcif++], [], [], [AC_MSG_ERROR([the required package libcif++ is not installed])]) + AX_PKG_CHECK_MODULES([CIFPP], [libcifpp], [], [], [AC_MSG_ERROR([the required package libcifpp is not installed])]) else AC_CHECK_HEADER( [cif++/Config.hpp], @@ -118,13 +118,5 @@ pkg-config.])]) fi ]) - -AX_CHECK_LIBRARY([LIBZ], [zlib.h], [z], - [ LIBS="$LIBS -lz" ], - [AC_MSG_ERROR([libz not found - compressed files not supported])]) -AX_CHECK_LIBRARY([LIBBZ2], [bzlib.h], [bz2], - [ LIBS="$LIBS -lbz2"], - [AC_MSG_ERROR([libbz2 not found - compressed files not supported])]) - dnl Process Makefile.in to create Makefile AC_OUTPUT([GNUmakefile]) diff --git a/mkdssp.1 b/mkdssp.1 new file mode 100644 index 0000000..3c0f2a2 --- /dev/null +++ b/mkdssp.1 @@ -0,0 +1,76 @@ +.TH mkdssp 1 "2020-11-23" "version 1.0.0" "User Commands" +.if n .ad l +.nh +.SH NAME +mkdssp \- Assign secondary structure to proteins +.SH SYNOPSIS +mkdssp [OPTION] input [output] +.SH DESCRIPTION +The DSSP program was designed by Wolfgang Kabsch and Chris Sander to +standardize secondary structure assignment. DSSP is a database of +secondary structure assignments (and much more) for all protein entries +in the Protein Data Bank (PDB). mkdssp is the program that calculates +DSSP entries from PDB entries. mkdssp does \fBnot\fR predict secondary structure. +.sp +The original DSSP program wrote output in a fixed format, this version +by default writes annotated mmCIF files, storing the secondary structure +information in the _struct_conf category. +.sp +Since version 4.0 the mkdssp program also assigns PP helices. +.SH OPTIONS +The input file can be either mmCIF or PDB format and the file may be +gzip or bzip2 compressed. +.sp +The output is optional, if ommited the output is written to \fIstdout\fR. If +the name of the output file ends with either \fI.gz\fR or \fI.bz2\fR the +output is compressed accordingly. +.TP +\fB--output-format\fR=[dssp|mmcif] +If an output file is specified, the extension of the filename is used to +choose to output format, but if it is unclear, mmcif is the default. Use +this option to force output in either the old fixed column DSSP format or +the new annotated mmCIF format. +.TP +\fB--min-pp-stretch\fR +This option can be used to define the minimal number of residues with PHI/PSI +angles within the range required to assing a PP helix. +.TP +\fB--write-other\fR +By default the new format does not write the structure information for OTHER. +Use this flag to change that. +.SH DETAILS +The DSSP algorithm assings secondary structure based on the energy calculated +for H-bonds. +.br +.B Table\ \&1.\ \&Secondary\ Structures\ recognized +.TS +allbox; +cb cb cb . +DSSP Code mmCIF Code Description +.T& +l l l. +H HELX_RH_AL_P Alphahelix +B STRN Betabridge +E STRN Strand +G HELX_RH_3T_P Helix_3 +I HELX_RH_PI_P Helix_5 +P HELX_LH_PP_P Helix_PPII +T TURN_TY1_P Turn +S BEND Bend +' ' OTHER Loop +.TE +.SH BUGS +The mmCIF format currently lacks a lot of information that was available +in the old format like information about the bridge pairs or the span +of the various helices recognized. Also the accessibility information +is left out. +.sp +If you think this information should be part of the output, please contact +the author. +.SH AUTHOR +Written by Maarten L. Hekkelman +.SH "REPORTING BUGS" +Report bugs at /~https://github.com/PDB-REDO/cif-tools/issues +.SH "SEE ALSO" +\fBcif-drop\fR, \fBcif-grep\fR, \fBcif-merge\fR, \fBcif-validate\fR, +\fBcif2pdb\fR, \fBmmCQL\fR, \fBpdb2cif\fR. diff --git a/src/config.hpp.in b/src/config.hpp.in index b4a68f4..20520e0 100644 --- a/src/config.hpp.in +++ b/src/config.hpp.in @@ -21,12 +21,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H -/* Define to 1 if LIBBZ2 is found */ -#undef HAVE_LIBBZ2 - -/* Define to 1 if LIBZ is found */ -#undef HAVE_LIBZ - /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H @@ -81,6 +75,3 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS - -/* Use mrc to store resources */ -#undef USE_RSRC diff --git a/src/dssp.cpp b/src/dssp.cpp index 32383b5..ed7bd50 100644 --- a/src/dssp.cpp +++ b/src/dssp.cpp @@ -24,12 +24,12 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "dssp.hpp" +#include "config.hpp" #include #include -#include #include +#include #include #include @@ -49,7 +49,87 @@ namespace fs = std::filesystem; namespace io = boost::iostreams; namespace po = boost::program_options; -extern std::string VERSION_STRING; +// -------------------------------------------------------------------- + +// recursively print exception whats: +void print_what (const std::exception& e) +{ + std::cerr << e.what() << std::endl; + try + { + std::rethrow_if_nested(e); + } + catch (const std::exception& nested) + { + std::cerr << " >> "; + print_what(nested); + } +} + +// -------------------------------------------------------------------- + +namespace { + std::string gVersionNr, gVersionDate, VERSION_STRING; +} + +void load_version_info() +{ + const std::regex + rxVersionNr(R"(build-(\d+)-g[0-9a-f]{7}(-dirty)?)"), + rxVersionDate(R"(Date: +(\d{4}-\d{2}-\d{2}).*)"), + rxVersionNr2(R"(dssp-version: (\d+(?:\.\d+)+))"); + +#include "revision.hpp" + + struct membuf : public std::streambuf + { + membuf(char* data, size_t length) { this->setg(data, data, data + length); } + } buffer(const_cast(kRevision), sizeof(kRevision)); + + std::istream is(&buffer); + + std::string line; + + while (getline(is, line)) + { + std::smatch m; + + if (std::regex_match(line, m, rxVersionNr)) + { + gVersionNr = m[1]; + if (m[2].matched) + gVersionNr += '*'; + continue; + } + + if (std::regex_match(line, m, rxVersionDate)) + { + gVersionDate = m[1]; + continue; + } + + // always the first, replace with more specific if followed by the other info + if (std::regex_match(line, m, rxVersionNr2)) + { + gVersionNr = m[1]; + continue; + } + } + + if (not VERSION_STRING.empty()) + VERSION_STRING += "\n"; + VERSION_STRING += gVersionNr + " " + gVersionDate; +} + +std::string get_version_nr() +{ + return gVersionNr/* + '/' + cif::get_version_nr()*/; +} + +std::string get_version_date() +{ + return gVersionDate; +} // -------------------------------------------------------------------- @@ -240,33 +320,6 @@ void writeDSSP(const mmcif::Structure& structure, const mmcif::DSSP& dssp, std:: os << ResidueToDSSPLine(ri) << std::endl; last = ri.nr(); } - - // std::vector residues; - - // foreach (const MChain* chain, protein.GetChains()) - // { - // foreach (const MResidue* residue, chain->GetResidues()) - // residues.push_back(residue); - // } - - // // keep residues sorted by residue number as assigned during reading the PDB file - // sort(residues.begin(), residues.end(), boost::bind(&MResidue::GetNumber, _1) < boost::bind(&MResidue::GetNumber, _2)); - - // const MResidue* last = nullptr; - // foreach (const MResidue* residue, residues) - // { - // // insert a break line whenever we detect missing residues - // // can be the transition to a different chain, or missing residues in the current chain - // if (last != nullptr and last->GetNumber() + 1 != residue->GetNumber()) - // { - // char breaktype = ' '; - // if (last->GetChainID() != residue->GetChainID()) - // breaktype = '*'; - // os << (kDSSPResidueLine % (last->GetNumber() + 1) % breaktype) << std::endl; - // } - // os << ResidueToDSSPLine(*residue) << std::endl; - // last = residue; - // } } void annotateDSSP(mmcif::Structure& structure, const mmcif::DSSP& dssp, bool writeOther, std::ostream& os) @@ -388,250 +441,34 @@ void annotateDSSP(mmcif::Structure& structure, const mmcif::DSSP& dssp, bool wri } } - db.add_software("dssp " PACKAGE_VERSION, "other", get_version_nr(), get_version_date()); + db.add_software("dssp", "other", get_version_nr(), get_version_date()); db.write(os); - -// cif::File df; - -// df.append(new cif::Datablock("DSSP_" + structure.getFile().data().getName())); - -// auto& db = df.firstDatablock(); - -// int last = 0; -// for (auto info: dssp) -// { -// // insert a break line whenever we detect missing residues -// // can be the transition to a different chain, or missing residues in the current chain - - -// // os << (kDSSPResidueLine % (last + 1) % (ri.chainBreak() == mmcif::ChainBreak::NewChain ? '*' : ' ')) << std::endl; - -// // os << ResidueToDSSPLine(ri) << std::endl; - -// auto& mon = info.residue(); - -// auto&& [row, rn] = db["struct_mon_prot"].emplace({ -// { "chain_break", (info.chainBreak() == mmcif::ChainBreak::Gap ? 'Y' : '.') }, -// { "label_comp_id", mon.compoundID() }, -// { "label_asym_id", mon.asymID() }, -// { "label_seq_id", mon.seqID() }, -// { "label_alt_id", info.alt_id() }, -// { "auth_asym_id", mon.authAsymID() }, -// { "auth_seq_id", mon.authSeqID() }, -// { "auth_ins_code", mon.authInsCode() }, -// }); - -// if (mon.is_first_in_chain()) -// row["phi"] = "."; -// else -// row["phi"].os(std::fixed, std::setprecision(1), mon.phi()); - -// if (mon.is_last_in_chain()) -// row["psi"] = "."; -// else -// row["psi"].os(std::fixed, std::setprecision(1), mon.psi()); - -// if (mon.is_last_in_chain()) -// row["omega"] = "."; -// else -// row["omega"].os(std::fixed, std::setprecision(1), mon.omega()); - -// int nrOfChis = mon.nrOfChis(); -// for (int i = 0; i < 5; ++i) -// { -// auto cl = "chi" + std::to_string(i + 1); -// if (i < nrOfChis) -// row[cl].os(std::fixed, std::setprecision(1), mon.chi(i)); -// else -// row[cl] = '.'; -// } - -// if (not mon.has_alpha()) -// row["alpha"] = "."; -// else -// row["alpha"].os(std::fixed, std::setprecision(1), mon.alpha()); - -// if (not mon.has_kappa()) -// row["kappa"] = "."; -// else -// row["kappa"].os(std::fixed, std::setprecision(1), mon.kappa()); - -// if (mon.is_first_in_chain()) -// row["tco"] = "."; -// else -// row["tco"].os(std::fixed, std::setprecision(1), mon.tco()); - -// // sec structure info - -// char ss; -// switch (info.ss()) -// { -// case mmcif::ssAlphahelix: ss = 'H'; break; -// case mmcif::ssBetabridge: ss = 'B'; break; -// case mmcif::ssStrand: ss = 'E'; break; -// case mmcif::ssHelix_3: ss = 'G'; break; -// case mmcif::ssHelix_5: ss = 'I'; break; -// case mmcif::ssHelix_PPII: ss = 'P'; break; -// case mmcif::ssTurn: ss = 'T'; break; -// case mmcif::ssBend: ss = 'S'; break; -// case mmcif::ssLoop: ss = '.'; break; -// } -// row["dssp_symbol"] = ss; - -// if (mon.has_alpha()) -// row["Calpha_chiral_sign"] = mon.alpha() < 0 ? "neg" : "pos"; -// else -// row["Calpha_chiral_sign"] = "."; - -// row["sheet_id"] = info.sheet() ? std::to_string(info.sheet()) : "."; - -// for (uint32_t i: { 0, 1 }) -// { -// std::string il = "bridge_partner_" + std::to_string(i + 1); - -// const auto& [p, ladder, parallel] = info.bridgePartner(i); -// if (not p) -// { -// row[il + "_label_comp_id"] = "."; -// row[il + "_label_asym_id"] = "."; -// row[il + "_label_seq_id"] = "."; -// row[il + "_auth_asym_id"] = "."; -// row[il + "_auth_seq_id"] = "."; -// row[il + "_ladder"] = "."; -// row[il + "_sense"] = "."; -// continue; -// } - -// auto& pm = p.residue(); - -// row[il + "_label_comp_id"] = pm.compoundID(); -// row[il + "_label_asym_id"] = pm.asymID(); -// row[il + "_label_seq_id"] = pm.seqID(); -// row[il + "_auth_asym_id"] = pm.authAsymID(); -// row[il + "_auth_seq_id"] = pm.authSeqID(); -// row[il + "_ladder"] = ladder; -// row[il + "_sense"] = parallel ? "parallel" : "anti-parallel"; -// } - -// for (auto stride: { 3, 4, 5}) -// { -// std::string hs = "helix_info_" + std::to_string(stride); -// switch (info.helix(stride)) -// { -// #if 0 -// case mmcif::Helix::None: row[hs] = '.'; break; -// case mmcif::Helix::Start: row[hs] = "start"; break; -// case mmcif::Helix::End: row[hs] = "end"; break; -// case mmcif::Helix::StartAndEnd: row[hs] = "start-and-end"; break; -// case mmcif::Helix::Middle: row[hs] = "middle"; break; -// #else -// case mmcif::Helix::None: row[hs] = '.'; break; -// case mmcif::Helix::Start: row[hs] = '>'; break; -// case mmcif::Helix::End: row[hs] = '<'; break; -// case mmcif::Helix::StartAndEnd: row[hs] = 'X'; break; -// case mmcif::Helix::Middle: row[hs] = '0' + stride; break; -// #endif -// } -// } - -// if (info.bend()) -// row["bend"] = 'S'; -// else -// row["bend"] = "."; - -// for (int i: { 0, 1 }) -// { -// const auto& [donor, donorE] = info.donor(i); -// const auto& [acceptor, acceptorE] = info.acceptor(i); - -// std::string ds = "O_donor_" + std::to_string(i + 1); -// std::string as = "NH_acceptor_" + std::to_string(i + 1); - -// if (acceptor) -// { -// auto& am = acceptor.residue(); - -// row[as + "_label_comp_id"] = am.compoundID(); -// row[as + "_label_asym_id"] = am.asymID(); -// row[as + "_label_seq_id"] = am.seqID(); -// row[as + "_auth_asym_id"] = am.authAsymID(); -// row[as + "_auth_seq_id"] = am.authSeqID(); -// row[as + "_energy"].os(std::fixed, std::setprecision(2), acceptorE); -// } -// else -// { -// row[as + "_label_comp_id"] = "."; -// row[as + "_label_asym_id"] = "."; -// row[as + "_label_seq_id"] = "."; -// row[as + "_auth_asym_id"] = "."; -// row[as + "_auth_seq_id"] = "."; -// row[as + "_energy"] = "."; -// } - -// if (donor) -// { -// auto& dm = donor.residue(); - -// row[ds + "_label_comp_id"] = dm.compoundID(); -// row[ds + "_label_asym_id"] = dm.asymID(); -// row[ds + "_label_seq_id"] = dm.seqID(); -// row[ds + "_auth_asym_id"] = dm.authAsymID(); -// row[ds + "_auth_seq_id"] = dm.authSeqID(); -// row[ds + "_energy"].os(std::fixed, std::setprecision(2), donorE); -// } -// else -// { -// row[ds + "_label_comp_id"] = "."; -// row[ds + "_label_asym_id"] = "."; -// row[ds + "_label_seq_id"] = "."; -// row[ds + "_auth_asym_id"] = "."; -// row[ds + "_auth_seq_id"] = "."; -// row[ds + "_energy"] = "."; -// } -// } - -// last = info.nr(); -// } - - -// df.write(os, {}); } // -------------------------------------------------------------------- -int pr_main(int argc, char* argv[]) +int d_main(int argc, const char* argv[]) { using namespace std::literals; - po::options_description visible_options(argv[0] + " input-file [output-file] [options]"s); + po::options_description visible_options(argv[0] + " [options] input-file [output-file]"s); visible_options.add_options() - ("xyzin", po::value(), "coordinates file") - ("output", po::value(), "Output to this file") - ("dict", po::value>(), "Dictionary file containing restraints for residues in this specific target, can be specified multiple times.") - - ("help,h", "Display help message") - ("version", "Print version") - ("output-format", po::value(), "Output format, can be either 'dssp' for classic DSSP or 'mmcif' for annotated mmCIF. The default is chosen based on the extension of the output file, if any.") - - // ("create-missing", "Create missing backbone atoms") - -#if not USE_RSRC - ("rsrc-dir", po::value(), "Directory containing the 'resources' used by this application") -#endif - ("min-pp-stretch", po::value(), "Minimal number of residues having PSI/PHI in range for a PP helix, default is 3") - ("write-other", "If set, write the type OTHER for loops, default is to leave this out") + ("help,h", "Display help message") + ("version", "Print version") ("verbose,v", "verbose output") ; po::options_description hidden_options("hidden options"); hidden_options.add_options() + ("xyzin", po::value(), "coordinates file") + ("output", po::value(), "Output to this file") ("debug,d", po::value(), "Debug level (for even more verbose output)") ; @@ -651,7 +488,7 @@ int pr_main(int argc, char* argv[]) if (vm.count("version")) { - std::cout << argv[0] << ' ' << PACKAGE_VERSION " version " << VERSION_STRING << std::endl; + std::cout << argv[0] << " version " << VERSION_STRING << std::endl; exit(0); } @@ -688,11 +525,6 @@ int pr_main(int argc, char* argv[]) mmcif::File f(vm["xyzin"].as()); mmcif::Structure structure(f, 1, mmcif::StructureOpenOptions::SkipHydrogen); - // // -------------------------------------------------------------------- - - // if (vm.count("create-missing")) - // mmcif::CreateMissingBackboneAtoms(structure, true); - // -------------------------------------------------------------------- short pp_stretch = 3; @@ -758,3 +590,24 @@ int pr_main(int argc, char* argv[]) return 0; } + +// -------------------------------------------------------------------- + +int main(int argc, const char* argv[]) +{ + int result = 0; + + try + { + load_version_info(); + + result = d_main(argc, argv); + } + catch (const std::exception& ex) + { + print_what(ex); + exit(1); + } + + return result; +} diff --git a/src/dssp.hpp b/src/dssp.hpp deleted file mode 100644 index 3602eed..0000000 --- a/src/dssp.hpp +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#include - -#include "config.hpp" - -extern std::string VERSION_STRING; - -std::string get_version_nr(); -std::string get_version_date();