[mmdb] 02/08: Imported Upstream version 2.0.1
Frédéric-Emmanuel Picca
picca at moszumanska.debian.org
Wed Dec 31 09:32:43 UTC 2014
This is an automated email from the git hooks/post-receive script.
picca pushed a commit to branch master
in repository mmdb.
commit f3af8fbe7a5ae3222c781b26bad4c548b6166e65
Author: Picca Frédéric-Emmanuel <picca at debian.org>
Date: Wed Sep 10 21:39:50 2014 +0200
Imported Upstream version 2.0.1
---
Makefile.am | 56 +-
Makefile.in | 482 +--
README | 99 +-
aclocal.m4 | 276 +-
configure | 51 +-
configure.ac | 6 +-
mmdb/bfgs_min.cpp | 936 -----
mmdb/bfgs_min.h | 257 --
mmdb/file_.cpp | 1857 ----------
mmdb/file_.h | 302 --
mmdb/linalg_.cpp | 987 ------
mmdb/linalg_.h | 233 --
mmdb/machine_.cpp | 148 -
mmdb/math_.cpp | 199 --
mmdb/math_.h | 73 -
mmdb/mattype_.cpp | 2116 ------------
mmdb/mattype_.h | 659 ----
mmdb/mmdb_align.cpp | 1219 -------
mmdb/mmdb_align.h | 189 -
mmdb/mmdb_atom.cpp | 3495 -------------------
mmdb/mmdb_atom.h | 739 ----
mmdb/mmdb_bondmngr.cpp | 125 -
mmdb/mmdb_chain.cpp | 2568 --------------
mmdb/mmdb_chain.h | 674 ----
mmdb/mmdb_cifdefs.cpp | 122 -
mmdb/mmdb_cifdefs.h | 327 --
mmdb/mmdb_coormngr.cpp | 4360 -----------------------
mmdb/mmdb_coormngr.h | 951 -----
mmdb/mmdb_cryst.cpp | 2288 -------------
mmdb/mmdb_cryst.h | 462 ---
mmdb/mmdb_defs.h | 259 --
mmdb/mmdb_file.cpp | 3060 -----------------
mmdb/mmdb_file.h | 650 ----
mmdb/mmdb_graph.cpp | 2460 -------------
mmdb/mmdb_graph.h | 484 ---
mmdb/mmdb_manager.cpp | 392 ---
mmdb/mmdb_manager.h | 122 -
mmdb/mmdb_mask.cpp | 246 --
mmdb/mmdb_mmcif.cpp | 3671 --------------------
mmdb/mmdb_mmcif.h | 2129 ------------
mmdb/mmdb_model.cpp | 5313 ----------------------------
mmdb/mmdb_model.h | 1085 ------
mmdb/mmdb_sbase.cpp | 320 --
mmdb/mmdb_sbase.h | 142 -
mmdb/mmdb_sbase0.cpp | 3124 -----------------
mmdb/mmdb_sbase0.h | 746 ----
mmdb/mmdb_selmngr.cpp | 3393 ------------------
mmdb/mmdb_selmngr.h | 624 ----
mmdb/mmdb_symop.cpp | 1009 ------
mmdb/mmdb_symop.h | 173 -
mmdb/mmdb_tables.cpp | 750 ----
mmdb/mmdb_tables.h | 129 -
mmdb/mmdb_title.cpp | 2653 --------------
mmdb/mmdb_title.h | 734 ----
mmdb/mmdb_uddata.cpp | 537 ---
mmdb/mmdb_uddata.h | 152 -
mmdb/mmdb_utils.cpp | 1974 -----------
mmdb/mmdb_utils.h | 639 ----
mmdb/mmdb_xml.cpp | 954 ------
mmdb/mmdb_xml.h | 148 -
mmdb/random_n.cpp | 235 --
mmdb/stream_.cpp | 106 -
mmdb/stream_.h | 192 --
mmdb.pc.in => mmdb2.pc.in | 5 +-
{mmdb => mmdb2}/hybrid_36.cpp | 0
{mmdb => mmdb2}/hybrid_36.h | 0
mmdb2/mmdb_atom.cpp | 3486 +++++++++++++++++++
mmdb2/mmdb_atom.h | 732 ++++
mmdb2/mmdb_bondmngr.cpp | 121 +
{mmdb => mmdb2}/mmdb_bondmngr.h | 52 +-
mmdb2/mmdb_chain.cpp | 2575 ++++++++++++++
mmdb2/mmdb_chain.h | 662 ++++
mmdb2/mmdb_cifdefs.cpp | 369 ++
mmdb2/mmdb_cifdefs.h | 329 ++
mmdb2/mmdb_coormngr.cpp | 4347 +++++++++++++++++++++++
mmdb2/mmdb_coormngr.h | 959 ++++++
mmdb2/mmdb_cryst.cpp | 2312 +++++++++++++
mmdb2/mmdb_cryst.h | 458 +++
mmdb2/mmdb_defs.h | 271 ++
{mmdb => mmdb2}/mmdb_ficif.cpp | 81 +-
{mmdb => mmdb2}/mmdb_ficif.h | 47 +-
mmdb2/mmdb_io_file.cpp | 1873 ++++++++++
mmdb2/mmdb_io_file.h | 301 ++
mmdb2/mmdb_io_stream.cpp | 112 +
mmdb2/mmdb_io_stream.h | 193 ++
mmdb2/mmdb_machine_.cpp | 155 +
mmdb/machine_.h => mmdb2/mmdb_machine_.h | 157 +-
mmdb2/mmdb_manager.cpp | 389 +++
mmdb2/mmdb_manager.h | 124 +
mmdb2/mmdb_mask.cpp | 240 ++
{mmdb => mmdb2}/mmdb_mask.h | 76 +-
mmdb2/mmdb_math_.cpp | 203 ++
mmdb2/mmdb_math_.h | 77 +
mmdb2/mmdb_math_align.cpp | 1226 +++++++
mmdb2/mmdb_math_align.h | 195 ++
mmdb2/mmdb_math_bfgsmin.cpp | 938 +++++
mmdb2/mmdb_math_bfgsmin.h | 260 ++
mmdb2/mmdb_math_fft.cpp | 338 ++
mmdb2/mmdb_math_fft.h | 93 +
mmdb2/mmdb_math_graph.cpp | 2461 +++++++++++++
mmdb2/mmdb_math_graph.h | 494 +++
mmdb2/mmdb_math_linalg.cpp | 990 ++++++
mmdb2/mmdb_math_linalg.h | 236 ++
mmdb2/mmdb_math_rand.cpp | 241 ++
mmdb/random_n.h => mmdb2/mmdb_math_rand.h | 79 +-
mmdb2/mmdb_mattype.cpp | 2087 +++++++++++
mmdb2/mmdb_mattype.h | 652 ++++
mmdb2/mmdb_mmcif_.cpp | 3666 ++++++++++++++++++++
mmdb2/mmdb_mmcif_.h | 2146 ++++++++++++
mmdb2/mmdb_model.cpp | 5332 +++++++++++++++++++++++++++++
mmdb2/mmdb_model.h | 1073 ++++++
mmdb2/mmdb_root.cpp | 3054 +++++++++++++++++
mmdb2/mmdb_root.h | 639 ++++
{mmdb => mmdb2}/mmdb_rwbrook.cpp | 1762 +++++-----
{mmdb => mmdb2}/mmdb_rwbrook.h | 591 ++--
mmdb2/mmdb_selmngr.cpp | 3421 ++++++++++++++++++
mmdb2/mmdb_selmngr.h | 634 ++++
mmdb2/mmdb_seqsuperpose.cpp | 366 ++
mmdb2/mmdb_seqsuperpose.h | 134 +
mmdb2/mmdb_symop.cpp | 1001 ++++++
mmdb2/mmdb_symop.h | 168 +
mmdb2/mmdb_tables.cpp | 748 ++++
mmdb2/mmdb_tables.h | 127 +
mmdb2/mmdb_title.cpp | 2662 ++++++++++++++
mmdb2/mmdb_title.h | 696 ++++
mmdb2/mmdb_uddata.cpp | 534 +++
mmdb2/mmdb_uddata.h | 154 +
mmdb2/mmdb_utils.cpp | 1994 +++++++++++
mmdb2/mmdb_utils.h | 633 ++++
mmdb2/mmdb_xml_.cpp | 986 ++++++
mmdb2/mmdb_xml_.h | 162 +
131 files changed, 62814 insertions(+), 65726 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 2f33492..209f5cc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,38 +1,34 @@
ACLOCAL_AMFLAGS = -I m4
-lib_LTLIBRARIES = mmdb/libmmdb.la
+lib_LTLIBRARIES = mmdb2/libmmdb2.la
pkginclude_HEADERS = \
-mmdb/bfgs_min.h mmdb/mmdb_atom.h mmdb/mmdb_ficif.h \
-mmdb/mmdb_rwbrook.h mmdb/mmdb_uddata.h mmdb/file_.h \
-mmdb/mmdb_bondmngr.h mmdb/mmdb_file.h mmdb/mmdb_sbase0.h \
-mmdb/mmdb_utils.h mmdb/linalg_.h mmdb/mmdb_chain.h \
-mmdb/mmdb_graph.h mmdb/mmdb_sbase.h mmdb/mmdb_xml.h \
-mmdb/machine_.h mmdb/mmdb_cifdefs.h mmdb/mmdb_manager.h \
-mmdb/mmdb_selmngr.h mmdb/random_n.h mmdb/math_.h \
-mmdb/mmdb_coormngr.h mmdb/mmdb_mask.h mmdb/mmdb_symop.h \
-mmdb/stream_.h mmdb/mattype_.h mmdb/mmdb_cryst.h \
-mmdb/mmdb_mmcif.h mmdb/mmdb_tables.h mmdb/mmdb_align.h \
-mmdb/mmdb_defs.h mmdb/mmdb_model.h mmdb/mmdb_title.h \
-mmdb/hybrid_36.h
-
-
-mmdb_libmmdb_la_SOURCES = \
-mmdb/bfgs_min.cpp mmdb/mmdb_bondmngr.cpp mmdb/mmdb_manager.cpp \
-mmdb/mmdb_symop.cpp mmdb/file_.cpp mmdb/mmdb_chain.cpp \
-mmdb/mmdb_mask.cpp mmdb/mmdb_tables.cpp mmdb/linalg_.cpp \
-mmdb/mmdb_cifdefs.cpp mmdb/mmdb_mmcif.cpp mmdb/mmdb_title.cpp \
-mmdb/machine_.cpp mmdb/mmdb_coormngr.cpp mmdb/mmdb_model.cpp \
-mmdb/mmdb_uddata.cpp mmdb/math_.cpp mmdb/mmdb_cryst.cpp \
-mmdb/mmdb_rwbrook.cpp mmdb/mmdb_utils.cpp mmdb/mattype_.cpp \
-mmdb/mmdb_ficif.cpp mmdb/mmdb_sbase0.cpp mmdb/mmdb_xml.cpp \
-mmdb/mmdb_align.cpp mmdb/mmdb_file.cpp mmdb/mmdb_sbase.cpp \
-mmdb/random_n.cpp mmdb/mmdb_atom.cpp mmdb/mmdb_graph.cpp \
-mmdb/mmdb_selmngr.cpp mmdb/stream_.cpp mmdb/hybrid_36.cpp
-
-mmdb_libmmdb_la_LDFLAGS = -no-undefined
+mmdb2/hybrid_36.h mmdb2/mmdb_io_file.h mmdb2/mmdb_math_graph.h mmdb2/mmdb_seqsuperpose.h \
+mmdb2/mmdb_atom.h mmdb2/mmdb_io_stream.h mmdb2/mmdb_math_linalg.h mmdb2/mmdb_symop.h \
+mmdb2/mmdb_bondmngr.h mmdb2/mmdb_machine_.h mmdb2/mmdb_math_rand.h mmdb2/mmdb_tables.h \
+mmdb2/mmdb_chain.h mmdb2/mmdb_manager.h mmdb2/mmdb_mattype.h mmdb2/mmdb_title.h \
+mmdb2/mmdb_cifdefs.h mmdb2/mmdb_mask.h mmdb2/mmdb_mmcif_.h mmdb2/mmdb_uddata.h \
+mmdb2/mmdb_coormngr.h mmdb2/mmdb_math_.h mmdb2/mmdb_model.h mmdb2/mmdb_utils.h \
+mmdb2/mmdb_cryst.h mmdb2/mmdb_math_align.h mmdb2/mmdb_root.h mmdb2/mmdb_xml_.h \
+mmdb2/mmdb_defs.h mmdb2/mmdb_math_bfgsmin.h mmdb2/mmdb_rwbrook.h mmdb2/mmdb_ficif.h \
+mmdb2/mmdb_math_fft.h mmdb2/mmdb_selmngr.h
+
+
+mmdb2_libmmdb2_la_SOURCES = \
+mmdb2/hybrid_36.cpp mmdb2/mmdb_io_stream.cpp mmdb2/mmdb_math_linalg.cpp mmdb2/mmdb_symop.cpp \
+mmdb2/mmdb_atom.cpp mmdb2/mmdb_machine_.cpp mmdb2/mmdb_math_rand.cpp mmdb2/mmdb_tables.cpp \
+mmdb2/mmdb_bondmngr.cpp mmdb2/mmdb_manager.cpp mmdb2/mmdb_mattype.cpp mmdb2/mmdb_title.cpp \
+mmdb2/mmdb_chain.cpp mmdb2/mmdb_mask.cpp mmdb2/mmdb_mmcif_.cpp mmdb2/mmdb_uddata.cpp \
+mmdb2/mmdb_cifdefs.cpp mmdb2/mmdb_math_.cpp mmdb2/mmdb_model.cpp mmdb2/mmdb_utils.cpp \
+mmdb2/mmdb_coormngr.cpp mmdb2/mmdb_math_align.cpp mmdb2/mmdb_root.cpp mmdb2/mmdb_xml_.cpp \
+mmdb2/mmdb_cryst.cpp mmdb2/mmdb_math_bfgsmin.cpp mmdb2/mmdb_rwbrook.cpp mmdb2/mmdb_ficif.cpp \
+mmdb2/mmdb_math_fft.cpp mmdb2/mmdb_selmngr.cpp mmdb2/mmdb_io_file.cpp mmdb2/mmdb_math_graph.cpp \
+mmdb2/mmdb_seqsuperpose.cpp
+
+mmdb2_libmmdb2_la_LDFLAGS = -no-undefined
pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = mmdb.pc
+pkgconfig_DATA = mmdb2.pc
+
diff --git a/Makefile.in b/Makefile.in
index 6e8eade..bb9dde5 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.12.2 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2012 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -17,23 +17,51 @@
VPATH = @srcdir@
-am__make_dryrun = \
- { \
- am__dry=no; \
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
- echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
- | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
- *) \
- for am__flg in $$MAKEFLAGS; do \
- case $$am__flg in \
- *=*|--*) ;; \
- *n*) am__dry=yes; break;; \
- esac; \
- done;; \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
- test $$am__dry = yes; \
- }
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -53,19 +81,19 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = .
-DIST_COMMON = README $(am__configure_deps) $(pkginclude_HEADERS) \
- $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
- $(srcdir)/config.h.in $(srcdir)/mmdb.pc.in \
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/configure $(am__configure_deps) \
+ $(srcdir)/config.h.in $(srcdir)/mmdb2.pc.in \
+ $(top_srcdir)/build-aux/depcomp $(pkginclude_HEADERS) AUTHORS \
+ COPYING COPYING.LESSER INSTALL README build-aux/ar-lib \
+ build-aux/config.guess build-aux/config.sub build-aux/depcomp \
+ build-aux/install-sh build-aux/missing build-aux/ltmain.sh \
$(top_srcdir)/build-aux/ar-lib \
$(top_srcdir)/build-aux/config.guess \
$(top_srcdir)/build-aux/config.sub \
- $(top_srcdir)/build-aux/depcomp \
$(top_srcdir)/build-aux/install-sh \
$(top_srcdir)/build-aux/ltmain.sh \
- $(top_srcdir)/build-aux/missing $(top_srcdir)/configure \
- AUTHORS COPYING COPYING.LESSER INSTALL build-aux/ar-lib \
- build-aux/config.guess build-aux/config.sub build-aux/depcomp \
- build-aux/install-sh build-aux/ltmain.sh build-aux/missing
+ $(top_srcdir)/build-aux/missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -77,7 +105,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h
-CONFIG_CLEAN_FILES = mmdb.pc
+CONFIG_CLEAN_FILES = mmdb2.pc
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
@@ -109,28 +137,31 @@ am__uninstall_files_from_dir = { \
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \
"$(DESTDIR)$(pkgincludedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
-mmdb_libmmdb_la_LIBADD =
+mmdb2_libmmdb2_la_LIBADD =
am__dirstamp = $(am__leading_dot)dirstamp
-am_mmdb_libmmdb_la_OBJECTS = mmdb/bfgs_min.lo mmdb/mmdb_bondmngr.lo \
- mmdb/mmdb_manager.lo mmdb/mmdb_symop.lo mmdb/file_.lo \
- mmdb/mmdb_chain.lo mmdb/mmdb_mask.lo mmdb/mmdb_tables.lo \
- mmdb/linalg_.lo mmdb/mmdb_cifdefs.lo mmdb/mmdb_mmcif.lo \
- mmdb/mmdb_title.lo mmdb/machine_.lo mmdb/mmdb_coormngr.lo \
- mmdb/mmdb_model.lo mmdb/mmdb_uddata.lo mmdb/math_.lo \
- mmdb/mmdb_cryst.lo mmdb/mmdb_rwbrook.lo mmdb/mmdb_utils.lo \
- mmdb/mattype_.lo mmdb/mmdb_ficif.lo mmdb/mmdb_sbase0.lo \
- mmdb/mmdb_xml.lo mmdb/mmdb_align.lo mmdb/mmdb_file.lo \
- mmdb/mmdb_sbase.lo mmdb/random_n.lo mmdb/mmdb_atom.lo \
- mmdb/mmdb_graph.lo mmdb/mmdb_selmngr.lo mmdb/stream_.lo \
- mmdb/hybrid_36.lo
-mmdb_libmmdb_la_OBJECTS = $(am_mmdb_libmmdb_la_OBJECTS)
+am_mmdb2_libmmdb2_la_OBJECTS = mmdb2/hybrid_36.lo \
+ mmdb2/mmdb_io_stream.lo mmdb2/mmdb_math_linalg.lo \
+ mmdb2/mmdb_symop.lo mmdb2/mmdb_atom.lo mmdb2/mmdb_machine_.lo \
+ mmdb2/mmdb_math_rand.lo mmdb2/mmdb_tables.lo \
+ mmdb2/mmdb_bondmngr.lo mmdb2/mmdb_manager.lo \
+ mmdb2/mmdb_mattype.lo mmdb2/mmdb_title.lo mmdb2/mmdb_chain.lo \
+ mmdb2/mmdb_mask.lo mmdb2/mmdb_mmcif_.lo mmdb2/mmdb_uddata.lo \
+ mmdb2/mmdb_cifdefs.lo mmdb2/mmdb_math_.lo mmdb2/mmdb_model.lo \
+ mmdb2/mmdb_utils.lo mmdb2/mmdb_coormngr.lo \
+ mmdb2/mmdb_math_align.lo mmdb2/mmdb_root.lo mmdb2/mmdb_xml_.lo \
+ mmdb2/mmdb_cryst.lo mmdb2/mmdb_math_bfgsmin.lo \
+ mmdb2/mmdb_rwbrook.lo mmdb2/mmdb_ficif.lo \
+ mmdb2/mmdb_math_fft.lo mmdb2/mmdb_selmngr.lo \
+ mmdb2/mmdb_io_file.lo mmdb2/mmdb_math_graph.lo \
+ mmdb2/mmdb_seqsuperpose.lo
+mmdb2_libmmdb2_la_OBJECTS = $(am_mmdb2_libmmdb2_la_OBJECTS)
AM_V_lt = $(am__v_lt_ at AM_V@)
am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
-mmdb_libmmdb_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+mmdb2_libmmdb2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
- $(AM_CXXFLAGS) $(CXXFLAGS) $(mmdb_libmmdb_la_LDFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS) $(mmdb2_libmmdb2_la_LDFLAGS) \
$(LDFLAGS) -o $@
AM_V_P = $(am__v_P_ at AM_V@)
am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
@@ -166,8 +197,8 @@ AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
-SOURCES = $(mmdb_libmmdb_la_SOURCES)
-DIST_SOURCES = $(mmdb_libmmdb_la_SOURCES)
+SOURCES = $(mmdb2_libmmdb2_la_SOURCES)
+DIST_SOURCES = $(mmdb2_libmmdb2_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -175,6 +206,24 @@ am__can_run_installinfo = \
esac
DATA = $(pkgconfig_DATA)
HEADERS = $(pkginclude_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+ $(LISP)config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
CSCOPE = cscope
@@ -318,37 +367,32 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
ACLOCAL_AMFLAGS = -I m4
-lib_LTLIBRARIES = mmdb/libmmdb.la
+lib_LTLIBRARIES = mmdb2/libmmdb2.la
pkginclude_HEADERS = \
-mmdb/bfgs_min.h mmdb/mmdb_atom.h mmdb/mmdb_ficif.h \
-mmdb/mmdb_rwbrook.h mmdb/mmdb_uddata.h mmdb/file_.h \
-mmdb/mmdb_bondmngr.h mmdb/mmdb_file.h mmdb/mmdb_sbase0.h \
-mmdb/mmdb_utils.h mmdb/linalg_.h mmdb/mmdb_chain.h \
-mmdb/mmdb_graph.h mmdb/mmdb_sbase.h mmdb/mmdb_xml.h \
-mmdb/machine_.h mmdb/mmdb_cifdefs.h mmdb/mmdb_manager.h \
-mmdb/mmdb_selmngr.h mmdb/random_n.h mmdb/math_.h \
-mmdb/mmdb_coormngr.h mmdb/mmdb_mask.h mmdb/mmdb_symop.h \
-mmdb/stream_.h mmdb/mattype_.h mmdb/mmdb_cryst.h \
-mmdb/mmdb_mmcif.h mmdb/mmdb_tables.h mmdb/mmdb_align.h \
-mmdb/mmdb_defs.h mmdb/mmdb_model.h mmdb/mmdb_title.h \
-mmdb/hybrid_36.h
-
-mmdb_libmmdb_la_SOURCES = \
-mmdb/bfgs_min.cpp mmdb/mmdb_bondmngr.cpp mmdb/mmdb_manager.cpp \
-mmdb/mmdb_symop.cpp mmdb/file_.cpp mmdb/mmdb_chain.cpp \
-mmdb/mmdb_mask.cpp mmdb/mmdb_tables.cpp mmdb/linalg_.cpp \
-mmdb/mmdb_cifdefs.cpp mmdb/mmdb_mmcif.cpp mmdb/mmdb_title.cpp \
-mmdb/machine_.cpp mmdb/mmdb_coormngr.cpp mmdb/mmdb_model.cpp \
-mmdb/mmdb_uddata.cpp mmdb/math_.cpp mmdb/mmdb_cryst.cpp \
-mmdb/mmdb_rwbrook.cpp mmdb/mmdb_utils.cpp mmdb/mattype_.cpp \
-mmdb/mmdb_ficif.cpp mmdb/mmdb_sbase0.cpp mmdb/mmdb_xml.cpp \
-mmdb/mmdb_align.cpp mmdb/mmdb_file.cpp mmdb/mmdb_sbase.cpp \
-mmdb/random_n.cpp mmdb/mmdb_atom.cpp mmdb/mmdb_graph.cpp \
-mmdb/mmdb_selmngr.cpp mmdb/stream_.cpp mmdb/hybrid_36.cpp
-
-mmdb_libmmdb_la_LDFLAGS = -no-undefined
+mmdb2/hybrid_36.h mmdb2/mmdb_io_file.h mmdb2/mmdb_math_graph.h mmdb2/mmdb_seqsuperpose.h \
+mmdb2/mmdb_atom.h mmdb2/mmdb_io_stream.h mmdb2/mmdb_math_linalg.h mmdb2/mmdb_symop.h \
+mmdb2/mmdb_bondmngr.h mmdb2/mmdb_machine_.h mmdb2/mmdb_math_rand.h mmdb2/mmdb_tables.h \
+mmdb2/mmdb_chain.h mmdb2/mmdb_manager.h mmdb2/mmdb_mattype.h mmdb2/mmdb_title.h \
+mmdb2/mmdb_cifdefs.h mmdb2/mmdb_mask.h mmdb2/mmdb_mmcif_.h mmdb2/mmdb_uddata.h \
+mmdb2/mmdb_coormngr.h mmdb2/mmdb_math_.h mmdb2/mmdb_model.h mmdb2/mmdb_utils.h \
+mmdb2/mmdb_cryst.h mmdb2/mmdb_math_align.h mmdb2/mmdb_root.h mmdb2/mmdb_xml_.h \
+mmdb2/mmdb_defs.h mmdb2/mmdb_math_bfgsmin.h mmdb2/mmdb_rwbrook.h mmdb2/mmdb_ficif.h \
+mmdb2/mmdb_math_fft.h mmdb2/mmdb_selmngr.h
+
+mmdb2_libmmdb2_la_SOURCES = \
+mmdb2/hybrid_36.cpp mmdb2/mmdb_io_stream.cpp mmdb2/mmdb_math_linalg.cpp mmdb2/mmdb_symop.cpp \
+mmdb2/mmdb_atom.cpp mmdb2/mmdb_machine_.cpp mmdb2/mmdb_math_rand.cpp mmdb2/mmdb_tables.cpp \
+mmdb2/mmdb_bondmngr.cpp mmdb2/mmdb_manager.cpp mmdb2/mmdb_mattype.cpp mmdb2/mmdb_title.cpp \
+mmdb2/mmdb_chain.cpp mmdb2/mmdb_mask.cpp mmdb2/mmdb_mmcif_.cpp mmdb2/mmdb_uddata.cpp \
+mmdb2/mmdb_cifdefs.cpp mmdb2/mmdb_math_.cpp mmdb2/mmdb_model.cpp mmdb2/mmdb_utils.cpp \
+mmdb2/mmdb_coormngr.cpp mmdb2/mmdb_math_align.cpp mmdb2/mmdb_root.cpp mmdb2/mmdb_xml_.cpp \
+mmdb2/mmdb_cryst.cpp mmdb2/mmdb_math_bfgsmin.cpp mmdb2/mmdb_rwbrook.cpp mmdb2/mmdb_ficif.cpp \
+mmdb2/mmdb_math_fft.cpp mmdb2/mmdb_selmngr.cpp mmdb2/mmdb_io_file.cpp mmdb2/mmdb_math_graph.cpp \
+mmdb2/mmdb_seqsuperpose.cpp
+
+mmdb2_libmmdb2_la_LDFLAGS = -no-undefined
pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = mmdb.pc
+pkgconfig_DATA = mmdb2.pc
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-am
@@ -403,8 +447,9 @@ $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
distclean-hdr:
-rm -f config.h stamp-h1
-mmdb.pc: $(top_builddir)/config.status $(srcdir)/mmdb.pc.in
+mmdb2.pc: $(top_builddir)/config.status $(srcdir)/mmdb2.pc.in
cd $(top_builddir) && $(SHELL) ./config.status $@
+
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
@@ -439,109 +484,123 @@ clean-libLTLIBRARIES:
echo rm -f $${locs}; \
rm -f $${locs}; \
}
-mmdb/$(am__dirstamp):
- @$(MKDIR_P) mmdb
- @: > mmdb/$(am__dirstamp)
-mmdb/$(DEPDIR)/$(am__dirstamp):
- @$(MKDIR_P) mmdb/$(DEPDIR)
- @: > mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/bfgs_min.lo: mmdb/$(am__dirstamp) mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_bondmngr.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_manager.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_symop.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/file_.lo: mmdb/$(am__dirstamp) mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_chain.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_mask.lo: mmdb/$(am__dirstamp) mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_tables.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/linalg_.lo: mmdb/$(am__dirstamp) mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_cifdefs.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_mmcif.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_title.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/machine_.lo: mmdb/$(am__dirstamp) mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_coormngr.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_model.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_uddata.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/math_.lo: mmdb/$(am__dirstamp) mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_cryst.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_rwbrook.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_utils.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mattype_.lo: mmdb/$(am__dirstamp) mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_ficif.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_sbase0.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_xml.lo: mmdb/$(am__dirstamp) mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_align.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_file.lo: mmdb/$(am__dirstamp) mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_sbase.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/random_n.lo: mmdb/$(am__dirstamp) mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_atom.lo: mmdb/$(am__dirstamp) mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_graph.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/mmdb_selmngr.lo: mmdb/$(am__dirstamp) \
- mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/stream_.lo: mmdb/$(am__dirstamp) mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/hybrid_36.lo: mmdb/$(am__dirstamp) mmdb/$(DEPDIR)/$(am__dirstamp)
-mmdb/libmmdb.la: $(mmdb_libmmdb_la_OBJECTS) $(mmdb_libmmdb_la_DEPENDENCIES) $(EXTRA_mmdb_libmmdb_la_DEPENDENCIES) mmdb/$(am__dirstamp)
- $(AM_V_CXXLD)$(mmdb_libmmdb_la_LINK) -rpath $(libdir) $(mmdb_libmmdb_la_OBJECTS) $(mmdb_libmmdb_la_LIBADD) $(LIBS)
+mmdb2/$(am__dirstamp):
+ @$(MKDIR_P) mmdb2
+ @: > mmdb2/$(am__dirstamp)
+mmdb2/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) mmdb2/$(DEPDIR)
+ @: > mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/hybrid_36.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_io_stream.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_math_linalg.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_symop.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_atom.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_machine_.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_math_rand.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_tables.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_bondmngr.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_manager.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_mattype.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_title.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_chain.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_mask.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_mmcif_.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_uddata.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_cifdefs.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_math_.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_model.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_utils.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_coormngr.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_math_align.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_root.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_xml_.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_cryst.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_math_bfgsmin.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_rwbrook.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_ficif.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_math_fft.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_selmngr.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_io_file.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_math_graph.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+mmdb2/mmdb_seqsuperpose.lo: mmdb2/$(am__dirstamp) \
+ mmdb2/$(DEPDIR)/$(am__dirstamp)
+
+mmdb2/libmmdb2.la: $(mmdb2_libmmdb2_la_OBJECTS) $(mmdb2_libmmdb2_la_DEPENDENCIES) $(EXTRA_mmdb2_libmmdb2_la_DEPENDENCIES) mmdb2/$(am__dirstamp)
+ $(AM_V_CXXLD)$(mmdb2_libmmdb2_la_LINK) -rpath $(libdir) $(mmdb2_libmmdb2_la_OBJECTS) $(mmdb2_libmmdb2_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
- -rm -f mmdb/*.$(OBJEXT)
- -rm -f mmdb/*.lo
+ -rm -f mmdb2/*.$(OBJEXT)
+ -rm -f mmdb2/*.lo
distclean-compile:
-rm -f *.tab.c
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/bfgs_min.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/file_.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/hybrid_36.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/linalg_.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/machine_.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/math_.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mattype_.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_align.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_atom.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_bondmngr.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_chain.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_cifdefs.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_coormngr.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_cryst.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_ficif.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_file.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_graph.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_manager.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_mask.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_mmcif.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_model.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_rwbrook.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_sbase.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_sbase0.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_selmngr.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_symop.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_tables.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_title.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_uddata.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_utils.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/mmdb_xml.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/random_n.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at mmdb/$(DEPDIR)/stream_.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/hybrid_36.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_atom.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_bondmngr.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_chain.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_cifdefs.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_coormngr.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_cryst.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_ficif.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_io_file.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_io_stream.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_machine_.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_manager.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_mask.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_math_.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_math_align.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_math_bfgsmin.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_math_fft.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_math_graph.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_math_linalg.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_math_rand.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_mattype.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_mmcif_.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_model.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_root.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_rwbrook.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_selmngr.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_seqsuperpose.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_symop.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_tables.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_title.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_uddata.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_utils.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mmdb2/$(DEPDIR)/mmdb_xml_.Plo at am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -572,7 +631,7 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
- -rm -rf mmdb/.libs mmdb/_libs
+ -rm -rf mmdb2/.libs mmdb2/_libs
distclean-libtool:
-rm -f libtool config.lt
@@ -619,26 +678,15 @@ uninstall-pkgincludeHEADERS:
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir)
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
- list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
+ $(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
@@ -650,15 +698,11 @@ TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$$unique; \
fi; \
fi
-ctags: CTAGS
-CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
@@ -667,18 +711,16 @@ GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
-
cscope: cscope.files
test ! -s cscope.files \
|| $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
-
clean-cscope:
-rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-am
-cscope.files: clean-cscope cscopelist
-
-cscopelist: $(HEADERS) $(SOURCES) $(LISP)
- list='$(SOURCES) $(HEADERS) $(LISP)'; \
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
@@ -787,9 +829,9 @@ distcheck: dist
*.zip*) \
unzip $(distdir).zip ;;\
esac
- chmod -R a-w $(distdir); chmod u+w $(distdir)
- mkdir $(distdir)/_build
- mkdir $(distdir)/_inst
+ chmod -R a-w $(distdir)
+ chmod u+w $(distdir)
+ mkdir $(distdir)/_build $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
@@ -884,8 +926,8 @@ clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
- -rm -f mmdb/$(DEPDIR)/$(am__dirstamp)
- -rm -f mmdb/$(am__dirstamp)
+ -rm -f mmdb2/$(DEPDIR)/$(am__dirstamp)
+ -rm -f mmdb2/$(am__dirstamp)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -897,7 +939,7 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
distclean: distclean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
- -rm -rf mmdb/$(DEPDIR)
+ -rm -rf mmdb2/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-hdr distclean-libtool distclean-tags
@@ -945,7 +987,7 @@ installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
- -rm -rf mmdb/$(DEPDIR)
+ -rm -rf mmdb2/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
@@ -967,22 +1009,22 @@ uninstall-am: uninstall-libLTLIBRARIES uninstall-pkgconfigDATA \
.MAKE: all install-am install-strip
-.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
+.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \
clean-cscope clean-generic clean-libLTLIBRARIES clean-libtool \
- cscope cscopelist ctags dist dist-all dist-bzip2 dist-gzip \
- dist-lzip dist-shar dist-tarZ dist-xz dist-zip distcheck \
- distclean distclean-compile distclean-generic distclean-hdr \
- distclean-libtool distclean-tags distcleancheck distdir \
- distuninstallcheck dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am install-dvi \
- install-dvi-am install-exec install-exec-am install-html \
- install-html-am install-info install-info-am \
+ cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
+ dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
+ distcheck distclean distclean-compile distclean-generic \
+ distclean-hdr distclean-libtool distclean-tags distcleancheck \
+ distdir distuninstallcheck dvi dvi-am html html-am info \
+ info-am install install-am install-data install-data-am \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-html install-html-am install-info install-info-am \
install-libLTLIBRARIES install-man install-pdf install-pdf-am \
install-pkgconfigDATA install-pkgincludeHEADERS install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am uninstall-libLTLIBRARIES uninstall-pkgconfigDATA \
uninstall-pkgincludeHEADERS
diff --git a/README b/README
index 22a8101..703606e 100755
--- a/README
+++ b/README
@@ -1,33 +1,94 @@
+
+ CCP4 Coordinate Library: support of coordinate-related
+ functionality in protein crystallography applications.
+
+ Version 1.05 from 26.03.2004
+
+ Copyright (C) Eugene Krissinel 2004.
+
+============================================================================
+
+This file contains:
+
+ 1. License agreement
+ 2. List of incompatibilities with earlier versions. Please read
+ this carefully if you update your version of the Library.
+
+
+=======================
+1. LICENSE AGREEMENT.
+=======================
+
+ This library is free software and is distributed under the terms
+ and conditions of the CCP4 licence agreement as `Part 0' (Annex 2)
+ software, which is version 2.1 of the GNU Lesser General Public
+ Licence (LGPL) with the following additional clause:
+
+ `You may also combine or link a "work that uses the Library"
+ to produce a work containing portions of the Library, and
+ distribute that work under terms of your choice, provided that
+ you give prominent notice with each copy of the work that the
+ specified version of the Library is used in it, and that you
+ include or provide public access to the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work. (i.e. If you make changes to the
+ Library you must distribute those, but you do not need to
+ distribute source or object code to those portions of the work
+ not covered by this licence.)'
+
+ Note that this clause grants an additional right and does not
+ impose any additional restriction, and so does not affect
+ compatibility with the GNU General Public Licence (GPL). If you
+ wish to negotiate other terms, please contact the maintainer.
+
+ You can redistribute it and/or modify the library under the terms
+ of the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the CCP4 licence and/or GNU
+ Lesser General Public License along with this library; if not,
+ write to the CCP4 Secretary, Daresbury Laboratory, Warrington
+ WA4 4AD, UK. The GNU Lesser General Public can also be obtained
+ by writing to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
====================================================
- KNOWN INCOMPATIBILITIES WITH PREVIOUS VERSIONS
+2. KNOWN INCOMPATIBILITIES WITH PREVIOUS VERSIONS
====================================================
--------------------------
-Version 1.05 (26.03.2004)
+Version 2.0.1 (03.02.2014)
--------------------------
-1. CAtom::GetBonds ( RPSAtomBond AtomBond, int & nAtomBonds );
+1. Namespacing
-now returns a pointer to internal list of bonded atoms. Therefore
-application MUST NEITHER attempt to deallocate AtomBond obtained from
-this function NOR modify it (doing so will cause crash). This is in
-difference of previous versions where deallocation of AtomBond was
-explicitely required.
+Versions 2.x is namespaced throughout. The following namespaces are introduced:
-2. CAtom::GetBonds ( RPSAtomBondI AtomBondI, int & nAtomBonds );
+mmdb
+mmdb::io
+mmdb::math
+mmdb::mmcif
+mmdb::xml
+mmdb::machine
-on contrary, now returns an allocated instance of the atom's bond list.
-If AtomBondI is not NULL on input, the function attempts to deallocate
-it (which will cause crash if you feed uninitialized non-NULL AtomBondI
-into the function). Application is responsible for deallocation of
-AtomBondI when appropriate.
+2. Object renaming
-3. CAtom::GetBonds ( PSAtomBondI AtomBondI, int & nAtomBonds, int maxlength );
+As a general rule, prefixes 'CMMDB' and 'C' from object names in MMDB versions 1.x
+have been removed, so that, e.g.,
-is a new function for pre-allocated AtomBondI[0..maxlength]. Application
-is responsible for allocation and deallocation of AtomBondI.
+CMMDBManager is now mmdb::Manager
+CAtom is now mmdb::Atom
+CFile is now mmdb::io::File
-4. CAtom::GetBonds ( RPSAtomBond AtomBond, int & nAtomBonds, int maxlength );
+and so forth.
-removed as there is no need in it in view of change #1 above.
diff --git a/aclocal.m4 b/aclocal.m4
index c15146a..1efe2e1 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.12.2 -*- Autoconf -*-
+# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
-# Copyright (C) 1996-2012 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -11,6 +11,7 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
@@ -19,24 +20,22 @@ You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
-# Copyright (C) 2002-2012 Free Software Foundation, Inc.
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 8
-
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.12'
+[am__api_version='1.13'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.12.2], [],
+m4_if([$1], [1.13.4], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -52,19 +51,17 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.12.2])dnl
+[AM_AUTOMAKE_VERSION([1.13.4])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
-# Copyright (C) 2011-2012 Free Software Foundation, Inc.
+# Copyright (C) 2011-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 1
-
# AM_PROG_AR([ACT-IF-FAIL])
# -------------------------
# Try to determine the archiver interface, and trigger the ar-lib wrapper
@@ -120,14 +117,12 @@ AC_SUBST([AR])dnl
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-# Copyright (C) 2001-2012 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 2
-
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
@@ -175,14 +170,12 @@ am_aux_dir=`cd $ac_aux_dir && pwd`
# AM_CONDITIONAL -*- Autoconf -*-
-# Copyright (C) 1997-2012 Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 10
-
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
# Define a conditional.
@@ -208,13 +201,12 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
-# Copyright (C) 1999-2012 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 17
# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
@@ -400,19 +392,18 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*-
-# Copyright (C) 1999-2012 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 6
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
[{
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
case $CONFIG_FILES in
@@ -441,7 +432,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
+ test -z "$am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
@@ -477,14 +468,12 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# Do all the work for Automake. -*- Autoconf -*-
-# Copyright (C) 1996-2012 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 19
-
# This macro actually does too much. Some checks are only needed if
# your package does certain things. But this isn't really a big deal.
@@ -500,7 +489,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# arguments mandatory, and then we can depend on a new Autoconf
# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_PREREQ([2.62])dnl
+[AC_PREREQ([2.65])dnl
dnl Autoconf wants to disallow AM_ names. We explicitly allow
dnl the ones we care about.
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
@@ -530,8 +519,7 @@ AC_SUBST([CYGPATH_W])
dnl Distinguish between old-style and new-style calls.
m4_ifval([$2],
[AC_DIAGNOSE([obsolete],
-[$0: two- and three-arguments forms are deprecated. For more info, see:
-http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_INIT_AUTOMAKE-invocation])
+ [$0: two- and three-arguments forms are deprecated.])
m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
AC_SUBST([PACKAGE], [$1])dnl
AC_SUBST([VERSION], [$2])],
@@ -585,18 +573,15 @@ AC_PROVIDE_IFELSE([AC_PROG_OBJC],
[_AM_DEPENDENCIES([OBJC])],
[m4_define([AC_PROG_OBJC],
m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
-dnl Support for Objective C++ was only introduced in Autoconf 2.65,
-dnl but we still cater to Autoconf 2.62.
-m4_ifdef([AC_PROG_OBJCXX],
-[AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
[_AM_DEPENDENCIES([OBJCXX])],
[m4_define([AC_PROG_OBJCXX],
- m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])])dnl
+ m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
])
-_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
-dnl The 'parallel-tests' driver may need to know about EXEEXT, so add the
-dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
-dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
AC_CONFIG_COMMANDS_PRE(dnl
[m4_provide_if([_AM_COMPILER_EXEEXT],
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
@@ -630,14 +615,12 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-# Copyright (C) 2001-2012 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 8
-
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
@@ -653,14 +636,12 @@ if test x"${install_sh}" != xset; then
fi
AC_SUBST([install_sh])])
-# Copyright (C) 2003-2012 Free Software Foundation, Inc.
+# Copyright (C) 2003-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 2
-
# Check whether the underlying file-system supports filenames
# with a leading dot. For instance MS-DOS doesn't.
AC_DEFUN([AM_SET_LEADING_DOT],
@@ -677,14 +658,12 @@ AC_SUBST([am__leading_dot])])
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
# From Jim Meyering
-# Copyright (C) 1996-2012 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 7
-
# AM_MAINTAINER_MODE([DEFAULT-MODE])
# ----------------------------------
# Control maintainer-specific portions of Makefiles.
@@ -712,18 +691,14 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
]
)
-AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
-
# Check to see how 'make' treats includes. -*- Autoconf -*-
-# Copyright (C) 2001-2012 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 5
-
# AM_MAKE_INCLUDE()
# -----------------
# Check to see how make treats includes.
@@ -768,14 +743,12 @@ rm -f confinc confmf
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-# Copyright (C) 1997-2012 Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 7
-
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
@@ -783,11 +756,10 @@ AC_DEFUN([AM_MISSING_PROG],
$1=${$1-"${am_missing_run}$2"}
AC_SUBST($1)])
-
# AM_MISSING_HAS_RUN
# ------------------
-# Define MISSING if not defined so far and test if it supports --run.
-# If it does, set am_missing_run to use it, otherwise, to nothing.
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([missing])dnl
@@ -800,8 +772,8 @@ if test x"${MISSING+set}" != xset; then
esac
fi
# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
else
am_missing_run=
AC_MSG_WARN(['missing' script is too old or missing])
@@ -810,14 +782,12 @@ fi
# Helper functions for option handling. -*- Autoconf -*-
-# Copyright (C) 2001-2012 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 6
-
# _AM_MANGLE_OPTION(NAME)
# -----------------------
AC_DEFUN([_AM_MANGLE_OPTION],
@@ -843,14 +813,12 @@ AC_DEFUN([_AM_IF_OPTION],
# Check to make sure that the build environment is sane. -*- Autoconf -*-
-# Copyright (C) 1996-2012 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 9
-
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
@@ -926,14 +894,12 @@ AC_CONFIG_COMMANDS_PRE(
rm -f conftest.file
])
-# Copyright (C) 2009-2012 Free Software Foundation, Inc.
+# Copyright (C) 2009-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 3
-
# AM_SILENT_RULES([DEFAULT])
# --------------------------
# Enable less verbose build rules; with the default set to DEFAULT
@@ -988,14 +954,12 @@ AC_SUBST([AM_BACKSLASH])dnl
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
])
-# Copyright (C) 2001-2012 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 2
-
# AM_PROG_INSTALL_STRIP
# ---------------------
# One issue with vendor 'install' (even GNU) is that you can't
@@ -1018,14 +982,12 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
-# Copyright (C) 2006-2012 Free Software Foundation, Inc.
+# Copyright (C) 2006-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 3
-
# _AM_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
@@ -1039,14 +1001,12 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
-# Copyright (C) 2004-2012 Free Software Foundation, Inc.
+# Copyright (C) 2004-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 3
-
# _AM_PROG_TAR(FORMAT)
# --------------------
# Check how to create a tarball in format FORMAT.
@@ -1060,76 +1020,114 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Substitute a variable $(am__untar) that extract such
# a tarball read from stdin.
# $(am__untar) < result.tar
+#
AC_DEFUN([_AM_PROG_TAR],
[# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AC_SUBST([AMTAR], ['$${TAR-tar}'])
-m4_if([$1], [v7],
- [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
- [m4_case([$1], [ustar],, [pax],,
- [m4_fatal([Unknown tar format])])
-AC_MSG_CHECKING([how to create a $1 tar archive])
-# Loop over all known methods to create a tar archive until one works.
+
+# We'll loop over all known methods to create a tar archive until one works.
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
-_am_tools=${am_cv_prog_tar_$1-$_am_tools}
-# Do not fold the above two line into one, because Tru64 sh and
-# Solaris sh will not grok spaces in the rhs of '-'.
-for _am_tool in $_am_tools
-do
- case $_am_tool in
- gnutar)
- for _am_tar in tar gnutar gtar;
- do
- AM_RUN_LOG([$_am_tar --version]) && break
- done
- am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
- am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
- am__untar="$_am_tar -xf -"
- ;;
- plaintar)
- # Must skip GNU tar: if it does not support --format= it doesn't create
- # ustar tarball either.
- (tar --version) >/dev/null 2>&1 && continue
- am__tar='tar chf - "$$tardir"'
- am__tar_='tar chf - "$tardir"'
- am__untar='tar xf -'
- ;;
- pax)
- am__tar='pax -L -x $1 -w "$$tardir"'
- am__tar_='pax -L -x $1 -w "$tardir"'
- am__untar='pax -r'
- ;;
- cpio)
- am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
- am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
- am__untar='cpio -i -H $1 -d'
- ;;
- none)
- am__tar=false
- am__tar_=false
- am__untar=false
- ;;
- esac
- # If the value was cached, stop now. We just wanted to have am__tar
- # and am__untar set.
- test -n "${am_cv_prog_tar_$1}" && break
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+ [m4_case([$1],
+ [ustar],
+ [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+ # There is notably a 21 bits limit for the UID and the GID. In fact,
+ # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+ # and bug#13588).
+ am_max_uid=2097151 # 2^21 - 1
+ am_max_gid=$am_max_uid
+ # The $UID and $GID variables are not portable, so we need to resort
+ # to the POSIX-mandated id(1) utility. Errors in the 'id' calls
+ # below are definitely unexpected, so allow the users to see them
+ # (that is, avoid stderr redirection).
+ am_uid=`id -u || echo unknown`
+ am_gid=`id -g || echo unknown`
+ AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+ if test $am_uid -le $am_max_uid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi
+ AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+ if test $am_gid -le $am_max_gid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi],
+
+ [pax],
+ [],
+
+ [m4_fatal([Unknown tar format])])
+
+ AC_MSG_CHECKING([how to create a $1 tar archive])
+
+ # Go ahead even if we have the value already cached. We do so because we
+ # need to set the values for the 'am__tar' and 'am__untar' variables.
+ _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+ for _am_tool in $_am_tools; do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar; do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
- # tar/untar a dummy directory, and stop if the command works
- rm -rf conftest.dir
- mkdir conftest.dir
- echo GrepMe > conftest.dir/file
- AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ AM_RUN_LOG([cat conftest.dir/file])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+ done
rm -rf conftest.dir
- if test -s conftest.tar; then
- AM_RUN_LOG([$am__untar <conftest.tar])
- grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
- fi
-done
-rm -rf conftest.dir
-AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
-AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+ AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+ AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
AC_SUBST([am__tar])
AC_SUBST([am__untar])
]) # _AM_PROG_TAR
diff --git a/configure b/configure
index 46aa5d7..7f513a1 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for mmdb 1.25.5.
+# Generated by GNU Autoconf 2.69 for mmdb2 2.0.1.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -585,14 +585,14 @@ MFLAGS=
MAKEFLAGS=
# Identity of this package.
-PACKAGE_NAME='mmdb'
-PACKAGE_TARNAME='mmdb'
-PACKAGE_VERSION='1.25.5'
-PACKAGE_STRING='mmdb 1.25.5'
+PACKAGE_NAME='mmdb2'
+PACKAGE_TARNAME='mmdb2'
+PACKAGE_VERSION='2.0.1'
+PACKAGE_STRING='mmdb2 2.0.1'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
-ac_unique_file="mmdb/mmdb_align.cpp"
+ac_unique_file="mmdb2/mmdb_math_align.cpp"
# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
@@ -1323,7 +1323,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures mmdb 1.25.5 to adapt to many kinds of systems.
+\`configure' configures mmdb2 2.0.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1371,7 +1371,7 @@ Fine tuning of the installation directories:
--infodir=DIR info documentation [DATAROOTDIR/info]
--localedir=DIR locale-dependent data [DATAROOTDIR/locale]
--mandir=DIR man documentation [DATAROOTDIR/man]
- --docdir=DIR documentation root [DATAROOTDIR/doc/mmdb]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/mmdb2]
--htmldir=DIR html documentation [DOCDIR]
--dvidir=DIR dvi documentation [DOCDIR]
--pdfdir=DIR pdf documentation [DOCDIR]
@@ -1393,7 +1393,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of mmdb 1.25.5:";;
+ short | recursive ) echo "Configuration of mmdb2 2.0.1:";;
esac
cat <<\_ACEOF
@@ -1504,7 +1504,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-mmdb configure 1.25.5
+mmdb2 configure 2.0.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1903,7 +1903,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by mmdb $as_me 1.25.5, which was
+It was created by mmdb2 $as_me 2.0.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2250,7 +2250,7 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
- # keep in sync with mmdb/mmdb_defs.h
+ # keep in sync with mmdb2/mmdb_defs.h
ac_aux_dir=
for ac_dir in build-aux "$srcdir"/build-aux; do
@@ -2285,7 +2285,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
ac_config_headers="$ac_config_headers config.h"
-am__api_version='1.12'
+am__api_version='1.13'
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
@@ -2469,8 +2469,8 @@ if test x"${MISSING+set}" != xset; then
esac
fi
# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
else
am_missing_run=
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
@@ -2770,8 +2770,8 @@ fi
# Define the identity of the package.
- PACKAGE='mmdb'
- VERSION='1.25.5'
+ PACKAGE='mmdb2'
+ VERSION='2.0.1'
cat >>confdefs.h <<_ACEOF
@@ -2811,12 +2811,17 @@ mkdir_p='$(MKDIR_P)'
# in the wild :-( We should find a proper way to deprecate it ...
AMTAR='$${TAR-tar}'
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar pax cpio none'
+
am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
DEPDIR="${am__leading_dot}deps"
ac_config_commands="$ac_config_commands depfiles"
@@ -15483,7 +15488,7 @@ else
as_fn_error $? "need math library" "$LINENO" 5
fi
-ac_config_files="$ac_config_files Makefile mmdb.pc"
+ac_config_files="$ac_config_files Makefile mmdb2.pc"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -16023,7 +16028,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by mmdb $as_me 1.25.5, which was
+This file was extended by mmdb2 $as_me 2.0.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -16089,7 +16094,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-mmdb config.status 1.25.5
+mmdb2 config.status 2.0.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@@ -16601,7 +16606,7 @@ do
"depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
"libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
- "mmdb.pc") CONFIG_FILES="$CONFIG_FILES mmdb.pc" ;;
+ "mmdb2.pc") CONFIG_FILES="$CONFIG_FILES mmdb2.pc" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
@@ -17198,7 +17203,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
case $ac_file$ac_mode in
"depfiles":C) test x"$AMDEP_TRUE" != x"" || {
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
case $CONFIG_FILES in
@@ -17249,7 +17254,7 @@ $as_echo X"$mf" |
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
+ test -z "$am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
diff --git a/configure.ac b/configure.ac
index 92ff8d6..f685b56 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,9 +1,9 @@
-AC_INIT(mmdb, 1.25.5) # keep in sync with mmdb/mmdb_defs.h
+AC_INIT(mmdb2, 2.0.1) # keep in sync with mmdb2/mmdb_defs.h
AC_CONFIG_AUX_DIR(build-aux)
AC_CONFIG_MACRO_DIR(m4)
-AC_CONFIG_SRCDIR(mmdb/mmdb_align.cpp)
+AC_CONFIG_SRCDIR(mmdb2/mmdb_math_align.cpp)
AC_CONFIG_HEADERS(config.h)
AM_INIT_AUTOMAKE([1.11 foreign subdir-objects silent-rules -Wall])
AM_PROG_AR
@@ -18,4 +18,4 @@ AC_LANG_POP(C++)
AM_MAINTAINER_MODE dnl disable (by default) maintainer mode
AC_SEARCH_LIBS([cos], [m], [], [AC_MSG_ERROR([need math library])])
-AC_OUTPUT(Makefile mmdb.pc)
+AC_OUTPUT(Makefile mmdb2.pc)
diff --git a/mmdb/bfgs_min.cpp b/mmdb/bfgs_min.cpp
deleted file mode 100755
index 9b3a95e..0000000
--- a/mmdb/bfgs_min.cpp
+++ /dev/null
@@ -1,936 +0,0 @@
-// $Id: bfgs_min.cpp,v 1.19 2012/01/26 17:52:19 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-
-// =================================================================
-//
-// 27.06.01 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : bfgs_min <implementation>
-// ~~~~~~~~~
-// **** Classes : CBFGSMin ( minimization driver )
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-#ifndef __MATH_H
-#include <math.h>
-#endif
-
-#ifndef __BFGS_Min__
-#include "bfgs_min.h"
-#endif
-
-
-// ==============================================================
-
-CBFGSMin::CBFGSMin() {
-
- MFunc = NULL;
- MFuncData = NULL;
- PFunc = NULL;
- PFuncData = NULL;
-
- N = 0;
- NAlloc = 0;
-
- Hsn = NULL;
- TL = NULL;
- LL = NULL;
- XOpt = NULL;
- XPlus = NULL;
- Sx = NULL;
- SN = NULL;
- HDiag = NULL;
- GradX = NULL;
- GPlus = NULL;
- StepSize = NULL;
- FNeighbor = NULL;
- us = NULL;
- uy = NULL;
- ut = NULL;
- Freese = NULL;
- Func = 0.0;
- FPlus = 0.0;
- FOpt = 0.0;
- TakenLambda = 0.0;
- ForDiff = False;
- CalcHess = False;
-
- Etha = 0.0;
- SqrtEtha = 0.0;
- CubertEtha = 0.0;
- TpF = 1.0;
- GrdEps = 0.0;
- StpEps = 0.0;
- MxStep = MaxReal;
- CnsMax = 0;
- MaxItn = 100;
- TermCode = BFGS_NoTermination;
- ModF = False;
-
-}
-
-CBFGSMin::~CBFGSMin() {
- FreeMemory();
-}
-
-void CBFGSMin::MinFunc ( rvector X, realtype & F ) {
- if (MFunc) (*MFunc)(MFuncData,N,X,F);
- else F = 0.0;
-}
-
-void CBFGSMin::MinFunc1 ( rvector X, realtype & F ) {
-int i;
- MinFunc ( X,F );
- if (ModF && (F<FOpt)) {
- for (i=1;i<=N;i++)
- XOpt[i] = X[i];
- FOpt = F;
- }
-}
-
-void CBFGSMin::Print ( int Itn, rvector X, rvector G, realtype F ) {
- if (PFunc) (*PFunc)(PFuncData,N,Itn,X,G,F);
-}
-
-void CBFGSMin::SetMinFunction ( void * UserData, PBFGSMinFunc Fnc ) {
- MFuncData = UserData;
- MFunc = Fnc;
-}
-
-void CBFGSMin::SetPrintFunction ( void * UserData, PBFGSPrintFunc Fnc ) {
- PFuncData = UserData;
- PFunc = Fnc;
-}
-
-
-// -------------------------------------------------------------------
-
-void CBFGSMin::UMInCk ( rvector x0, rvector TypX,
- int Digits, realtype TypF,
- realtype GrdTol, realtype StpTol,
- realtype MaxStp, int ItnLmt ) {
-int i;
-realtype S0,S1,S2;
-
- SqrtEps = sqrt(MachEps);
-
- if (N<1) {
- TermCode = BFGS_WrongSpaceDim;
- return;
- }
-
- for (i=1;i<=N;i++)
- if (fabs(TypX[i])!=0.0) Sx[i] = 1.0/fabs(TypX[i]);
- else Sx[i] = 1.0;
-
- if (Digits<=0) Etha = MachEps;
- else {
- Etha = Exp((-Digits)*log(10.0));
- if (MachEps>Etha) Etha = MachEps;
- }
- SqrtEtha = sqrt(Etha);
- CubertEtha = Exp ( log(Etha)/3.0 );
-
- if (Etha>0.01) {
- TermCode = BFGS_TooFewDigits;
- return;
- }
-
- if (TypF<=0.0) TpF = 1.0;
- else TpF = TypF;
-
- S1 = Exp(log(MachEps)/3.0);
- if (GrdTol>0.0) GrdEps = GrdTol;
- else {
- GrdEps = sqrt(Etha);
- if (S1>GrdEps) GrdEps = S1;
- }
-
- if (StpTol>0.0) StpEps = StpTol;
- else StpEps = Exp ( log(MachEps)*2.0/3.0 );
-
- if (MaxStp>0.0) MxStep = MaxStp;
- else {
- S1 = 0.0;
- S2 = 0.0;
- for (i=1;i<=N;i++) {
- S0 = Sx[i];
- S0 *= Sx[i];
- S2 += S0;
- S0 *= x0[i];
- S1 += S0*x0[i];
- }
- S1 = sqrt(S1);
- S2 = sqrt(S2);
- if (S2>S1) MxStep = S2;
- else MxStep = S1;
- MxStep *= 1000.0;
- }
-
- if (ItnLmt>0) MaxItn = ItnLmt;
- else MaxItn = 100;
-
- TermCode = BFGS_NoTermination;
-
-}
-
-
-// -------------------------------------------------------------------
-
-void CBFGSMin::UMStop0 ( rvector x0, rvector Grad ) {
-int i;
-realtype S,Fmax,St;
-
- CnsMax = 0;
- if (TpF>fabs(Func)) Fmax = TpF;
- else Fmax = fabs(Func);
- S = 0.0;
- for (i=1;i<=N;i++) {
- St = fabs(x0[i]);
- if (1.0/Sx[i]>St) St = 1.0/Sx[i];
- St = fabs(Grad[i])*St/Fmax;
- if (St>S) S = St;
- }
- if (S>=0.001*GrdEps) TermCode = BFGS_NoTermination;
- else TermCode = BFGS_SmallGradient;
-
-}
-
-
-// -------------------------------------------------------------------
-
-void CBFGSMin::UMStop ( rvector x0, rvector Grad,
- int RetCode, int ItnCnt,
- Boolean MaxTkn ) {
-
-// A7.2.1 : Checking the Stop Conditions
-
-int i;
-realtype Max1,Max2,MaxGrad,MaxStep, BB1,BB2;
-
- TermCode = BFGS_NoTermination;
- if (RetCode==1) TermCode = BFGS_LineSearchComplete;
- else {
- if (fabs(FPlus)>TpF) Max2 = fabs(FPlus);
- else Max2 = TpF;
- MaxGrad = 0.0;
- MaxStep = 0.0;
- for (i=1;i<=N;i++) {
- BB1 = fabs(XPlus[i]);
- BB2 = 1.0/Sx[i];
- if (BB1>BB2) Max1 = BB1;
- else Max1 = BB2;
- BB1 = fabs(Grad[i])*Max1/Max2;
- if (BB1>MaxGrad) MaxGrad = BB1;
- BB2 = fabs(XPlus[i]-x0[i])/Max1;
- if (BB2>MaxStep) MaxStep = BB2;
- }
- if (MaxGrad<GrdEps) TermCode = BFGS_SmallGradient;
- else if (MaxStep<StpEps) TermCode = BFGS_SmallStep;
- else if (ItnCnt>MaxItn) TermCode = BFGS_IterationLimit;
- else if (MaxTkn) {
- CnsMax++;
- if (CnsMax==5) TermCode = BFGS_LargeSteps;
- } else
- CnsMax = 0;
- }
-
-}
-
-
-// -------------------------------------------------------------------
-
-void CBFGSMin::MdHess ( rmatrix H, rvector HDg ) {
-
-// A5.5.1 : Setting up the hessian of model
-
-int i,j;
-realtype MaxDiag,MaxOff, MinEv,Mue,MaxPosDiag;
-realtype MaxOffl,MinDiag,MaxEv,MaxAdd,Sdd,OffRow;
-realtype BB;
-
- // Scaling
- for (i=1;i<=N;i++)
- for (j=i;j<=N;j++)
- H[i][j] /= (Sx[i]*Sx[j]);
-
- MaxDiag = H[1][1];
- MinDiag = H[1][1];
- MaxOff = 0.0;
- for (i=1;i<=N;i++) {
- if (H[i][i]>MaxDiag) MaxDiag = H[i][i];
- if (H[i][i]<MinDiag) MinDiag = H[i][i];
- if (i<N)
- for (j=i+1;j<=N;j++) {
- BB = fabs(H[i][j]);
- if (BB>MaxOff) MaxOff = BB;
- }
- }
- MaxPosDiag = 0.0;
- if (MaxDiag>MaxPosDiag) MaxPosDiag = MaxDiag;
-
- // Computing the shift of the spectra (the Mue)
- if (MinDiag>SqrtEps*MaxPosDiag) Mue = 0.0;
- else {
- Mue = 2.0*(MaxPosDiag-MinDiag)*SqrtEps-MinDiag;
- MaxDiag += Mue;
- }
- BB = MaxOff*(1.0+2.0*SqrtEps);
- if (BB>MaxDiag) {
- Mue = Mue+(MaxOff-MaxDiag)+2.0*SqrtEps*MaxOff;
- MaxDiag = BB;
- }
- if (MaxDiag==0.0) { // H = 0
- Mue = 1.0;
- MaxDiag = 1.0;
- }
- if (Mue>0.0)
- for (i=1;i<=N;i++)
- Hsn[i][i] += Mue;
-
- MaxOffl = MaxOff/N;
- if (MaxDiag>MaxOffl) MaxOffl = MaxDiag;
- MaxOffl = sqrt(MaxOffl);
- for (i=1;i<=N;i++)
- HDg[i] = H[i][i];
-
- PbCholDecomp ( N,HDg,MaxOffl,MachEps,H,MaxAdd );
-
- if (MaxAdd>0.0) {
- MaxEv = HDg[1];
- MinEv = HDg[1];
- for (i=1;i<=N;i++) {
- OffRow = 0.0;
- if (i>1)
- for (j=1;j<i;j++)
- OffRow += fabs(H[j][i]);
- if (i<N)
- for (j=i+1;j<=N;j++)
- OffRow += fabs(H[i][j]);
- BB = HDg[i]+OffRow;
- if (BB>MaxEv) MaxEv = BB;
- BB = HDg[i]-OffRow;
- if (BB<MinEv) MinEv = BB;
- }
- Sdd = (MaxEv-MinEv)*SqrtEps-MinEv;
- if (Sdd<0.0) Sdd = 0.0;
- if (MaxAdd<Sdd) Mue = MaxAdd;
- else Mue = Sdd;
- for (i=1;i<=N;i++)
- HDg[i] += Mue;
-
- PbCholDecomp ( N,HDg,0.0,MachEps,H,MaxAdd );
-
- }
-
- // Scaling back
- for (i=1;i<=N;i++) {
- if (i<N)
- for (j=i+1;j<=N;j++)
- H[i][j] *= (Sx[i]*Sx[j]);
- HDg[i] *= Sx[i]*Sx[i];
- for (j=1;j<=i;j++)
- H[i][j] *= Sx[i];
- }
-
-}
-
-
-// -------------------------------------------------------------------
-
-void CBFGSMin::FDGrad ( rvector X, rvector G, realtype Fc ) {
-
-// A5.6.4 : Forward Finite-Differencies Approximation of
-// the Gradient
-
-realtype StepSizeJ,TempJ,Fj, BB1,BB2;
-int j;
-
- for (j=1;j<=N;j++) {
- BB1 = fabs(X[j]);
- BB2 = 1.0/Sx[j];
- if (BB1>BB2) StepSizeJ = BB1;
- else StepSizeJ = BB2;
- if (X[j]<0.0) StepSizeJ = -StepSizeJ;
- StepSizeJ *= SqrtEtha;
- TempJ = X[j];
- X[j] += StepSizeJ;
- StepSizeJ = X[j]-TempJ;
- MinFunc1 ( X,Fj );
- if (TermCode!=BFGS_NoTermination) return;
- G[j] = (Fj-Fc)/StepSizeJ;
- X[j] = TempJ;
- Freese[j] = False;
- if (TL) {
- if ((fabs(X[j]-TL[j])<=StepSizeJ) && (G[j]<0.0)) {
- G[j] = 0.0; Freese[j] = True;
- }
- }
- if (LL) {
- if ((fabs(X[j]-LL[j])<=StepSizeJ) && (G[j]>0.0)) {
- G[j] = 0.0; Freese[j] = True;
- }
- }
- }
-
-}
-
-
-// -------------------------------------------------------------------
-
-void CBFGSMin::CDGrad ( rvector X, rvector G ) {
-
-// A5.6.4 : Central Differencies Approximation of
-// Gradient
-
-realtype StepSizeJ,TempJ,Fp,Fm, BB1,BB2;
-int j;
-
- for (j=1;j<=N;j++) {
- BB1 = fabs(X[j]);
- BB2 = 1.0/Sx[j];
- if (BB1>BB2) StepSizeJ = BB1;
- else StepSizeJ = BB2;
- if (X[j]<0.0) StepSizeJ = -StepSizeJ;
- StepSizeJ *= CubertEtha;
- TempJ = X[j];
- X[j] += StepSizeJ;
- StepSizeJ = X[j]-TempJ;
- MinFunc1 ( X,Fp );
- if (TermCode!=BFGS_NoTermination) return;
- X[j] = TempJ-StepSizeJ;
- MinFunc1 ( X,Fm );
- if (TermCode!=BFGS_NoTermination) return;
- G[j] = (Fp-Fm)/(2.0*StepSizeJ);
- X[j] = TempJ;
- }
-
-}
-
-
-// -------------------------------------------------------------------
-
-void CBFGSMin::Gradient ( rvector X, rvector G, realtype Fc ) {
- if (ForDiff) FDGrad ( X,G,Fc );
- else CDGrad ( X,G );
-}
-
-
-// -------------------------------------------------------------------
-
-void CBFGSMin::FDHessF ( realtype Fc, rvector X ) {
-
-// A5.6.2 : Finite-Difference Approximation of
-// the Hessian employing only the
-// function's values
-
-int i,j;
-realtype S,TempI,Fii,TempJ,Fij, BB1,BB2;
-
-
- for (i=1;i<=N;i++)
- if (!Freese[i]) {
- BB1 = fabs(X[i]);
- BB2 = 1.0/Sx[i];
- if (BB1>BB2) S = BB1;
- else S = BB2;
- if (X[i]<0.0) S = -S;
- StepSize[i] = S*CubertEtha;
- TempI = X[i];
- X[i] += StepSize[i];
- StepSize[i] = X[i]-TempI;
- MinFunc1 ( X,FNeighbor[i] );
- X[i] = TempI;
- if (TermCode!=BFGS_NoTermination) return;
- }
- for (i=1;i<=N;i++)
- if (!Freese[i]) {
- TempI = X[i];
- X[i] += 2.0*StepSize[i];
- MinFunc1 ( X,Fii );
- if (TermCode!=BFGS_NoTermination) return;
- Hsn[i][i] = (( Fc -FNeighbor[i] ) +
- ( Fii-FNeighbor[i] )) /
- (StepSize[i]*StepSize[i]);
- X[i] = TempI+StepSize[i];
- if (i<N)
- for (j=i+1;j<=N;j++)
- if (!Freese[j]) {
- TempJ = X[j];
- X[j] += StepSize[j];
- MinFunc1 ( X,Fij );
- if (TermCode!=BFGS_NoTermination) return;
- Hsn[i][j] = (( Fc -FNeighbor[i] ) +
- ( Fij-FNeighbor[j] )) /
- (StepSize[i]*StepSize[j]);
- X[j] = TempJ;
- } else
- Hsn[i][j] = 0.0;
- X[i] = TempI;
- } else
- for (j=i;j<=N;j++)
- Hsn[i][j] = 0.0;
-
-}
-
-
-// -------------------------------------------------------------------
-
-void CBFGSMin::InitHessUnFac ( realtype F, rmatrix H ) {
-
-// A9.4.3 - Initialization of the unfactorized BFGS
-
-realtype Temp;
-int i,j;
-
- Temp = fabs(F);
- if (TpF>Temp) Temp = TpF;
- for (i=1;i<=N;i++) {
- H[i][i] = Temp*Sx[i]*Sx[i];
- if (i<N)
- for (j=i+1;j<=N;j++)
- H[i][j] = 0.0;
- }
-
-}
-
-
-// -------------------------------------------------------------------
-
-void CBFGSMin::BFGSUnFac ( rvector Xc, rvector Xp,
- rvector Gc, rvector Gp,
- Boolean AnalGrad, rvector HDg,
- rmatrix H ) {
-
-// A9.4.1 - Calculation of the Hessian by the
-// unfactorized BFGS
-
-int i,j;
-realtype Temp1,Temp2, NormS,NormY,Tol,tt, BB;
-Boolean SkipUpdate;
-
- Temp1 = 0.0;
- NormS = 0.0;
- NormY = 0.0;
- for (i=1;i<=N;i++) {
- H[i][i] = HDg[i];
- us[i] = Xp[i] - Xc[i];
- uy[i] = Gp[i] - Gc[i];
- Temp1 += us[i]*uy[i];
- NormS += us[i]*us[i];
- NormY += uy[i]*uy[i];
- }
-
- if (Temp1>sqrt(MachEps*NormS*NormY)) {
- if (AnalGrad) Tol = Etha;
- else Tol = sqrt(Etha);
- SkipUpdate = True;
- for (i=1;i<=N;i++) {
- tt = 0.0;
- for (j=1;j<=i;j++)
- tt += H[j][i]*us[j];
- if (i<N)
- for (j=i+1;j<=N;j++)
- tt += H[i][j]*us[j];
- ut[i] = tt;
- tt = fabs(Gc[i]);
- BB = fabs(Gp[i]);
- if (BB>tt) tt = BB;
- if (fabs(uy[i]-ut[i])>=Tol*tt)
- SkipUpdate = False;
- }
-
- if (!SkipUpdate) {
- Temp2 = 0.0;
- for (i=1;i<=N;i++)
- Temp2 += us[i]*ut[i];
- for (i=1;i<=N;i++)
- for (j=i;j<=N;j++)
- H[i][j] += uy[i]*uy[j]/Temp1 -
- ut[i]*ut[j]/Temp2;
- }
-
- }
-
-}
-
-
-// -------------------------------------------------------------------
-
-void CBFGSMin::Choose_Lambda ( rvector X, rvector S,
- realtype & Lambda0 ) {
-int i;
-realtype SS;
-
- for (i=1;i<=N;i++)
- if ((S[i]!=0.0) && (!Freese[i])) {
- SS = X[i] + Lambda0*S[i];
- if (TL) {
- if (SS>TL[i]) Lambda0 = (TL[i]-X[i])/S[i]/(1.0+MachEps);
- }
- if (LL) {
- if (SS<LL[i]) Lambda0 = (LL[i]-X[i])/S[i]/(1.0+MachEps);
- }
- } else if (Freese[i]) S[i] = 0.0;
-
-}
-
-
-// -------------------------------------------------------------------
-
-void CBFGSMin::Stop() {
- TermCode = BFGS_Stopped;
-}
-
-
-// -------------------------------------------------------------------
-
-void CBFGSMin::LineSearch ( rvector px0, rvector G,
- rvector P, realtype pFunc,
- int & RetCode, Boolean & MaxTkn ) {
-
-// A6.3.1 : Linear Search
-
-int i;
-realtype Alpha, NewtLn, S, InitSp, RelLng, MinLam;
-realtype Lambda,LamTem, LamPre, FplPre, A, B;
-realtype Disc, B1, B2, Lambda0;
-
- LamPre = 1.0; // only to keep compiler happy
- FplPre = 1.0; // only to keep compiler happy
-
- MaxTkn = False;
- RetCode = 2;
- Alpha = 1.0e-4;
- NewtLn = 0.0;
- for (i=1;i<=N;i++) { // calculate Newtonian step along the -gradient
- B1 = Sx[i]*P[i];
- NewtLn += B1*B1;
- }
- NewtLn = sqrt(NewtLn);
-
- if (NewtLn>MxStep) { // restrict Newtonian step to MxStep
- S = MxStep/NewtLn;
- for (i=1;i<=N;i++)
- P[i] *= S;
- NewtLn = MxStep;
- }
-
- InitSp = 0.0;
- RelLng = 0.0;
- Lambda0 = 1.0;
- Choose_Lambda ( px0,P,Lambda0 );
- for (i=1;i<=N;i++) {
- InitSp += G[i]*P[i];
- B1 = fabs(px0[i]);
- B2 = 1.0/Sx[i];
- if (B1>B2) S = B1;
- else S = B2;
- S = fabs(P[i])/S;
- if (S>RelLng) RelLng = S;
- }
- InitSp *= Lambda0;
-
- MinLam = StpEps/RelLng;
- Lambda = Lambda0;
- do {
- for (i=1;i<=N;i++)
- XPlus[i] = px0[i] + Lambda*P[i];
-
- MinFunc1 ( XPlus,FPlus );
- if (TermCode!=BFGS_NoTermination) return;
- if (FPlus<=pFunc+Alpha*Lambda*InitSp) {
- RetCode = 0;
- MaxTkn = (Lambda==Lambda0) && (NewtLn>0.99*MxStep);
- } else if (Lambda<MinLam) {
- RetCode = 1;
- for (i=1;i<=N;i++)
- XPlus[i] = px0[i];
- } else if (Lambda==Lambda0) {
- LamTem = -InitSp/(2.0*(FPlus-pFunc-InitSp));
- LamTem = LamTem*Lambda;
- LamPre = Lambda;
- FplPre = FPlus;
- if (LamTem>0.1*Lambda) Lambda = LamTem;
- else {
- Lambda *= 0.1;
- Lambda0 = Lambda;
- }
- if (Lambda>Lambda0) {
- Lambda = Lambda0;
- RetCode = 0;
- for (i=1;i<=N;i++)
- XPlus[i] = px0[i] + Lambda*P[i];
- }
- } else {
- B1 = FPlus - pFunc - Lambda*InitSp;
- B2 = FplPre - pFunc - LamPre*InitSp;
- A = ( B1/(Lambda*Lambda) - B2/(LamPre*LamPre) ) /
- ( Lambda - LamPre );
- B = ( -LamPre*B1/(Lambda*Lambda) +
- Lambda*B2/(LamPre*LamPre) ) /
- ( Lambda - LamPre );
- Disc = B*B - 3.0*A*InitSp;
- if (A==0.0) LamTem = -InitSp/(2.0*B);
- else LamTem = (-B+sqrt(RMax(Disc,0.0)))/(3.0*A);
- B1 = 0.5*Lambda;
- if (B1<LamTem) LamTem = B1;
- LamPre = Lambda;
- FplPre = FPlus;
- if (LamTem>0.1*Lambda) Lambda = LamTem;
- else {
- Lambda *= 0.1;
- Lambda0 = Lambda;
- }
- if (Lambda>Lambda0) {
- Lambda = Lambda0;
- RetCode = 0;
- for (i=1;i<=N;i++)
- XPlus[i] = px0[i] + Lambda*P[i];
- }
- }
-
- } while (RetCode>=2);
-
- TakenLambda = Lambda;
-
-}
-
-
-// -------------------------------------------------------------------
-
-void CBFGSMin::GetMemory() {
- if (N!=NAlloc) {
- FreeMemory();
- GetMatrixMemory ( Hsn , N,N, 1,1 );
- GetVectorMemory ( GPlus , N, 1 );
- GetVectorMemory ( GradX , N, 1 );
- GetVectorMemory ( HDiag , N, 1 );
- GetVectorMemory ( SN , N, 1 );
- GetVectorMemory ( Sx , N, 1 );
- GetVectorMemory ( XPlus , N, 1 );
- GetVectorMemory ( XOpt , N, 1 );
- GetVectorMemory ( Freese, N, 1 );
- if (CalcHess) {
- GetVectorMemory ( StepSize , N, 1 );
- GetVectorMemory ( FNeighbor, N, 1 );
- } else {
- GetVectorMemory ( us , N, 1 );
- GetVectorMemory ( uy , N, 1 );
- GetVectorMemory ( ut , N, 1 );
- }
- NAlloc = N;
- }
-}
-
-void CBFGSMin::FreeMemory() {
- if (NAlloc>0) {
- FreeVectorMemory ( us , 1 );
- FreeVectorMemory ( uy , 1 );
- FreeVectorMemory ( ut , 1 );
- FreeVectorMemory ( Freese , 1 );
- FreeVectorMemory ( StepSize , 1 );
- FreeVectorMemory ( FNeighbor, 1 );
- FreeVectorMemory ( XOpt , 1 );
- FreeVectorMemory ( XPlus , 1 );
- FreeVectorMemory ( Sx , 1 );
- FreeVectorMemory ( SN , 1 );
- FreeVectorMemory ( HDiag , 1 );
- FreeVectorMemory ( GradX , 1 );
- FreeVectorMemory ( GPlus , 1 );
- FreeMatrixMemory ( Hsn , NAlloc, 1,1 );
- }
- NAlloc = 0;
-}
-
-
-// -------------------------------------------------------------------
-
-void CBFGSMin::Relax() {
-int i;
- if (FPlus>FOpt) {
- for (i=1;i<=N;i++)
- XPlus[i] = XOpt[i];
- FPlus = FOpt;
- } else {
- for (i=1;i<=N;i++)
- XOpt[i] = XPlus[i];
- FOpt = FPlus;
- }
-}
-
-void CBFGSMin::CopyPlus ( rvector x0 ) {
-int i;
- for (i=1;i<=N;i++) {
- x0 [i] = XPlus[i];
- GradX[i] = GPlus[i];
- }
- Func = FPlus;
-}
-
-
-// -------------------------------------------------------------------
-
-void CBFGSMin::BFGS_Driver ( int MinN,
- rvector x0,
- rvector TypX,
- realtype & FuncValue,
- int & TerminationCode,
- int Digits,
- int ItnLmt,
- realtype TypF,
- realtype GrdTol,
- realtype StpTol,
- realtype MaxStp,
- Boolean Hess,
- rvector LowLimit,
- rvector TopLimit ) {
-
-// D6.1.1 : Unconstrained Minimization Driver
-
-int i,RetCode;
-int ItnCnt;
-Boolean MaxTkn;
-
- TL = TopLimit;
- LL = LowLimit;
- ForDiff = True;
- N = MinN;
- CalcHess = Hess;
-
- ModF = False;
-
- GetMemory();
-
- UMInCk ( x0,TypX,Digits,TypF,
- GrdTol,StpTol,MaxStp,
- ItnLmt );
- if (TermCode!=BFGS_NoTermination) {
- FreeMemory();
- FuncValue = Func;
- TerminationCode = TermCode;
- return;
- }
-
- ItnCnt = 0;
-
- MinFunc1 ( x0,Func );
- if (TermCode!=BFGS_NoTermination) {
- FreeMemory();
- FuncValue = Func;
- TerminationCode = TermCode;
- return;
- }
- FOpt = Func;
- FPlus = Func;
- for (i=1;i<=N;i++) {
- XOpt [i] = x0[i];
- XPlus[i] = x0[i];
- }
- ModF = True;
- Gradient ( x0,GradX,Func );
- Print ( ItnCnt,x0,GradX,Func );
- for (i=1;i<=N;i++)
- GPlus[i] = GradX[i];
- if (TermCode!=BFGS_NoTermination) {
- Relax ();
- CopyPlus ( x0 );
- FreeMemory();
- FuncValue = Func;
- TerminationCode = TermCode;
- return;
- }
-
- UMStop0 ( x0,GradX );
- if (TermCode!=BFGS_NoTermination) {
- FreeMemory();
- FuncValue = Func;
- TerminationCode = TermCode;
- return;
- }
-
- if (!CalcHess) InitHessUnFac ( Func,Hsn );
-
- RetCode = 0;
- while (TermCode==BFGS_NoTermination) {
- ItnCnt++;
- if (RetCode>=0) {
- if (CalcHess) {
- FDHessF ( Func,x0 );
- if (TermCode!=BFGS_NoTermination) {
- Relax ();
- CopyPlus ( x0 );
- FreeMemory();
- FuncValue = Func;
- TerminationCode = TermCode;
- return;
- }
- }
- MdHess ( Hsn,HDiag );
- }
- ChSolve ( N,Hsn,GradX,SN );
- LineSearch ( x0,GradX,SN,Func,RetCode,MaxTkn );
- if ((RetCode==1) && ForDiff) {
- RetCode = -1;
- ForDiff = False;
- } else
- Relax();
- if (TermCode!=BFGS_NoTermination) {
- Relax ();
- CopyPlus ( x0 );
- FreeMemory();
- FuncValue = Func;
- TerminationCode = TermCode;
- return;
- } else
- Gradient ( XPlus,GPlus,FPlus );
- if (TermCode!=BFGS_NoTermination) {
- Relax ();
- CopyPlus ( x0 );
- FreeMemory();
- FuncValue = Func;
- TerminationCode = TermCode;
- return;
- }
- if (RetCode>=0) {
- UMStop ( x0,GPlus,RetCode,ItnCnt,MaxTkn );
- if ((!CalcHess) && (TermCode==BFGS_NoTermination))
- BFGSUnFac ( x0,XPlus,GradX,GPlus,False,HDiag,Hsn );
- }
- CopyPlus ( x0 );
- Print ( ItnCnt, x0,GradX,Func );
- }
-
- Relax ();
- FreeMemory();
- FuncValue = Func;
- TerminationCode = TermCode;
-
-}
-
-
diff --git a/mmdb/bfgs_min.h b/mmdb/bfgs_min.h
deleted file mode 100755
index ec6741b..0000000
--- a/mmdb/bfgs_min.h
+++ /dev/null
@@ -1,257 +0,0 @@
-// $Id: bfgs_min.h,v 1.20 2012/01/26 17:52:19 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 27.06.01 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : bfgs_min <interface>
-// ~~~~~~~~~
-// **** Classes : CBFGSMin ( minimization driver )
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-#ifndef __BFGS_Min__
-#define __BFGS_Min__
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifndef __MatType__
-#include "mattype_.h"
-#endif
-
-#ifndef __LinAlg__
-#include "linalg_.h"
-#endif
-
-
-// ==============================================================
-
-#define BFGS_TooFewDigits -2
-#define BFGS_WrongSpaceDim -1
-#define BFGS_NoTermination 0
-#define BFGS_SmallGradient 1
-#define BFGS_SmallStep 2
-#define BFGS_LineSearchComplete 3
-#define BFGS_IterationLimit 4
-#define BFGS_LargeSteps 5
-#define BFGS_Stopped 6
-
-typedef void BFGSMinFunc ( void * UserData, int N, rvector X,
- realtype & F );
-typedef BFGSMinFunc * PBFGSMinFunc;
-
-typedef void BFGSPrintFunc ( void * UserData, int N, int Itn,
- rvector X, rvector G, realtype F );
-typedef BFGSPrintFunc * PBFGSPrintFunc;
-
-DefineClass(CBFGSMin);
-
-class CBFGSMin {
-
- public :
-
- CBFGSMin ();
- virtual ~CBFGSMin();
-
- virtual void MinFunc ( rvector X, realtype & F );
- virtual void Print ( int Itn, rvector X, rvector G,
- realtype F );
-
- void SetMinFunction ( void * UserData, PBFGSMinFunc Fnc );
- void SetPrintFunction ( void * UserData, PBFGSPrintFunc Fnc );
-
-
- // ======================================================
- //
- // .--------------------------------------------.
- // | |
- // | UNCONSTRAINED MINIMIZATION DRIVER |
- // | |
- // `--------------------------------------------'
- //
- // Finds a minimum of function F(X), X is vector [1..N], defined
- // by virtual MinFunc. Virtual Print provides information on every
- // iteration step.
- //
- //
- // Input parameters :
- // -----------------------
- //
- // N is the dimension the minimization space
- //
- // x0 [1..N] is the initial point for minimization
- //
- // TypX [1..N] is the array of the typical ranges of
- // X - components, which are used for the scaling.
- // If TypX<=0.0 then 1.0 will be substituted
- //
- // Digits is the number of valid decimal digits in
- // the calculated value of minimizing function ( F ).
- // If Digits<=0 then the Driver will consider
- // that the F is computed with usual machine's
- // noise
- //
- // ItnLmt is the maximum available number of iterations.
- // If ItnLmt=0 then 100 will be substituted
- //
- // TypF is the expected absolute value of F in the
- // minimum, which is used in the stop criterion.
- // If TypF<=0.0 then 1.0 will be substituted
- //
- // GrdTol is the desired absolute value of the gradient
- // vector in the minimum of F . If GrdTol<=0.0
- // then the some value correlated with machine's
- // noise will be substituted
- //
- // StpTol is the minimum available step for the minimi-
- // zation. The execution stops if the distance
- // between two consequential approximation will be
- // less then StpTol . If StpTol<=0.0 then the
- // some value correlated with machine's noise
- // will be substituted
- //
- // MaxStp is the maximum available step for then minimi-
- // zation. This parameter only prevents the appea-
- // rance of the too large steps, but the execution
- // stops if more than 5 steps with length of MaxStep
- // will consequently appear.
- //
- //
- //
- // Outpute parameters :
- // --------------------------
- //
- // x0 will be the point at which the minimisation
- // had stopped
- //
- // Func will be the function's value at x0
- //
- // TermCode will be the reason of stopping :
- //
- // 1 <=> the norm of gradient vector at x0 is
- // less than GrdTol ; the x0 is probable
- // point of the minimum
- // 2 <=> the distance between two last approxima-
- // tions was less than StpTol ; the x0
- // may be the point of minimum
- // 3 <=> the gradient length is greater than
- // GrdTol , but future minimization fails ;
- // it may be the consequence of the errors
- // at the computing of gradient, but also
- // x0 could be the point of minimum
- // 4 <=> the iteration limit had been exchausted
- // 5 <=> more than 5 steps with length of
- // MaxStp had been made
- // 6 <=> the termination key ( Esc or End )
- // had been pressed.
- //
- //
- // ========================================================
-
- void BFGS_Driver ( int MinN,
- rvector x0,
- rvector TypX,
- realtype & FuncValue,
- int & TerminationCode,
- int Digits = 0,
- int ItnLmt = 0,
- realtype TypF = 0.0,
- realtype GrdTol = 0.0,
- realtype StpTol = 0.0,
- realtype MaxStp = MaxReal,
- Boolean Hess = False,
- rvector LowLimit = NULL,
- rvector TopLimit = NULL );
-
- void Stop(); // generates stop signal to stop optimization
-
-
- protected :
-
- PBFGSMinFunc MFunc;
- void * MFuncData;
- PBFGSPrintFunc PFunc;
- void * PFuncData;
-
- int N,NAlloc;
- rmatrix Hsn;
- rvector TL,LL,XOpt,XPlus,Sx,SN,HDiag,GradX,GPlus;
- rvector StepSize,FNeighbor;
- rvector us,uy,ut;
- bvector Freese;
- realtype Func,FPlus,FOpt;
- realtype TakenLambda;
- Boolean ForDiff; // if True then forward differences are
- // used for the 1st estimation of the
- // Hessian (which is less expensive),
- // otherwise central differences will
- // be employed (which is more expensive).
- Boolean CalcHess;
-
- realtype Etha,SqrtEtha,CubertEtha,TpF,GrdEps,StpEps,MxStep;
- realtype SqrtEps;
- int CnsMax,MaxItn,TermCode;
- Boolean ModF;
-
- void MinFunc1 ( rvector X, realtype & F );
- void UMInCk ( rvector x0, rvector TypX,
- int Digits, realtype TypF,
- realtype GrdTol, realtype StpTol,
- realtype MaxStp, int ItnLmt );
- void UMStop0 ( rvector x0, rvector Grad );
- void UMStop ( rvector x0, rvector Grad, int RetCode,
- int ItnCnt, Boolean MaxTkn );
-
- virtual void Gradient ( rvector X, rvector G, realtype Fc );
- virtual void FDHessF ( realtype Fc, rvector X );
-
- void FDGrad ( rvector X, rvector G, realtype Fc );
- void CDGrad ( rvector X, rvector G );
- void MdHess ( rmatrix H, rvector HDg );
- void InitHessUnFac ( realtype F, rmatrix H );
- void BFGSUnFac ( rvector Xc, rvector Xp,
- rvector Gc, rvector Gp,
- Boolean AnalGrad, rvector HDg,
- rmatrix H );
- void Choose_Lambda ( rvector X, rvector S, realtype & Lambda0 );
- void LineSearch ( rvector px0, rvector G,
- rvector P, realtype pFunc,
- int & RetCode, Boolean & MaxTkn );
- void GetMemory ();
- void FreeMemory ();
- void Relax ();
- void CopyPlus ( rvector x0 );
-
-};
-
-#endif
-
-
diff --git a/mmdb/file_.cpp b/mmdb/file_.cpp
deleted file mode 100755
index b85b697..0000000
--- a/mmdb/file_.cpp
+++ /dev/null
@@ -1,1857 +0,0 @@
-// $Id: file_.cpp,v 1.29 2012/01/26 17:52:19 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 29.01.10 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : file_ <implementation>
-// ~~~~~~~~~
-// **** Classes : CFile - file I/O Support.
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2010
-//
-// =================================================================
-//
-
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifdef _WIN32
-# include <windows.h>
-# define sleep Sleep
-# endif
-
-#ifndef __STDIO_H
-#include <stdio.h>
-#endif
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef _WIN32
-#ifndef __UNISTD_H
-#include <unistd.h>
-#endif
-#endif
-
-#ifndef __File__
-#include "file_.h"
-#endif
-
-
-// _WIN32_NEWLINE should be raised when compilinig on Windows in
-// order to enforce Windows' line endings when writing text in
-// files opened for *binary* output. Otherwise, writing text lines
-// in binary files will results in UNIX line endings. Line endings
-// in files, opened for output in text mode, will be always
-// platform-specific.
-
-#ifdef _WIN32_NEWLINE
-// for DOS/WINDOWS machines:
-#define NEWLINE "\r\n"
-#else
-// for UNIX machines:
-#define NEWLINE "\n"
-#endif
-
-
-// =================== Auxilary Functions =========================
-
-cpstr GetFPath ( pstr FilePath, int syskey ) {
-pstr P;
-
- if (syskey==syskey_unix)
- P = strrchr(FilePath,'/');
- else if (syskey==syskey_win)
- P = strrchr(FilePath,'\\');
- else if (syskey==syskey_all) {
- P = strrchr(FilePath,'/');
- if (!P) P = strrchr(FilePath,'\\');
- } else
- P = NULL;
-
- if (P) {
- P = P + 1;
- *P = char(0);
- } else
- FilePath[0] = char(0);
-
- return FilePath;
-
-}
-
-cpstr GetFName ( cpstr FilePath, int syskey ) {
-pstr P;
- if (syskey==syskey_unix)
- P = strrchr(FilePath,'/');
- else if (syskey==syskey_win)
- P = strrchr(FilePath,'\\');
- else if (syskey==syskey_all) {
- P = strrchr(FilePath,'/');
- if (!P) P = strrchr(FilePath,'\\');
- } else
- P = NULL;
- if (!P) return FilePath;
- else return P + 1;
-}
-
-cpstr GetFExt ( cpstr FilePath ) {
-pstr P;
- P = strchr ( GetFName(FilePath),'.');
- if (!P) return &(FilePath[strlen(FilePath)]);
- else return P;
-}
-
-cpstr ChangeExt ( pstr FilePath, cpstr newExt, int syskey ) {
-int i;
- i = strlen(FilePath)-1;
- if (syskey==syskey_unix)
- while ((i>0) && (FilePath[i]!='.') && (FilePath[i]!='/')) i--;
- else if (syskey==syskey_win)
- while ((i>0) && (FilePath[i]!='.') && (FilePath[i]!='\\')) i--;
- else if (syskey==syskey_all)
- while ((i>0) && (FilePath[i]!='.') &&
- (FilePath[i]!='/') && (FilePath[i]!='\\')) i--;
- if (FilePath[i]=='.') {
- FilePath[i+1] = char(0);
- strcat ( FilePath,newExt );
- } else {
- strcat ( FilePath,"." );
- strcat ( FilePath,newExt );
- }
- return FilePath;
-}
-
-Boolean FileExists ( cpstr FileName, PCFile f ) {
-PCFile g;
-Boolean B;
- if (FileName) {
- if (!f) g = new CFile();
- else g = f;
- g->assign ( FileName );
- B = g->exists();
- if (!f) delete g;
- return B;
- } else
- return False;
-}
-
-
-// ======================== CFile Class ========================
-
-#define ARCH_NONE 0
-#define ARCH_GZIP 1
-#define ARCH_COMPRESS 2
-#define ARCH_ENFORCE 3
-
-CFile::CFile ( word BufSize ) {
- Buf_Size = BufSize;
- BufLen = 0;
- BufInc = 1;
- EofFile = False;
- hFile = NULL;
- FName = NULL;
- BufCnt = 0;
- IOBuf = NULL;
- IOSuccess = True;
- TextMode = False;
- UniBin = False;
- StdIO = False;
- gzipIO = ARCH_NONE;
- memIO = False;
-}
-
-CFile::~CFile() {
- shut ();
- FreeBuffer();
-}
-
-void CFile::FreeBuffer () {
- if (IOBuf) {
- if (!memIO) delete[] IOBuf;
- IOBuf = NULL;
- }
- if (FName) {
- delete[] FName;
- FName = NULL;
- }
-}
-
-void CFile::assign ( cpstr FileName, Boolean Text, Boolean UniB,
- byte gzMode ) {
-pstr p;
-
- shut();
-
- FreeBuffer();
-
- CreateCopy ( FName,FileName );
- StdIO = (!strcmp(FName,"stdin" )) ||
- (!strcmp(FName,"stdout")) ||
- (!strcmp(FName,"stderr"));
-
- if (StdIO) TextMode = True;
- else TextMode = Text;
-
- UniBin = UniB;
-
- gzipMode = gzMode;
- gzipIO = ARCH_NONE;
- if ((gzipMode==GZM_ENFORCE) || (gzipMode==GZM_ENFORCE_GZIP))
- gzipIO = ARCH_GZIP;
- else if (gzipMode==GZM_ENFORCE_COMPRESS)
- gzipIO = ARCH_COMPRESS;
- else if (gzipMode==GZM_CHECK) {
- p = strrchr ( FName,'.' );
- if (p) {
- if (!strcmp(p,".gz")) gzipIO = ARCH_GZIP;
- else if (!strcmp(p,".Z")) gzipIO = ARCH_COMPRESS;
- }
- }
-
- memIO = False;
-
-}
-
-
-void CFile::assign ( word poolSize, word sizeInc, pstr filePool ) {
-
- shut ();
- FreeBuffer();
-
- IOBuf = (pstr)filePool;
- BufLen = poolSize;
- FLength = poolSize;
- BufInc = sizeInc;
- BufCnt = 0;
-
- memIO = True;
- gzipMode = GZM_NONE;
- gzipIO = ARCH_NONE;
-
-}
-
-void CFile::GetFilePool ( pstr & filePool, word & fileSize ) {
- if (memIO) {
- filePool = IOBuf;
- fileSize = FLength;
- IOBuf = NULL;
- BufLen = 0;
- BufCnt = 0;
- FLength = 0;
- } else {
- filePool = NULL;
- fileSize = 0;
- }
-}
-
-static pstr gzip_path = pstr("gzip ");
-static pstr ungzip_path = pstr("gzip -dc ");
-static pstr compress_path = pstr("compress ");
-static pstr uncompress_path = pstr("uncompress -c ");
-
-void SetGZIPPath ( pstr gzipPath, pstr ungzipPath ) {
- if (!gzipPath) gzip_path = pstr("gzip ");
- else gzip_path = gzipPath;
- if (!ungzipPath) ungzip_path = pstr("gzip -d ");
- else ungzip_path = ungzipPath;
-}
-
-void SetCompressPath ( pstr compressPath, pstr uncompressPath ) {
- if (!compressPath) compress_path = pstr("compress ");
- else compress_path = compressPath;
- if (!uncompressPath) uncompress_path = pstr("uncompress -c ");
- else uncompress_path = uncompressPath;
-}
-
-
-Boolean CFile::reset ( Boolean ReadOnly, int retry ) {
-#ifndef _MSC_VER
-pstr p;
-int i;
-#endif
-
- if (memIO) {
-
- shut();
- if (!IOBuf) return False;
- BufCnt = 0;
- IOSuccess = True;
-
- } else {
-
- if (!FName) return False;
- shut();
- BufLen = 0;
- BufCnt = 0;
-
- if (!strcmp(FName,"stdin")) {
-
- hFile = stdin;
- StdIO = True;
- TextMode = True;
- FLength = 1;
- EofFile = False;
- IOSuccess = True;
-
- } else {
-
- StdIO = False;
- if (gzipIO==ARCH_GZIP) {
-#ifndef _MSC_VER
- p = NULL;
- CreateConcat ( p,ungzip_path,FName );
- for (i=0;(i<=retry) && (!hFile);i++) {
- if (i>0) sleep ( 1 );
- hFile = popen ( p,"r" );
- }
- if (p) delete[] p;
-#endif
-
- } else if (gzipIO==ARCH_COMPRESS) {
-#ifndef _MSC_VER
- p = NULL;
- CreateConcat ( p,uncompress_path,FName );
- for (i=0;(i<=retry) && (!hFile);i++) {
- if (i>0) sleep ( 1 );
- hFile = popen ( p,"r" );
- }
- if (p) delete[] p;
-#endif
-
- } else {
-
-#ifndef _MSC_VER
- for (i=0;(i<=retry) && (!hFile);i++) {
- if (i>0) sleep ( 1 );
- if (TextMode) {
- if (ReadOnly) hFile = fopen ( FName,"rt" );
- else hFile = fopen ( FName,"r+t" );
- } else {
- if (ReadOnly) hFile = fopen ( FName,"rb" );
- else hFile = fopen ( FName,"r+b" );
- }
- }
-#endif
-
- }
-
- if (hFile) {
- if (gzipIO==ARCH_NONE) {
- fseek ( hFile,0L,SEEK_END );
- FLength = ftell ( hFile );
- fseek ( hFile,0L,SEEK_SET );
- EofFile = (FLength<=0);
- } else {
- FLength = 1;
- EofFile = False;
- }
- IOSuccess = True;
- } else {
- EofFile = True;
- IOSuccess = False;
- }
-
- }
-
- }
-
- return IOSuccess;
-
-}
-
-Boolean CFile::rewrite() {
-#ifndef _MSC_VER
-pstr p;
-#endif
-
- if (memIO) {
-
- shut();
- FreeBuffer();
- IOBuf = new char[BufLen];
- BufCnt = 0;
- FLength = 0;
- IOSuccess = True;;
-
- } else {
-
- if (!FName) return False;
- shut();
- BufLen = 0;
- BufCnt = 0;
-
- if (gzipIO==ARCH_GZIP) {
-#ifndef _MSC_VER
- p = NULL;
- CreateConcat ( p,gzip_path,pstr(" > "),FName );
- hFile = popen ( p,"w" );
- if (p) delete[] p;
-#else
- hFile = NULL;
-#endif
- StdIO = False;
- } else if (gzipIO==ARCH_COMPRESS) {
-#ifndef _MSC_VER
- p = NULL;
- CreateConcat ( p,compress_path,pstr(" > "),FName );
- hFile = popen ( p,"w" );
- if (p) delete[] p;
-#else
- hFile = NULL;
-#endif
- StdIO = False;
- } else if (!TextMode) {
- hFile = fopen ( FName,"w+b" );
- StdIO = False;
- } else if (!strcmp(FName,"stdout")) {
- hFile = stdout;
- StdIO = True;
- } else if (!strcmp(FName,"stderr")) {
- hFile = stderr;
- StdIO = True;
- } else {
- hFile = fopen ( FName,"w+t" );
- StdIO = False;
- }
-
- FLength = 0;
- IOSuccess = (hFile!=NULL);
-
- }
-
- return IOSuccess;
-
-}
-
-
-Boolean CFile::append() {
-#ifndef _MSC_VER
-pstr p;
-#endif
-
- if (memIO) {
-
- if (!IOBuf) {
- IOBuf = new char[BufLen];
- BufCnt = 0;
- }
- FLength = BufCnt;
- IOSuccess = True;
-
- } else {
-
- if (!FName) return False;
-
- shut();
- BufLen = 0;
- BufCnt = 0;
- if (gzipIO==ARCH_GZIP) {
-#ifndef _MSC_VER
- p = NULL;
- CreateConcat ( p,gzip_path,pstr(" >> "),FName );
- hFile = popen ( p,"w" );
- if (p) delete[] p;
-#else
- hFile = NULL;
-#endif
- StdIO = False;
- } else if (gzipIO==ARCH_COMPRESS) {
-#ifndef _MSC_VER
- p = NULL;
- CreateConcat ( p,compress_path,pstr(" >> "),FName );
- hFile = popen ( p,"w" );
- if (p) delete[] p;
-#else
- hFile = NULL;
-#endif
- StdIO = False;
- } else if (!TextMode) {
- hFile = fopen ( FName,"ab" );
- StdIO = False;
- } else if (!strcmp(FName,"stdout")) {
- hFile = stdout;
- StdIO = True;
- } else if (!strcmp(FName,"stderr")) {
- hFile = stderr;
- StdIO = True;
- } else {
- hFile = fopen ( FName,"at" );
- StdIO = False;
- }
-
- FLength = 0;
- IOSuccess = hFile!=NULL;
-
- }
-
- return IOSuccess;
-
-}
-
-Boolean CFile::erase() {
- if (!FName) return False;
- shut();
- if (!StdIO) {
- BufLen = 0;
- BufCnt = 0;
- if (FName)
- IOSuccess = (remove(FName)==0);
- FLength = 0;
- } else
- IOSuccess = True;
- return IOSuccess;
-}
-
-Boolean CFile::exists() {
-
- if (memIO) {
-
- IOSuccess = (IOBuf!=NULL);
-
- } else {
-
- if (!FName) return False;
- shut();
- if (!StdIO) {
- hFile = fopen ( FName,"r" );
- IOSuccess = (hFile!=NULL);
- BufLen = 0;
- BufCnt = 0;
- FLength = 0;
- if (hFile) fclose ( hFile );
- } else
- IOSuccess = True;
- hFile = NULL;
- }
-
- return IOSuccess;
-
-}
-
-Boolean CFile::parse ( cpstr FileName ) {
-UNUSED_ARGUMENT(FileName);
- return True;
-}
-
-Boolean CFile::rename ( cpstr NewFileName ) {
- if (!FName) return False;
- shut();
- if (!StdIO)
- IOSuccess = (::rename(FName,NewFileName)==0);
- if (IOSuccess) assign ( NewFileName,TextMode,UniBin,gzipMode );
- return IOSuccess;
-}
-
-long CFile::Position() {
-// do not use on text files
-
- if (memIO) return BufCnt;
-
- if (hFile==NULL) return 0L;
- return ftell ( hFile );
-
-}
-
-Boolean CFile::seek ( long Position ) {
-// do not use on text files
- if (memIO) {
- if (Position<=(long)BufLen) {
- BufCnt = Position;
- IOSuccess = True;
- } else
- IOSuccess = False;
- return IOSuccess;
- } else if (hFile==NULL)
- return False;
- else if (!StdIO) {
- IOSuccess = fseek(hFile,Position,SEEK_SET)==0;
- return IOSuccess;
- } else
- return True;
-}
-
-Boolean CFile::FileEnd() {
-
- if (memIO) return ((long)BufCnt>=FLength);
-
- if (TextMode) {
- if (EofFile || ((!hFile) && (!StdIO)))
- return True;
- if (feof(hFile)==0)
- return False;
- return True;
- }
-
- return EofFile && (BufLen==0);
-
-}
-
-void CFile::shut () {
-
- if (hFile!=NULL) {
- if (!StdIO) {
-#ifndef _MSC_VER
- if (gzipIO!=ARCH_NONE) pclose ( hFile );
- else fclose ( hFile );
-#else
- fclose ( hFile );
-#endif
- }
- hFile = NULL;
- }
-
-}
-
-Boolean CFile::isOpen() {
- if (memIO) return (IOBuf!=NULL);
- return (hFile!=NULL);
-}
-
-word CFile::ReadLine ( pstr Line, word MaxLen ) {
-word LCnt;
-int Done;
-Boolean HSuccess = IOSuccess;
-
- if (memIO) {
-
- LCnt = 0;
- while (((long)BufCnt<FLength) &&
- (LCnt<MaxLen-1) &&
- (IOBuf[BufCnt]!='\r') &&
- (IOBuf[BufCnt]!='\n') )
- Line[LCnt++] = IOBuf[BufCnt++];
- Line[LCnt] = char(0);
-
- while (((long)BufCnt<FLength) &&
- (IOBuf[BufCnt]!='\r') &&
- (IOBuf[BufCnt]!='\n') )
- BufCnt++;
-
- if ((long)BufCnt<FLength) {
- if (IOBuf[BufCnt]=='\r') {
- BufCnt++;
- if ((long)BufCnt<FLength) {
- if (IOBuf[BufCnt]=='\n') BufCnt++;
- }
- } else if (IOBuf[BufCnt]=='\n') {
- BufCnt++;
- if ((long)BufCnt<FLength) {
- if (IOBuf[BufCnt]=='\r') BufCnt++;
- }
- }
- }
-
- return LCnt;
-
- } else {
-
- if ((!hFile) && (!StdIO)) {
- Line[0] = char(0);
- EofFile = True;
- BufLen = 0;
- IOSuccess = False;
- return 0;
- }
- if (TextMode) {
- Line[0] = char(0);
- if (fgets(Line,MaxLen,hFile)) {
- LCnt = strlen(Line);
- while (LCnt>0) {
- if ((Line[LCnt-1]!='\n') &&
- (Line[LCnt-1]!='\r')) break;
- Line[LCnt-1] = char(0);
- LCnt--;
- }
- } else
- LCnt = 0;
- return LCnt;
- } else {
- if (IOBuf==NULL) {
- IOBuf = new char[Buf_Size];
- BufLen = ReadFile ( IOBuf,Buf_Size );
- IOSuccess = HSuccess;
- BufCnt = 0;
- }
- LCnt = 0;
- do {
- while ((BufCnt<BufLen) &&
- (LCnt<MaxLen-1) &&
- (IOBuf[BufCnt]!='\r') &&
- (IOBuf[BufCnt]!='\n') )
- Line[LCnt++] = IOBuf[BufCnt++];
- if (BufCnt>=BufLen) {
- HSuccess = IOSuccess;
- BufLen = ReadFile ( IOBuf,Buf_Size );
- IOSuccess = HSuccess;
- BufCnt = 0;
- }
- if (IOBuf[BufCnt]=='\r') Done = 1;
- else if (IOBuf[BufCnt]=='\n') Done = 2;
- else Done = 0;
- if (Done) BufCnt++;
- if (BufCnt>=BufLen) {
- HSuccess = IOSuccess;
- BufLen = ReadFile ( IOBuf,Buf_Size );
- IOSuccess = HSuccess;
- BufCnt = 0;
- }
- if (BufLen>0) {
- if (((Done==2) && (IOBuf[BufCnt]=='\r')) ||
- ((Done==1) && (IOBuf[BufCnt]=='\n')))
- BufCnt++;
- }
- } while ((!Done) && (LCnt<MaxLen-1) && (BufLen>0));
- Line[LCnt] = char(0);
- return LCnt;
- }
-
- }
-
-}
-
-word CFile::ReadNonBlankLine ( pstr S, word MaxLen ) {
-word i,j;
- do {
- j = ReadLine ( S,MaxLen );
- i = 0;
- while ((i<j) && (S[i]==' ')) i++;
- } while ((i>=j) && (!FileEnd()));
- if (i>=j) {
- S[0] = char(0);
- j = 0;
- }
- return j;
-}
-
-
-Boolean CFile::WriteLine ( cpstr Line ) {
- if ((!memIO) && TextMode) {
- if (hFile==NULL) return False;
- fputs ( Line,hFile );
-// return (fputs(NEWLINE,hFile)>=0);
- return (fputs("\n",hFile)>=0);
- } else {
- if (WriteFile(Line,strlen(Line)))
- return WriteFile ( (void *)NEWLINE,strlen(NEWLINE) );
- else return False;
- }
-}
-
-Boolean CFile::Write ( cpstr Line ) {
- if ((!memIO) && TextMode) {
- if (hFile==NULL) return False;
- return (fputs(Line,hFile)>=0);
- } else
- return WriteFile(Line,strlen(Line));
-}
-
-Boolean CFile::Write ( realtype V, int length ) {
-char N[50];
- sprintf ( N,"%-.*g",length,V );
- if ((!memIO) && TextMode) {
- if (hFile==NULL) return False;
- return (fputs(N,hFile)>=0);
- } else
- return WriteFile(N,strlen(N));
-}
-
-Boolean CFile::Write ( int iV, int length ) {
-char N[50];
- sprintf ( N,"%*i",length,iV );
- if ((!memIO) && TextMode) {
- if (hFile==NULL) return False;
- return (fputs(N,hFile)>=0);
- } else
- return WriteFile(N,strlen(N));
-}
-
-Boolean CFile::LF() {
- if ((!memIO) && TextMode) {
- if (hFile==NULL) return False;
-// return (fputs(NEWLINE,hFile)>=0);
- return (fputs("\n",hFile)>=0);
- } else
- return WriteFile ( (void *)NEWLINE,strlen(NEWLINE) );
-}
-
-Boolean CFile::WriteDataLine ( realtype X, realtype Y, int length ) {
- Write ( pstr(" ") );
- Write ( X,length );
- Write ( pstr(" ") );
- Write ( Y,length );
- return LF();
-}
-
-Boolean CFile::WriteParameter ( cpstr S, realtype X,
- int ParColumn, int length ) {
-int l=strlen(S);
- if ((!memIO) && TextMode) {
- fputs ( S,hFile );
- while (l<ParColumn) {
- fputs ( " ",hFile );
- l++;
- }
- } else {
- WriteFile ( S,l );
- while (l<ParColumn) {
- WriteFile ( (void *)" ",1 );
- l++;
- }
- }
- Write ( X,length );
- return LF();
-}
-
-Boolean CFile::WriteParameters ( cpstr S, int n_X, rvector X,
- int ParColumn, int length ) {
-int i;
-int l=strlen(S);
- if ((!memIO) && TextMode) {
- fputs ( S,hFile );
- while (l<ParColumn) {
- fputs ( " ",hFile );
- l++;
- }
- } else {
- WriteFile ( S,l );
- while (l<ParColumn) {
- WriteFile ( (void *)" ",1 );
- l++;
- }
- }
- for (i=0;i<n_X;i++) {
- Write ( X[i],length );
- if (i!=n_X-1) WriteFile ( (void *)", ",2 );
- }
- return LF();
-}
-
-Boolean CFile::ReadParameter ( pstr S, realtype & X,
- int ParColumn ) {
- ReadLine ( S );
- if ((int)strlen(S)>ParColumn) {
-// X = atof ( &(S[ParColumn]) );
- X = GetNumber ( &(S[ParColumn]) );
- return True;
- } else {
- X = 0.0;
- return False;
- }
-}
-
-Boolean CFile::ReadParameters ( pstr S, int & n_X, rvector X,
- int MaxLen, int ParColumn ) {
-pstr S1,S2;
- ReadLine ( S,MaxLen );
- if ((int)strlen(S)>ParColumn) {
- n_X = 0;
- S2 = &(S[ParColumn]);
- S1 = S2;
- while (*S1!=char(0)) {
- if (*S1==',') *S1 = ' ';
- S1++;
- }
- while (*S2!=char(0)) {
- S1 = S2;
- X[n_X] = strtod ( S1,&S2 );
- n_X++;
- while ((*S2!=char(0)) && (*S2==' ')) S2++;
- }
- return True;
- } else {
- n_X = 0;
- X[0] = 0.0;
- return False;
- }
-}
-
-Boolean CFile::ReadParameter ( pstr S, int & X,
- int ParColumn ) {
-realtype V;
- if (ReadParameter(S,V,ParColumn)) {
- X = mround(V);
- return True;
- } else {
- X = 0;
- return False;
- }
-}
-
-Boolean CFile::CreateWrite ( cpstr Line ) {
-wordUniBin wUB;
-word i;
- if (UniBin) {
- if (Line) {
- i = strlen(Line)+1;
- word2UniBin ( i,wUB );
- if (WriteFile(wUB,sizeof(wordUniBin)))
- return WriteFile ( Line,i );
- else return False;
- } else {
- i = 0;
- word2UniBin ( i,wUB );
- return WriteFile ( wUB,sizeof(wordUniBin) );
- }
- } else {
- if (Line) {
- i = strlen(Line)+1;
- if (WriteFile(&i,sizeof(i)))
- return WriteFile ( Line,i );
- else return False;
- } else {
- i = 0;
- return WriteFile ( &i,sizeof(i) );
- }
- }
-}
-
-#define _max_dyn_string_len 1073741824
-
-word CFile::CreateRead ( pstr & Line ) {
-wordUniBin wUB;
-word i;
-//unsigned short int i;
- if (Line) {
- delete[] Line;
- Line = NULL;
- }
- if (UniBin) {
- ReadFile ( wUB,sizeof(wordUniBin) );
- UniBin2word ( wUB,i );
- } else
- ReadFile ( &i,sizeof(i) );
- if ((i>0) && (i<_max_dyn_string_len)) {
- Line = new char[i];
- ReadFile ( Line,i );
- }
- return i;
-}
-
-Boolean CFile::WriteTerLine ( cpstr Line, Boolean longLine ) {
-wordUniBin wUB;
-word ll;
-byte sl;
-Boolean B;
- if (Line) ll = strlen(Line);
- else ll = 0;
- if (!longLine) {
- sl = byte(ll);
- B = WriteFile ( &sl,sizeof(sl) );
- } else if (UniBin) {
- word2UniBin ( ll,wUB );
- B = WriteFile ( wUB,sizeof(wordUniBin) );
- } else
- B = WriteFile ( &ll,sizeof(ll) );
- if (B && (ll>0)) B = WriteFile ( Line,ll );
- return B;
-}
-
-word CFile::ReadTerLine ( pstr Line, Boolean longLine ) {
-wordUniBin wUB;
-word ll;
-byte sl;
- if (!longLine) {
- ReadFile ( &sl,sizeof(sl) );
- ll = sl;
- } else if (UniBin) {
- ReadFile ( wUB,sizeof(wordUniBin) );
- UniBin2word ( wUB,ll );
- } else
- ReadFile ( &ll,sizeof(ll) );
- if (ll>0) ReadFile ( Line,ll );
- Line[ll] = char(0);
- return ll+1;
-}
-
-word CFile::ReadFile ( void * Buffer, word Count ) {
-word Cnt;
- if (memIO) {
- Cnt = WMin(Count,FLength-BufCnt);
- if (Cnt>0) {
- memcpy ( Buffer,&(IOBuf[BufCnt]),Cnt );
- BufCnt += Cnt;
- }
- IOSuccess = (Cnt==Count);
- EofFile = ((Cnt<Count) || ((long)BufCnt>=FLength));
- return Cnt;
- } else if (hFile) {
- Cnt = (word)fread ( Buffer,1,Count,hFile );
- EofFile = (Cnt<Count) ||
- ((gzipIO==ARCH_NONE) && (Position()==FLength));
- IOSuccess = (Cnt==Count);
- return Cnt;
- } else
- return 0;
-}
-
-Boolean CFile::WriteFile ( const void * Buffer, word Count ) {
-pstr IOB;
-word Cnt;
-long Pos;
-
- if (memIO) {
-
- Cnt = BufCnt + Count;
- if (Cnt>BufLen) {
- Cnt += BufInc;
- IOB = new char[Cnt];
- if (IOBuf) {
- memcpy ( IOB,IOBuf,BufCnt );
- delete[] IOBuf;
- }
- IOBuf = IOB;
- BufLen = Cnt;
- }
- memcpy ( &(IOBuf[BufCnt]),Buffer,Count );
- BufCnt += Count;
- FLength = BufCnt;
- IOSuccess = True;
-
- } else {
-
- if (hFile==NULL) return False;
- Cnt = (word)fwrite ( Buffer,1,Count,hFile );
- Pos = Position();
- if (Pos>FLength) FLength = Pos;
- IOSuccess = Cnt==Count;
-
- }
-
- return IOSuccess;
-
-}
-
-Boolean CFile::WriteReal ( realtype * V ) {
-realUniBin rUB;
- if (UniBin) {
- real2UniBin ( *V,rUB );
- return WriteFile ( rUB,sizeof(realUniBin) );
- } else
- return WriteFile ( V,sizeof(realtype) );
-}
-
-Boolean CFile::WriteFloat ( realtype * V ) {
-floatUniBin fUB;
-float fV;
- if (UniBin) {
- float2UniBin ( *V,fUB );
- return WriteFile ( fUB,sizeof(floatUniBin) );
- } else {
- fV = (float)*V;
- return WriteFile ( &fV,sizeof(float) );
- }
-}
-
-Boolean CFile::WriteInt ( int * I ) {
-intUniBin iUB;
- if (UniBin) {
- int2UniBin ( *I,iUB );
- return WriteFile ( iUB,sizeof(intUniBin) );
- } else
- return WriteFile ( I,sizeof(int) );
-}
-
-Boolean CFile::WriteShort ( short * S ) {
-shortUniBin sUB;
- if (UniBin) {
- short2UniBin ( *S,sUB );
- return WriteFile ( sUB,sizeof(shortUniBin) );
- } else
- return WriteFile ( S,sizeof(short) );
-}
-
-Boolean CFile::WriteLong ( long * L ) {
-longUniBin lUB;
- if (UniBin) {
- long2UniBin ( *L,lUB );
- return WriteFile ( lUB,sizeof(longUniBin) );
- } else
- return WriteFile ( L,sizeof(long) );
-}
-
-Boolean CFile::WriteBool ( Boolean * B ) {
-intUniBin iUB;
-int k;
- if (UniBin) {
- if (*B) k = 1;
- else k = 0;
- int2UniBin ( k,iUB );
- return WriteFile ( iUB,sizeof(intUniBin) );
- } else
- return WriteFile ( B,sizeof(Boolean) );
-}
-
-Boolean CFile::WriteByte ( byte * B ) {
- return WriteFile ( B,sizeof(byte) );
-}
-
-Boolean CFile::WriteWord ( word * W ) {
-wordUniBin wUB;
- if (UniBin) {
- word2UniBin ( *W,wUB );
- return WriteFile ( wUB,sizeof(wordUniBin) );
- } else
- return WriteFile ( W,sizeof(word) );
-}
-
-Boolean CFile::ReadReal ( realtype * V ) {
-realUniBin rUB;
- if (UniBin) {
- if (ReadFile(rUB,sizeof(realUniBin))==sizeof(realUniBin)) {
- UniBin2real ( rUB,*V );
- return True;
- } else
- return False;
- } else
- return ( ReadFile(V,sizeof(realtype))==sizeof(realtype) );
-}
-
-Boolean CFile::ReadFloat ( realtype * V ) {
-floatUniBin fUB;
-float fV;
- if (UniBin) {
- if (ReadFile(fUB,sizeof(floatUniBin))==sizeof(floatUniBin)) {
- UniBin2float ( fUB,*V );
- return True;
- }
- } else if (ReadFile(&fV,sizeof(float))==sizeof(float)) {
- *V = fV;
- return True;
- }
- return False;
-}
-
-Boolean CFile::ReadInt ( int * I ) {
-intUniBin iUB;
- if (UniBin) {
- if (ReadFile(iUB,sizeof(intUniBin))==sizeof(intUniBin)) {
- UniBin2int ( iUB,*I );
- return True;
- } else
- return False;
- } else
- return ( ReadFile(I,sizeof(int))==sizeof(int) );
-}
-
-Boolean CFile::ReadShort ( short * S ) {
-shortUniBin sUB;
- if (UniBin) {
- if (ReadFile(sUB,sizeof(shortUniBin))==sizeof(shortUniBin)) {
- UniBin2short ( sUB,*S );
- return True;
- } else
- return False;
- } else
- return ( ReadFile(S,sizeof(short))==sizeof(short) );
-}
-
-Boolean CFile::ReadLong ( long * L ) {
-longUniBin lUB;
- if (UniBin) {
- if (ReadFile(lUB,sizeof(longUniBin))==sizeof(longUniBin)) {
- UniBin2long ( lUB,*L );
- return True;
- } else
- return False;
- } else
- return ( ReadFile(L,sizeof(long))==sizeof(long) );
-}
-
-Boolean CFile::ReadBool ( Boolean * B ) {
-intUniBin iUB;
-int k;
- if (UniBin) {
- if (ReadFile(iUB,sizeof(intUniBin))==sizeof(intUniBin)) {
- UniBin2int ( iUB,k );
- *B = (k!=0);
- return True;
- } else
- return False;
- } else
- return ( ReadFile(B,sizeof(Boolean))==sizeof(Boolean) );
-}
-
-Boolean CFile::ReadByte ( byte * B ) {
- return ( ReadFile(B,sizeof(byte))==sizeof(byte) );
-}
-
-Boolean CFile::ReadWord ( word * W ) {
-wordUniBin wUB;
- if (UniBin) {
- if (ReadFile(wUB,sizeof(wordUniBin))==sizeof(wordUniBin)) {
- UniBin2word ( wUB,*W );
- return True;
- } else
- return False;
- } else
- return ( ReadFile(W,sizeof(word))==sizeof(word) );
-}
-
-Boolean CFile::AddReal ( realtype * V ) {
-realtype x;
- if (ReadReal(&x)) {
- *V += x;
- return True;
- }
- return False;
-}
-
-Boolean CFile::AddFloat ( realtype * V ) {
-realtype x;
- if (ReadFloat(&x)) {
- *V += x;
- return True;
- }
- return False;
-}
-
-
-Boolean CFile::AddInt ( int * I ) {
-int k;
- if (ReadInt(&k)) {
- *I += k;
- return True;
- }
- return False;
-}
-
-Boolean CFile::AddShort ( short * S ) {
-short k;
- if (ReadShort(&k)) {
- *S += k;
- return True;
- }
- return False;
-}
-
-Boolean CFile::AddLong ( long * L ) {
-long k;
- if (ReadLong(&k)) {
- *L += k;
- return True;
- }
- return False;
-}
-
-Boolean CFile::AddByte ( byte * B ) {
-byte k;
- if (ReadByte(&k)) {
- *B += k;
- return True;
- }
- return False;
-}
-
-Boolean CFile::AddWord ( word * W ) {
-word k;
- if (ReadWord(&k)) {
- *W += k;
- return True;
- }
- return False;
-}
-
-Boolean CFile::WriteVector ( rvector V, int len, int Shift ) {
-intUniBin iUB;
-realUniBin rUB;
-int i;
-int l = len;
- if (V==NULL) l = 0;
- if (UniBin) {
- int2UniBin ( l,iUB );
- WriteFile ( iUB,sizeof(intUniBin) );
- for (i=0;i<len;i++) {
- real2UniBin ( V[Shift+i],rUB );
- WriteFile ( rUB,sizeof(realUniBin) );
- }
- } else {
- WriteFile ( &l,sizeof(l) );
- if (l>0) WriteFile ( &(V[Shift]),sizeof(realtype)*l );
- }
- return IOSuccess;
-}
-
-Boolean CFile::WriteVector ( ivector iV, int len, int Shift ) {
-intUniBin iUB;
-int i;
-int l = len;
- if (iV==NULL) l = 0;
- if (UniBin) {
- int2UniBin ( l,iUB );
- WriteFile ( iUB,sizeof(intUniBin) );
- for (i=0;i<len;i++) {
- int2UniBin ( iV[Shift+i],iUB );
- WriteFile ( iUB,sizeof(intUniBin) );
- }
- } else {
- WriteFile ( &l,sizeof(l) );
- if (l>0) WriteFile ( &(iV[Shift]),sizeof(int)*l );
- }
- return IOSuccess;
-}
-
-Boolean CFile::WriteVector ( lvector lV, int len, int Shift ) {
-intUniBin iUB;
-longUniBin lUB;
-int i;
-int l = len;
- if (lV==NULL) l = 0;
- if (UniBin) {
- int2UniBin ( l,iUB );
- WriteFile ( iUB,sizeof(intUniBin) );
- for (i=0;i<len;i++) {
- long2UniBin ( lV[Shift+i],lUB );
- WriteFile ( lUB,sizeof(longUniBin) );
- }
- } else {
- WriteFile ( &l,sizeof(l) );
- if (l>0) WriteFile ( &(lV[Shift]),sizeof(long)*l );
- }
- return IOSuccess;
-}
-
-Boolean CFile::WriteVector ( bvector B, int len, int Shift ) {
-intUniBin iUB;
-int l = len;
- if (B==NULL) l = 0;
- if (UniBin) {
- int2UniBin ( l,iUB );
- WriteFile ( iUB,sizeof(intUniBin) );
- } else
- WriteFile ( &l,sizeof(l) );
- if (l>0) WriteFile ( &(B[Shift]),sizeof(byte)*l );
- return IOSuccess;
-}
-
-Boolean CFile::ReadVector ( rvector V, int maxlen, int Shift ) {
-intUniBin iUB;
-realUniBin rUB;
-int i,l,ll;
-realtype B;
- if (UniBin) {
- ReadFile ( iUB,sizeof(intUniBin) );
- UniBin2int ( iUB,l );
- if (IOSuccess && (l>0)) {
- ll = IMin(l,maxlen);
- if (V)
- for (i=0;i<=ll;i++) {
- ReadFile ( rUB,sizeof(realUniBin) );
- UniBin2real ( rUB,V[Shift+i] );
- }
- for (i=ll+1;i<=l;i++)
- ReadFile ( rUB,sizeof(realUniBin) );
- }
- } else {
- ReadFile ( &l,sizeof(l) );
- if (IOSuccess && (l>0)) {
- ll = IMin(l,maxlen);
- if (V) ReadFile ( &(V[Shift]),sizeof(realtype)*ll );
- for (i=ll+1;i<=l;i++) ReadFile ( &B,sizeof(B) );
- }
- }
- return IOSuccess;
-}
-
-Boolean CFile::ReadVector ( ivector iV, int maxlen, int Shift ) {
-intUniBin iUB;
-int i,l,ll,iB;
- if (UniBin) {
- ReadFile ( iUB,sizeof(intUniBin) );
- UniBin2int ( iUB,l );
- if (IOSuccess && (l>0)) {
- ll = IMin(l,maxlen);
- if (iV)
- for (i=0;i<=ll;i++) {
- ReadFile ( iUB,sizeof(intUniBin) );
- UniBin2int ( iUB,iV[Shift+i] );
- }
- for (i=ll+1;i<=l;i++)
- ReadFile ( iUB,sizeof(intUniBin) );
- }
- } else {
- ReadFile ( &l,sizeof(l) );
- if (IOSuccess && (l>0)) {
- ll = IMin(l,maxlen);
- if (iV) ReadFile ( &(iV[Shift]),sizeof(int)*ll );
- for (i=ll+1;i<=l;i++) ReadFile ( &iB,sizeof(iB) );
- }
- }
- return IOSuccess;
-}
-
-Boolean CFile::ReadVector ( lvector lV, int maxlen, int Shift ) {
-intUniBin iUB;
-longUniBin lUB;
-int i,l,ll;
-long lB;
- if (UniBin) {
- ReadFile ( iUB,sizeof(intUniBin) );
- UniBin2int ( iUB,l );
- if (IOSuccess && (l>0)) {
- ll = IMin(l,maxlen);
- if (lV)
- for (i=0;i<=ll;i++) {
- ReadFile ( lUB,sizeof(longUniBin) );
- UniBin2long ( lUB,lV[Shift+i] );
- }
- for (i=ll+1;i<=l;i++)
- ReadFile ( lUB,sizeof(longUniBin) );
- }
- } else {
- ReadFile ( &l,sizeof(l) );
- if (IOSuccess && (l>0)) {
- ll = IMin(l,maxlen);
- if (lV) ReadFile ( &(lV[Shift]),sizeof(long)*ll );
- for (i=ll+1;i<=l;i++) ReadFile ( &lB,sizeof(lB) );
- }
- }
- return IOSuccess;
-}
-
-Boolean CFile::ReadVector ( bvector B, int maxlen, int Shift ) {
-intUniBin iUB;
-int i,l,ll;
-byte t;
- if (UniBin) {
- ReadFile ( iUB,sizeof(intUniBin) );
- UniBin2int ( iUB,l );
- } else
- ReadFile ( &l,sizeof(l) );
- if (IOSuccess && (l>0)) {
- ll = IMin(l,maxlen);
- if (B) ReadFile ( &(B[Shift]),sizeof(byte)*ll );
- for (i=ll+1;i<=l;i++) ReadFile ( &t,sizeof(t) );
- }
- return IOSuccess;
-}
-
-Boolean CFile::CreateReadVector ( rvector & V, int & len,
- int Shift ) {
-intUniBin iUB;
-realUniBin rUB;
-int i;
-realtype B;
- FreeVectorMemory ( V,Shift );
- if (UniBin) {
- ReadFile ( iUB,sizeof(intUniBin) );
- UniBin2int ( iUB,len );
- if (IOSuccess && (len>0)) {
- GetVectorMemory ( V,len,Shift );
- if (V)
- for (i=0;i<len;i++) {
- ReadFile ( rUB,sizeof(realUniBin) );
- UniBin2real ( rUB,V[Shift+i] );
- }
- else for (i=0;i<len;i++)
- ReadFile ( rUB,sizeof(realUniBin) );
- }
- } else {
- ReadFile ( &len,sizeof(len) );
- if (IOSuccess && (len>0)) {
- GetVectorMemory ( V,len,Shift );
- if (V) ReadFile ( &(V[Shift]),sizeof(realtype)*len );
- else for (i=0;i<len;i++)
- ReadFile ( &B,sizeof(B) );
- }
- }
- return IOSuccess;
-}
-
-Boolean CFile::CreateReadVector ( rvector & V, int Shift ) {
-int len;
- return CreateReadVector ( V,len,Shift );
-}
-
-Boolean CFile::CreateReadVector ( ivector & iV, int & len,
- int Shift ) {
-intUniBin iUB;
-int i,iB;
- FreeVectorMemory ( iV,Shift );
- if (UniBin) {
- ReadFile ( iUB,sizeof(intUniBin) );
- UniBin2int ( iUB,len );
- if (IOSuccess && (len>0)) {
- GetVectorMemory ( iV,len,Shift );
- if (iV)
- for (i=0;i<len;i++) {
- ReadFile ( iUB,sizeof(intUniBin) );
- UniBin2int ( iUB,iV[Shift+i] );
- }
- else for (i=0;i<len;i++)
- ReadFile ( iUB,sizeof(intUniBin) );
- }
- } else {
- ReadFile ( &len,sizeof(len) );
- if (IOSuccess && (len>0)) {
- GetVectorMemory ( iV,len,Shift );
- if (iV) ReadFile ( &(iV[Shift]),sizeof(int)*len );
- else for (i=0;i<len;i++)
- ReadFile ( &iB,sizeof(iB) );
- }
- }
- return IOSuccess;
-}
-
-Boolean CFile::CreateReadVector ( ivector & iV, int Shift ) {
-int len;
- return CreateReadVector ( iV,len,Shift );
-}
-
-Boolean CFile::CreateReadVector ( lvector & lV, int & len,
- int Shift ) {
-intUniBin iUB;
-longUniBin lUB;
-int i;
-long lB;
- FreeVectorMemory ( lV,Shift );
- if (UniBin) {
- ReadFile ( iUB,sizeof(intUniBin) );
- UniBin2int ( iUB,len );
- if (IOSuccess && (len>0)) {
- GetVectorMemory ( lV,len,Shift );
- if (lV)
- for (i=0;i<len;i++) {
- ReadFile ( lUB,sizeof(intUniBin) );
- UniBin2long ( lUB,lV[Shift+i] );
- }
- else for (i=0;i<len;i++)
- ReadFile ( lUB,sizeof(longUniBin) );
- }
- } else {
- ReadFile ( &len,sizeof(len) );
- if (IOSuccess && (len>0)) {
- GetVectorMemory ( lV,len,Shift );
- if (lV) ReadFile ( &(lV[Shift]),sizeof(long)*len );
- else for (i=0;i<len;i++)
- ReadFile ( &lB,sizeof(lB) );
- }
- }
- return IOSuccess;
-}
-
-Boolean CFile::CreateReadVector ( lvector & lV, int Shift ) {
-int len;
- return CreateReadVector ( lV,len,Shift );
-}
-
-
-Boolean CFile::CreateReadVector ( bvector & B, int & len,
- int Shift ) {
-intUniBin iUB;
-int i;
-byte t;
- FreeVectorMemory ( B,Shift );
- if (UniBin) {
- ReadFile ( iUB,sizeof(intUniBin) );
- UniBin2int ( iUB,len );
- } else
- ReadFile ( &len,sizeof(len) );
- if (IOSuccess && (len>0)) {
- GetVectorMemory ( B,len,Shift );
- if (B) ReadFile ( &(B[Shift]),sizeof(byte)*len );
- else for (i=0;i<len;i++)
- ReadFile ( &t,sizeof(t) );
- }
- return IOSuccess;
-}
-
-Boolean CFile::CreateReadVector ( bvector & B, int Shift ) {
-int len;
- return CreateReadVector ( B,len,Shift );
-}
-
-
-Boolean CFile::WriteMatrix ( rmatrix & A, int N, int M,
- int ShiftN, int ShiftM ) {
-intUniBin iUB;
-realUniBin rUB;
-int i,j;
- if (UniBin) {
- if (!A) {
- i = 0;
- int2UniBin ( i,iUB );
- WriteFile ( iUB,sizeof(intUniBin) );
- } else {
- int2UniBin ( N,iUB );
- WriteFile ( iUB,sizeof(intUniBin) );
- int2UniBin ( M,iUB );
- WriteFile ( iUB,sizeof(intUniBin) );
- for (i=0;i<N;i++)
- for (j=0;j<M;j++) {
- real2UniBin ( A[ShiftN+i][ShiftM+j],rUB );
- WriteFile ( rUB,sizeof(realUniBin) );
- }
- }
- } else if (!A) {
- i = 0;
- WriteFile ( &i,sizeof(i) );
- } else {
- WriteFile ( &N,sizeof(N) );
- WriteFile ( &M,sizeof(M) );
- for (i=0;i<N;i++)
- WriteFile ( &(A[ShiftN][ShiftM]),sizeof(realtype)*M );
- }
- return IOSuccess;
-}
-
-Boolean CFile::CreateReadMatrix ( rmatrix & A, int ShiftN,
- int ShiftM ) {
-int N,M;
- return CreateReadMatrix ( A,N,M,ShiftN,ShiftM );
-}
-
-Boolean CFile::CreateReadMatrix ( rmatrix & A, int & N, int & M,
- int ShiftN, int ShiftM ) {
-intUniBin iUB;
-realUniBin rUB;
-int i,j;
- FreeMatrixMemory ( A,N,ShiftN,ShiftM );
- if (UniBin) {
- ReadFile ( iUB,sizeof(intUniBin) );
- UniBin2int ( iUB,N );
- if (IOSuccess && (N>0)) {
- ReadFile ( iUB,sizeof(intUniBin) );
- UniBin2int ( iUB,M );
- if (IOSuccess && (M>0)) {
- GetMatrixMemory ( A,N,M,ShiftN,ShiftM );
- for (i=0;i<N;i++)
- for (j=0;j<M;j++) {
- ReadFile ( rUB,sizeof(realUniBin) );
- UniBin2real ( rUB,A[ShiftN+i][ShiftM+j] );
- }
- }
- }
- } else {
- ReadFile ( &N,sizeof(N) );
- if (N>0) {
- ReadFile ( &M,sizeof(M) );
- if (M>0) {
- GetMatrixMemory ( A,N,M,ShiftN,ShiftM );
- for (i=0;i<N;i++)
- ReadFile ( &(A[ShiftN][ShiftM]),sizeof(realtype)*M );
- }
- }
- }
- return IOSuccess;
-}
-
-
-Boolean CFile::WriteColumns ( rvector X, rvector Y, rvector Z,
- int len, int Shift, int MLength ) {
-// WriteColumns writes data stored in X, Y and Z in the form
-// of columns, adding a blank line in the end. If Z (or Z and Y)
-// are set to NULL, then only X and Y (or only X) are written.
-// Shift corresponds to the begining of arrays' enumeration
-// X[Shift..Shift+len-1].
-int i,l;
- l = Shift+len;
- for (i=Shift;i<l;i++) {
- Write ( pstr(" ") );
- Write ( X[i],MLength );
- if (Y) {
- Write ( pstr(", ") );
- Write ( Y[i],MLength );
- }
- if (Z) {
- Write ( pstr(", ") );
- Write ( Z[i],MLength );
- }
- LF();
- }
- return LF();
-}
-
-Boolean CFile::WriteColumns ( rvector X, rvector Y,
- int len, int Shift, int MLength ) {
- return WriteColumns ( X,Y,NULL,len,Shift,MLength );
-}
-
-int CFile::ReadColumns ( int maxlen, rvector X, rvector Y, rvector Z,
- int xCol, int yCol, int zCol, int Shift ) {
-// ReadColumns reads data stored by WriteColumns. X, Y, and Z must
-// be allocated prior to call.
-// xCol, yCol and zCol specify the order number of columns
-// (starting from 0) to be read into X, Y and Z, correspondingly.
-// If zCol (or zCol and yCol) < 0 then Z (or Z and Y) are not read.
-// Shift corresponds to the begining of arrays' enumeration
-// X[Shift..Shift+len-1].
-// Returns number of lines read.
-int DataLen;
-char S[1025];
- DataLen = maxlen;
- _ReadColumns ( DataLen,S,sizeof(S),X,Y,Z,xCol,yCol,zCol,Shift );
- return DataLen;
-}
-
-int CFile::ReadColumns ( int maxlen, rvector X, rvector Y,
- int xCol, int yCol, int Shift ) {
- return ReadColumns ( maxlen,X,Y,NULL,xCol,yCol,-1,Shift );
-}
-
-
-int CFile::CreateReadColumns ( rvector & X, rvector & Y, rvector & Z,
- int xCol, int yCol, int zCol,
- int Shift ) {
-// ReadColumns reads data stored by WriteColumns. X, Y, and Z
-// must be set to NULL prior to call. They will be allocated
-// within the procedure.
-// xCol, yCol and zCol specify the order number of columns
-// (starting from 0) to be read into X, Y and Z, correspondingly.
-// If zCol (or zCol and yCol) < 0 then Z (or Z and Y) are not read.
-// Shift corresponds to the begining of arrays' enumeration
-// X[Shift..Shift+len-1].
-// Returns number of lines read, errors are reported by ErrorCode().
-int i,j,DataLen;
-char S[1025];
-Boolean Ok;
- DataLen = 0;
- ErrCode = 0;
- if (!FileEnd()) {
- i = 0;
- j = 1;
- // the loop terminates at first blank line
- while ((i<j) && (!FileEnd())) {
- j = ReadLine ( S,sizeof(S) );
- i = 0;
- // check for blank line
- while ((i<j) && (S[i]==' ')) i++;
- DataLen++;
- }
- if (i>=j) DataLen--;
- if (DataLen>0) {
- Ok = GetVectorMemory(X,DataLen,Shift);
- if (Ok && (yCol>=0))
- Ok = Ok && GetVectorMemory(Y,DataLen,Shift);
- if (Ok && (zCol>=0))
- Ok = Ok && GetVectorMemory(Z,DataLen,Shift);
- if (Ok) {
- reset();
- _ReadColumns ( DataLen,S,sizeof(S),X,Y,Z,xCol,yCol,
- zCol,Shift );
- } else ErrCode = FileError_NoMemory;
- } else ErrCode = FileError_NoDataFound;
- } else ErrCode = FileError_NoDataFound;
- return DataLen;
-}
-
-int CFile::CreateReadColumns ( rvector & X, rvector & Y,
- int xCol, int yCol, int Shift ) {
- return CreateReadColumns ( X,Y,X,xCol,yCol,-1,Shift );
-}
-
-void CFile::_ReadColumns ( int & DLen, pstr S, int SLen,
- rvector X, rvector Y, rvector Z,
- int xCol, int yCol, int zCol,
- int Shift ) {
-int i,is,j,k,m,n,cmax;
-char SV[256];
-realtype Res;
- ErrCode = 0;
- i = 0;
- cmax = IMax(zCol,IMax(xCol,yCol));
- while ((i<DLen) && (ErrCode==0)) {
- k = ReadLine ( S,SLen );
- RemoveDelimiters(S,k);
- j = 0;
- m = -1;
- n = 0;
- while ((m<cmax) && (ErrCode==0)) {
- do {
- PickOutNumber ( S,SV,k,j );
- if ((m<0) && (SV[0]==char(0)) && (j>=k)) {
- DLen = i;
- return;
- }
- m++;
- } while ((m!=xCol) && (m!=yCol) && (m!=zCol));
- if (SV[0]==char(0)) {
- if (n>0) ErrCode = FileError_NoColumn;
- else ErrCode = FileError_ShortData;
- } else {
- Res = GetNumber ( SV );
- if (ErrCode==0) {
- is = i+Shift;
- if (m==xCol) X[is] = Res;
- else if (m==yCol) Y[is] = Res;
- else Z[is] = Res;
- n++;
- }
- }
- }
- if ((ErrCode==0) && (n<2)) ErrCode = FileError_NoColumn;
- i++;
- }
- if ((ErrCode==FileError_ShortData) && (i>1)) {
- ErrCode = 0;
- DLen = i-1;
- }
- if (ErrCode!=0) ErrCode = FileError_BadData;
-}
-
-void RemoveDelimiters ( pstr S, int SLen ) {
-int j;
- for (j=0;j<SLen;j++)
- if ((S[j]==',') || (S[j]==';') ||
- (S[j]==':') || (S[j]==char(9)))
- S[j] = ' ';
-}
-
-void PickOutNumber ( cpstr S, pstr SV, int SLen, int & j ) {
-int l;
- l = 0;
- while ((j<SLen) && (S[j]==' ')) j++;
- if ((S[j]=='+') || (S[j]=='-')) SV[l++] = S[j++];
- if (S[j]=='.') SV[l++] = '0';
- while ((j<SLen) && (S[j]!=' ')) SV[l++] = S[j++];
- SV[l] = char(0);
-}
-
-realtype CFile::GetNumber ( cpstr S ) {
-char * endptr;
-realtype V;
- V = strtod ( S,&endptr );
- if ((*endptr!=' ') && (*endptr))
- ErrCode = FileError_BadData;
- return V;
-}
-
-cpstr FileError ( int ErrCode ) {
- switch (ErrCode) {
- case 0 : return "Ok";
- case FileError_NoMemory : return "Insufficient memory";
- case FileError_NoDataFound : return "No data found";
- case FileError_NoColumn : return "No column structure";
- case FileError_BadData : return "Incorrect data format";
- case FileError_WrongMemoryAllocation
- : return "Wrong Memory Allocation";
- default : return "Unknown I/O error";
- }
-}
-
diff --git a/mmdb/file_.h b/mmdb/file_.h
deleted file mode 100755
index c0fe978..0000000
--- a/mmdb/file_.h
+++ /dev/null
@@ -1,302 +0,0 @@
-// $Id: file_.h,v 1.23 2012/01/26 17:52:19 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 29.01.10 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : file_ <interface>
-// ~~~~~~~~~
-// **** Classes : CFile - file I/O Support.
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2010
-//
-// =================================================================
-//
-
-#ifndef __File__
-#define __File__
-
-#ifndef __STDIO_H
-#include <stdio.h>
-#endif
-
-#ifndef __MatType__
-#include "mattype_.h"
-#endif
-
-
-// ======================== CFile Class ========================
-
-#define MaxFileNameLength 512
-
-#define FM_Binary False
-#define FM_Text True
-
-#define GZM_NONE 0
-#define GZM_CHECK 1
-#define GZM_ENFORCE 2
-#define GZM_ENFORCE_GZIP 2
-#define GZM_ENFORCE_COMPRESS 3
-
-
-#define FileError_NoMemory 110
-#define FileError_ShortData 111
-#define FileError_NoDataFound 112
-#define FileError_NoColumn 113
-#define FileError_BadData 114
-#define FileError_WrongMemoryAllocation 115
-
-
-// =================== Auxilary Functions =========================
-
-#define syskey_unix 1
-#define syskey_win 2
-#define syskey_all 3
-
-extern cpstr GetFPath ( pstr FilePath, int syskey=syskey_unix );
-extern cpstr GetFName ( cpstr FilePath, int syskey=syskey_unix );
-extern cpstr GetFExt ( cpstr FilePath );
-extern cpstr ChangeExt ( pstr FilePath, cpstr newExt,
- int syskey=syskey_unix );
-extern cpstr FileError ( int ErrCode );
-extern void RemoveDelimiters ( pstr S, int SLen );
-extern void PickOutNumber ( cpstr S, pstr SV, int SLen, int & j );
-
-
-#ifdef _WIN32
-#define _dir_sep_c '\\'
-#define _dir_sep "\\"
-#else
-#define _dir_sep_c '/'
-#define _dir_sep "/"
-#endif
-
-
-// ========================= CFile ================================
-
-DefineClass(CFile)
-
-class CFile {
-
- public :
-
- CFile ( word BufSize=4096 );
- virtual ~CFile();
-
- // ---- control functions
- // FileName allows for "stdin", "stdout" and "stderr" as
- // for standard UNIX streams.
- void assign ( cpstr FileName,
- Boolean Text=False,
- Boolean UniB=False,
- byte gzMode=GZM_NONE );
- // assign for memory IO
- void assign ( word poolSize, word sizeInc, pstr filePool );
- void GetFilePool ( pstr & filePool, word & fileSize );
-
- pstr FileName () { return FName; }
- Boolean reset ( Boolean ReadOnly=False, int retry=0 );
- // = true if opened, each retry 1 sec sleep
- Boolean erase (); // = true if erased
- Boolean exists (); // = true if exists
- Boolean parse ( cpstr FileName ); // true if filled
- Boolean rename ( cpstr NewFileName ); // true if renamed
- Boolean rewrite (); // = true if opened
- Boolean append (); // = true if opened
- Boolean isOpen ();
- long Position ();
- long FileLength () { return FLength; }
- Boolean seek ( long Position );
- Boolean FileEnd ();
- Boolean Success () { return IOSuccess; }
- void SetSuccess () { IOSuccess = True; }
- void shut ();
-
- // ---- binary I/O
- word ReadFile ( void * Buffer, word Count );
- word CreateRead ( pstr & Line );
- word ReadTerLine ( pstr Line, Boolean longLine=False );
- Boolean WriteFile ( const void * Buffer, word Count );
- Boolean CreateWrite ( cpstr Line );
- Boolean WriteTerLine ( cpstr Line, Boolean longLine=False );
- // machine-dependent binary I/O
- Boolean WriteReal ( realtype * V );
- Boolean WriteFloat ( realtype * V );
- Boolean WriteInt ( int * I );
- Boolean WriteShort ( short * S );
- Boolean WriteLong ( long * L );
- Boolean WriteBool ( Boolean * B );
- Boolean WriteByte ( byte * B );
- Boolean WriteWord ( word * W );
- Boolean ReadReal ( realtype * V );
- Boolean ReadFloat ( realtype * V );
- Boolean ReadInt ( int * I );
- Boolean ReadShort ( short * S );
- Boolean ReadLong ( long * L );
- Boolean ReadBool ( Boolean * B );
- Boolean ReadByte ( byte * B );
- Boolean ReadWord ( word * B );
- Boolean AddReal ( realtype * V );
- Boolean AddFloat ( realtype * V );
- Boolean AddInt ( int * I );
- Boolean AddShort ( short * S );
- Boolean AddLong ( long * L );
- Boolean AddByte ( byte * B );
- Boolean AddWord ( word * B );
- // complex data binary I/O
- Boolean WriteVector ( rvector V, int len, int Shift );
- Boolean WriteVector ( ivector iV, int len, int Shift );
- Boolean WriteVector ( lvector lV, int len, int Shift );
- Boolean WriteVector ( bvector B, int len, int Shift );
- Boolean ReadVector ( rvector V, int maxlen, int Shift );
- Boolean ReadVector ( ivector iV, int maxlen, int Shift );
- Boolean ReadVector ( lvector lV, int maxlen, int Shift );
- Boolean ReadVector ( bvector B, int maxlen, int Shift );
- Boolean CreateReadVector ( rvector & V, int & len, int Shift );
- Boolean CreateReadVector ( ivector & iV, int & len, int Shift );
- Boolean CreateReadVector ( lvector & lV, int & len, int Shift );
- Boolean CreateReadVector ( bvector & B, int & len, int Shift );
- Boolean CreateReadVector ( rvector & V, int Shift );
- Boolean CreateReadVector ( ivector & iV, int Shift );
- Boolean CreateReadVector ( lvector & lV, int Shift );
- Boolean CreateReadVector ( bvector & B, int Shift );
- Boolean WriteMatrix ( rmatrix & A, int N, int M,
- int ShiftN, int ShiftM );
- Boolean CreateReadMatrix ( rmatrix & A, int ShiftN, int ShiftM );
- Boolean CreateReadMatrix ( rmatrix & A, int & N, int & M,
- int ShiftN, int ShiftM );
-
- /// ---- text I/O
- Boolean Write ( cpstr Line ); //!< writes without LF
- Boolean Write ( realtype V, int length=10 ); //!< w/o LF
- Boolean Write ( int iV, int length=5 ); //!< w/o LF
- Boolean WriteLine ( cpstr Line ); //!< writes and adds LF
- Boolean LF (); //!< just adds LF
- word ReadLine ( pstr Line, word MaxLen=255 );
- word ReadNonBlankLine ( pstr S, word MaxLen=255 );
-
- /// complex data text I/O
-
- // writes with spaces and adds LF
- Boolean WriteDataLine ( realtype X, realtype Y,
- int length=10 );
-
- Boolean WriteParameter ( cpstr S, realtype X, // writes parameter
- int ParColumn=40, // name S and value X
- int length=10 ); // at column ParColumn
- // and adds LF.
-
- Boolean WriteParameters ( cpstr S, int n_X, // writes parameter
- rvector X, // name S and n_X values
- int ParColumn=40, // X[0..n_X-1] at col
- int length=10 ); // ParColumn, ads LF.
-
- Boolean ReadParameter ( pstr S, realtype & X, // reads parameter
- int ParColumn=40 ); // name S and val X
- Boolean ReadParameter ( pstr S, int & X,
- int ParColumn=40 );
-
- Boolean ReadParameters ( pstr S, int & n_X, // reads parameter
- rvector X, // name S, counts the
- int MaxLen=255, // of values n_X and
- int ParColumn=40 ); // reads X[0..n_X-1].
- // MaxLen gives sizeof(S)
-
- // WriteColumns writes data stored in X, Y and Z in the form
- // of columns, adding a blank line in the end. If Z (or Z and Y)
- // are set to NULL, then only X and Y (or only X) are written.
- // Shift corresponds to the begining of arrays' enumeration
- // X[Shift..Shift+len-1].
- Boolean WriteColumns ( rvector X, rvector Y, rvector Z,
- int len, int Shift, int MLength );
- Boolean WriteColumns ( rvector X, rvector Y,
- int len, int Shift, int MLength );
-
- // ReadColumns reads data stored by WriteColumns. X, Y, and Z
- // must be allocated prior to call.
- // xCol, yCol and zCol specify the order number of columns
- // (starting from 0) to be read into X, Y and Z, correspondingly.
- // If zCol (or zCol and yCol) < 0 then Z (or Z and Y) are not read.
- // Shift corresponds to the begining of arrays' enumeration
- // X[Shift..Shift+len-1].
- // Returns number of lines read.
- int ReadColumns ( int maxlen, rvector X, rvector Y, rvector Z,
- int xCol, int yCol, int zCol, int Shift );
- int ReadColumns ( int maxlen, rvector X, rvector Y,
- int xCol, int yCol, int Shift );
-
- // CreateReadColumns reads data stored by WriteColumns. X, Y,
- // and Z must be set to NULL prior to call. They will be allocated
- // within the procedure.
- // xCol, yCol and zCol specify the order number of columns
- // (starting from 0) to be read into X, Y and Z, correspondingly.
- // If zCol (or zCol and yCol) < 0 then Z (or Z and Y) are not read.
- // Shift corresponds to the begining of arrays' enumeration
- // X[Shift..Shift+len-1].
- // Returns number of lines read, errors are reported by
- // ErrorCode().
- int CreateReadColumns ( rvector & X, rvector & Y, rvector & Z,
- int xCol, int yCol, int zCol, int Shift );
- int CreateReadColumns ( rvector & X, rvector & Y,
- int xCol, int yCol, int Shift );
-
- // ---- miscellaneous
- realtype GetNumber ( cpstr S );
- FILE * GetHandle () { return hFile; }
-
- protected :
- word Buf_Size;
- Boolean TextMode,UniBin;
- byte gzipMode;
- pstr IOBuf;
- word BufCnt,BufLen,BufInc;
- FILE * hFile;
- Boolean EofFile;
- pstr FName;
- long FLength;
- Boolean IOSuccess;
- int ErrCode;
-
- void FreeBuffer ();
- void _ReadColumns ( int & DLen, pstr S, int SLen,
- rvector X, rvector Y, rvector Z,
- int xCol, int yCol, int zCol, int Shift );
-
- private :
- int gzipIO;
- Boolean StdIO,memIO;
-
-};
-
-
-extern void SetGZIPPath ( pstr gzipPath, pstr ungzipPath );
-extern void SetCompressPath ( pstr compressPath, pstr uncompressPath );
-
-extern Boolean FileExists ( cpstr FileName, PCFile f=NULL );
-
-
-#endif
-
diff --git a/mmdb/linalg_.cpp b/mmdb/linalg_.cpp
deleted file mode 100755
index 26012d1..0000000
--- a/mmdb/linalg_.cpp
+++ /dev/null
@@ -1,987 +0,0 @@
-// $Id: linalg_.cpp,v 1.21 2012/01/26 17:52:19 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 27.06.01 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : linalg_ <implementation>
-// ~~~~~~~~~
-// **** Project : MMDB ( MacroMolecular Data Base )
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-#include <stdio.h>
-
-#ifndef __MATH_H
-#include <math.h>
-#endif
-
-#ifndef __LinAlg__
-#include "linalg_.h"
-#endif
-
-
-// ========================== Jacobi =============================
-
-
-void Jacobi ( int N, // dimension of the matrix
- rmatrix A, // matrix to diagonalize; the lower
- // triangle, except the diagonal,
- // will remain unchanged
- rmatrix T, // eigenvectors placed as columns
- rvector Eigen, // vector of eigenvalues, orderd
- // by increasing
- rvector Aik, // working array
- int & Signal // 0 <=> Ok, ItMax <=> iteration limit
- // exchausted.
- ) {
-// Diagonalization of symmetric matrices by the method of Jacobi.
-// Key variables:
-// ItMax - the maximum available number of iterations
-// Eps1 - is used in SNA and CSA calculations
-// Eps2 - is the level of the elimination of the
-// non-diagonal matrix elements
-// Eps3 - the criterion to stop the iterations.
-// The iterations stop if (1-Sigma1/Sigma2)<=Eps3
-// where Sigma1 is the dekart norm of the eigenvalues
-// at the preceding iteration and Sigma2 is
-// the same for the current iteration.
-
-realtype Eps1,Eps2,Eps3;
-realtype Sigma1,Sigma2,OffDsq, SPQ,CSA,SNA,Q,P, HoldIK,HoldKI;
-int ItMax;
-int i,j,k,Iter;
-
- Eps1 = 6.0e-9;
- Eps2 = 9.0e-12;
- Eps3 = 1.0e-8;
- ItMax = 9999;
-
- Signal = 0;
-
- if (N<=1) {
- T[1][1] = 1.0;
- Eigen[1] = A[1][1];
- return;
- }
-
- for (i=1;i<=N;i++) {
- for (j=1;j<=N;j++)
- T[i][j] = 0.0;
- T[i][i] = 1.0;
- Eigen[i] = A[i][i];
- }
-
- Sigma1 = 0.0;
- OffDsq = 0.0;
-
- // Sigma1 is the Dekart measure of the diagonal elements
- // OffDsq is the Dekart measure of the non-diagonal elements
-
- for (i=1;i<=N;i++) {
- Sigma1 += A[i][i]*A[i][i];
- if (i<N)
- for (j=i+1;j<=N;j++)
- OffDsq += A[i][j]*A[i][j];
- }
-
- if (OffDsq<Eps2*Eps2) return;
-
- // S = OffDsq*2.0+Sigma1;
- Iter = 1;
- HoldIK = 1.0;
-
- while ((Iter<=ItMax) && (HoldIK>Eps3)) {
-
- for (i=1;i<N;i++)
- for (j=i+1;j<=N;j++) {
-
- Q = fabs(A[i][i]-A[j][j]);
-
- if ((Q<=Eps1) || (fabs(A[i][j])>Eps2)) {
- if (Q>Eps1) {
- P = 2.0*A[i][j]*(Q/(A[i][i]-A[j][j]));
- SPQ = sqrt(P*P+Q*Q);
- CSA = sqrt((1.0+Q/SPQ)/2.0);
- SNA = P/(SPQ*CSA*2.0);
- } else {
- CSA = sqrt(0.5);
- SNA = CSA;
- }
- for (k=1;k<=N;k++) {
- HoldKI = T[k][i];
- T[k][i] = HoldKI*CSA + T[k][j]*SNA;
- T[k][j] = HoldKI*SNA - T[k][j]*CSA;
- }
-
- for (k=i;k<=N;k++)
- if (k<=j) {
- Aik[k] = A[i][k];
- A[i][k] = CSA*Aik[k] + SNA*A[k][j];
- if (k==j) {
- A[j][k] = SNA*Aik[k] - CSA*A[j][k];
- Aik[j] = SNA*Aik[i] - CSA*Aik[j];
- }
- } else {
- HoldIK = A[i][k];
- A[i][k] = CSA*HoldIK + SNA*A[j][k];
- A[j][k] = SNA*HoldIK - CSA*A[j][k];
- }
-
- for (k=1;k<=j;k++)
- if (k>i)
- A[k][j] = SNA*Aik[k] - CSA*A[k][j];
- else {
- HoldKI = A[k][i];
- A[k][i] = CSA*HoldKI + SNA*A[k][j];
- A[k][j] = SNA*HoldKI - CSA*A[k][j];
- }
-
- }
-
- }
-
- Sigma2 = 0.0;
- for (i=1;i<=N;i++) {
- Eigen[i] = A[i][i];
- Sigma2 += Eigen[i]*Eigen[i];
- }
-
- HoldIK = fabs(1.0-Sigma1/Sigma2);
- Sigma1 = Sigma2;
- Iter++;
-
- }
-
- if (Iter>ItMax) Signal = ItMax;
-
- for (i=1;i<=N;i++) {
- k = i;
- for (j=i;j<=N;j++)
- if (Eigen[j]<Eigen[k]) k = j;
- if (k!=i) {
- P = Eigen[k];
- Eigen[k] = Eigen[i];
- Eigen[i] = P;
- for (j=1;j<=N;j++) {
- P = T[j][k];
- T[j][k] = T[j][i];
- T[j][i] = P;
- }
- }
- }
-
-
-}
-
-
-// -----------------------------------------------------
-
-void PbCholDecomp ( int N,
- rvector HDiag,
- realtype MaxOff,
- realtype MachEps,
- rmatrix L,
- realtype & MaxAdd ) {
-
-// A5.5.2 : Perturbed Cholesky Decomposition
-// Part of the modular software system from
-// the appendix of the book "Numerical Methods for Unconstrained
-// Optimization and Nonlinear Equations" by Dennis & Schnabel 1983.
-
-int i,j,k;
-realtype MinL,MinL2,S,MinLjj,MaxOffl, BB;
-
- MaxOffl = MaxOff;
- MinL = sqrt(sqrt(MachEps))*MaxOffl;
- if (MaxOffl==0.0) {
- for (i=1;i<=N;i++) {
- BB = fabs(HDiag[i]);
- if (BB>MaxOffl) MaxOffl = BB;
- }
- MaxOffl = sqrt(MaxOffl);
- }
-
- MinL2 = sqrt(MachEps)*MaxOffl;
- MaxAdd = 0.0;
- for (j=1;j<=N;j++) {
- S = 0.0;
- if (j>1)
- for (i=1;i<j;i++)
- S += L[j][i]*L[j][i];
- L[j][j] = HDiag[j] - S;
- MinLjj = 0.0;
- if (j<N)
- for (i=j+1;i<=N;i++) {
- S = 0.0;
- if (j>1)
- for (k=1;k<j;k++)
- S += L[i][k]*L[j][k];
- L[i][j] = L[j][i] - S;
- BB = fabs(L[i][j]);
- if (BB>MinLjj) MinLjj = BB;
- }
- BB = MinLjj/MaxOffl;
- if (BB>MinL) MinLjj = BB;
- else MinLjj = MinL;
- if (L[j][j]>MinLjj*MinLjj) L[j][j] = sqrt(L[j][j]);
- else {
- if (MinL2>MinLjj) MinLjj = MinL2;
- BB = MinLjj*MinLjj-L[j][j];
- if (BB>MaxAdd) MaxAdd = BB;
- L[j][j] = MinLjj;
- }
- if (j<N)
- for (i=j+1;i<=N;i++)
- L[i][j] /= L[j][j];
- }
-
-}
-
-
-
-// -----------------------------------------------------
-
-void LSolve ( int N, rmatrix L, rvector B, rvector Y ) {
-// A3.2.3a : Cholesky's L - Solution of
-// L*Y = B ( given B )
-int i,j;
- Y[1] = B[1]/L[1][1];
- if (N>1)
- for (i=2;i<=N;i++) {
- Y[i] = B[i];
- for (j=1;j<i;j++)
- Y[i] -= L[i][j]*Y[j];
- Y[i] /= L[i][i];
- }
-}
-
-
-// -----------------------------------------------------
-
-void LTSolve ( int N, rmatrix L, rvector Y, rvector X ) {
-// A3.2.3b : Cholesky's LT - Solution of
-// LT*X = Y ( given Y )
-int i,j;
- X[N] = Y[N]/L[N][N];
- if (N>1)
- for (i=N-1;i>=1;i--) {
- X[i] = Y[i];
- for (j=i+1;j<=N;j++)
- X[i] -= L[j][i]*X[j];
- X[i] /= L[i][i];
- }
-}
-
-
-// -----------------------------------------------------
-
-void ChSolve ( int N, rmatrix L, rvector G, rvector S ) {
-// A3.2.3 : Solution of the equation L*LT*S = G
-// by the Cholesky's method
-//int i;
- LSolve ( N,L,G,S );
- LTSolve ( N,L,S,S );
-// for (i=1;i<=N;i++)
-// S[i] = -S[i];
-}
-
-
-
-// ----------------------------------------------------
-
-void FastInverse ( int N, rmatrix A, ivector J0,
-//#D realtype & Det,
- int & Signal ) {
-//
-// 17.01.91 <-- Last Date of Modification.
-// ----------------------------
-//
-// ================================================
-//
-// Fast Inversion of the matrix A
-// by the method of GAUSS - JOIRDAN .
-//
-// ------------------------------------------------
-//
-// Input parameters are :
-//
-// N - dimension of the matrix
-// A - the matrix [1..N][1..N] to be inverted.
-//
-// ------------------------------------------------
-//
-// J0 - integer vector [1..N] for temporal storage
-//
-//
-// ------------------------------------------------
-//
-// Output parameters are :
-//
-// A - the inverted matrix
-// Signal - the error key :
-// = 0 <=> O'K
-// else
-// degeneration was found, and
-// the rang of matrix is Signal-1.
-//
-// Variable Det may return the determinant
-// of matrix A. To obtain it, remove all comments
-// of form //#D .
-//
-// ------------------------------------------------
-//
-// Key Variables are :
-//
-// Eps - is the level for the degeneration
-// detection. Keep in mind, that
-// this routine does not norm the
-// matrix given, and thus Eps1
-// is the ABSOLUTE value.
-//
-// ================================================
-//
-
-realtype Eps = 1.0e-16;
-
-int i,j,k,i0;
-realtype A0,B;
-rvector Ai,Ai0;
-
- Signal = 0;
- if (N<=1) {
- if (fabs(A[1][1])<Eps) {
- Signal = 1;
- return;
- }
- A[1][1] = 1.0/A[1][1];
-//#D Det = A[1][1];
- return;
- }
-
- if (N==2) {
- A0 = A[1][1];
- B = A0*A[2][2] - A[1][2]*A[2][1];
-//#D Det = B;
- if (fabs(B)<Eps) {
- Signal = 1;
- return;
- }
- A[1][1] = A[2][2]/B;
- A[2][2] = A0/B;
- B = -B;
- A[1][2] /= B;
- A[2][1] /= B;
- return;
- }
-
- for (i=1;i<=N;i++) {
- // 1. Finding of the leading element ( in A0 );
- // i0 is the number of the leading string
- A0 = 0.0;
- i0 = 0;
- for (j=i;j<=N;j++) {
- if (fabs(A[j][i])>A0) {
- A0 = fabs(A[j][i]);
- i0 = j;
- }
- }
- if (A0<Eps) {
- Signal = i; // Degeneration is found here
- return;
- }
-
- // 2. Swapping the string
- J0[i] = i0;
- B = 1.0/A[i0][i];
- Ai = A[i0];
- Ai0 = A[i];
- A[i] = Ai;
- A[i0] = Ai0;
- for (j=1;j<=N;j++)
- Ai[j] = Ai[j]*B;
- Ai[i] = B;
-
- // 3. Substracting the strings
- for (j=1;j<=N;j++)
- if (i!=j) {
- Ai0 = A[j];
- B = Ai0[i];
- Ai0[i] = 0.0;
- for (k=1;k<=N;k++)
- Ai0[k] = Ai0[k] - B*Ai[k];
- }
-
-//#D Det = Det/Ai[i];
-
- }
-
- // 4. Back Swapping the columns
- for (i=N;i>=1;i--) {
- j = J0[i];
- if (j!=i) {
-//#D Det = -Det;
- for (k=1;k<=N;k++) {
- B = A[k][i];
- A[k][i] = A[k][j];
- A[k][j] = B;
- }
- }
- }
-
- return;
-
-} // End of the procedure FastInverse
-
-
-
-
-// ----------------------------------------------------
-
-realtype Sign ( realtype A, realtype B ) {
- if (B>=0.0) return A;
- else return -A;
-}
-
-realtype SrX2Y2 ( realtype X, realtype Y ) {
-realtype Ax,Ay;
- Ax = fabs(X);
- Ay = fabs(Y);
- if (Ay>Ax) return Ay*sqrt((X*X)/(Y*Y)+1.0);
- if (Ay==Ax) return Ax*sqrt(2.0);
- return Ax*sqrt((Y*Y)/(X*X)+1.0);
-}
-
-
-// ----------------------------------------------------
-
-void SVD ( int NA, int M, int N,
- rmatrix A, rmatrix U, rmatrix V,
- rvector W, rvector RV1,
- Boolean MatU, Boolean MatV,
- int & RetCode ) {
-//
-// 13.12.01 <-- Last Modification Date
-// ------------------------
-//
-// ================================================
-//
-// The Singular Value Decomposition
-// of the matrix A by the algorithm from
-// G.Forsait, M.Malkolm, K.Mouler. Numerical
-// methods of mathematical calculations
-// M., Mir, 1980.
-//
-// Matrix A is represented as
-//
-// A = U * W * VT
-//
-// ------------------------------------------------
-//
-// All dimensions are indexed from 1 on.
-//
-// ------------------------------------------------
-//
-// Input parameters:
-//
-// NA - number of lines in A. NA may be
-// equal to M or N only. If NA=M
-// then usual SVD will be made. If MA=N
-// then matrix A is transposed before
-// the decomposition, and the meaning of
-// output parameters U and V is
-// swapped (U accepts VT and VT accepts U).
-// In other words, matrix A has physical
-// dimension of M x N , same as U and V;
-// however the logical dimension of it
-// remains that of N x M .
-// M - number of lines in U
-// N - number of columns in U,V and length
-// of W,RV1 . Always provide M >= N !
-// A - matrix [1..M][1..N] or [1..N][1..M]
-// to be decomposed. The matrix does not
-// change, and it may coincide with U or
-// V, if NA=M (in which case A does change)
-// MatU - compute U , if set True
-// MatV - compute V , if set True
-// RV1 - temporary array [1..N].
-// U - should be always supplied as an array of
-// [1..M][1..N], M>=N .
-// V - should be suuplied as an array of
-// [1..N][1..N] if MatV is True .
-//
-// ------------------------------------------------
-//
-// Output parameters are :
-//
-// W - N non-ordered singular values,
-// if RetCode=0. If RetCode<>0, the
-// RetCode+1 ... N -th values are still
-// valid
-// U - matrix of right singular vectors
-// (arranged in columns), corresponding
-// to the singular values in W, if
-// RetCode=0 and MatU is True. If MatU
-// is False, U is still used as a
-// temporary array. If RetCode<>0 then
-// the RetCode+1 ... N -th vectors
-// are valid
-// V - matrix of left singular vectors
-// (arranged in columns), corresponding
-// to the singular values in W, if
-// RetCode=0 and MatV is True. If MatV
-// is False, V is not used and may be set
-// to NULL. If RetCode<>0 then the
-// RetCode+1 ... N -th vectors are valid
-// RetCode - the error key :
-// = 0 <=> O'K
-// else
-// = k, if the k-th singular value
-// was not computed after 30 iterations.
-//
-// ------------------------------------------------
-//
-// Key Variables are :
-//
-// ItnLimit - the limit for iterations
-//
-// This routine does not use any machine-dependent
-// constants.
-//
-// ================================================
-//
-//
-int ItnLimit=300;
-int i,j,k,l,i1,k1,l1,its,mn,ExitKey;
-realtype C,G,F,X,S,H,Y,Z,Scale,ANorm,GG;
-
- l1 = 0; // this is to keep compiler happy
- RetCode = 0;
-
- if (U!=A) {
- if (NA==M)
- for (i=1;i<=M;i++)
- for (j=1;j<=N;j++)
- U[i][j] = A[i][j];
- else
- for (i=1;i<=M;i++)
- for (j=1;j<=N;j++)
- U[i][j] = A[j][i];
- }
-
- G = 0.0;
- Scale = 0.0;
- ANorm = 0.0;
-
- for (i=1;i<=N;i++) {
- l = i+1;
- RV1[i] = Scale*G;
- G = 0.0;
- S = 0.0;
- Scale = 0.0;
- if (i<=M) {
- for (k=i;k<=M;k++)
- Scale += fabs(U[k][i]);
- if (Scale!=0.0) {
- for (k=i;k<=M;k++) {
- U[k][i] /= Scale;
- S += U[k][i]*U[k][i];
- }
- F = U[i][i];
- G = -Sign(sqrt(S),F);
- H = F*G-S;
- U[i][i] = F-G;
- if (i!=N)
- for (j=l;j<=N;j++) {
- S = 0.0;
- for (k=i;k<=M;k++)
- S += U[k][i]*U[k][j];
- F = S/H;
- for (k=i;k<=M;k++)
- U[k][j] += F*U[k][i];
- }
- for (k=i;k<=M;k++)
- U[k][i] *= Scale;
- }
- }
-
- W[i] = Scale*G;
- G = 0.0;
- S = 0.0;
- Scale = 0.0;
-
- if ((i<=M) && (i!=N)) {
- for (k=l;k<=N;k++)
- Scale += fabs(U[i][k]);
- if (Scale!=0.0) {
- for (k=l;k<=N;k++) {
- U[i][k] /= Scale;
- S += U[i][k]*U[i][k];
- }
- F = U[i][l];
- G = -Sign(sqrt(S),F);
- H = F*G-S;
- U[i][l] = F-G;
- for (k=l;k<=N;k++)
- RV1[k] = U[i][k]/H;
- if (i!=M)
- for (j=l;j<=M;j++) {
- S = 0.0;
- for (k=l;k<=N;k++)
- S += U[j][k]*U[i][k];
- for (k=l;k<=N;k++)
- U[j][k] += S*RV1[k];
- }
- for (k=l;k<=N;k++)
- U[i][k] *= Scale;
- }
- }
-
- ANorm = RMax( ANorm,fabs(W[i])+fabs(RV1[i]) );
-
- }
-
- // Accumulation of the right-hand transformations
-
- if (MatV)
- for (i=N;i>=1;i--) {
- if (i!=N) {
- if (G!=0.0) {
- for (j=l;j<=N;j++)
- V[j][i] = (U[i][j]/U[i][l]) / G;
- for (j=l;j<=N;j++) {
- S = 0.0;
- for (k=l;k<=N;k++)
- S += U[i][k]*V[k][j];
- for (k=l;k<=N;k++)
- V[k][j] += S*V[k][i];
- }
- }
- for (j=l;j<=N;j++) {
- V[i][j] = 0.0;
- V[j][i] = 0.0;
- }
- }
-
- V[i][i] = 1.0;
- G = RV1[i];
- l = i;
-
- }
-
-
- // Accumulation of the left-hand transformations
-
- if (MatU) {
- mn = N;
- if (M<N) mn = M;
-
- for (i=mn;i>=1;i--) {
- l = i+1;
- G = W[i];
- if (i!=N)
- for (j=l;j<=N;j++)
- U[i][j] = 0.0;
- if (G!=0.0) {
- if (i!=mn)
- for (j=l;j<=N;j++) {
- S = 0.0;
- for (k=l;k<=M;k++)
- S += U[k][i]*U[k][j];
- F = (S/U[i][i]) / G;
- for (k=i;k<=M;k++)
- U[k][j] += F*U[k][i];
- }
- for (j=i;j<=M;j++)
- U[j][i] /= G;
- } else
- for (j=i;j<=M;j++)
- U[j][i] = 0.0;
-
- U[i][i] += 1.0;
-
- }
- }
-
- // Diagonalization of the two-diagonal form.
-
- for (k=N;k>=1;k--) {
- k1 = k-1;
- its = 0;
-
- do {
- ExitKey = 0;
- l = k+1;
- while ((ExitKey==0) && (l>1)) {
- l--;
- l1 = l-1;
- if (fabs(RV1[l])+ANorm==ANorm) ExitKey=1;
- else if (l1>0) {
- if (fabs(W[l1])+ANorm==ANorm) ExitKey=2;
- }
- }
-
-// if (ExitKey!=1) { <-- this is original statement
- if (ExitKey>1) { // <-- prevents from corruption due to l1<1.
- // This is a rare case as RV1[1] should be
- // always 0.0 . Apparently this logics is
- // on the edge of float-point arithmetic,
- // therefore extra precaution for the case
- // of l1<1 was found necessary.
- C = 0.0;
- S = 1.0;
- ExitKey = 0;
- i = l;
- while ((ExitKey==0) && (i<=k)) {
- F = S*RV1[i];
- RV1[i] = C*RV1[i];
- if (fabs(F)+ANorm==ANorm) ExitKey = 1;
- else {
- G = W[i];
- H = SrX2Y2(F,G);
- W[i] = H;
- C = G/H;
- S = -F/H;
- if (MatU)
- for (j=1;j<=M;j++) {
- Y = U[j][l1];
- Z = U[j][i];
- U[j][l1] = Y*C+Z*S;
- U[j][i] = -Y*S+Z*C;
- }
- i++;
- }
- }
- }
-
- // Convergence Checking
-
- Z = W[k];
- if (l!=k) {
- if (its>=ItnLimit) {
- RetCode = k;
- return;
- }
- its++;
- X = W[l];
- Y = W[k1];
- G = RV1[k1];
- H = RV1[k];
- F = ((Y-Z)*(Y+Z) + (G-H)*(G+H)) / ( 2.0*H*Y );
- if (fabs(F)<=1.0) GG = Sign(sqrt(F*F+1.0),F);
- else GG = F*sqrt(1.0+1.0/F/F);
- F = ((X-Z)*(X+Z) + H*(Y/(F+GG)-H)) / X;
-
- // Next QR - Transformation
-
- C = 1.0;
- S = 1.0;
- for (i1=l;i1<=k1;i1++) {
- i = i1+1;
- G = RV1[i];
- Y = W[i];
- H = S*G;
- G = C*G;
- Z = SrX2Y2(F,H);
- RV1[i1] = Z;
- C = F/Z;
- S = H/Z;
- F = X*C+G*S;
- G = -X*S+G*C;
- H = Y*S;
- Y = Y*C;
- if (MatV)
- for (j=1;j<=N;j++) {
- X = V[j][i1];
- Z = V[j][i];
- V[j][i1] = X*C+Z*S;
- V[j][i] = -X*S+Z*C;
- }
-
- Z = SrX2Y2(F,H);
- W[i1] = Z;
- if (Z!=0.0) {
- C = F/Z;
- S = H/Z;
- }
- F = C*G+S*Y;
- X = -S*G+C*Y;
- if (MatU)
- for (j=1;j<=M;j++) {
- Y = U[j][i1];
- Z = U[j][i];
- U[j][i1] = Y*C+Z*S;
- U[j][i] = -Y*S+Z*C;
- }
-
- }
-
- RV1[l] = 0.0;
- RV1[k] = F;
- W[k] = X;
-
- } else if (Z<0.0) {
-
- W[k] = -Z;
- if (MatV)
- for (j=1;j<=N;j++)
- V[j][k] = -V[j][k];
- }
-
- } while (l!=k);
-
- }
-
-}
-
-// -----------------------------------------------------
-
-void OrderSVD ( int M, int N, rmatrix U, rmatrix V,
- rvector W, Boolean MatU, Boolean MatV ) {
-
-int i,k,j;
-realtype P;
-
- // External loop of the re-ordering
- for (i=1;i<N;i++) {
- k = i;
- P = W[i];
-
- // Internal loop : finding of the index of greatest
- // singular value over the remaining ones.
- for (j=i+1;j<=N;j++)
- if (W[j]>P) {
- k = j;
- P = W[j];
- }
-
- if (k!=i) {
- // Swapping the singular value
- W[k] = W[i];
- W[i] = P;
- // Swapping the U's columns ( if needed )
- if (MatU)
- for (j=1;j<=M;j++) {
- P = U[j][i];
- U[j][i] = U[j][k];
- U[j][k] = P;
- }
- // Swapping the V's columns ( if needed )
- if (MatV)
- for (j=1;j<=N;j++) {
- P = V[j][i];
- V[j][i] = V[j][k];
- V[j][k] = P;
- }
- }
-
- }
-
-}
-
-
-/*
-
-#ifndef __STDIO_H
-#include <stdio.h>
-#endif
-
-int main ( int argc, char ** argv, char ** env ) {
-// Test Jacobi
-matrix A,T,A1;
-vector Eigen,Aik;
-realtype SR;
-int N,i,j,k,Signal;
-
- N = 4;
-
- GetMatrixMemory ( A,N,N,1,1 );
- GetMatrixMemory ( T,N,N,1,1 );
- GetMatrixMemory ( A1,N,N,1,1 );
- GetVectorMemory ( Eigen,N,1 );
- GetVectorMemory ( Aik ,N,1 );
-
- k = 1;
- for (i=1;i<=N;i++)
- for (j=i;j<=N;j++) {
- A[i][j] = k++;
- A[i][j] *= 1000.0;
- A[j][i] = A[i][j];
- }
-
- printf ( " INITIAL MATRIX:\n" );
- for (i=1;i<=N;i++) {
- for (j=1;j<=N;j++)
- printf ( " %10.4f",A[i][j] );
- printf ( "\n" );
- }
-
- Jacobi ( N,A,T,Eigen,Aik,Signal );
-
- printf ( "\n EIGEN VALUES AND EIGEN VECTORS:\n" );
- for (i=1;i<=N;i++) {
- printf ( " %10.4f ",Eigen[i] );
- for (j=1;j<=N;j++)
- printf ( " %10.4f",T[j][i] );
- printf ( "\n" );
- }
- printf ( "\n measure: " );
- for (i=1;i<=N;i++) {
- SR = 0.0;
- for (j=1;j<=N;j++)
- SR += T[j][i]*T[j][i];
- printf ( " %10.4f",sqrt(SR) );
- }
- printf ( "\n" );
-
- for (i=1;i<=N;i++)
- for (j=1;j<=N;j++) {
- A1[i][j] = 0.0;
- for (k=1;k<=N;k++)
- A1[i][j] += T[i][k]*Eigen[k]*T[j][k];
- }
-
- printf ( "\n RESTORED INITIAL MATRIX:\n" );
- for (i=1;i<=N;i++) {
- for (j=1;j<=N;j++)
- printf ( " %10.4f",A1[j][i] );
- printf ( "\n" );
- }
-
- FreeMatrixMemory ( A,N,1,1 );
- FreeMatrixMemory ( T,N,1,1 );
- FreeMatrixMemory ( A1,N,1,1 );
- FreeVectorMemory ( Eigen,1 );
- FreeVectorMemory ( Aik ,1 );
-
-
-}
-
-*/
-
diff --git a/mmdb/linalg_.h b/mmdb/linalg_.h
deleted file mode 100755
index 9813ee3..0000000
--- a/mmdb/linalg_.h
+++ /dev/null
@@ -1,233 +0,0 @@
-// $Id: linalg_.h,v 1.21 2012/01/26 17:52:19 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 27.06.01 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : linalg_ <interface>
-// ~~~~~~~~~
-// **** Project : MMDB ( MacroMolecular Data Base )
-// ~~~~~~~~~
-//
-// (C) E.Krissinel 2000-2008
-//
-// =================================================================
-//
-//
-
-#ifndef __LinAlg__
-#define __LinAlg__
-
-#ifndef __MatType__
-#include "mattype_.h"
-#endif
-
-
-// ========================== Jacobi =============================
-
-
-/// Diagonalization of symmetric matrices A[1..N][1..N]
-/// by the method of Jacobi.
-extern void Jacobi ( int N, //!< dimension of the matrix
- rmatrix A, //!< matrix to diagonalize; the
- /// lower triangle, except the
- /// diagonal, will remain unchanged
- rmatrix T, //!< eigenvectors placed as columns
- rvector Eigen, //!< vector of eigenvalues, orderd
- /// by increasing
- rvector Aik, //!< working array
- int & Signal //!< 0 <=> Ok, ItMax <=> iteration
- /// limit exchausted.
- );
-
-
-// A5.5.2 : Perturbed Cholesky Decomposition
-extern void PbCholDecomp ( int N,
- rvector HDiag,
- realtype MaxOff,
- realtype MachEps,
- rmatrix L,
- realtype & MaxAdd );
-
-// A3.2.3a : Cholesky's L - Solution of
-// L*Y = B ( given B )
-extern void LSolve ( int N, rmatrix L, rvector B, rvector Y );
-
-// A3.2.3b : Cholesky's LT - Solution of
-// LT*X = Y ( given Y )
-extern void LTSolve ( int N, rmatrix L, rvector Y, rvector X );
-
-// A3.2.3 : Solution of the equation L*LT*S = G
-// by the Cholesky's method
-extern void ChSolve ( int N, rmatrix L, rvector G, rvector S );
-
-
-// ----------------------------------------------------
-
-extern void FastInverse ( int N, rmatrix A, ivector J0,
-//#D realtype & Det,
- int & Signal );
-//
-// 13.09.90 <-- Last Modification Date
-// ------------------------
-//
-// ================================================
-//
-// Fast Inversion of the matrix A
-// by the method of GAUSS - JORDAN .
-//
-// ------------------------------------------------
-//
-// Input parameters are :
-//
-// N - dimension of the matrix
-// A - the matrix [1..N][1..N] to be inverted.
-// ------------------------------------------------
-//
-// J0 - integer vector [1..N] for temporal storage
-//
-// ------------------------------------------------
-//
-// Output parameters are :
-//
-// A - the inverted matrix
-// Signal - the error key :
-// = 0 <=> O'K
-// else
-// degeneration was found, and
-// the rang of matrix is Signal-1.
-//
-// Variable Det may return the determinant
-// of matrix A. To obtain it, remove all comments
-// of form //#D.
-//
-// ================================================
-
-
-// ----------------------------------------------------
-
-
-void SVD ( int NA, int M, int N,
- rmatrix A, rmatrix U, rmatrix V,
- rvector W, rvector RV1,
- Boolean MatU, Boolean MatV,
- int & RetCode );
-//
-// 13.12.01 <-- Last Modification Date
-// ------------------------
-//
-// ================================================
-//
-// The Singular Value Decomposition
-// of the matrix A by the algorithm from
-// G.Forsait, M.Malkolm, K.Mouler. Numerical
-// methods of mathematical calculations //
-// M., Mir, 1980.
-//
-// Matrix A is represented as
-//
-// A = U * W * VT
-//
-// ------------------------------------------------
-//
-// All dimensions are indexed from 1 on.
-//
-// ------------------------------------------------
-//
-// Input parameters:
-//
-// NA - number of lines in A. NA may be
-// equal to M or N only. If NA=M
-// then usual SVD will be made. If MA=N
-// then matrix A is transposed before
-// the decomposition, and the meaning of
-// output parameters U and V is
-// swapped (U accepts VT and VT accepts U).
-// In other words, matrix A has physical
-// dimension of M x N , same as U and V;
-// however the logical dimension of it
-// remains that of N x M .
-// M - number of lines in U
-// N - number of columns in U,V and length
-// of W,RV1 . Always provide M >= N !
-// A - matrix [1..M][1..N] or [1..N][1..M]
-// to be decomposed. The matrix does not
-// change, and it may coincide with U or
-// V, if NA=M (in which case A does change)
-// MatU - compute U , if set True
-// MatV - compute V , if set True
-// RV1 - temporary array [1..N].
-// U - should be always supplied as an array of
-// [1..M][1..N], M>=N .
-// V - should be suuplied as an array of
-// [1..N][1..N] if MatV is True .
-//
-// ------------------------------------------------
-//
-// Output parameters are :
-//
-// W - N non-ordered singular values,
-// if RetCode=0. If RetCode<>0, the
-// RetCode+1 ... N -th values are still
-// valid
-// U - matrix of right singular vectors
-// (arranged in columns), corresponding
-// to the singular values in W, if
-// RetCode=0 and MatU is True. If MatU
-// is False, U is still used as a
-// temporary array. If RetCode<>0 then
-// the RetCode+1 ... N -th vectors
-// are valid
-// V - matrix of left singular vectors
-// (arranged in columns), corresponding
-// to the singular values in W, if
-// RetCode=0 and MatV is True. If MatV
-// is False, V is not used and may be set
-// to NULL. If RetCode<>0 then the
-// RetCode+1 ... N -th vectors are valid
-// RetCode - the error key :
-// = 0 <=> O'K
-// else
-// = k, if the k-th singular value
-// was not computed after 30 iterations.
-//
-// ------------------------------------------------
-//
-// Key Variables are :
-//
-// ItnLimit - the limit for iterations
-//
-// This routine does not use any machine-dependent
-// constants.
-//
-// ================================================
-//
-//
-
-void OrderSVD ( int M, int N, rmatrix U, rmatrix V,
- rvector W, Boolean MatU, Boolean MatV );
-
-
-#endif
diff --git a/mmdb/machine_.cpp b/mmdb/machine_.cpp
deleted file mode 100755
index 0e3e55b..0000000
--- a/mmdb/machine_.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-// $Id: machine_.cpp,v 1.21 2012/01/26 17:52:19 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 08.07.08 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : machine_ <implementation>
-// ~~~~~~~~~
-// **** Functions : GetMachineID - returns ID code for the machine
-// ~~~~~~~~~~~ GetMachineName - returns name of a machine
-//
-// (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-#ifndef __Machine__
-#include "machine_.h"
-#endif
-
-
-#ifdef CALL_LIKE_SUN
-
-int GetMachineID() {
-int k = CALL_LIKE_SUN;
- switch (k) {
- case 1 : return MACHINE_ALLIANT;
- case 2 : return MACHINE_CONVEX;
- case 3 : return MACHINE_ESV;
- case 4 : return MACHINE_SGI;
- case 5 : return MACHINE_SOLBOURNE;
- case 6 : return MACHINE_SOLARIS;
- case 7 : return MACHINE_ALPHA;
- case 8 : return MACHINE_F2C_G77;
- case 9 : return MACHINE_LINUX;
- default : return MACHINE_UNKNOWN;
- }
-}
-
-#elif defined(CALL_LIKE_HPUX)
-
-int GetMachineID() {
-int k = CALL_LIKE_HPUX;
- switch (k) {
- case 1 : return MACHINE_RS6000;
- case 2 : return MACHINE_HP9000;
- default : return MACHINE_UNKNOWN;
- }
-}
-
-#elif defined(CALL_LIKE_STARDENT)
-
-int GetMachineID() {
-int k = CALL_LIKE_STARDENT;
- switch (k) {
- case 1 : return MACHINE_ARDENT;
- case 2 : return MACHINE_TITAN;
- case 3 : return MACHINE_STARDENT;
- default : return MACHINE_UNKNOWN;
- }
-}
-
-#elif defined(CALL_LIKE_VMS)
-
-int GetMachineID() {
- return MACHINE_VMS;
-}
-
-#elif defined(CALL_LIKE_MVS)
-
-int GetMachineID() {
- return MACHINE_MVS;
-}
-
-#else
-
-int GetMachineID() {
- return MACHINE_UNKNOWN;
-}
-
-#endif
-
-static cpstr MCH_SGI = cpstr("Silicon Graphics");
-static cpstr MCH_RS6000 = cpstr("IBM RS/6000");
-static cpstr MCH_ALLIANT = cpstr("Alliant");
-static cpstr MCH_ARDENT = cpstr("Ardent");
-static cpstr MCH_TITAN = cpstr("Titan");
-static cpstr MCH_STARDENT = cpstr("Stardent");
-static cpstr MCH_CONVEX = cpstr("Convex");
-static cpstr MCH_ESV = cpstr("Evans or Sutherland");
-static cpstr MCH_HP9000 = cpstr("Hewlett Packard 9000");
-static cpstr MCH_SOLBOURNE = cpstr("Solbourne");
-static cpstr MCH_SOLARIS = cpstr("Solaris");
-static cpstr MCH_ALPHA = cpstr("DEC Alpha");
-static cpstr MCH_VMS = cpstr("A VMS machine");
-static cpstr MCH_MVS = cpstr("MS Windows");
-static cpstr MCH_F2C_G77 = cpstr("SUN compatible");
-static cpstr MCH_LINUX = cpstr("Linux");
-
-cpstr GetMachineName ( int MachineID ) {
- switch (MachineID) {
- case MACHINE_SGI : return MCH_SGI;
- case MACHINE_RS6000 : return MCH_RS6000;
- case MACHINE_ALLIANT : return MCH_ALLIANT;
- case MACHINE_ARDENT : return MCH_ARDENT;
- case MACHINE_TITAN : return MCH_TITAN;
- case MACHINE_STARDENT : return MCH_STARDENT;
- case MACHINE_CONVEX : return MCH_CONVEX;
- case MACHINE_ESV : return MCH_ESV;
- case MACHINE_HP9000 : return MCH_HP9000;
- case MACHINE_SOLBOURNE : return MCH_SOLBOURNE;
- case MACHINE_SOLARIS : return MCH_SOLARIS;
- case MACHINE_ALPHA : return MCH_ALPHA;
- case MACHINE_VMS : return MCH_VMS;
- case MACHINE_MVS : return MCH_MVS;
- case MACHINE_F2C_G77 : return MCH_F2C_G77;
- case MACHINE_LINUX : return MCH_LINUX;
- default :
- case MACHINE_UNKNOWN : return pstr("Unidentified machine");
- }
-}
-
-cpstr GetMachineName() {
- return GetMachineName ( GetMachineID() );
-}
-
diff --git a/mmdb/math_.cpp b/mmdb/math_.cpp
deleted file mode 100755
index 35e7fa2..0000000
--- a/mmdb/math_.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-// $Id: math_.cpp,v 1.20 2012/01/26 17:52:19 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 10.04.03 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : Math_ <implementation>
-// ~~~~~~~~~
-// **** Functions : GetTorsion
-// ~~~~~~~~~~~ GetAngle
-//
-// (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-#ifndef __MATH_H
-#include <math.h>
-#endif
-
-#ifndef __Math__
-#include "math_.h"
-#endif
-
-// ------------------------------------------------------------------
-
-realtype GetTorsion ( rvector U, rvector W, rvector V ) {
-// U W V
-// o<----o----->o----->o
-//
-realtype A[3],B[3],C[3],Wmag,S,T;
-
- A[0] = U[1]*W[2] - W[1]*U[2];
- A[1] = U[2]*W[0] - W[2]*U[0];
- A[2] = U[0]*W[1] - W[0]*U[1];
-
- B[0] = V[1]*W[2] - W[1]*V[2];
- B[1] = V[2]*W[0] - W[2]*V[0];
- B[2] = V[0]*W[1] - W[0]*V[1];
-
- C[0] = A[1]*B[2] - B[1]*A[2];
- C[1] = A[2]*B[0] - B[2]*A[0];
- C[2] = A[0]*B[1] - B[0]*A[1];
-
- Wmag = sqrt(W[0]*W[0]+W[1]*W[1]+W[2]*W[2]);
-
- S = C[0]*W[0] + C[1]*W[1] + C[2]*W[2];
- T = A[0]*B[0] + A[1]*B[1] + A[2]*B[2];
- T *= Wmag;
-
- if ((S==0.0) && (T==0.0)) return NO_TORSION;
- else return atan2(S,T);
-
-}
-
-
-realtype GetAngle ( rvector v1, rvector v2 ) {
-realtype l1,l2;
-
- l1 = v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2];
- if (l1==0.0) l1 = 1.0;
- l2 = v2[0]*v2[0] + v2[1]*v2[1] + v2[2]*v2[2];
- if (l2==0.0) l2 = 1.0;
-
- return acos((v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])/sqrt(l1*l2));
-
-}
-
-
-#define nCombMax 500
-
-realtype Combinations ( int n, int m ) {
-// 0<=n<=nCombMax, 0<=m<=n
-realtype P[nCombMax+1];
-int i,j;
- if ((m<0) || (m>n)) return 0.0;
- if ((m==0) || (m==n)) return 1.0;
- if ((m==1) || (m==n-1)) return realtype(n);
- P[0] = 1.0;
- P[1] = 3.0;
- P[2] = 3.0;
- P[3] = 1.0;
- for (i=4;i<=n;i++) {
- P[i] = 1.0;
- for (j=i-1;j>0;j--)
- P[j] += P[j-1];
- }
- return P[m];
-}
-
-realtype log1mx ( realtype x ) {
-// Calculates precisely log(1-x) for x<1, including
-// very small x
-realtype z,z1,z2,n;
-
- if (x>=1.0-10.0*MachEps) z = -MaxReal;
- else if (fabs(x)>1.0e-8) z = log(1.0-x);
- else {
- z1 = x;
- z = 0.0;
- n = 1.0;
- do {
- z2 = z;
- z -= z1/n;
- z1 *= x;
- n += 1.0;
- } while (z!=z2);
- }
-
- return z;
-
-}
-
-realtype expc ( realtype x ) {
-// Calculates precisely 1 - exp(x) for any x including
-// very small values
-realtype z,z1,z2,n;
-
- if (x>LnMaxReal) z = -MaxReal;
- else if (x<-LnMaxReal) z = 1.0;
- else if (fabs(x)>1.0e-8) z = 1.0 - Exp(x);
- else {
- z1 = x;
- z = x;
- n = 1.0;
- do {
- z2 = z;
- n += 1.0;
- z1 *= x/n;
- z += z1;
- } while (z!=z2);
- z = -z;
- }
-
- return z;
-
-}
-
-
-realtype expc1mx ( realtype x, realtype y ) {
-// Calculates precisely 1-(1-x)**y including very small x and
-// very large y
-realtype z,z1,z2,n,s;
-
- // Calculate (1-x)**y as exp(y*log(1-x)). Get log(1-x) first:
- if (x>1.0e-8) z = log(1.0-x);
- else {
- z1 = x;
- z = 0.0;
- n = 1.0;
- do {
- z2 = z;
- z -= z1/n;
- z1 *= x;
- n += 1.0;
- } while (z!=z2);
- }
-
- // Now calculate 1 - exp(y*log(1-x)) :
- z *= y;
- if (fabs(z)>1.0e-8) s = 1.0 - exp(z);
- else {
- z1 = z;
- s = z;
- n = 1.0;
- do {
- z2 = s;
- n += 1.0;
- z1 *= z/n;
- s += z1;
- } while (s!=z2);
- s = -s;
- }
-
- return s;
-
-}
diff --git a/mmdb/math_.h b/mmdb/math_.h
deleted file mode 100755
index 9c68241..0000000
--- a/mmdb/math_.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// $Id: math_.h,v 1.20 2012/01/26 17:52:19 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 09.04.03 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : Math_ <interface>
-// ~~~~~~~~~
-// **** Functions : GetTorsion
-// ~~~~~~~~~~~ GetAngle
-//
-// (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-
-#ifndef __Math__
-#define __Math__
-
-#ifndef __MatType__
-#include "mattype_.h"
-#endif
-
-
-// ------------------------------------------------------------------
-
-#define NO_TORSION (-MaxReal)
-// U[0,1,2] = x,y,z
-extern realtype GetTorsion ( rvector U, rvector W, rvector V );
-extern realtype GetAngle ( rvector U, rvector V );
-
-// Calculates the binomial coefficient n choose m, 0<=n<=500, 0<=m<=n
-extern realtype Combinations ( int n, int m );
-
-// Calculates precisely log(1-x) for x<1, including very small x
-extern realtype log1mx ( realtype x );
-
-// Calculates precisely 1 - exp(x) for any x including very small values
-extern realtype expc ( realtype x );
-
-inline double exp10 ( double x ) { return exp(x*ln10); }
-
-// Calculates precisely 1-(1-x)**y including very small x and very large y
-extern realtype expc1mx ( realtype x, realtype y );
-
-
-
-#endif
-
-
diff --git a/mmdb/mattype_.cpp b/mmdb/mattype_.cpp
deleted file mode 100755
index c3fb873..0000000
--- a/mmdb/mattype_.cpp
+++ /dev/null
@@ -1,2116 +0,0 @@
-// $Id: mattype_.cpp,v 1.30 2012/01/26 17:52:19 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 29.01.10 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MatType_ <implementation>
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2010
-//
-// =================================================================
-//
-
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __CTYPE_H
-#include <ctype.h>
-#endif
-
-#ifndef __MatType__
-#include "mattype_.h"
-#endif
-
-#include <limits>
-#include <stdio.h>
-
-// -------------------------------------------------------
-
-realtype MachEps;
-realtype floatMachEps;
-realtype LnMaxReal;
-realtype LnMinReal;
-static realtype LnMaxRealExp;
-static realtype LnMinRealExp;
-
-// Initialization. Some C++ enviroments do not do the
-// following statements automatically, therefore it is
-// always advisable to call InitMatType() explicitely
-// from the top of main(). See body of InitMatType()
-// in the very end of this file. It is completely
-// harmless and cheap to call InitMatType() multiple
-// times.
-
-static Boolean MatTypeInit = InitMatType();
-
-
-// -------------------------------------------------------
-
-/*
-int mround ( realtype X ) {
- return (int)floor(X+0.5);
-}
-
-int ifloor ( realtype X ) {
- return (int)floor(X);
-}
-
-int Abs ( int x ) {
- return ( x >= 0 ? x : -x );
-}
-*/
-
-#ifdef _WIN32
-pstr strcasestr ( pstr s1, cpstr s2 ) {
-pstr l1,l2,l;
- l1 = NULL;
- l2 = NULL;
- CreateCopy ( l1,s1 );
- CreateCopy ( l2,s2 );
- LowerCase ( l1 );
- LowerCase ( l2 );
- l = strstr ( l1,l2 );
- if (l)
- l = s1 + (l-l1);
- delete[] l1;
- delete[] l2;
- return l;
-}
-#endif
-
-// -------------------------------------------------------
-
-/*
-void ISwap ( int & x, int & y ) {
-int b;
- b = x; x = y; y = b;
-}
-void WSwap ( word & x, word & y ) {
-word b;
- b = x; x = y; y = b;
-}
-void BSwap ( byte & x, byte & y ) {
-byte b;
- b = x; x = y; y = b;
-}
-void LSwap ( long & x, long & y ) {
-long b;
- b = x; x = y; y = b;
-}
-void RSwap ( realtype & x, realtype & y ) {
-realtype b;
- b = x; x = y; y = b;
-}
-*/
-
-// -------------------------------------------------------
-/*
-realtype RMax ( const realtype x1, const realtype x2 )
-{ return ( x1 > x2 ? x1 : x2 ); }
-
-long LMax ( const long x1, const long x2 )
-{ return ( x1 > x2 ? x1 : x2 ); }
-
-word WMax ( const word x1, const word x2 )
-{ return ( x1 > x2 ? x1 : x2 ); }
-
-int IMax ( const int x1, const int x2 )
-{ return ( x1 > x2 ? x1 : x2 ); }
-
-realtype RMin ( const realtype x1, const realtype x2 )
-{ return ( x1 < x2 ? x1 : x2 ); }
-
-long LMin ( const long x1, const long x2 )
-{ return ( x1 < x2 ? x1 : x2 ); }
-
-word WMin ( const word x1, const word x2 )
-{ return ( x1 < x2 ? x1 : x2 ); }
-
-int IMin ( const int x1, const int x2 )
-{ return ( x1 < x2 ? x1 : x2 ); }
-*/
-
-// -------------------------------------------------------
-/*
-realtype fsign ( const realtype x1, const realtype x2 ) {
-realtype ax;
- if (x1>=0.0) ax = x1;
- else ax = -x1;
- return ( x2 >= 0.0 ? ax : -ax );
-}
-*/
-
-// -------------------------------------------------------
-Boolean GetVectorMemory ( rvector & V, word N, word Shift ) {
- V = new realtype[N];
- if (V!=NULL) V = V - Shift; // shift for abovementioned enumeration
- return (V!=NULL);
-}
-
-Boolean GetVectorMemory ( ivector & I, word N, word Shift ) {
- I = new int[N];
- if (I!=NULL) I = I - Shift; // shift for abovementioned enumeration
- return (I!=NULL);
-}
-
-Boolean GetVectorMemory ( wvector & W, word N, word Shift ) {
- W = new word[N];
- if (W!=NULL) W = W - Shift; // shift for abovementioned enumeration
- return (W!=NULL);
-}
-
-Boolean GetVectorMemory ( bvector & B, word N, word Shift ) {
- B = new byte[N];
- if (B!=NULL) B = B - Shift; // shift for abovementioned enumeration
- return (B!=NULL);
-}
-
-Boolean GetVectorMemory ( lvector & L, word N, word Shift ) {
- L = new long[N];
- if (L!=NULL) L = L - Shift; // shift for abovementioned enumeration
- return (L!=NULL);
-}
-
-Boolean GetVectorMemory ( lwvector & L, word N, word Shift ) {
- L = new lword[N];
- if (L!=NULL) L = L - Shift; // shift for abovementioned enumeration
- return (L!=NULL);
-}
-
-Boolean GetVectorMemory ( psvector & P, word N, word Shift ) {
- P = new pstr[N];
- if (P!=NULL) P = P - Shift; // shift for abovementioned enumeration
- return (P!=NULL);
-}
-
-void FreeVectorMemory ( rvector & V, word Shift ) {
- if (V!=NULL) {
- V = V + Shift; // back shift for the work of heap system
- delete[] V;
- V = NULL;
- }
-}
-
-void FreeVectorMemory ( ivector & I, word Shift ) {
- if (I!=NULL) {
- I = I + Shift; // back shift for the work of heap system
- delete[] I;
- I = NULL;
- }
-}
-
-void FreeVectorMemory ( wvector & W, word Shift ) {
- if (W!=NULL) {
- W = W + Shift; // back shift for the work of heap system
- delete[] W;
- W = NULL;
- }
-}
-
-void FreeVectorMemory ( bvector & B, word Shift ) {
- if (B!=NULL) {
- B = B + Shift; // back shift for the work of heap system
- delete[] B;
- B = NULL;
- }
-}
-
-void FreeVectorMemory ( lvector & L, word Shift ) {
- if (L!=NULL) {
- L = L + Shift; // back shift for the work of heap system
- delete[] L;
- L = NULL;
- }
-}
-
-void FreeVectorMemory ( lwvector & L, word Shift ) {
- if (L!=NULL) {
- L = L + Shift; // back shift for the work of heap system
- delete[] L;
- L = NULL;
- }
-}
-
-void FreeVectorMemory ( psvector & P, word Shift ) {
- if (P!=NULL) {
- P = P + Shift; // back shift for the work of heap system
- delete[] P;
- P = NULL;
- }
-}
-
-Boolean GetMatrixMemory ( rmatrix & A, word N, word M,
- word ShiftN, word ShiftM ) {
- A = new rvector[N];
- if (A!=NULL) {
- for (word i=0;i<N;i++)
- GetVectorMemory ( A[i],M,ShiftM );
- if (A[N-1]==NULL)
- FreeMatrixMemory ( A,N,0,ShiftM );
- else A = A - ShiftN; // shift for the enumeration with 1
- }
- return (A!=NULL);
-}
-
-Boolean GetMatrixMemory ( imatrix & A, word N, word M,
- word ShiftN, word ShiftM ) {
- A = new ivector[N];
- if (A!=NULL) {
- for (word i=0;i<N;i++)
- GetVectorMemory ( A[i],M,ShiftM );
- if (A[N-1]==NULL)
- FreeMatrixMemory ( A,N,0,ShiftM );
- else A = A - ShiftN; // shift for the enumeration with 1
- }
- return (A!=NULL);
-}
-
-Boolean GetMatrixMemory ( wmatrix & W, word N, word M,
- word ShiftN, word ShiftM ) {
- W = new wvector[N];
- if (W!=NULL) {
- for (word i=0;i<N;i++)
- GetVectorMemory ( W[i],M,ShiftM );
- if (W[N-1]==NULL)
- FreeMatrixMemory ( W,N,0,ShiftM );
- else W = W - ShiftN; // shift for the enumeration with 1
- }
- return (W!=NULL);
-}
-
-Boolean GetMatrixMemory ( bmatrix & B, word N, word M,
- word ShiftN, word ShiftM ) {
- B = new bvector[N];
- if (B!=NULL) {
- for (word i=0;i<N;i++)
- GetVectorMemory ( B[i],M,ShiftM );
- if (B[N-1]==NULL)
- FreeMatrixMemory ( B,N,0,ShiftM );
- else B = B - ShiftN; // shift for the enumeration with 1
- }
- return (B!=NULL);
-}
-
-Boolean GetMatrixMemory ( lmatrix & L, word N, word M,
- word ShiftN, word ShiftM ) {
- L = new lvector[N];
- if (L!=NULL) {
- for (word i=0;i<N;i++)
- GetVectorMemory ( L[i],M,ShiftM );
- if (L[N-1]==NULL)
- FreeMatrixMemory ( L,N,0,ShiftM );
- else L = L - ShiftN; // shift for the enumeration with 1
- }
- return (L!=NULL);
-}
-
-Boolean GetMatrixMemory ( lwmatrix & L, word N, word M,
- word ShiftN, word ShiftM ) {
- L = new lwvector[N];
- if (L!=NULL) {
- for (word i=0;i<N;i++)
- GetVectorMemory ( L[i],M,ShiftM );
- if (L[N-1]==NULL)
- FreeMatrixMemory ( L,N,0,ShiftM );
- else L = L - ShiftN; // shift for the enumeration with 1
- }
- return (L!=NULL);
-}
-
-Boolean GetMatrixMemory ( psmatrix & P, word N, word M,
- word ShiftN, word ShiftM ) {
- P = new psvector[N];
- if (P!=NULL) {
- for (word i=0;i<N;i++)
- GetVectorMemory ( P[i],M,ShiftM );
- if (P[N-1]==NULL)
- FreeMatrixMemory ( P,N,0,ShiftM );
- else P = P - ShiftN; // shift for the enumeration with 1
- }
- return (P!=NULL);
-}
-
-void FreeMatrixMemory ( rmatrix & A, word N,
- word ShiftN, word ShiftM ) {
- if (A!=NULL) {
- A = A + ShiftN; // back shift for the work of heap system
- for (word i=0;i<N;i++)
- FreeVectorMemory ( A[i],ShiftM );
- delete[] A;
- A = NULL;
- }
-}
-
-void FreeMatrixMemory ( imatrix & A, word N,
- word ShiftN, word ShiftM ) {
- if (A!=NULL) {
- A = A + ShiftN; // back shift for the work of heap system
- for (word i=0;i<N;i++)
- FreeVectorMemory ( A[i],ShiftM );
- delete[] A;
- A = NULL;
- }
-}
-
-void FreeMatrixMemory ( wmatrix & W, word N,
- word ShiftN, word ShiftM ) {
- if (W!=NULL) {
- W = W + ShiftN; // back shift for the work of heap system
- for (word i=0;i<N;i++)
- FreeVectorMemory ( W[i],ShiftM );
- delete[] W;
- W = NULL;
- }
-}
-
-void FreeMatrixMemory ( bmatrix & B, word N,
- word ShiftN, word ShiftM ) {
- if (B!=NULL) {
- B = B + ShiftN; // back shift for the work of heap system
- for (word i=0;i<N;i++)
- FreeVectorMemory ( B[i],ShiftM );
- delete[] B;
- B = NULL;
- }
-}
-
-void FreeMatrixMemory ( lmatrix & L, word N,
- word ShiftN, word ShiftM ) {
- if (L!=NULL) {
- L = L + ShiftN; // back shift for the work of heap system
- for (word i=0;i<N;i++)
- FreeVectorMemory ( L[i],ShiftM );
- delete[] L;
- L = NULL;
- }
-}
-
-void FreeMatrixMemory ( lwmatrix & L, word N,
- word ShiftN, word ShiftM ) {
- if (L!=NULL) {
- L = L + ShiftN; // back shift for the work of heap system
- for (word i=0;i<N;i++)
- FreeVectorMemory ( L[i],ShiftM );
- delete[] L;
- L = NULL;
- }
-}
-
-void FreeMatrixMemory ( psmatrix & P, word N,
- word ShiftN, word ShiftM ) {
- if (P!=NULL) {
- P = P + ShiftN; // back shift for the work of heap system
- for (word i=0;i<N;i++)
- FreeVectorMemory ( P[i],ShiftM );
- delete[] P;
- P = NULL;
- }
-}
-
-Boolean GetMatrix3Memory ( rmatrix3 & A, word N, word M, word K,
- word ShiftN, word ShiftM, word ShiftK ) {
- A = new rmatrix[N];
- if (A!=NULL) {
- for (word i=0;i<N;i++)
- GetMatrixMemory ( A[i],M,K,ShiftM,ShiftK );
- if (A[N-1]==NULL)
- FreeMatrix3Memory ( A,N,M,0,ShiftM,ShiftK );
- else
- A = A - ShiftN; // shift for the enumeration with 1
- }
- return (A!=NULL);
-}
-
-Boolean GetMatrix3Memory ( imatrix3 & A, word N, word M, word K,
- word ShiftN, word ShiftM, word ShiftK ) {
- A = new imatrix[N];
- if (A!=NULL) {
- for (word i=0;i<N;i++)
- GetMatrixMemory ( A[i],M,K,ShiftM,ShiftK );
- if (A[N-1]==NULL)
- FreeMatrix3Memory ( A,N,M,0,ShiftM,ShiftK );
- else
- A = A - ShiftN; // shift for the enumeration with 1
- }
- return (A!=NULL);
-}
-
-Boolean GetMatrix3Memory ( wmatrix3 & A, word N, word M, word K,
- word ShiftN, word ShiftM, word ShiftK ) {
- A = new wmatrix[N];
- if (A!=NULL) {
- for (word i=0;i<N;i++)
- GetMatrixMemory ( A[i],M,K,ShiftM,ShiftK );
- if (A[N-1]==NULL)
- FreeMatrix3Memory ( A,N,M,0,ShiftM,ShiftK );
- else
- A = A - ShiftN; // shift for the enumeration with 1
- }
- return (A!=NULL);
-}
-
-Boolean GetMatrix3Memory ( bmatrix3 &A, word N, word M, word K,
- word ShiftN, word ShiftM, word ShiftK ) {
- A = new bmatrix[N];
- if (A!=NULL) {
- for (word i=0;i<N;i++)
- GetMatrixMemory ( A[i],M,K,ShiftM,ShiftK );
- if (A[N-1]==NULL)
- FreeMatrix3Memory ( A,N,M,0,ShiftM,ShiftK );
- else
- A = A - ShiftN; // shift for the enumeration with 1
- }
- return (A!=NULL);
-}
-
-Boolean GetMatrix3Memory ( lmatrix3 & A, word N, word M, word K,
- word ShiftN, word ShiftM, word ShiftK ) {
- A = new lmatrix[N];
- if (A!=NULL) {
- for (word i=0;i<N;i++)
- GetMatrixMemory ( A[i],M,K,ShiftM,ShiftK );
- if (A[N-1]==NULL)
- FreeMatrix3Memory ( A,N,M,0,ShiftM,ShiftK );
- else
- A = A - ShiftN; // shift for the enumeration with 1
- }
- return (A!=NULL);
-}
-
-Boolean GetMatrix3Memory ( lwmatrix3 & A, word N, word M, word K,
- word ShiftN, word ShiftM, word ShiftK ) {
- A = new lwmatrix[N];
- if (A!=NULL) {
- for (word i=0;i<N;i++)
- GetMatrixMemory ( A[i],M,K,ShiftM,ShiftK );
- if (A[N-1]==NULL)
- FreeMatrix3Memory ( A,N,M,0,ShiftM,ShiftK );
- else
- A = A - ShiftN; // shift for the enumeration with 1
- }
- return (A!=NULL);
-}
-
-Boolean GetMatrix3Memory ( psmatrix3 & A, word N, word M, word K,
- word ShiftN, word ShiftM, word ShiftK ) {
- A = new psmatrix[N];
- if (A!=NULL) {
- for (word i=0;i<N;i++)
- GetMatrixMemory ( A[i],M,K,ShiftM,ShiftK );
- if (A[N-1]==NULL)
- FreeMatrix3Memory ( A,N,M,0,ShiftM,ShiftK );
- else
- A = A - ShiftN; // shift for the enumeration with 1
- }
- return (A!=NULL);
-}
-
-void FreeMatrix3Memory ( rmatrix3 & A, word N, word M,
- word ShiftN, word ShiftM, word ShiftK ) {
- if (A!=NULL) {
- A = A + ShiftN; // back shift for the work of heap system
- for (word i=0;i<N;i++)
- FreeMatrixMemory ( A[i],M,ShiftM,ShiftK );
- delete[] A;
- A = NULL;
- }
-}
-
-void FreeMatrix3Memory ( imatrix3 & A, word N, word M,
- word ShiftN, word ShiftM, word ShiftK ) {
- if (A!=NULL) {
- A = A + ShiftN; // back shift for the work of heap system
- for (word i=0;i<N;i++)
- FreeMatrixMemory ( A[i],M,ShiftM,ShiftK );
- delete[] A;
- A = NULL;
- }
-}
-
-void FreeMatrix3Memory ( wmatrix3 & A, word N, word M,
- word ShiftN, word ShiftM, word ShiftK ) {
- if (A!=NULL) {
- A = A + ShiftN; // back shift for the work of heap system
- for (word i=0;i<N;i++)
- FreeMatrixMemory ( A[i],M,ShiftM,ShiftK );
- delete[] A;
- A = NULL;
- }
-}
-
-void FreeMatrix3Memory ( bmatrix3 & A, word N, word M,
- word ShiftN, word ShiftM, word ShiftK ) {
- if (A!=NULL) {
- A = A + ShiftN; // back shift for the work of heap system
- for (word i=0;i<N;i++)
- FreeMatrixMemory ( A[i],M,ShiftM,ShiftK );
- delete[] A;
- A = NULL;
- }
-}
-
-void FreeMatrix3Memory ( lmatrix3 & A, word N, word M,
- word ShiftN, word ShiftM, word ShiftK ) {
- if (A!=NULL) {
- A = A + ShiftN; // back shift for the work of heap system
- for (word i=0;i<N;i++)
- FreeMatrixMemory ( A[i],M,ShiftM,ShiftK );
- delete[] A;
- A = NULL;
- }
-}
-
-void FreeMatrix3Memory ( lwmatrix3 & A, word N, word M,
- word ShiftN, word ShiftM, word ShiftK ) {
- if (A!=NULL) {
- A = A + ShiftN; // back shift for the work of heap system
- for (word i=0;i<N;i++)
- FreeMatrixMemory ( A[i],M,ShiftM,ShiftK );
- delete[] A;
- A = NULL;
- }
-}
-
-void FreeMatrix3Memory ( psmatrix3 & A, word N, word M,
- word ShiftN, word ShiftM, word ShiftK ) {
- if (A!=NULL) {
- A = A + ShiftN; // back shift for the work of heap system
- for (word i=0;i<N;i++)
- FreeMatrixMemory ( A[i],M,ShiftM,ShiftK );
- delete[] A;
- A = NULL;
- }
-}
-
-realtype MachinEps () {
-// A1.3.1 : Calculation of the machine's epsilon
-/*
-realtype rMachEps = 1.0;
- do
- rMachEps /= 2.0;
- while ((1.0+rMachEps)!=1.0);
- return 2.0*rMachEps;
-*/
- return std::numeric_limits<realtype>::epsilon();
-}
-
-realtype floatMachinEps() {
-// A1.3.1 : Calculation of the machine's epsilon
-/*
-float fMachEps = 1.0;
- do
- fMachEps /= 2.0;
- while (float(1.0+fMachEps)!=1.0);
- return 2.0*fMachEps;
-*/
- return std::numeric_limits<float>::epsilon();
-}
-
-realtype frac ( realtype R ) {
-realtype i;
- return modf ( R,&i );
-}
-
-long mod ( long x, long y ) {
-long k=x/y;
-long f=x-k*y;
- while (f<0) f += y;
- return f;
-}
-
-realtype Pow ( realtype X, int y ) {
-int m,l;
-realtype B;
- if (y==0) return 1.0;
- else if (X!=0.0) {
- B = X;
- m = 1;
- if (y>=0) l = y;
- else l = -y;
- while (m++<l) B = B*X;
- if (y>=0) return B;
- else return 1.0/B;
- } else return 0.0;
-}
-
-realtype Pow1 ( realtype X, realtype Y ) {
-int k = mround(Y);
- if (fabs(k-Y)<=100.0*MachEps) return Pow(X,k);
- if (X==0.0) return 0.0;
- else return pow(X,Y);
-}
-
-realtype Exp ( realtype X ) {
-//realtype X1 = X;
-//realtype B = 1.0;
- if (X>=LnMaxRealExp) return MaxReal;
- else if (X<=LnMinRealExp) return 0.0;
- else {
- return exp(X);
- /*
- while (X1>LnMaxReal) {
- X1 -= LnMaxReal;
- B *= MaxExponent;
- }
- while (X1<-LnMaxReal) {
- X1 += LnMaxReal;
- B /= MaxExponent;
- }
- return B*exp(X1);
- */
- }
-}
-
-Boolean Odd ( int i ) {
- return (i & 1);
-}
-
-
-// ----------------------------------------------------
-
-long HexValL ( cpstr S ) {
-char C;
-int i;
-long z=0;
- for (i=0;S[i];i++) {
- z <<= 4;
- C = (char)toupper(S[i]);
- if (isdigit(C)) z += S[i]-'0';
- else z += C-'A'+10;
- }
- return z;
-}
-
-
-// ----------------------------------------------------
-
-long OctValL ( cpstr S ) {
-int i;
-long z=0;
- for (i=0;S[i];i++) {
- z <<= 3;
- z += S[i]-'0';
- }
- return z;
-}
-
-
-// ----------------------------------------------------
-
-long BinValL ( cpstr S ) {
-int i;
-long z=0;
- for (i=0;S[i];i++) {
- z <<= 1;
- z += S[i]-'0';
- }
- return z;
-}
-
-pstr BinValS ( long L, pstr S ) {
-int i;
-long z;
- z = long(1) << (8*sizeof(long)-1);
- for (i=0;i<8*(int)sizeof(long);i++) {
- if (L & z) S[i] = '1';
- else S[i] = '0';
- z >>= 1;
- }
- S[8*sizeof(long)] = char(0);
- return S;
-}
-
-
-
-// ----------------------------------------------------
-
-pstr ParamStr ( pstr D, cpstr S, realtype V, int M, cpstr S1 ) {
-char VS[30];
- strcat ( D,S );
- sprintf ( VS,"%-.*g",M,V );
- strcat ( D,VS );
- return strcat(D,S1);
-}
-
-
-pstr ParamStr ( pstr D, cpstr S, realtype V, int M,
- cpstr S1, realtype V2, int M2, cpstr S2 ) {
-char VS[30];
- ParamStr ( D,S,V,M,S1 );
- sprintf ( VS,"%-.*g",M2,V2 );
- strcat ( D,VS );
- return strcat(D,S2);
-}
-
-
-pstr CreateCopy ( pstr & Dest, cpstr Source ) {
- if (Dest) delete[] Dest;
- if (Source) {
- Dest = new char[strlen(Source)+1];
- strcpy ( Dest,Source );
- } else
- Dest = NULL;
- return Dest;
-}
-
-pstr CreateCopy_n ( pstr & Dest, cpstr Source, int n ) {
-int l;
- if (Dest) delete[] Dest;
- if (Source) {
- l = IMin ( strlen(Source),n );
- Dest = new char[l+1];
- strncpy ( Dest,Source,l );
- Dest[l] = char(0);
- } else
- Dest = NULL;
- return Dest;
-}
-
-pstr CreateCopCat ( pstr & Dest,
- cpstr Source1, cpstr Source2,
- cpstr Source3, cpstr Source4,
- cpstr Source5 ) {
- if (Dest) {
- delete[] Dest;
- Dest = NULL;
- }
- return CreateConcat ( Dest,Source1,Source2,Source3,Source4,Source5 );
-}
-
-pstr CreateCopCat ( pstr & Dest,
- cpstr Source1, cpstr Source2,
- cpstr Source3, cpstr Source4 ) {
- if (Dest) {
- delete[] Dest;
- Dest = NULL;
- }
- return CreateConcat ( Dest,Source1,Source2,Source3,Source4 );
-}
-
-pstr CreateCopCat ( pstr & Dest,
- cpstr Source1, cpstr Source2,
- cpstr Source3 ) {
- if (Dest) {
- delete[] Dest;
- Dest = NULL;
- }
- return CreateConcat ( Dest,Source1,Source2,Source3 );
-}
-
-pstr CreateCopCat ( pstr & Dest,
- cpstr Source1, cpstr Source2 ) {
- if (Dest) {
- delete[] Dest;
- Dest = NULL;
- }
- return CreateConcat ( Dest,Source1,Source2 );
-}
-
-
-pstr CreateConcat ( pstr & Dest,
- cpstr Source1, cpstr Source2,
- cpstr Source3, cpstr Source4,
- cpstr Source5 ) {
-pstr S;
-int ld,ls;
- if (Dest) ld = strlen(Dest);
- else ld = 0;
- ls = 0;
- if (Source1) ls += strlen(Source1);
- if (Source2) ls += strlen(Source2);
- if (Source3) ls += strlen(Source3);
- if (Source4) ls += strlen(Source4);
- if (Source5) ls += strlen(Source5);
- if (ls>0) {
- S = new char[ls+ld+1];
- if (Dest) {
- strcpy ( S,Dest );
- delete[] Dest;
- } else
- S[0] = char(0);
- if (Source1) strcat ( S,Source1 );
- if (Source2) strcat ( S,Source2 );
- if (Source3) strcat ( S,Source3 );
- if (Source4) strcat ( S,Source4 );
- if (Source5) strcat ( S,Source5 );
- Dest = S;
- }
- return Dest;
-}
-
-
-pstr CreateConcat ( pstr & Dest,
- cpstr Source1, cpstr Source2,
- cpstr Source3, cpstr Source4 ) {
-pstr S;
-int ld,ls;
- if (Dest) ld = strlen(Dest);
- else ld = 0;
- ls = 0;
- if (Source1) ls += strlen(Source1);
- if (Source2) ls += strlen(Source2);
- if (Source3) ls += strlen(Source3);
- if (Source4) ls += strlen(Source4);
- if (ls>0) {
- S = new char[ls+ld+1];
- if (Dest) {
- strcpy ( S,Dest );
- delete[] Dest;
- } else
- S[0] = char(0);
- if (Source1) strcat ( S,Source1 );
- if (Source2) strcat ( S,Source2 );
- if (Source3) strcat ( S,Source3 );
- if (Source4) strcat ( S,Source4 );
- Dest = S;
- }
- return Dest;
-}
-
-
-pstr CreateConcat ( pstr & Dest,
- cpstr Source1, cpstr Source2,
- cpstr Source3 ) {
-pstr S;
-int ld,ls;
- if (Dest) ld = strlen(Dest);
- else ld = 0;
- ls = 0;
- if (Source1) ls += strlen(Source1);
- if (Source2) ls += strlen(Source2);
- if (Source3) ls += strlen(Source3);
- if (ls>0) {
- S = new char[ls+ld+1];
- if (Dest) {
- strcpy ( S,Dest );
- delete[] Dest;
- } else
- S[0] = char(0);
- if (Source1) strcat ( S,Source1 );
- if (Source2) strcat ( S,Source2 );
- if (Source3) strcat ( S,Source3 );
- Dest = S;
- }
- return Dest;
-}
-
-pstr CreateConcat ( pstr & Dest,
- cpstr Source1, cpstr Source2 ) {
-pstr S;
-int ld,ls;
- if (Dest) ld = strlen(Dest);
- else ld = 0;
- ls = 0;
- if (Source1) ls += strlen(Source1);
- if (Source2) ls += strlen(Source2);
- if (ls>0) {
- S = new char[ls+ld+1];
- if (Dest) {
- strcpy ( S,Dest );
- delete[] Dest;
- } else
- S[0] = char(0);
- if (Source1) strcat ( S,Source1 );
- if (Source2) strcat ( S,Source2 );
- Dest = S;
- }
- return Dest;
-}
-
-pstr CreateConcat ( pstr & Dest, cpstr Source ) {
-pstr S;
-int ld,ls;
- if (Dest) ld = strlen(Dest);
- else ld = 0;
- if (Source) ls = strlen(Source);
- else ls = 0;
- if (ls>0) {
- S = new char[ls+ld+1];
- if (Dest) {
- strcpy ( S,Dest );
- delete[] Dest;
- } else
- S[0] = char(0);
- strcat ( S,Source );
- Dest = S;
- }
- return Dest;
-}
-
-
-pstr LastOccurence ( cpstr S, char c ) {
-pstr P=(pstr)S;
-pstr R=NULL;
- while (*P) {
- if (*P==c) R = P;
- P++;
- }
- return R;
-}
-
-
-pstr FirstOccurence ( cpstr S, char c ) {
-pstr P=(pstr)S;
- while (*P) {
- if (*P==c) return P;
- P++;
- }
- return NULL;
-}
-
-int indexOf ( cpstr S, char c ) {
-int i=0;
- while (S[i]) {
- if (S[i]==c) return i;
- i++;
- }
- return -1;
-}
-
-pstr FirstOccurence ( cpstr S, int Slen, cpstr Q, int Qlen ) {
-int i,j,k,l;
- l = Slen-Qlen;
- for (i=0;i<=l;i++) {
- j = 0;
- k = i;
- while (j<Qlen)
- if (S[k++]!=Q[j]) break;
- else j++;
- if (j>=Qlen) return pstr(&(S[i]));
- }
- return NULL;
-}
-
-int indexOf ( cpstr S, int Slen, cpstr Q, int Qlen ) {
-int i,j,k,l;
- l = Slen-Qlen;
- for (i=0;i<=l;i++) {
- j = 0;
- k = i;
- while (j<Qlen)
- if (S[k++]!=Q[j]) break;
- else j++;
- if (j>=Qlen) return i;
- }
- return -1;
-}
-
-
-pstr LowerCase ( pstr s ) {
-pstr p=s;
- while (*p) {
- *p = char(tolower(int(*p)));
- p++;
- }
- return s;
-}
-
-pstr UpperCase ( pstr s ) {
-pstr p=s;
- while (*p) {
- *p = char(toupper(int(*p)));
- p++;
- }
- return s;
-}
-
-
-void GetString ( pstr L, cpstr S, int M ) {
-// Copies first M characters of string S into string L,
-// appending the terminating null. If S contains less
-// then M characters, L will be padded with spaces.
-int i,j;
- i = 0;
- j = 0;
- while (S[i] && (i<M))
- L[j++] = S[i++];
- while (j<M)
- L[j++] = ' ';
- L[j] = char(0);
-}
-
-
-void GetStrTer ( pstr L, cpstr S, int n, int LMax, int SMax ) {
-// Copies at least n (or LMax if LMax<n) first symbols of
-// string S into string L, then continues copying until first
-// space or terminating null is found. If the terminating null
-// is met among the first n characters or if SMax<n, the string
-// L will be padded with spaces till the length of minimum of
-// n and LMax and then terminated with the null.
-// SMax are buffer lengths of L and S, respectively. Even if
-// no space is found, the last character in L will be the
-// terminating null.
-int i,k,lm1,msl,mnsl;
- lm1 = LMax-1;
- msl = IMin(lm1,SMax);
- mnsl = IMin(n,msl);
- k = 0;
- for (i=0;i<mnsl;i++)
- if (S[i]) L[k++] = S[i];
- else break;
- if ((k>=SMax) || (!S[k])) {
- lm1 = IMin(n,lm1);
- while (k<lm1)
- L[k++] = ' ';
- } else {
- lm1 = k;
- for (i=lm1;i<msl;i++)
- if (S[i] && (S[i]!=' ')) L[k++] = S[i];
- else break;
- }
- L[k] = char(0);
-}
-
-
-void GetStrTerWin32File ( pstr L, cpstr S, int n, int LMax,
- int SMax ) {
-//
-// Version of GetStrTer(..) allowing for spaces in the string.
-//
-// Copies at least n (or LMax if LMax<n) first symbols of
-// string S into string L, then continues copying until first
-// terminating null is found. If the terminating null
-// is met among the first n characters or if SMax<n, the string
-// L will be padded with spaces till the length of minimum of
-// n and LMax and then terminated with the null.
-// SMax are buffer lengths of L and S, respectively. The last
-// character in L will be the terminating null.
-//
-int i,k,lm1,msl,mnsl;
- lm1 = LMax-1;
- msl = IMin(lm1,SMax);
- mnsl = IMin(n,msl);
- k = 0;
- for (i=0;i<mnsl;i++)
- if (S[i]) L[k++] = S[i];
- else break;
- if ((!S[k]) || (k>=SMax)) {
- lm1 = IMin(n,lm1);
- while (k<lm1)
- L[k++] = ' ';
- } else {
- lm1 = k;
- for (i=lm1;i<msl;i++)
- if (S[i]) L[k++] = S[i];
- else break;
- }
- L[k] = char(0);
-}
-
-void strcpy_n ( pstr d, cpstr s, int n ) {
-// Copies at most n symbols from string s to d, but
-// no more than strlen(s) (s must contain a terminating
-// null). The terminating null IS NEITHER appended NOR
-// copied to d.
-int i;
- i = 0;
- while ((i<n) && (s[i])) {
- d[i] = s[i];
- i++;
- }
-}
-
-
-void strcpy_n1 ( pstr d, cpstr s, int n ) {
-// Copies at most n last symbols from string s to d, but
-// no more than strlen(s) (s must contain a terminating null).
-// The string in d is aligned to the right and added with
-// spaces at the left, if necessary. The terminating null
-// IS NEITHER appended NOR copied to d.
-int i,k;
- i = n-1;
- k = strlen(s)-1;
- while ((i>=0) && (k>=0))
- d[i--] = s[k--];
- while (i>=0)
- d[i--] = ' ';
-}
-
-void strcpy_nr ( pstr d, cpstr s, int n ) {
-// Copies at most n symbols from string s to d, but
-// no more than strlen(s) (s must contain a terminating null).
-// The string in d is aligned to the right and added with
-// spaces at the left, if necessary. The terminating null
-// IS NEITHER appended NOR copied to d.
-int i,k;
- i = n-1;
- k = IMin(i,strlen(s)-1);
- while ((i>=0) && (k>=0))
- d[i--] = s[k--];
- while (i>=0)
- d[i--] = ' ';
-}
-
-
-void strcpy_ns ( pstr d, cpstr s, int n ) {
-// Copies at most n symbols from string s to d, but
-// no more than strlen(s) (s must contain a terminating
-// null). The terminating null IS NEITHER appended NOR
-// copied to d; rather, d is padded with spaces if
-// strlen(s)<n.
-int i;
- i = 0;
- while ((i<n) && (s[i])) {
- d[i] = s[i];
- i++;
- }
- while (i<n)
- d[i++] = ' ';
-}
-
-
-pstr strcpy_cs ( pstr d, cpstr s ) {
-// Copies string s to string d cutting all spaces at
-// at the end. Thus, " abcde " will be copied like
-// " abcde" (terminating null appended).
-// The function returns d.
-int i;
- i = 0;
- while (s[i]) {
- d[i] = s[i];
- i++;
- }
- i--;
- while ((i>0) && (d[i]==' ')) i--;
- if (d[i]==' ') d[i] = char(0);
- else d[i+1] = char(0);
- return d;
-}
-
-
-pstr strcpy_ncs ( pstr d, cpstr s, int n ) {
-// Copies at most n characters from string s to string d
-// cutting all spaces at at the end. Thus, " abcde " will
-// be copied like " abc" at n=4 and like " abcde" at n>5
-// (terminating null appended).
-// The function returns d.
-int i;
- i = 0;
- while (s[i] && (i<n)) {
- d[i] = s[i];
- i++;
- }
- i--;
- while ((i>0) && (d[i]==' ')) i--;
- if (d[i]==' ') d[i] = char(0);
- else d[i+1] = char(0);
- return d;
-}
-
-pstr strcpy_css ( pstr d, cpstr s ) {
-// Copies string s to string d cutting all spaces at
-// at the begining and at the end. Thus, " ab c de "
-// will be copied like "ab c de" (terminating null
-// appended).
-// The function returns d.
-int i,k;
- i = 0;
- while (s[i]==' ') i++;
- k = 0;
- while (s[i])
- d[k++] = s[i++];
- if (k>0) {
- k--;
- while ((k>0) && (d[k]==' ')) k--;
- if (d[k]==' ') d[k] = char(0);
- else d[k+1] = char(0);
- } else
- d[k] = char(0);
- return d;
-}
-
-pstr strcpy_ncss ( pstr d, cpstr s, int n ) {
-// Copies at most n characters from string s to string d cutting
-// all spaces at the begining and at the end. Thus, " ab c de "
-// will be copied like "ab" at n=3 (terminating null appended).
-// The function returns d.
-int i,k;
- i = 0;
- while ((s[i]==' ') && (i<n)) i++;
- k = 0;
- while (s[i] && (i<n))
- d[k++] = s[i++];
- if (k>0) {
- k--;
- while ((k>0) && (d[k]==' ')) k--;
- if (d[k]==' ') d[k] = char(0);
- else d[k+1] = char(0);
- } else
- d[k] = char(0);
- return d;
-}
-
-
-pstr strcpy_n0 ( pstr d, cpstr s, int n ) {
-// Copies at most n symbols from string s to d, but
-// no more than strlen(s) (s must contain a terminating
-// null). The terminating null IS appended to d.
-// The function returns d.
-int i;
- i = 0;
- while ((i<n) && (s[i])) {
- d[i] = s[i];
- i++;
- }
- d[i] = char(0);
- return d;
-}
-
-
-int strlen_des ( cpstr s ) {
-// strlen_des returns the length of a string as if all extra
-// spaces from the latter have been deleted. Extra spaces
-// include all leading and tracing spaces and any sequential
-// spaces when more than one. The string does not change.
-int i,l;
- l = 0;
- i = 0;
- while (s[i]==' ') i++;
- while (s[i]) {
- if ((s[i]!=' ') || ((s[i+1]!=' ') && s[i+1]))
- l++;
- i++;
- }
- return l;
-}
-
-pstr strcpy_des ( pstr d, cpstr s ) {
-// strcpy_des copies string s into string d removing all extra
-// spaces from the latter. Extra spaces include all leading and
-// tracing spaces and any sequential spaces when more than one.
-int i,j;
- j = 0;
- i = 0;
- while (s[i]==' ') i++;
- while (s[i]) {
- if ((s[i]!=' ') || ((s[i+1]!=' ') && s[i+1]))
- d[j++] = s[i];
- i++;
- }
- d[j] = char(0);
- return d;
-}
-
-pstr strcat_des ( pstr d, cpstr s ) {
-// strcpy_des appends string s to string d removing all extra
-// spaces from the latter. Extra spaces include all leading and
-// tracing spaces and any sequential spaces when more than one.
-int i,j;
- j = strlen(d);
- i = 0;
- while (s[i]==' ') i++;
- while (s[i]) {
- if ((s[i]!=' ') || ((s[i+1]!=' ') && s[i+1]))
- d[j++] = s[i];
- i++;
- }
- d[j] = char(0);
- return d;
-}
-
-
-void PadSpaces ( pstr S, int len ) {
-// Pads string S with spaces making its length equal to len.
-// The terminating zero is added, so that S should reserve
-// space of a minimum len+1 characters.
-int i=strlen(S);
- while (i<len) S[i++] = ' ';
- S[i] = char(0);
-}
-
-
-pstr CutSpaces ( pstr S, int CutKey ) {
-// Cuts spaces at the begining or end of string S
-// according to the value of CutKey. THe function
-// returns S;
-int i,k;
- i = 0;
- k = 0;
- if (CutKey & SCUTKEY_BEGIN)
- while (S[i]==' ') i++;
- if (k<i)
- while (S[i])
- S[k++] = S[i++];
- else
- k = strlen(S);
- if ((CutKey & SCUTKEY_END) && (k>0)) {
- k--;
- while ((k>0) && (S[k]==' ')) k--;
- if (S[k]!=' ') k++;
- }
- S[k] = char(0);
- return S;
-}
-
-
-pstr DelSpaces ( pstr S, char c ) {
-// Removes all spaces (or other symbols as specified by 'c')
-// from the string. The string is then shrinked by the number
-// of removed characters. Thus, " as ttt " becomes "asttt".
-int i,j;
- j = 0;
- for (i=0;S[i];i++)
- if (S[i]!=c) {
- if (j<i) S[j] = S[i];
- j++;
- }
- S[j] = char(0);
- return S;
-}
-
-pstr EnforceSpaces ( pstr S ) {
-int i,k;
- i = 0;
- while (S[i]) {
- k = int(S[i]);
- if ((k<32) && (k!=9) && (k!=10) && (k!=13)) S[i] = ' ';
- i++;
- }
- return S;
-}
-
-
-// ----------------------------------------------------
-
-#define _fbase 256
-#define _rfbase 256.0
-#define _fsign 0x80
-#define _fsign1 0x7F
-
-#ifdef UseDoubleFloat
-# define _nfPowers 255
-# define _nfPower0 127
-# define _nfPower8 135
-//# define _nfPower4 131
-# define _nfPower4 130
-#else
-# define _nfPowers 31
-# define _nfPower0 15
-# define _nfPower8 19
-# define _nfPower4 19
-#endif
-
-static realtype _fpower[_nfPowers+1];
-static realtype _fpower8;
-static realtype _fpower4;
-static Boolean _old_float_unibin;
-
-Boolean InitFPowers() {
-int i;
- _fpower[_nfPower0] = 1.0;
- for (i=1;i<=_nfPower0;i++) {
- _fpower[_nfPower0+i] = _fpower[_nfPower0+i-1]*_rfbase;
- _fpower[_nfPower0-i] = _fpower[_nfPower0-i+1]/_rfbase;
- }
- _fpower[_nfPowers] = fMaxReal;
- _fpower8 = _fpower[_nfPower8];
- _fpower4 = _fpower[_nfPower4];
- _old_float_unibin = False;
- return True;
-}
-
-void __modify4() {
- _fpower4 = _fpower[_nfPower4-1];
-}
-
-void set_new_float_unibin() {
- _old_float_unibin = False;
-}
-
-Boolean is_new_float_unibin() {
- return !_old_float_unibin;
-}
-
-void set_old_float_unibin() {
- _old_float_unibin = True;
-}
-
-/*
-void int2UniBin ( int I, intUniBin iUB ) {
-int j,n,sh;
- sh = 8*(sizeof(intUniBin)-1);
- for (j=sizeof(intUniBin)-1;j>=0;j--) {
- n = (I >> sh) & 0xFF;
- iUB[j] = byte(n);
- sh -= 8;
- }
-}
-*/
-
-void int2UniBin ( int I, intUniBin iUB ) {
-int n;
-word j;
- n = I;
- for (j=0;j<sizeof(intUniBin);j++) {
- iUB[j] = byte(n & 0xFF);
- n >>= 8;
- }
-}
-
-void short2UniBin ( short S, shortUniBin sUB ) {
-int j,sh;
-short n;
- sh = 8*(sizeof(shortUniBin)-1);
- for (j=sizeof(shortUniBin)-1;j>=0;j--) {
- n = (S >> sh) & 0xFF;
- sUB[j] = byte(n);
- sh -= 8;
- }
-}
-
-void long2UniBin ( long L, longUniBin lUB ) {
-int j,sh;
-long n;
- sh = 8*(sizeof(longUniBin)-1);
- for (j=sizeof(longUniBin)-1;j>=0;j--) {
- n = (L >> sh) & 0xFF;
- lUB[j] = byte(n);
- sh -= 8;
- }
-}
-
-void word2UniBin ( word W, wordUniBin wUB ) {
-int j,sh;
-word n;
- sh = 8*(sizeof(wordUniBin)-1);
- for (j=sizeof(wordUniBin)-1;j>=0;j--) {
- n = (W >> sh) & 0xFF;
- wUB[j] = byte(n);
- sh -= 8;
- }
-}
-
-
-void real2UniBin ( realtype R, realUniBin rUB ) {
-int k1,k2,k;
-realtype Q,L;
- if (R>=0) Q = R;
- else Q = -R;
- k1 = 0;
- k2 = _nfPowers;
- do {
- k = (k1+k2)/2;
- if (Q>=_fpower[k]) k1 = k;
- else k2 = k;
- } while (k2>k1+1);
- if (Q<=_fpower[0]) k2 = 0;
- Q = (Q/_fpower[k2])*_fpower8;
- rUB[0] = byte(k2);
- for (k=sizeof(realUniBin)-1;k>0;k--) {
- L = floor(Q/_rfbase);
- rUB[k] = byte(int(Q-L*_rfbase));
- Q = L;
- }
- if (R<0) rUB[1] |= _fsign;
-
-}
-
-void shortreal2UniBin ( shortreal R, shortrealUniBin srUB ) {
-int k1,k2,k;
-realtype Q,L;
-
- if (R>=0) Q = R;
- else Q = -R;
- k1 = 0;
- k2 = _nfPowers;
- do {
- k = (k1+k2)/2;
- if (Q>=_fpower[k]) k1 = k;
- else k2 = k;
- } while (k2>k1+1);
- if (Q<=_fpower[0]) k2 = 0;
- Q = (Q/_fpower[k2])*_fpower4;
- srUB[0] = byte(k2);
- for (k=sizeof(shortrealUniBin)-1;k>0;k--) {
- L = floor(Q/_rfbase);
- srUB[k] = byte(int(Q-L*_rfbase));
- Q = L;
- }
- if (R<0) srUB[1] |= _fsign;
-
-}
-
-/*
-#undef _new_float_unibin
-
-#ifdef _new_float_unibin
-
-void float2UniBin ( realtype R, floatUniBin fUB ) {
-int k1,k2,k;
-realtype Q,L;
-
- if (R>=0) Q = R;
- else Q = -R;
- k1 = 0;
- k2 = _nfPowers;
- do {
- k = (k1+k2)/2;
- if (Q>=_fpower[k]) k1 = k;
- else k2 = k;
- } while (k2>k1+1);
- if (Q<=_fpower[0]) k2 = 0;
- Q = (Q/_fpower[k2])*_fpower4;
- fUB[0] = byte(k2);
- for (k=sizeof(floatUniBin)-1;k>0;k--) {
- L = floor(Q/_rfbase);
- fUB[k] = byte(int(Q-L*_rfbase));
- Q = L;
- }
- if (R<0) fUB[1] |= _fsign;
-
-}
-
-#else
-
-void float2UniBin ( realtype R, floatUniBin fUB ) {
-int k1,k2,k;
-realtype Q,L;
- if (R>=0) Q = R;
- else Q = -R;
- k1 = 0;
- k2 = _nfPowers;
- do {
- k = (k1+k2)/2;
- if (Q>=_fpower[k]) k1 = k;
- else k2 = k;
- } while (k2>k1+1);
- if (Q<=_fpower[0]) k2 = 0;
- Q = (Q/_fpower[k2])*_fpower8;
- fUB[0] = byte(k2);
- for (k=sizeof(realUniBin)-1;k>0;k--) {
- L = floor(Q/_rfbase);
- if (k<=sizeof(floatUniBin))
- fUB[k] = byte(int(Q-L*_rfbase));
- Q = L;
- }
- if (R<0) fUB[1] |= _fsign;
-
-}
-
-#endif
-*/
-
-void float2UniBin ( realtype R, floatUniBin fUB ) {
-int k1,k2,k;
-realtype Q,L;
-
- if (R>=0) Q = R;
- else Q = -R;
- k1 = 0;
- k2 = _nfPowers;
- do {
- k = (k1+k2)/2;
- if (Q>=_fpower[k]) k1 = k;
- else k2 = k;
- } while (k2>k1+1);
- if (Q<=_fpower[0]) k2 = 0;
- fUB[0] = byte(k2);
-
- if (_old_float_unibin) {
- // this is wrong but compatible with already existing files :(
- // in the result, it gives errors in 6th digit at back conversion
- Q = (Q/_fpower[k2])*_fpower8;
- for (k=sizeof(realUniBin)-1;k>0;k--) {
- L = floor(Q/_rfbase);
- if (k<=(int)sizeof(floatUniBin))
- fUB[k] = byte(int(Q-L*_rfbase));
- Q = L;
- }
- } else {
- // this is correct
- Q = (Q/_fpower[k2])*_fpower4;
- for (k=sizeof(floatUniBin)-1;k>0;k--) {
- L = floor(Q/_rfbase);
- fUB[k] = byte(int(Q-L*_rfbase));
- Q = L;
- }
- }
-
-//if (fUB[1] & _fsign) printf ( " error!\n" );
-
- if (R<0) fUB[1] |= _fsign;
-
-}
-
-
-void UniBin2float ( floatUniBin fUB, realtype & R ) {
-int j,s;
-
- if (fUB[1] & _fsign) {
- s = 1;
- fUB[1] &= _fsign1;
- } else
- s = 0;
-
- R = int(fUB[1]);
-
- if (_old_float_unibin) {
- // this is wrong and gives a conversion error in 6th digit :(
- // we have to keep this for compatibility with already existing
- // files
- for (j=2;j<(int)sizeof(floatUniBin);j++)
- R = R*_rfbase + int(fUB[j]);
- for (j=sizeof(floatUniBin);j<(int)sizeof(realUniBin);j++)
- R *= _rfbase;
- R = (R/_fpower8)*_fpower[int(fUB[0])];
- } else {
- // this is correct
- for (j=2;j<(int)sizeof(floatUniBin);j++)
- R = R*_rfbase + int(fUB[j]);
- R = (R/_fpower4)*_fpower[int(fUB[0])];
- }
- if (s) R = -R;
-}
-
-
-/* -------------------------------------------------------
- This piece of code shows that float2Unibin - Unbin2float
- pair does same-quality job as the native float - double
- conversion:
-
- InitMatType();
- set_new_float_unibin();
-
- floatUniBin fUB;
- realUniBin rUB;
- realtype maxsh = MaxShortReal/2.0; // max manageable /2!
- float maxshf = maxsh;
- realtype maxshr = maxshf;
- realtype maxsh1;
-
- float2UniBin ( maxsh,fUB );
- UniBin2float ( fUB,maxsh1 );
-
- printf ( " float\n %10.3f\n %10.3f\n %10.3f\n %10.3f\n",
- maxsh,maxsh1,maxshf,maxshr );
-
- maxsh = MaxShortReal;
- real2UniBin ( maxsh,rUB );
- UniBin2real ( rUB,maxsh1 );
-
- printf ( " real\n %10.3f\n %10.3f\n",maxsh,maxsh1 );
-
----- RESULTS:
-
- float
- 170099999999999990938343446679146987520.000
- 170099999948540854500627141228603899904.000
- 170100000027769017014891478822147850240.000
- 170100000027769017014891478822147850240.000
- real
- 340199999999999981876686893358293975040.000
- 340199999999999981876686893358293975040.000
-
--------------------------------------------------------------- */
-
-/*
-void shortreal2UniBin ( shortreal R, shortrealUniBin srUB ) {
-int k1,k2,k;
-realtype Q,L;
-
- if (R>=0) Q = R;
- else Q = -R;
- k1 = 0;
- k2 = _nfPowers;
- do {
- k = (k1+k2)/2;
- if (Q>=_fpower[k]) k1 = k;
- else k2 = k;
- } while (k2>k1+1);
- if (Q<=_fpower[0]) k2 = 0;
- Q = (Q/_fpower[k2])*_fpower8;
- srUB[0] = byte(k2);
- for (k=sizeof(realUniBin)-1;k>0;k--) {
- L = floor(Q/_rfbase);
- if (k<=(int)sizeof(shortrealUniBin))
- srUB[k] = byte(int(Q-L*_rfbase));
- Q = L;
- }
- if (R<0) srUB[1] |= _fsign;
-
-}
-
-void float2UniBin ( realtype R, floatUniBin fUB ) {
-int k1,k2,k;
-realtype Q,L;
-
- if (R>=0) Q = R;
- else Q = -R;
- k1 = 0;
- k2 = _nfPowers;
- do {
- k = (k1+k2)/2;
- if (Q>=_fpower[k]) k1 = k;
- else k2 = k;
- } while (k2>k1+1);
- if (Q<=_fpower[0]) k2 = 0;
- Q = (Q/_fpower[k2])*_fpower8;
- fUB[0] = byte(k2);
- for (k=sizeof(realUniBin)-1;k>0;k--) {
- L = floor(Q/_rfbase);
- if (k<=(int)sizeof(floatUniBin))
- fUB[k] = byte(int(Q-L*_rfbase));
- Q = L;
- }
- if (R<0) fUB[1] |= _fsign;
-
-}
-*/
-
-/*
-void UniBin2int ( intUniBin iUB, int & I ) {
-int j,n,sh;
- sh = 8*sizeof(intUniBin);
- I = 0x00;
- for (j=sizeof(intUniBin)-1;j>=0;j--) {
- sh -= 8;
- n = byte(iUB[j]);
- I = I | (n << sh);
- }
-}
-*/
-
-void UniBin2int ( intUniBin iUB, int & I ) {
-int j;
- I = 0x00;
- for (j=sizeof(intUniBin)-1;j>=0;j--) {
- I <<= 8;
- I |= int(iUB[j]);
- }
-}
-
-void UniBin2short ( shortUniBin sUB, short & S ) {
-int j,sh;
-short n;
- sh = 8*sizeof(shortUniBin);
- S = 0x00;
- for (j=sizeof(shortUniBin)-1;j>=0;j--) {
- sh -= 8;
- n = byte(sUB[j]);
- S = S | (n << sh);
- }
-}
-
-void UniBin2long ( longUniBin lUB, long & L ) {
-int j,sh;
-long n;
- sh = 8*sizeof(longUniBin);
- L = 0x00;
- for (j=sizeof(longUniBin)-1;j>=0;j--) {
- sh -= 8;
- n = byte(lUB[j]);
- L = L | (n << sh);
- }
-}
-
-void UniBin2word ( wordUniBin wUB, word & W ) {
-int j,sh;
-word n;
- sh = 8*sizeof(wordUniBin);
- W = 0x00;
- for (j=sizeof(wordUniBin)-1;j>=0;j--) {
- sh -= 8;
- n = byte(wUB[j]);
- W = W | (n << sh);
- }
-}
-
-void UniBin2real ( realUniBin rUB, realtype & R ) {
-int j,s;
- if (rUB[1] & _fsign) {
- s = 1;
- rUB[1] &= _fsign1;
- } else
- s = 0;
- R = int(rUB[1]);
- for (j=2;j<(int)sizeof(realUniBin);j++)
- R = R*_rfbase + int(rUB[j]);
- R = (R/_fpower8)*_fpower[int(rUB[0])];
- if (s) R = -R;
-}
-
-void UniBin2shortreal ( shortrealUniBin srUB, shortreal & R ) {
-int j,s;
- if (srUB[1] & _fsign) {
- s = 1;
- srUB[1] &= _fsign1;
- } else
- s = 0;
- R = int(srUB[1]);
- for (j=2;j<(int)sizeof(shortrealUniBin);j++)
- R = R*_rfbase + int(srUB[j]);
- R = (R/_fpower4)*_fpower[int(srUB[0])];
- if (s) R = -R;
-}
-
-/*
-#ifdef _new_float_unibin
-
-void UniBin2float ( floatUniBin fUB, realtype & R ) {
-int j,s;
- if (fUB[1] & _fsign) {
- s = 1;
- fUB[1] &= _fsign1;
- } else
- s = 0;
- R = int(fUB[1]);
- for (j=2;j<(int)sizeof(floatUniBin);j++)
- R = R*_rfbase + int(fUB[j]);
- R = (R/_fpower4)*_fpower[int(fUB[0])];
- if (s) R = -R;
-}
-
-#else
-
-void UniBin2float ( floatUniBin fUB, realtype & R ) {
-int j,s;
- if (fUB[1] & _fsign) {
- s = 1;
- fUB[1] &= _fsign1;
- } else
- s = 0;
- R = int(fUB[1]);
- for (j=2;j<sizeof(floatUniBin);j++)
- R = R*_rfbase + int(fUB[j]);
- for (j=sizeof(floatUniBin);j<sizeof(realUniBin);j++)
- R *= _rfbase;
- R = (R/_fpower8)*_fpower[int(fUB[0])];
- if (s) R = -R;
-}
-
-#endif
-*/
-
-
-
-
-
-/*
-void UniBin2shortreal ( shortrealUniBin srUB, shortreal & R ) {
-int j,s;
- if (srUB[1] & _fsign) {
- s = 1;
- srUB[1] &= _fsign1;
- } else
- s = 0;
- R = int(srUB[1]);
- for (j=2;j<(int)sizeof(shortrealUniBin);j++)
- R = R*_rfbase + int(srUB[j]);
- for (j=sizeof(shortrealUniBin);j<(int)sizeof(realUniBin);j++)
- R *= _rfbase;
- R = (R/_fpower8)*_fpower[int(srUB[0])];
- if (s) R = -R;
-}
-
-void UniBin2float ( floatUniBin fUB, realtype & R ) {
-int j,s;
- if (fUB[1] & _fsign) {
- s = 1;
- fUB[1] &= _fsign1;
- } else
- s = 0;
- R = int(fUB[1]);
- for (j=2;j<(int)sizeof(floatUniBin);j++)
- R = R*_rfbase + int(fUB[j]);
- for (j=sizeof(floatUniBin);j<(int)sizeof(realUniBin);j++)
- R *= _rfbase;
- R = (R/_fpower8)*_fpower[int(fUB[0])];
- if (s) R = -R;
-}
-*/
-
-
-void mem_write ( int I, pstr S, int & l ) {
-intUniBin iUB;
- int2UniBin ( I,iUB );
- memcpy ( &(S[l]),iUB,sizeof(intUniBin) );
- l += sizeof(intUniBin);
- S[l] = char(0);
-}
-
-void mem_write ( short I, pstr S, int & l ) {
-shortUniBin sUB;
- short2UniBin ( I,sUB );
- memcpy ( &(S[l]),sUB,sizeof(shortUniBin) );
- l += sizeof(shortUniBin);
- S[l] = char(0);
-}
-
-void mem_write ( long I, pstr S, int & l ) {
-longUniBin lUB;
- long2UniBin ( I,lUB );
- memcpy ( &(S[l]),lUB,sizeof(longUniBin) );
- l += sizeof(longUniBin);
- S[l] = char(0);
-}
-
-void mem_write ( word W, pstr S, int & l ) {
-wordUniBin wUB;
- word2UniBin ( W,wUB );
- memcpy ( &(S[l]),wUB,sizeof(wordUniBin) );
- l += sizeof(wordUniBin);
- S[l] = char(0);
-}
-
-void mem_write ( realtype R, pstr S, int & l ) {
-realUniBin rUB;
- real2UniBin ( R,rUB );
- memcpy ( &(S[l]),rUB,sizeof(realUniBin) );
- l += sizeof(realUniBin);
- S[l] = char(0);
-}
-
-void mem_write ( shortreal R, pstr S, int & l ) {
-shortrealUniBin srUB;
- shortreal2UniBin ( R,srUB );
- memcpy ( &(S[l]),srUB,sizeof(shortrealUniBin) );
- l += sizeof(shortrealUniBin);
- S[l] = char(0);
-}
-
-void mem_write ( pstr L, int len, pstr S, int & l ) {
- memcpy ( &(S[l]),L,len );
- l += len;
- S[l] = char(0);
-}
-
-void mem_write ( pstr L, pstr S, int & l ) {
-int len;
- if (L) len = strlen(L);
- else len = 0;
- mem_write ( len,S,l );
- if (len>0) {
- memcpy ( &(S[l]),L,len );
- l += len;
- S[l] = char(0);
- }
-}
-
-void mem_write ( Boolean B, pstr S, int & l ) {
- if (B) S[l++] = 'Y';
- else S[l++] = 'N';
- S[l] = char(0);
-}
-
-void mem_write_byte ( byte B, pstr S, int & l ) {
- S[l++] = char(B);
- S[l] = char(0);
-}
-
-
-void mem_read ( int & I, cpstr S, int & l ) {
-intUniBin iUB;
- memcpy ( iUB,&(S[l]),sizeof(intUniBin) );
- l += sizeof(intUniBin);
- UniBin2int ( iUB,I );
-}
-
-void mem_read ( short & I, cpstr S, int & l ) {
-shortUniBin sUB;
- memcpy ( sUB,&(S[l]),sizeof(shortUniBin) );
- l += sizeof(shortUniBin);
- UniBin2short ( sUB,I );
-}
-
-void mem_read ( long & I, cpstr S, int & l ) {
-longUniBin lUB;
- memcpy ( lUB,&(S[l]),sizeof(longUniBin) );
- l += sizeof(longUniBin);
- UniBin2long ( lUB,I );
-}
-
-void mem_read ( word & W, cpstr S, int & l ) {
-wordUniBin wUB;
- memcpy ( wUB,&(S[l]),sizeof(wordUniBin) );
- l += sizeof(wordUniBin);
- UniBin2word ( wUB,W );
-}
-
-void mem_read ( realtype & R, cpstr S, int & l ) {
-realUniBin rUB;
- memcpy ( rUB,&(S[l]),sizeof(realUniBin) );
- l += sizeof(realUniBin);
- UniBin2real ( rUB,R );
-}
-
-void mem_read ( shortreal & R, cpstr S, int & l ) {
-shortrealUniBin srUB;
- memcpy ( srUB,&(S[l]),sizeof(shortrealUniBin) );
- l += sizeof(shortrealUniBin);
- UniBin2shortreal ( srUB,R );
-}
-
-void mem_read ( pstr L, int len, cpstr S, int & l ) {
- memcpy ( L,&(S[l]),len );
- l += len;
-}
-
-void mem_read ( pstr & L, cpstr S, int & l ) {
-int len;
- if (L) {
- delete[] L;
- L = NULL;
- }
- mem_read ( len,S,l );
- if (len>0) {
- L = new char[len+1];
- memcpy ( L,&(S[l]),len );
- L[len] = char(0);
- l += len;
- }
-}
-
-void mem_read ( Boolean & B, cpstr S, int & l ) {
- B = (S[l++]=='Y');
-}
-
-void mem_read_byte ( byte & B, cpstr S, int & l ) {
- B = byte(S[l++]);
-}
-
-// -------------------------------------------------------
-
-Boolean InitMatType() {
- MachEps = MachinEps();
- floatMachEps = floatMachinEps();
- LnMaxReal = log(fMaxReal);
- LnMinReal = log(fMinReal);
- LnMaxRealExp = LnMaxReal;
- LnMinRealExp = LnMinReal;
- InitFPowers();
- return True;
-}
-
-/* =================================================== */
-
-// *** end of <MatType>
diff --git a/mmdb/mattype_.h b/mmdb/mattype_.h
deleted file mode 100755
index 43ecd4f..0000000
--- a/mmdb/mattype_.h
+++ /dev/null
@@ -1,659 +0,0 @@
-// $Id: mattype_.h,v 1.30 2012/02/23 23:12:22 gxg60988 Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 29.01.10 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MatType_ <interface>
-// ~~~~~~~~~
-// **** Functions :
-// ~~~~~~~~~~~
-// GetString ( reads substring from a string )
-// GetStrTer ( reads substring and put term-ing null )
-// strcpy_n ( copies not more than n characters )
-// strcpy_ns ( like strcpy_ns and pads with spaces )
-// strcpy_n0 ( like strcpy_n and adds terminating 0 )
-// PadSpaces ( pads a string with spaces )
-//
-// (C) E. Krissinel 2000-2010
-//
-// =================================================================
-//
-
-
-#ifndef __MatType__
-#define __MatType__
-
-#ifndef __MATH_H
-#include <math.h>
-#endif
-
-#define UseDoubleFloat
-
-#ifndef __ClassMacros
-
-# define __ClassMacros
-
- // A Class definition macros
-# define DefineClass(ClassName) \
- class ClassName; \
- typedef ClassName * P##ClassName; \
- typedef ClassName & R##ClassName; \
- typedef P##ClassName * PP##ClassName; \
- typedef P##ClassName & RP##ClassName;
-
- // A Structure definition macros
-# define DefineStructure(StructureName) \
- struct StructureName; \
- typedef StructureName * P##StructureName; \
- typedef StructureName & R##StructureName; \
- typedef P##StructureName * PP##StructureName; \
- typedef P##StructureName & RP##StructureName;
-
-#endif
-
-#define UNUSED_ARGUMENT(x) (void)x
-
-// -----------------------------------------------------
-
-#ifdef UseDoubleFloat
-
-# define MinReal 2.2250e-307
-# define MaxReal 1.7976e+308
-# define fMinReal 2.2250e-307
-# define fMaxReal 1.7976e+308
- typedef double realtype;
-
-#else
-
-# define MinReal 1.1755e-38
-# define MaxReal 3.4020e+38
-# define fMinReal 1.1755e-38
-# define fMaxReal 3.4020e+38
- typedef float realtype;
-
-#endif
-
-typedef float shortreal;
-#define MinShortReal 1.1755e-38
-#define MaxShortReal 3.4020e+38
-
-#define strrchr LastOccurence
-#define fstrrchr LastOccurence
-#define strchr FirstOccurence
-#define fstrchr FirstOccurence
-
-typedef char * pstr;
-typedef const char * cpstr;
-typedef unsigned int word;
-typedef unsigned char byte;
-typedef signed char short_int;
-typedef byte Boolean;
-typedef unsigned int word2;
-typedef byte * byteptr;
-typedef unsigned long lword;
-
-typedef byte intUniBin [4];
-typedef byte shortUniBin [2];
-typedef byte longUniBin [4];
-typedef byte wordUniBin [4];
-typedef byte realUniBin [10];
-typedef byte floatUniBin [5];
-typedef byte shortrealUniBin[5];
-
-#ifdef _WIN32
-pstr strcasestr ( pstr s1, cpstr s2 );
-#endif
-
-#ifdef _MSC_VER
-#define strncasecmp _strnicmp
-#define strcasecmp _stricmp
-#endif
-
-#define True Boolean(1)
-#define False Boolean(0)
-
-#define MaxInt 32767
-#define MinInt (-32768)
-#define MaxWord 65535L
-#define MaxInt4 2147483647
-
-// MinInt4 would have to be defined as -2147483648,
-// however some compilers do not like that. To be on safe,
-// we define it as -2147483647:
-#define MinInt4 (-2147483647)
-#define MaxWord4 4294967295
-
-#define Pi 3.141592653589793238462643
-#define Eu 2.718281828459045235360287
-#define ln10 2.3025850929940456840179915
-
-
-// *** vectors X[1..N] :
-typedef realtype * rvector;
-typedef int * ivector;
-typedef word * wvector;
-typedef byte * bvector;
-typedef long * lvector;
-typedef lword * lwvector;
-typedef pstr * psvector;
-
-// *** matrices X[1..N][1..M] :
-typedef rvector * rmatrix;
-typedef ivector * imatrix;
-typedef wvector * wmatrix;
-typedef bvector * bmatrix;
-typedef lvector * lmatrix;
-typedef lwvector * lwmatrix;
-typedef psvector * psmatrix;
-
-// *** matrices X[1..N][1..M][1..K] :
-typedef rmatrix * rmatrix3;
-typedef imatrix * imatrix3;
-typedef wmatrix * wmatrix3;
-typedef bmatrix * bmatrix3;
-typedef lmatrix * lmatrix3;
-typedef lwmatrix * lwmatrix3;
-typedef psmatrix * psmatrix3;
-
-
-
-// ------------------------------------------------------------
-
-// Initialization. Some C++ enviroments do not do call
-// InitMatType() automatically, therefore it is always
-// advisable to call InitMatType() explicitely from the top of
-// main(). It is completely harmless and cheap (although
-// unnecessary) to call InitMatType() multiple times.
-extern Boolean InitMatType();
-
-// ------------------------------------------------------------
-
-/*
-extern int mround ( realtype X );
-extern int ifloor ( realtype X );
-extern int Abs ( int x );
-
-extern void ISwap ( int & x, int & y );
-extern void WSwap ( word & x, word & y );
-extern void BSwap ( byte & x, byte & y );
-extern void LSwap ( long & x, long & y );
-extern void RSwap ( realtype & x, realtype & y );
-
-extern realtype RMax ( const realtype x1, const realtype x2 );
-extern long LMax ( const long x1, const long x2 );
-extern word WMax ( const word x1, const word x2 );
-extern int IMax ( const int x1, const int x2 );
-extern realtype RMin ( const realtype x1, const realtype x2 );
-extern long LMin ( const long x1, const long x2 );
-extern word WMin ( const word x1, const word x2 );
-extern int IMin ( const int x1, const int x2 );
-extern realtype fsign ( const realtype x1, const realtype x2 );
-*/
-
-inline int mround ( realtype X ) { return (int)floor(X+0.5); }
-inline int ifloor ( realtype X ) { return (int)floor(X); }
-inline int Abs ( int x ) { return ( x >= 0 ? x : -x ); }
-
-inline void ISwap ( int & x, int & y )
-{ int b = x; x = y; y = b; }
-
-inline void WSwap ( word & x, word & y )
-{ word b = x; x = y; y = b; }
-
-inline void BSwap ( byte & x, byte & y )
-{ byte b = x; x = y; y = b; }
-
-inline void LSwap ( long & x, long & y )
-{ long b = x; x = y; y = b; }
-
-inline void RSwap ( realtype & x, realtype & y )
-{ realtype b = x; x = y; y = b; }
-
-inline realtype RMax ( const realtype x1, const realtype x2 )
-{ return ( x1 > x2 ? x1 : x2 ); }
-
-inline long LMax ( const long x1, const long x2 )
-{ return ( x1 > x2 ? x1 : x2 ); }
-
-inline word WMax ( const word x1, const word x2 )
-{ return ( x1 > x2 ? x1 : x2 ); }
-
-inline int IMax ( const int x1, const int x2 )
-{ return ( x1 > x2 ? x1 : x2 ); }
-
-inline realtype RMin ( const realtype x1, const realtype x2 )
-{ return ( x1 < x2 ? x1 : x2 ); }
-
-inline long LMin ( const long x1, const long x2 )
-{ return ( x1 < x2 ? x1 : x2 ); }
-
-inline word WMin ( const word x1, const word x2 )
-{ return ( x1 < x2 ? x1 : x2 ); }
-
-inline int IMin ( const int x1, const int x2 )
-{ return ( x1 < x2 ? x1 : x2 ); }
-
-inline realtype fsign ( const realtype x1, const realtype x2 ) {
-realtype ax;
- if (x1>=0.0) ax = x1;
- else ax = -x1;
- return ( x2 >= 0.0 ? ax : -ax );
-}
-
-
-// ------------------------------------------------------------
-
-// Allocated vectors are enumerated as [Shift..Shift+N-1]
-// rather than [0..N-1] !
-// Get-functions return <true> if memory was allocated;
-// if allocation attemt fails, vector is assigned with NULL
-
-extern Boolean GetVectorMemory ( rvector & V, word N, word Shift=1 );
-extern Boolean GetVectorMemory ( ivector & I, word N, word Shift=1 );
-extern Boolean GetVectorMemory ( wvector & W, word N, word Shift=1 );
-extern Boolean GetVectorMemory ( bvector & B, word N, word Shift=1 );
-extern Boolean GetVectorMemory ( lvector & L, word N, word Shift=1 );
-extern Boolean GetVectorMemory ( lwvector & L, word N, word Shift=1 );
-extern Boolean GetVectorMemory ( psvector & P, word N, word Shift=1 );
-
-// Shift at deallocation MUST be the same as that at allocation !
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Free-functions do nothing if vector has value NULL (e.g.
-// after unsuccessful allocation).
-
-extern void FreeVectorMemory ( rvector & V, word Shift=1 );
-extern void FreeVectorMemory ( ivector & I, word Shift=1 );
-extern void FreeVectorMemory ( wvector & W, word Shift=1 );
-extern void FreeVectorMemory ( bvector & B, word Shift=1 );
-extern void FreeVectorMemory ( lvector & L, word Shift=1 );
-extern void FreeVectorMemory ( lwvector & L, word Shift=1 );
-extern void FreeVectorMemory ( psvector & P, word Shift=1 );
-
-// -------------------------------------------------------------
-
-// Allocated matrices are enumerated as
-// [ShiftN..ShiftN+N-1, ShiftM..ShiftM+M-1]
-// rather than [0..N-1,0..M-1] !
-// Get-functions return <true> if memory was allocated;
-// if allocation attemt fails, matrix is assigned with NULL
-// Free-functions do nothing if matrix has value NULL (e.g.
-// after unsuccessful allocation).
-
-extern Boolean GetMatrixMemory
- ( rmatrix & A, word N, word M, word ShiftN=1, word ShiftM=1 );
-extern Boolean GetMatrixMemory
- ( imatrix & A, word N, word M, word ShiftN=1, word ShiftM=1 );
-extern Boolean GetMatrixMemory
- ( wmatrix & W, word N, word M, word ShiftN=1, word ShiftM=1 );
-extern Boolean GetMatrixMemory
- ( bmatrix & B, word N, word M, word ShiftN=1, word ShiftM=1 );
-extern Boolean GetMatrixMemory
- ( lmatrix & L, word N, word M, word ShiftN=1, word ShiftM=1 );
-extern Boolean GetMatrixMemory
- ( lwmatrix & L, word N, word M, word ShiftN=1, word ShiftM=1 );
-extern Boolean GetMatrixMemory
- ( psmatrix & P, word N, word M, word ShiftN=1, word ShiftM=1 );
-
-// ShiftN and ShiftM at deallocation MUST be the same as those at
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// allocation !
-// ~~~~~~~~~~~~~
-
-extern void FreeMatrixMemory ( rmatrix & A, word N,
- word ShiftN=1, word ShiftM=1 );
-extern void FreeMatrixMemory ( imatrix & A, word N,
- word ShiftN=1, word ShiftM=1 );
-extern void FreeMatrixMemory ( wmatrix & W, word N,
- word ShiftN=1, word ShiftM=1 );
-extern void FreeMatrixMemory ( bmatrix & B, word N,
- word ShiftN=1, word ShiftM=1 );
-extern void FreeMatrixMemory ( lmatrix & L, word N,
- word ShiftN=1, word ShiftM=1 );
-extern void FreeMatrixMemory ( lwmatrix & L, word N,
- word ShiftN=1, word ShiftM=1 );
-extern void FreeMatrixMemory ( psmatrix & P, word N,
- word ShiftN=1, word ShiftM=1 );
-
-
-// -------------------------------------------------------------
-// 3D matrices
-
-extern Boolean GetMatrix3Memory
- ( rmatrix3 & A, word N, word M, word K,
- word ShiftN=1, word ShiftM=1, word ShiftK=1 );
-extern Boolean GetMatrix3Memory
- ( imatrix3 & A, word N, word M, word K,
- word ShiftN=1, word ShiftM=1, word ShiftK=1 );
-extern Boolean GetMatrix3Memory
- ( wmatrix3 & A, word N, word M, word K,
- word ShiftN=1, word ShiftM=1, word ShiftK=1 );
-extern Boolean GetMatrix3Memory
- ( bmatrix3 & A, word N, word M, word K,
- word ShiftN=1, word ShiftM=1, word ShiftK=1 );
-extern Boolean GetMatrix3Memory
- ( lmatrix3 & A, word N, word M, word K,
- word ShiftN=1, word ShiftM=1, word ShiftK=1 );
-extern Boolean GetMatrix3Memory
- ( lwmatrix3 & A, word N, word M, word K,
- word ShiftN=1, word ShiftM=1, word ShiftK=1 );
-extern Boolean GetMatrix3Memory
- ( psmatrix3 & A, word N, word M, word K,
- word ShiftN=1, word ShiftM=1, word ShiftK=1 );
-
-//
-// ShiftN, ShiftM and ShiftK at deallocation MUST be
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// the same as those at allocation !
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-extern void FreeMatrix3Memory
- ( rmatrix3 & A, word N, word M,
- word ShiftN=1, word ShiftM=1, word ShiftK=1 );
-extern void FreeMatrix3Memory
- ( imatrix3 & A, word N, word M,
- word ShiftN=1, word ShiftM=1, word ShiftK=1 );
-extern void FreeMatrix3Memory
- ( wmatrix3 & A, word N, word M,
- word ShiftN=1, word ShiftM=1, word ShiftK=1 );
-extern void FreeMatrix3Memory
- ( bmatrix3 & A, word N, word M,
- word ShiftN=1, word ShiftM=1, word ShiftK=1 );
-extern void FreeMatrix3Memory
- ( lmatrix3 & A, word N, word M,
- word ShiftN=1, word ShiftM=1, word ShiftK=1 );
-extern void FreeMatrix3Memory
- ( lwmatrix3 & A, word N, word M,
- word ShiftN=1, word ShiftM=1, word ShiftK=1 );
-extern void FreeMatrix3Memory
- ( psmatrix3 & A, word N, word M,
- word ShiftN=1, word ShiftM=1, word ShiftK=1 );
-
-// -------------------------------------------------------------
-
-extern realtype MachEps;
-extern realtype floatMachEps;
-extern realtype LnMaxReal;
-extern realtype LnMinReal;
-
-extern realtype MachinEps ();
-extern realtype floatMachinEps();
-extern realtype frac ( realtype R );
-extern long mod ( long x, long y );
-extern realtype Pow ( realtype X, int y );
-extern realtype Pow1 ( realtype X, realtype Y );
-extern realtype Exp ( realtype X ); // use to avoid catastrophies
-extern Boolean Odd ( int i );
-extern long HexValL ( cpstr S );
-extern long OctValL ( cpstr S );
-extern long BinValL ( cpstr S );
-extern pstr BinValS ( long L, pstr S ); // S[sizeof(long)+1] at least
-
-extern pstr ParamStr ( pstr D, cpstr S, realtype V, int M=5,
- cpstr S1=(pstr)"" );
-extern pstr ParamStr ( pstr D, cpstr S, realtype V, int M,
- cpstr S1, realtype V2, int M2=5,
- cpstr S2=(pstr)"" );
-
-
-
-// ---------- Strings
-
-// CreateCopy(..) allocates Dest string and copies the contents of
-// Source into it. If Dest is not NULL prior calling the function,
-// it is attempted to deallocate first.
-
-extern pstr CreateCopy ( pstr & Dest, cpstr Source );
-extern pstr CreateCopy_n ( pstr & Dest, cpstr Source, int n );
-
-extern pstr CreateConcat ( pstr & Dest, cpstr Source );
-extern pstr CreateConcat ( pstr & Dest, cpstr Source1,
- cpstr Source2 );
-extern pstr CreateConcat ( pstr & Dest, cpstr Source1,
- cpstr Source2,
- cpstr Source3 );
-extern pstr CreateConcat ( pstr & Dest, cpstr Source1,
- cpstr Source2,
- cpstr Source3,
- cpstr Source4 );
-extern pstr CreateConcat ( pstr & Dest, cpstr Source1,
- cpstr Source2,
- cpstr Source3,
- cpstr Source4,
- cpstr Source5 );
-
-extern pstr CreateCopCat ( pstr & Dest, cpstr Source1,
- cpstr Source2,
- cpstr Source3,
- cpstr Source4,
- cpstr Source5 );
-extern pstr CreateCopCat ( pstr & Dest, cpstr Source1,
- cpstr Source2,
- cpstr Source3,
- cpstr Source4 );
-extern pstr CreateCopCat ( pstr & Dest, cpstr Source1,
- cpstr Source2,
- cpstr Source3 );
-extern pstr CreateCopCat ( pstr & Dest, cpstr Source1,
- cpstr Source2 );
-
-extern pstr LastOccurence ( cpstr S , char c );
-extern pstr FirstOccurence ( cpstr S , char c );
-extern int indexOf ( cpstr S , char c );
-extern pstr FirstOccurence ( cpstr S, int Slen,
- cpstr Q, int Qlen );
-extern int indexOf ( cpstr S, int Slen,
- cpstr Q, int Qlen );
-
-extern pstr LowerCase ( pstr s );
-extern pstr UpperCase ( pstr s );
-
-// GetString(..) copies first M characters of string S into string
-// L, appending the terminating null. If S contains less then M
-// characters, L will be padded with spaces.
-extern void GetString ( pstr L, cpstr S, int M );
-
-// GetStrTer(..) copies at least n (or LMax if LMax<n) first symbols
-// of string S into string L, then continues copying until first space
-// or terminating null is found. If the terminating null is met among
-// the first n characters or if SMax<n, the string L will be padded
-// with spaces till the length of minimum of n and LMax and then
-// terminated with the null.
-// LMax and SMax are the buffer lengths of L and S,
-// respectively. Even if no space is found, the last character
-// in L will be the terminating null.
-extern void GetStrTer ( pstr L, cpstr S, int n, int LMax,
- int SMax );
-
-
-// Version of GetStrTer(..) allowing for spaces in the string.
-//
-// Copies at least n (or LMax if LMax<n) first symbols of
-// string S into string L, then continues copying until first
-// terminating null is found. If the terminating null
-// is met among the first n characters or if SMax<n, the string
-// L will be padded with spaces till the length of minimum of
-// n and LMax and then terminated with the null.
-// SMax are buffer lengths of L and S, respectively. The last
-// character in L will be the terminating null.
-extern void GetStrTerWin32File ( pstr L, cpstr S, int n,
- int LMax, int SMax );
-
-
-// strcpy_n(..) copies at most n symbols from string s to d,
-// but no more than strlen(s) (s must contain a terminating
-// null). The terminating null IS NEITHER appended OR copied
-// to d.
-extern void strcpy_n ( pstr d, cpstr s, int n );
-
-// strcpy_n1(..) copies at most n last symbols from string s
-// to d, but no more than strlen(s) (s must contain a terminating
-// null). The string in d is aligned to the right and added with
-// spaces at the left, if necessary. The terminating null
-// IS NEITHER appended OR copied to d.
-extern void strcpy_n1 ( pstr d, cpstr s, int n );
-
-// Copies at most n symbols from string s to d, but no
-// more than strlen(s) (s must contain a terminating null).
-// The string in d is aligned to the right and added with
-// spaces at the left, if necessary. The terminating null
-// IS NEITHER appended NOR copied to d.
-extern void strcpy_nr ( pstr d, cpstr s, int n );
-
-// strcpy_ns(..) copies at most n symbols from string s to d,
-// but no more than strlen(s) (s must contain a terminating
-// null). The terminating null IS NEITHER appended NOR copied
-// to d; rather, d is padded with spaces up to the length of n
-// if strlen(s)<n.
-extern void strcpy_ns ( pstr d, cpstr s, int n );
-
-// strcpy_cs(..) copies string s to string d cutting all
-// spaces at the end. Thus, " abcde " will be copied
-// like " abcde" (terminating null appended).
-// The function returns d.
-extern pstr strcpy_cs ( pstr d, cpstr s );
-
-// strcpy_ncs(..) copies at most n characters from string s
-// to string d cutting all spaces at at the end. Thus, " abcde "
-// will be copied like " abc" at n=4 and like " abcde" at n>5
-// (terminating null appended).
-// The function returns d.
-extern pstr strcpy_ncs ( pstr d, cpstr s, int n );
-
-// strcpy_css(..) copies string s to string d cutting all
-// spaces at the begining and at the end. Thus, " ab c de "
-// will be copied like "ab c de" (terminating null appended).
-// The function returns d.
-extern pstr strcpy_css ( pstr d, cpstr s );
-
-// strcpy_ncss(..) copies at most n characters from string s
-// to string d cutting all spaces at the begining and at the end.
-// Thus, " ab c de " will be copied like "ab" at n=3 (terminating
-// null appended).
-// The function returns d.
-extern pstr strcpy_ncss ( pstr d, cpstr s, int n );
-
-// strcpy_n0(..) copies at most n symbols from string s to d,
-// but no more than strlen(s) (s must contain a terminating
-// null). The terminating null IS appended to d.
-// The function returns d.
-extern pstr strcpy_n0 ( pstr d, cpstr s, int n );
-
-// strlen_des returns the length of a string as if all extra
-// spaces from the latter have been deleted. Extra spaces
-// include all leading and tracing spaces and any sequential
-// spaces when more than one. The string does not change.
-extern int strlen_des ( cpstr s );
-
-// strcpy_des copies string s into string d removing all extra
-// spaces from the latter. Extra spaces include all leading and
-// tracing spaces and any sequential spaces when more than one.
-extern pstr strcpy_des ( pstr d, cpstr s );
-
-// strcat_des appends string s to string d removing all extra
-// spaces from the latter. Extra spaces include all leading and
-// tracing spaces and any sequential spaces when more than one.
-extern pstr strcat_des ( pstr d, cpstr s );
-
-// PadSpaces(..) pads string S with spaces making its length
-// equal to len. The terminating zero is added, so that S should
-// reserve space of a minimum len+1 characters.
-extern void PadSpaces ( pstr S, int len );
-
-
-#define SCUTKEY_BEGIN 0x00000001
-#define SCUTKEY_END 0x00000002
-#define SCUTKEY_BEGEND 0x00000003
-
-// CutSpaces(..) cuts spaces at the begining or end of
-// string S according to the value of CutKey. The function
-// returns S.
-extern pstr CutSpaces ( pstr S, int CutKey );
-
-// DelSpaces(..) removes all spaces (or other symbols as
-// specified by 'c') from the string. The string is then
-// shrinked by the number of removed characters. Thus,
-// " as ttt " becomes "asttt".
-extern pstr DelSpaces ( pstr S, char c=' ' );
-
-// EnforceSpaces(..) replaces all unprintable characters,
-// except <CR>, <LF>, <TAB> and some others, for spaces
-extern pstr EnforceSpaces ( pstr S );
-
-// -------------------------------------------------------------
-
-/// This call will produce correct floats in universal binaries but
-/// make them incompatible with old files. Without this call, float
-/// read/write will result in error after 6th digit.
-/// UniBin read/write of other types (realtype, shortreal, int etc)
-/// is not affected by this call, and to the best of knowledge is
-/// correct (no loss of precision).
-extern void set_new_float_unibin();
-extern Boolean is_new_float_unibin();
-extern void set_old_float_unibin();
-
-extern void __modify4();
-
-extern void int2UniBin ( int I, intUniBin iUB );
-extern void short2UniBin ( short S, shortUniBin sUB );
-extern void long2UniBin ( long L, longUniBin lUB );
-extern void word2UniBin ( word W, wordUniBin wUB );
-extern void real2UniBin ( realtype R, realUniBin rUB );
-extern void float2UniBin ( realtype R, floatUniBin fUB );
-extern void shortreal2UniBin ( shortreal R, shortrealUniBin srUB );
-extern void UniBin2int ( intUniBin iUB, int & I );
-extern void UniBin2short ( shortUniBin sUB, short & S );
-extern void UniBin2long ( longUniBin lUB, long & L );
-extern void UniBin2word ( wordUniBin wUB, word & W );
-extern void UniBin2real ( realUniBin rUB, realtype & R );
-extern void UniBin2shortreal ( shortrealUniBin srUB, shortreal & R );
-extern void UniBin2float ( floatUniBin fUB, realtype & R );
-
-extern void mem_write ( int I, pstr S, int & l );
-extern void mem_write ( short I, pstr S, int & l );
-extern void mem_write ( long I, pstr S, int & l );
-extern void mem_write ( word W, pstr S, int & l );
-extern void mem_write ( realtype R, pstr S, int & l );
-extern void mem_write ( shortreal R, pstr S, int & l );
-extern void mem_write ( pstr L, int len, pstr S, int & l );
-extern void mem_write ( pstr L, pstr S, int & l );
-extern void mem_write ( Boolean B, pstr S, int & l );
-extern void mem_write_byte ( byte B, pstr S, int & l );
-
-extern void mem_read ( int & I, cpstr S, int & l );
-extern void mem_read ( short & I, cpstr S, int & l );
-extern void mem_read ( long & I, cpstr S, int & l );
-extern void mem_read ( word & W, cpstr S, int & l );
-extern void mem_read ( realtype & R, cpstr S, int & l );
-extern void mem_read ( shortreal & R, cpstr S, int & l );
-extern void mem_read ( pstr L, int len, cpstr S, int & l );
-extern void mem_read ( pstr & L, cpstr S, int & l );
-extern void mem_read ( Boolean & B, cpstr S, int & l );
-extern void mem_read_byte ( byte & B, cpstr S, int & l );
-
-#endif
-
-/* =================================================== */
-
diff --git a/mmdb/mmdb_align.cpp b/mmdb/mmdb_align.cpp
deleted file mode 100755
index 4081ce7..0000000
--- a/mmdb/mmdb_align.cpp
+++ /dev/null
@@ -1,1219 +0,0 @@
-// $Id: mmdb_align.cpp,v 1.22 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 19.04.11 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_Align <implementation>
-// ~~~~~~~~~
-// **** Classes : CAlignment ( alignment of character strings )
-// ~~~~~~~~~~~~ CAlignment1 ( alignment of integer vectors )
-//
-// (C) E.Krissinel' 2000-2011
-//
-// =================================================================
-//
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __MATH_H
-#include <math.h>
-#endif
-
-#ifndef __MMDB_Align__
-#include "mmdb_align.h"
-#endif
-
-
-// ===================== CAligParams ======================
-
-CAlignParams::CAlignParams() : CStream() {
- InitAlignParams();
-}
-
-CAlignParams::CAlignParams ( RPCStream Object ) : CStream ( Object ) {
- InitAlignParams();
-}
-
-void CAlignParams::InitAlignParams() {
- gapWeight = -1.0;
- spaceWeight = -1.0;
- equalScore = 2.0;
- nequalScore = -1.0;
- method = ALIGN_GLOBAL;
-}
-
-void CAlignParams::write ( RCFile f ) {
- f.WriteReal ( &gapWeight );
- f.WriteReal ( &spaceWeight );
- f.WriteReal ( &equalScore );
- f.WriteReal ( &nequalScore );
- f.WriteInt ( &method );
-}
-
-void CAlignParams::read ( RCFile f ) {
- f.ReadReal ( &gapWeight );
- f.ReadReal ( &spaceWeight );
- f.ReadReal ( &equalScore );
- f.ReadReal ( &nequalScore );
- f.ReadInt ( &method );
-}
-
-MakeStreamFunctions(CAlignParams)
-
-
-// ===================== CAlignment ======================
-
-CAlignment::CAlignment() : CStream() {
- InitAlignment();
-}
-
-CAlignment::CAlignment ( RPCStream Object ) : CStream ( Object ) {
- InitAlignment();
-}
-
-CAlignment::~CAlignment() {
- FreeMemory();
-}
-
-void CAlignment::InitAlignment() {
- Space = '-';
- SLen = 0;
- TLen = 0;
- VT = NULL;
- ET = NULL;
- FT = NULL;
- AlgnS = NULL;
- AlgnT = NULL;
- AlignKey = ALIGN_GLOBAL;
- VAchieved = 0.0;
- SEq = 2.0;
- SNEq = -1.0;
- Wg = 0.0;
- Ws = -1.0;
-}
-
-void CAlignment::FreeMemory() {
- FreeMatrixMemory ( VT,TLen+1,0,0 );
- FreeMatrixMemory ( ET,TLen+1,0,0 );
- FreeMatrixMemory ( FT,TLen+1,0,0 );
- if (AlgnS) {
- delete[] AlgnS;
- AlgnS = NULL;
- }
- if (AlgnT) {
- delete[] AlgnT;
- AlgnT = NULL;
- }
- TLen = 0;
- SLen = 0;
-}
-
-void CAlignment::SetAffineModel ( realtype WGap, realtype WSpace ) {
- Wg = WGap;
- Ws = WSpace;
-}
-
-void CAlignment::SetScores ( realtype SEqual, realtype SNEqual ) {
- SEq = SEqual;
- SNEq = SNEqual;
-}
-
-void CAlignment::Align ( cpstr S, cpstr T, int Method ) {
-int i,j,i0,j0;
-
- FreeMemory();
-
- AlignKey = Method;
-
- switch (Method) {
-
- default :
- case ALIGN_GLOBAL : // global pairwise alignment of S and T
- BuildGATable ( S,T, False,False );
- VAchieved = VT[TLen][SLen];
- Backtrace ( S,T,SLen,TLen,False );
- if ((AlgnS[0]!=Space) && (AlgnT[0]!=Space))
- VAchieved -= Wg;
- break;
-
- case ALIGN_LOCAL : // local pairwise alignment of S and T
- BuildLATable ( S,T );
- VAchieved = 0.0;
- i0 = -1;
- j0 = -1;
- for (i=0;i<=TLen;i++)
- for (j=0;j<=SLen;j++)
- if (VT[i][j]>VAchieved) {
- VAchieved = VT[i][j];
- i0 = i;
- j0 = j;
- }
- Backtrace ( S,T,j0,i0,True );
- break;
-
- case ALIGN_GLOBLOC : // global alignment with non-penalized
- // end gaps in T
- BuildGATable ( S,T,False,True );
- VAchieved = -MaxReal;
- i0 = -1;
- j0 = -1;
- for (i=0;i<=TLen;i++)
- if (VT[i][SLen]>VAchieved) {
- VAchieved = VT[i][SLen];
- i0 = i;
- j0 = SLen;
- }
- Backtrace ( S,T,j0,i0,False );
- AdjustEnds ( S,T,j0,i0 );
- break;
-
- case ALIGN_FREEENDS : // global alignment with non-penalized
- // end gaps in both S and T
- BuildGATable ( S,T,True,True );
- VAchieved = -MaxReal;
- i0 = -1;
- j0 = -1;
- for (i=0;i<=TLen;i++)
- if (VT[i][SLen]>VAchieved) {
- VAchieved = VT[i][SLen];
- i0 = i;
- j0 = SLen;
- }
- for (j=0;j<=SLen;j++)
- if (VT[TLen][j]>VAchieved) {
- VAchieved = VT[TLen][j];
- i0 = TLen;
- j0 = j;
- }
- Backtrace ( S,T,j0,i0,False );
- AdjustEnds ( S,T,j0,i0 );
-
- }
-
-}
-
-
-void CAlignment::BuildGATable ( cpstr S, cpstr T,
- Boolean FreeSEnd,
- Boolean FreeTEnd ) {
-int i,j;
-realtype V1;
-
- SLen = strlen ( S );
- TLen = strlen ( T );
- GetMatrixMemory ( VT,TLen+1,SLen+1,0,0 );
- GetMatrixMemory ( ET,TLen+1,SLen+1,0,0 );
- GetMatrixMemory ( FT,TLen+1,SLen+1,0,0 );
-
- // Base conditions
- if (FreeSEnd || FreeTEnd) VT[0][0] = RMax(0.0,Wg);
- else VT[0][0] = Wg;
- ET[0][0] = VT[0][0];
- FT[0][0] = VT[0][0];
-
- if (FreeTEnd)
- for (i=1;i<=TLen;i++) {
- V1 = RMax ( 0.0,VT[i-1][0]+Ws );
- VT[i][0] = V1;
- ET[i][0] = V1;
- }
- else
- for (i=1;i<=TLen;i++) {
- V1 = VT[i-1][0] + Ws;
- VT[i][0] = V1;
- ET[i][0] = V1;
- }
-
- if (FreeSEnd)
- for (j=1;j<=SLen;j++) {
- V1 = RMax ( 0.0,VT[0][j-1]+Ws );
- VT[0][j] = V1;
- FT[0][j] = V1;
- }
- else
- for (j=1;j<=SLen;j++) {
- V1 = VT[0][j-1] + Ws;
- VT[0][j] = V1;
- FT[0][j] = V1;
- }
-
- // Recurrence
- for (i=1;i<=TLen;i++)
- for (j=1;j<=SLen;j++) {
- V1 = VT[i-1][j-1] + Score(T[i-1],S[j-1]);
- ET[i][j] = RMax ( ET[i][j-1]+Ws,VT[i][j-1]+Wg+Ws );
- FT[i][j] = RMax ( FT[i-1][j]+Ws,VT[i-1][j]+Wg+Ws );
- VT[i][j] = RMax ( RMax(V1,ET[i][j]),FT[i][j] );
- }
-
- FreeMatrixMemory ( ET,TLen+1,0,0 );
- FreeMatrixMemory ( FT,TLen+1,0,0 );
-
-// PrintVT ( S,T );
-
-}
-
-
-void CAlignment::BuildLATable ( cpstr S, cpstr T ) {
-int i,j;
-realtype V1;
-
- SLen = strlen ( S );
- TLen = strlen ( T );
- GetMatrixMemory ( VT,TLen+1,SLen+1,0,0 );
- GetMatrixMemory ( ET,TLen+1,SLen+1,0,0 );
- GetMatrixMemory ( FT,TLen+1,SLen+1,0,0 );
-
- // Base conditions
- VT[0][0] = RMax ( 0.0,Wg );
- ET[0][0] = VT[0][0];
- FT[0][0] = VT[0][0];
- for (i=1;i<=TLen;i++) {
- V1 = RMax ( 0.0,VT[i-1][0]+Ws );
- VT[i][0] = V1;
- ET[i][0] = V1;
- }
- for (j=1;j<=SLen;j++) {
- V1 = RMax ( 0.0,VT[0][j-1]+Ws );
- VT[0][j] = V1;
- FT[0][j] = V1;
- }
-
- // Recurrence
- for (i=1;i<=TLen;i++)
- for (j=1;j<=SLen;j++) {
- V1 = VT[i-1][j-1] + Score(T[i-1],S[j-1]);
- ET[i][j] = RMax ( ET[i][j-1]+Ws,VT[i][j-1]+Wg+Ws );
- FT[i][j] = RMax ( FT[i-1][j]+Ws,VT[i-1][j]+Wg+Ws );
- VT[i][j] = RMax ( RMax(V1,ET[i][j]),RMax(0.0,FT[i][j]) );
- }
-
- FreeMatrixMemory ( ET,TLen+1,0,0 );
- FreeMatrixMemory ( FT,TLen+1,0,0 );
-
-// PrintVT ( S,T );
-
-}
-
-void CAlignment::PrintVT ( cpstr S, cpstr T ) {
-int i,j;
- printf ( "\n " );
- for (j=0;j<=SLen;j++)
- printf ( " %2i",j );
- printf ( " \n " );
- for (j=1;j<=SLen;j++)
- printf ( " %c ",S[j-1] );
- printf ( " \n\n " );
- for (i=0;i<=TLen;i++) {
- if (i>0) printf ( " %2i %c ",i,T[i-1] );
- else printf ( " %2i ",i );
- for (j=0;j<=SLen;j++)
- printf ( " %2i",mround(VT[i][j]) );
- printf ( " \n " );
- }
- printf ( " \n" );
-}
-
-
-void CAlignment::Backtrace ( cpstr S, cpstr T, int J, int I,
- Boolean StopAtZero ) {
-int i,j,k, i1,j1, sk,tk;
-char C;
-realtype V,SV,TV;
-Boolean Stop;
-
- // 1. Allocate memory
-
- if (AlgnS) delete[] AlgnS;
- if (AlgnT) delete[] AlgnT;
-
- i = SLen+TLen+1;
- AlgnS = new char[i];
- AlgnT = new char[i];
- memset ( AlgnS,Space,i );
- memset ( AlgnT,Space,i );
-
- // 2. Initialize backtracing
- i = I; // backtracing
- j = J; // indices
- k = 0; // alignment index
- SV = 0.0; sk = -1; // alignment indices and leading elements
- TV = 0.0; tk = -1; // for vertical and horizontal sections
-
-
- // 3. Backtracing
- Stop = False;
- while ((!Stop) && (i>0) && (j>0)) {
-
- V = VT[i][j];
-
- // find next leading element
- if (VT[i][j-1]>VT[i-1][j]) {
- i1 = i; j1 = j-1;
- } else {
- i1 = i-1; j1 = j;
- }
- if (VT[i-1][j-1]>=VT[i1][j1]) {
- i1 = i-1; j1 = j-1;
- }
-
-//printf ( " i=%i j=%i \n",i,j );
-
- Stop = StopAtZero && (VT[i1][j1]<=0.0); // used at local alignment
-
- // treat horizontal section
- if ((sk<0) || (V>SV)) {
- sk = k;
- SV = V;
- }
- if ((j1!=j) || Stop) { // end of horizontal section
- AlgnS[sk] = S[j-1];
- sk = -1;
- }
-
- // treat vertical section
- if ((tk<0) || (V>TV)) {
- tk = k;
- TV = V;
- }
- if ((i1!=i) || Stop) { // end of vertical section
- AlgnT[tk] = T[i-1];
- tk = -1;
- }
-
- i = i1;
- j = j1;
- k++;
-
- }
-
- if (!StopAtZero) {
- // 4. Finish the last horizontal section
- sk = k;
- while (j>0) AlgnS[k++] = S[--j];
- // 5. Finish the last vertical section
- while (i>0) AlgnT[sk++] = T[--i];
- k = IMax ( k,sk );
- }
-
- // 6. Put the termination character
- AlgnS[k] = char(0);
- AlgnT[k] = char(0);
-
- // 7. Reverse the strings
- i = 0;
- j = k-1;
- if (StopAtZero) {
- // should work only for local alignment
- while ((j>0) && ((AlgnS[j]==Space) || (AlgnT[j]==Space))) j--;
- k = j+1;
- AlgnS[k] = char(0);
- AlgnT[k] = char(0);
- }
- while (j>i) {
- C = AlgnS[i]; AlgnS[i] = AlgnS[j]; AlgnS[j] = C;
- C = AlgnT[i]; AlgnT[i] = AlgnT[j]; AlgnT[j] = C;
- i++;
- j--;
- }
-
- // 8. Collapse the alternating spaces
- do {
- k = 0;
- i = 0;
- while (AlgnS[k]) {
- if ((AlgnS[k]==Space) && (AlgnT[k]==Space)) k++;
- else if ((AlgnS[k]==Space) && (AlgnS[k+1]!=Space) &&
- (AlgnT[k]!=Space) && (AlgnT[k+1]==Space)) {
- AlgnS[i] = AlgnS[k+1];
- AlgnT[i] = AlgnT[k];
- k++;
- } else if ((AlgnS[k]!=Space) && (AlgnS[k+1]==Space) &&
- (AlgnT[k]==Space) && (AlgnT[k+1]!=Space)) {
- AlgnS[i] = AlgnS[k];
- AlgnT[i] = AlgnT[k+1];
- k++;
- } else if (i!=k) {
- AlgnS[i] = AlgnS[k];
- AlgnT[i] = AlgnT[k];
- }
- if (AlgnS[k]) {
- k++;
- i++;
- }
- }
- if (i!=k) { // terminating character
- AlgnS[i] = AlgnS[k];
- AlgnT[i] = AlgnT[k];
- }
- } while (k>i);
-
-}
-
-
-void CAlignment::AdjustEnds ( cpstr S, cpstr T, int J, int I ) {
-int si,ti,m;
-
- if (J<SLen) strcat ( AlgnS,&(S[J]) );
- if (I<TLen) strcat ( AlgnT,&(T[I]) );
- si = strlen ( AlgnS );
- ti = strlen ( AlgnT );
- m = IMax ( si,ti );
- while (si<m) AlgnS[si++] = Space;
- while (ti<m) AlgnT[ti++] = Space;
- AlgnS[si] = char(0);
- AlgnT[ti] = char(0);
-
-/*
-int k,m;
-
- if (J>I) {
- k = J-I;
- strcat ( AlgnT,&(T[IMax(0,TLen-k)]) );
- k = strlen ( AlgnS );
- m = strlen ( AlgnT );
- while (k<m)
- AlgnS[k++] = Space;
- AlgnS[k] = char(0);
- } else if (I>J) {
- k = I-J;
- strcat ( AlgnS,&(S[IMax(0,SLen-k)]) );
- k = strlen ( AlgnT );
- m = strlen ( AlgnS );
- while (k<m)
- AlgnT[k++] = Space;
- AlgnT[k] = char(0);
- }
-*/
-
-}
-
-
-realtype CAlignment::Score ( char A, char B ) {
- if (A==B) return SEq;
- if ((A==Space) || (B==Space)) return Ws;
- return SNEq;
-}
-
-realtype CAlignment::GetSimilarity() {
-realtype s,a;
-int i,n;
-
- s = 0.0;
- a = 0.0;
- n = IMin ( strlen(AlgnS),strlen(AlgnT) );
-
- for (i=0;i<n;i++)
- if ((AlgnS[i]!=Space) || (AlgnT[i]!=Space)) {
- a += RMax ( Score(AlgnS[i],AlgnS[i]),Score(AlgnT[i],AlgnT[i]) );
- s += Score ( AlgnS[i],AlgnT[i] );
- }
-
- if ((s>0.0) && (a>0.0)) return s/a;
- return 0.0;
-
-}
-
-
-realtype CAlignment::GetSeqId() {
-realtype s;
-int i,n,ne,ns,nt;
-
- ne = 0;
- ns = 0;
- nt = 0;
- n = IMin ( strlen(AlgnS),strlen(AlgnT) );
-
- for (i=0;i<n;i++) {
- if (AlgnS[i]!=Space) ns++;
- if (AlgnT[i]!=Space) {
- nt++;
- if (AlgnS[i]==AlgnT[i])
- ne++;
- }
- }
-
- s = IMin ( ns,nt );
- if (s>0.0) return ne/s;
- return 0.0;
-
-}
-
-
-#define WrapPeriod 61
-
-void CAlignment::OutputResults ( RCFile f, cpstr S, cpstr T ) {
-int k,l,n;
-char P[3];
-
- P[1] = char(0);
- if ((!AlgnS) || (!AlgnT)) {
- f.LF();
- f.WriteLine ( pstr(" NO ALIGNMENT HAS BEEN DONE.") );
- f.shut();
- return;
- }
- f.LF();
- f.WriteLine ( pstr(" ======== INPUT DATA") );
- f.LF();
- f.WriteLine ( pstr(" String S:") );
- f.Write ( pstr(" ") );
- l = 1;
- k = 0;
- while (S[k]) {
- P[0] = S[k++];
- f.Write ( P );
- l++;
- if (l>=WrapPeriod) {
- f.LF(); f.Write ( pstr(" ") ); l = 1;
- }
- }
- f.LF();
- f.LF();
- f.WriteLine ( pstr(" String T:") );
- f.Write ( pstr(" ") );
- l = 1;
- k = 0;
- while (T[k]) {
- P[0] = T[k++];
- f.Write ( P );
- l++;
- if (l>=WrapPeriod) {
- f.LF(); f.Write ( pstr(" ") ); l = 1;
- }
- }
- f.LF();
- f.LF();
- f.WriteParameter ( pstr(" Score equal") ,SEq ,20,10 );
- f.WriteParameter ( pstr(" Score unequal"),SNEq,20,10 );
- f.LF();
- f.WriteParameter ( pstr(" Gap weight") ,Wg ,20,10 );
- f.WriteParameter ( pstr(" Space weight") ,Ws ,20,10 );
- f.LF();
- f.LF();
- f.Write ( pstr(" ======== RESULT OF ") );
- switch (AlignKey) {
- default :
- case ALIGN_GLOBAL : f.Write ( pstr("GLOBAL") ); break;
- case ALIGN_LOCAL : f.Write ( pstr("LOCAL") ); break;
- case ALIGN_GLOBLOC : f.Write ( pstr("GLOBAL/LOCAL") ); break;
- case ALIGN_FREEENDS : f.Write ( pstr("FREE-ENDS") );
- }
- f.WriteLine ( pstr(" ALIGNMENT") );
- f.LF();
- if (AlignKey==ALIGN_GLOBLOC) {
- f.WriteLine ( pstr(" End gaps in T-string were not penalized") );
- f.LF();
- }
- f.WriteParameter ( pstr(" Highest score achieved:"),VAchieved,26,10 );
- f.LF();
- f.WriteLine ( pstr(" Aligned S (upper string) and T (lower string):") );
- f.LF();
- k = 0;
- n = 0;
- l = 1; f.Write ( pstr(" ") );
- while (AlgnS[k]) {
- P[0] = AlgnS[k++];
- f.Write ( P );
- l++;
- if ((l>=WrapPeriod) || (!AlgnS[k])) {
- f.LF(); f.Write ( pstr(" ") ); l = 1;
- while (AlgnT[n] && (l<WrapPeriod)) {
- P[0] = AlgnT[n++];
- f.Write ( P );
- l++;
- }
- f.LF(); f.LF(); f.Write ( pstr(" ") ); l = 1;
- }
- }
-
-}
-
-
-// ----------------- Streaming -----------------------------
-
-void CAlignment::write ( RCFile f ) {
-int Version=1;
- f.WriteFile ( &Version,sizeof(Version) );
- CStream::write ( f );
-}
-
-void CAlignment::read ( RCFile f ) {
-int Version;
- f.ReadFile ( &Version,sizeof(Version) );
- CStream::write ( f );
-}
-
-
-
-// ===================== CAlignment1 ======================
-
-CAlignment1::CAlignment1() : CStream() {
- InitAlignment1();
-}
-
-CAlignment1::~CAlignment1() {
- FreeMemory();
-}
-
-void CAlignment1::InitAlignment1() {
- Space = 0;
- SLen = 0;
- TLen = 0;
- AlgnLen = 0;
- VT = NULL;
- ET = NULL;
- FT = NULL;
- AlgnS = NULL;
- AlgnT = NULL;
- AlignKey = ALIGN_GLOBAL;
- VAchieved = 0.0;
- SEq = 2.0;
- SNEq = -1.0;
- Wg = 0.0;
- Ws = -1.0;
-}
-
-void CAlignment1::FreeMemory() {
- FreeMatrixMemory ( VT,TLen+1,0,0 );
- FreeMatrixMemory ( ET,TLen+1,0,0 );
- FreeMatrixMemory ( FT,TLen+1,0,0 );
- FreeVectorMemory ( AlgnS,0 );
- FreeVectorMemory ( AlgnT,0 );
- TLen = 0;
- SLen = 0;
- AlgnLen = 0;
-}
-
-void CAlignment1::SetAffineModel ( realtype WGap, realtype WSpace ) {
- Wg = WGap;
- Ws = WSpace;
-}
-
-void CAlignment1::SetScores ( realtype SEqual, realtype SNEqual ) {
- SEq = SEqual;
- SNEq = SNEqual;
-}
-
-void CAlignment1::Align ( ivector S, int SLength,
- ivector T, int TLength, int Method ) {
-int i,j,i0,j0;
-
- FreeMemory();
-
- SLen = SLength;
- TLen = TLength;
-
- AlignKey = Method;
-
- switch (Method) {
-
- default :
- case ALIGN_GLOBAL : // global pairwise alignment of S and T
- BuildGATable ( S,T, False,False );
- VAchieved = VT[TLen][SLen];
- Backtrace ( S,T,SLen,TLen,False );
- if ((AlgnS[0]!=Space) && (AlgnT[0]!=Space))
- VAchieved -= Wg;
- break;
-
- case ALIGN_LOCAL : // local pairwise alignment of S and T
- BuildLATable ( S,T );
- VAchieved = 0.0;
- i0 = -1;
- j0 = -1;
- for (i=0;i<=TLen;i++)
- for (j=0;j<=SLen;j++)
- if (VT[i][j]>VAchieved) {
- VAchieved = VT[i][j];
- i0 = i;
- j0 = j;
- }
- Backtrace ( S,T,j0,i0,True );
- break;
-
- case ALIGN_GLOBLOC : // global alignment with non-penalized
- // end gaps in T
- BuildGATable ( S,T,False,True );
- VAchieved = -MaxReal;
- i0 = -1;
- j0 = -1;
- for (i=0;i<=TLen;i++)
- if (VT[i][SLen]>VAchieved) {
- VAchieved = VT[i][SLen];
- i0 = i;
- j0 = SLen;
- }
- Backtrace ( S,T,j0,i0,False );
- AdjustEnds ( S,T,j0,i0 );
- break;
-
- case ALIGN_FREEENDS : // global alignment with non-penalized
- // end gaps in both S and T
- BuildGATable ( S,T,True,True );
- VAchieved = -MaxReal;
- i0 = -1;
- j0 = -1;
- for (i=0;i<=TLen;i++)
- if (VT[i][SLen]>VAchieved) {
- VAchieved = VT[i][SLen];
- i0 = i;
- j0 = SLen;
- }
- for (j=0;j<=SLen;j++)
- if (VT[TLen][j]>VAchieved) {
- VAchieved = VT[TLen][j];
- i0 = TLen;
- j0 = j;
- }
- Backtrace ( S,T,j0,i0,False );
- AdjustEnds ( S,T,j0,i0 );
- }
-
-}
-
-
-void CAlignment1::BuildGATable ( ivector S, ivector T,
- Boolean FreeSEnd,
- Boolean FreeTEnd ) {
-int i,j;
-realtype V1;
-
- GetMatrixMemory ( VT,TLen+1,SLen+1,0,0 );
- GetMatrixMemory ( ET,TLen+1,SLen+1,0,0 );
- GetMatrixMemory ( FT,TLen+1,SLen+1,0,0 );
-
- // Base conditions
- if (FreeSEnd || FreeTEnd) VT[0][0] = RMax(0.0,Wg);
- else VT[0][0] = Wg;
- ET[0][0] = VT[0][0];
- FT[0][0] = VT[0][0];
-
- if (FreeTEnd)
- for (i=1;i<=TLen;i++) {
- V1 = RMax ( 0.0,VT[i-1][0]+Ws );
- VT[i][0] = V1;
- ET[i][0] = V1;
- }
- else
- for (i=1;i<=TLen;i++) {
- V1 = VT[i-1][0] + Ws;
- VT[i][0] = V1;
- ET[i][0] = V1;
- }
-
- if (FreeSEnd)
- for (j=1;j<=SLen;j++) {
- V1 = RMax ( 0.0,VT[0][j-1]+Ws );
- VT[0][j] = V1;
- FT[0][j] = V1;
- }
- else
- for (j=1;j<=SLen;j++) {
- V1 = VT[0][j-1] + Ws;
- VT[0][j] = V1;
- FT[0][j] = V1;
- }
-
- // Recurrence
- for (i=1;i<=TLen;i++)
- for (j=1;j<=SLen;j++) {
- V1 = VT[i-1][j-1] + Score(T[i-1],S[j-1]);
- ET[i][j] = RMax ( ET[i][j-1]+Ws,VT[i][j-1]+Wg+Ws );
- FT[i][j] = RMax ( FT[i-1][j]+Ws,VT[i-1][j]+Wg+Ws );
- VT[i][j] = RMax ( RMax(V1,ET[i][j]),FT[i][j] );
- }
-
- FreeMatrixMemory ( ET,TLen+1,0,0 );
- FreeMatrixMemory ( FT,TLen+1,0,0 );
-
-// PrintVT ( S,T );
-
-}
-
-
-void CAlignment1::BuildLATable ( ivector S, ivector T ) {
-int i,j;
-realtype V1;
-
- GetMatrixMemory ( VT,TLen+1,SLen+1,0,0 );
- GetMatrixMemory ( ET,TLen+1,SLen+1,0,0 );
- GetMatrixMemory ( FT,TLen+1,SLen+1,0,0 );
-
- // Base conditions
- VT[0][0] = RMax ( 0.0,Wg );
- ET[0][0] = VT[0][0];
- FT[0][0] = VT[0][0];
- for (i=1;i<=TLen;i++) {
- V1 = RMax ( 0.0,VT[i-1][0]+Ws );
- VT[i][0] = V1;
- ET[i][0] = V1;
- }
- for (j=1;j<=SLen;j++) {
- V1 = RMax ( 0.0,VT[0][j-1]+Ws );
- VT[0][j] = V1;
- FT[0][j] = V1;
- }
-
- // Recurrence
- for (i=1;i<=TLen;i++)
- for (j=1;j<=SLen;j++) {
- V1 = VT[i-1][j-1] + Score(T[i-1],S[j-1]);
- ET[i][j] = RMax ( ET[i][j-1]+Ws,VT[i][j-1]+Wg+Ws );
- FT[i][j] = RMax ( FT[i-1][j]+Ws,VT[i-1][j]+Wg+Ws );
- VT[i][j] = RMax ( RMax(V1,ET[i][j]),RMax(0.0,FT[i][j]) );
- }
-
- FreeMatrixMemory ( ET,TLen+1,0,0 );
- FreeMatrixMemory ( FT,TLen+1,0,0 );
-
-// PrintVT ( S,T );
-
-}
-
-void CAlignment1::PrintVT ( ivector S, ivector T ) {
-int i,j;
- printf ( "\n " );
- for (j=0;j<=SLen;j++)
- printf ( " %2i",j );
- printf ( " \n " );
- for (j=1;j<=SLen;j++)
- printf ( " %3i ",S[j-1] );
- printf ( " \n\n " );
- for (i=0;i<=TLen;i++) {
- if (i>0) printf ( " %2i %3i ",i,T[i-1] );
- else printf ( " %2i ",i );
- for (j=0;j<=SLen;j++)
- printf ( " %2i",mround(VT[i][j]) );
- printf ( " \n " );
- }
- printf ( " \n" );
-}
-
-
-void CAlignment1::Backtrace ( ivector S, ivector T, int J, int I,
- Boolean StopAtZero ) {
-int i,j,k, i1,j1, sk,tk;
-int C;
-realtype V,SV,TV;
-Boolean Stop;
-
- // 1. Allocate memory
-
- FreeVectorMemory ( AlgnS,0 );
- FreeVectorMemory ( AlgnT,0 );
- AlgnLen = 0;
-
- k = SLen+TLen+1;
- GetVectorMemory ( AlgnS,k,0 );
- GetVectorMemory ( AlgnT,k,0 );
- for (i=0;i<k;i++) {
- AlgnS[i] = Space;
- AlgnT[i] = Space;
- }
-
- // 2. Initialize backtracing
- i = I; // backtracing
- j = J; // indices
-
- k = 0; // alignment index
- SV = 0.0; sk = -1; // alignment indices and leading elements
- TV = 0.0; tk = -1; // for vertical and horizontal sections
-
-
- // 3. Backtracing
- Stop = False;
- while ((!Stop) && (i>0) && (j>0)) {
-
- V = VT[i][j];
-
- // find next leading element
- if (VT[i][j-1]>VT[i-1][j]) {
- i1 = i; j1 = j-1;
- } else {
- i1 = i-1; j1 = j;
- }
- if (VT[i-1][j-1]>=VT[i1][j1]) {
- i1 = i-1; j1 = j-1;
- }
-
- Stop = StopAtZero && (VT[i1][j1]<=0.0); // used at local alignment
-
- // treat horizontal section
- if ((sk<0) || (V>SV)) {
- sk = k;
- SV = V;
- }
- if ((j1!=j) || Stop) { // end of horizontal section
- AlgnS[sk] = S[j-1];
- sk = -1;
- }
-
- // treat vertical section
- if ((tk<0) || (V>TV)) {
- tk = k;
- TV = V;
- }
- if ((i1!=i) || Stop) { // end of vertical section
- AlgnT[tk] = T[i-1];
- tk = -1;
- }
-
- i = i1;
- j = j1;
- k++;
-
- }
-
- if (!StopAtZero) {
- // 4. Finish the last horizontal section
- sk = k;
- while (j>0) AlgnS[k++] = S[--j];
- // 5. Finish the last vertical section
- while (i>0) AlgnT[sk++] = T[--i];
- k = IMax ( k,sk );
- }
-
- // 6. Put the termination character
- AlgnLen = k;
-
- // 7. Reverse the strings
- i = 0;
- j = k-1;
- if (StopAtZero) {
- // should work only for local alignment
- while ((j>0) && ((AlgnS[j]==Space) || (AlgnT[j]==Space))) j--;
- AlgnLen = j+1;
- }
- while (j>i) {
- C = AlgnS[i]; AlgnS[i] = AlgnS[j]; AlgnS[j] = C;
- C = AlgnT[i]; AlgnT[i] = AlgnT[j]; AlgnT[j] = C;
- i++;
- j--;
- }
-
- // 8. Filter out parasite spaces
- k = 0;
- i = 0;
- while (k<AlgnLen) {
- while ((k<AlgnLen) && (AlgnS[k]==Space) && (AlgnT[k]==Space)) k++;
- if (k<AlgnLen) {
- AlgnS[i] = AlgnS[k];
- AlgnT[i] = AlgnT[k];
- k++;
- i++;
- }
- }
-
- AlgnLen = i;
-
- // 9. Collapse the alternating spaces
- do {
-
- k = 0;
- i = 0;
- while (k<AlgnLen) {
- if ((AlgnS[k]==Space) && (AlgnT[k]==Space)) k++;
- else if ((k+1<AlgnLen) &&
- (AlgnS[k]==Space) && (AlgnS[k+1]!=Space) &&
- (AlgnT[k]!=Space) && (AlgnT[k+1]==Space)) {
- AlgnS[i] = AlgnS[k+1];
- AlgnT[i] = AlgnT[k];
- k++;
- } else if ((k+1<AlgnLen) &&
- (AlgnS[k]!=Space) && (AlgnS[k+1]==Space) &&
- (AlgnT[k]==Space) && (AlgnT[k+1]!=Space)) {
- AlgnS[i] = AlgnS[k];
- AlgnT[i] = AlgnT[k+1];
- k++;
- } else if (i!=k) {
- AlgnS[i] = AlgnS[k];
- AlgnT[i] = AlgnT[k];
- }
- if (k<AlgnLen) {
- k++;
- i++;
- }
- }
-
- AlgnLen = i;
-
- } while (k>i);
-
-
-}
-
-
-void CAlignment1::AdjustEnds ( ivector S, ivector T, int J, int I ) {
-int is,it;
- is = J;
- it = I;
- while ((is<SLen) || (it<TLen)) {
- if (is<SLen) AlgnS[AlgnLen] = S[is];
- else AlgnS[AlgnLen] = Space;
- if (it<TLen) AlgnT[AlgnLen] = T[it];
- else AlgnT[AlgnLen] = Space;
- is++;
- it++;
- AlgnLen++;
- }
-}
-
-realtype CAlignment1::Score ( int A, int B ) {
- if (A==B) {
- if (A==Space) return 0.0;
- else return SEq;
- }
- if ((A==Space) || (B==Space)) return Ws;
- return SNEq;
-}
-
-
-realtype CAlignment1::GetSimilarity() {
-realtype s,a;
-int i;
-
- s = 0.0;
- a = 0.0;
-
- for (i=0;i<AlgnLen;i++)
- if ((AlgnS[i]!=Space) || (AlgnT[i]!=Space)) {
- a += RMax ( Score(AlgnS[i],AlgnS[i]),Score(AlgnT[i],AlgnT[i]) );
- s += Score ( AlgnS[i],AlgnT[i] );
- }
-
- if ((s>0.0) && (a>0.0)) return s/a;
- return 0.0;
-
-}
-
-
-void CAlignment1::OutputResults ( RCFile f, ivector S, int lenS,
- ivector T, int lenT ) {
-int k,l,n;
-char P[10];
-
- if ((!AlgnS) || (!AlgnT)) {
- f.LF();
- f.WriteLine ( pstr(" NO ALIGNMENT HAS BEEN DONE.") );
- f.shut();
- return;
- }
- f.LF();
- f.WriteLine ( pstr(" ======== INPUT DATA") );
- f.LF();
- f.WriteLine ( pstr(" String S:") );
- f.Write ( pstr(" ") );
- l = 1;
- k = 0;
- while (k<lenS) {
- sprintf ( P,"%4i ",S[k++] );
- f.Write ( P );
- l += 5;
- if (l>=WrapPeriod) {
- f.LF(); f.Write ( pstr(" ") ); l = 1;
- }
- }
- f.LF();
- f.LF();
- f.WriteLine ( pstr(" String T:") );
- f.Write ( pstr(" ") );
- l = 1;
- k = 0;
- while (k<lenT) {
- sprintf ( P,"%4i ",T[k++] );
- f.Write ( P );
- l += 5;
- if (l>=WrapPeriod) {
- f.LF(); f.Write ( pstr(" ") ); l = 1;
- }
- }
- f.LF();
- f.LF();
- f.WriteParameter ( pstr(" Score equal") ,SEq ,20,10 );
- f.WriteParameter ( pstr(" Score unequal"),SNEq,20,10 );
- f.LF();
- f.WriteParameter ( pstr(" Gap weight") ,Wg ,20,10 );
- f.WriteParameter ( pstr(" Space weight") ,Ws ,20,10 );
- f.LF();
- f.LF();
- f.Write ( pstr(" ======== RESULT OF ") );
- switch (AlignKey) {
- default :
- case ALIGN_GLOBAL : f.Write ( pstr("GLOBAL") ); break;
- case ALIGN_LOCAL : f.Write ( pstr("LOCAL") ); break;
- case ALIGN_GLOBLOC : f.Write ( pstr("GLOBAL/LOCAL") ); break;
- case ALIGN_FREEENDS : f.Write ( pstr("FREE-ENDS") );
- }
- f.WriteLine ( pstr(" ALIGNMENT") );
- f.LF();
- if (AlignKey==ALIGN_GLOBLOC) {
- f.WriteLine ( pstr(" End gaps in T-string were not penalized") );
- f.LF();
- }
- f.WriteParameter ( pstr(" Highest score achieved:"),
- VAchieved,26,10 );
- f.LF();
- f.WriteLine ( pstr(" Aligned S (upper string) and T "
- "(lower string):") );
- f.LF();
- k = 0;
- n = 0;
- l = 1; f.Write ( pstr(" ") );
- while (k<AlgnLen) {
- sprintf ( P,"%4i ",AlgnS[k++] );
- f.Write ( P );
- l += 5;
- if ((l>=WrapPeriod) || (!AlgnS[k])) {
- f.LF(); f.Write ( pstr(" ") ); l = 1;
- while ((n<AlgnLen) && (l<WrapPeriod)) {
- sprintf ( P,"%4i ",AlgnT[n++] );
- f.Write ( P );
- l += 5;
- }
- f.LF(); f.LF(); f.Write ( pstr(" ") ); l = 1;
- }
- }
-
-}
-
-
-// ----------------- Streaming -----------------------------
-
-void CAlignment1::write ( RCFile f ) {
-int Version=1;
- f.WriteFile ( &Version,sizeof(Version) );
- CStream::write ( f );
-}
-
-void CAlignment1::read ( RCFile f ) {
-int Version;
- f.ReadFile ( &Version,sizeof(Version) );
- CStream::write ( f );
-}
-
diff --git a/mmdb/mmdb_align.h b/mmdb/mmdb_align.h
deleted file mode 100755
index be2ebb9..0000000
--- a/mmdb/mmdb_align.h
+++ /dev/null
@@ -1,189 +0,0 @@
-// $Id: mmdb_align.h,v 1.21 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 19.04.11 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_Align <interface>
-// ~~~~~~~~~
-// **** Classes : CAlignment ( alignment of character strings )
-// ~~~~~~~~~~~~ CAlignment1 ( alignment of integer vectors )
-//
-// (C) E.Krissinel' 2000-2011
-//
-// =================================================================
-//
-
-#ifndef __MMDB_Align__
-#define __MMDB_Align__
-
-#ifndef __Stream__
-#include "stream_.h"
-#endif
-
-
-// ===================== CAlignParams ======================
-
-
-DefineClass(CAlignParams);
-DefineStreamFunctions(CAlignParams);
-
-class CAlignParams : public CStream {
-
- public :
-
- realtype gapWeight,spaceWeight;
- realtype equalScore,nequalScore;
- int method;
-
- CAlignParams();
- CAlignParams ( RPCStream Object );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
- void InitAlignParams();
-
-};
-
-
-// ===================== CAlignment ======================
-
-DefineClass(CAlignment);
-
-#define ALIGN_GLOBAL 0
-#define ALIGN_LOCAL 1
-#define ALIGN_GLOBLOC 2
-#define ALIGN_FREEENDS 3
-
-class CAlignment : public CStream {
-
- public :
-
- CAlignment ();
- CAlignment ( RPCStream Object );
- ~CAlignment ();
-
- void SetAffineModel ( realtype WGap, realtype WSpace );
- void SetScores ( realtype SEqual, realtype SNEqual );
-
- void Align ( cpstr S, cpstr T, int Method=ALIGN_GLOBAL );
-
- pstr GetAlignedS() { return AlgnS; }
- pstr GetAlignedT() { return AlgnT; }
- realtype GetScore () { return VAchieved; }
- char GetSpace () { return Space; }
-
- realtype GetSimilarity(); // Score-weighted sequence id
- realtype GetSeqId (); // Primitive sequence id
-
- virtual void OutputResults ( RCFile f, cpstr S, cpstr T );
-
- void read ( RCFile f );
- void write ( RCFile f );
-
- protected :
-
- char Space;
- int AlignKey, SLen,TLen;
- rmatrix VT,ET,FT;
- pstr AlgnS,AlgnT;
- realtype VAchieved;
- realtype SEq,SNEq, Wg,Ws;
-
- virtual void InitAlignment();
- virtual void FreeMemory ();
- virtual realtype Score ( char A, char B );
-
- void BuildGATable ( cpstr S, cpstr T,
- Boolean FreeSEnd, Boolean FreeTEnd );
- void BuildLATable ( cpstr S, cpstr T );
- void Backtrace ( cpstr S, cpstr T, int J, int I,
- Boolean StopAtZero );
- void AdjustEnds ( cpstr S, cpstr T, int J, int I );
- void PrintVT ( cpstr S, cpstr T );
-
-};
-
-
-
-// ===================== CAlignment1 ======================
-
-DefineClass(CAlignment1);
-
-class CAlignment1 : public CStream {
-
- public :
-
- CAlignment1 ();
- CAlignment1 ( RPCStream Object );
- ~CAlignment1();
-
- void SetAffineModel ( realtype WGap, realtype WSpace );
- void SetScores ( realtype SEqual, realtype SNEqual );
-
- void Align ( ivector S, int SLength,
- ivector T, int TLength,
- int Method=ALIGN_GLOBAL );
-
- ivector GetAlignedS () { return AlgnS; }
- ivector GetAlignedT () { return AlgnT; }
- int GetAlignLength() { return AlgnLen; }
- realtype GetScore () { return VAchieved; }
-
- realtype GetSimilarity(); // Score-weighted sequence id
-
- virtual void OutputResults ( RCFile f, ivector S, int lenS,
- ivector T, int lenT );
-
- void read ( RCFile f );
- void write ( RCFile f );
-
- protected :
-
- int Space;
- int AlignKey, SLen,TLen, AlgnLen;
- rmatrix VT,ET,FT;
- ivector AlgnS,AlgnT;
- realtype VAchieved;
- realtype SEq,SNEq, Wg,Ws;
-
- virtual void InitAlignment1();
- virtual void FreeMemory ();
- virtual realtype Score ( int A, int B );
-
- void BuildGATable ( ivector S, ivector T,
- Boolean FreeSEnds, Boolean FreeTEnds );
- void BuildLATable ( ivector S, ivector T );
- void Backtrace ( ivector S, ivector T, int J, int I,
- Boolean StopAtZero );
- void AdjustEnds ( ivector S, ivector T, int J, int I );
- void PrintVT ( ivector S, ivector T );
-
-};
-
-
-#endif
diff --git a/mmdb/mmdb_atom.cpp b/mmdb/mmdb_atom.cpp
deleted file mode 100755
index b9c3285..0000000
--- a/mmdb/mmdb_atom.cpp
+++ /dev/null
@@ -1,3495 +0,0 @@
-// $Id: mmdb_atom.cpp,v 1.31 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 23.04.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_Atom <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CAtom ( atom class )
-// ~~~~~~~~~ CResidue ( residue class )
-//
-// Copyright (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifndef __MATH_H
-#include <math.h>
-#endif
-
-#ifndef __MMDB_Chain__
-#include "mmdb_chain.h"
-#endif
-
-#ifndef __MMDB_Model__
-#include "mmdb_model.h"
-#endif
-
-#ifndef __MMDB_File__
-#include "mmdb_file.h"
-#endif
-
-#ifndef __MMDB_Tables__
-#include "mmdb_tables.h"
-#endif
-
-#ifndef __MMDB_CIFDefs__
-#include "mmdb_cifdefs.h"
-#endif
-
-#ifndef IOTBX_PDB_HYBRID_36_C_H
-#include "hybrid_36.h"
-#endif
-
-
-// ================================================================
-
-#define ASET_ShortBinary 0x10000000
-#define ASET_ShortTer 0x20000000
-#define ASET_ShortHet 0x40000000
-
-Boolean ignoreSegID = False;
-Boolean ignoreElement = False;
-Boolean ignoreCharge = False;
-Boolean ignoreNonCoorPDBErrors = False;
-Boolean ignoreUnmatch = False;
-
-
-// ========================== CAtom =============================
-
-CAtom::CAtom() : CUDData() {
- InitAtom();
-}
-
-CAtom::CAtom ( PCResidue res ) : CUDData() {
- InitAtom();
- if (res)
- res->AddAtom ( this );
-}
-
-CAtom::CAtom ( RPCStream Object ) : CUDData(Object) {
- InitAtom();
-}
-
-CAtom::~CAtom() {
-int nA;
-PPCAtom A;
- FreeMemory();
- if (residue) {
- A = NULL;
- nA = 0;
- if (residue->chain) {
- if (residue->chain->model) {
- A = residue->chain->model->GetAllAtoms();
- nA = residue->chain->model->GetNumberOfAllAtoms();
- }
- }
- residue->_ExcludeAtom ( index );
- if ((0<index) && (index<=nA)) A[index-1] = NULL;
- }
-}
-
-void CAtom::InitAtom() {
- serNum = -1; // serial number
- index = -1; // index in the file
- name[0] = char(0); // atom name
- label_atom_id[0] = char(0); // assigned atom name (not aligned)
- altLoc[0] = char(0); // alternate location indicator
- residue = NULL; // reference to residue
- x = 0.0; // orthogonal x-coordinate in angstroms
- y = 0.0; // orthogonal y-coordinate in angstroms
- z = 0.0; // orthogonal z-coordinate in angstroms
- occupancy = 0.0; // occupancy
- tempFactor = 0.0; // temperature factor
- segID[0] = char(0); // segment identifier
- strcpy ( element," " ); // chemical element symbol - RIGHT JUSTIFIED
- energyType[0] = char(0); // chemical element symbol - RIGHT JUSTIFIED
- charge = 0.0; // charge on the atom
- sigX = 0.0; // standard deviation of the stored x-coord
- sigY = 0.0; // standard deviation of the stored y-coord
- sigZ = 0.0; // standard deviation of the stored z-coord
- sigOcc = 0.0; // standard deviation of occupancy
- sigTemp = 0.0; // standard deviation of temperature factor
- u11 = 0.0; //
- u22 = 0.0; // anisotropic
- u33 = 0.0; //
- u12 = 0.0; // temperature
- u13 = 0.0; //
- u23 = 0.0; // factors
- su11 = 0.0; //
- su22 = 0.0; // standard
- su33 = 0.0; // deviations of
- su12 = 0.0; // anisotropic
- su13 = 0.0; // temperature
- su23 = 0.0; // factors
- Het = False; // indicator of atom in non-standard groups
- Ter = False; // chain terminator
- WhatIsSet = 0x00000000; // nothing is set
- nBonds = 0; // no bonds
- Bond = NULL; // empty array of bonds
-}
-
-void CAtom::FreeMemory() {
- FreeBonds();
-}
-
-void CAtom::FreeBonds() {
- if (Bond) delete[] Bond;
- Bond = NULL;
- nBonds = 0;
-}
-
-int CAtom::GetNBonds() {
- return nBonds & 0x000000FF;
-}
-
-void CAtom::GetBonds ( RPSAtomBond AtomBond, int & nAtomBonds ) {
-// This GetBonds(..) returns pointer to the CAtom's
-// internal Bond structure, IT MUST NOT BE DISPOSED.
- nAtomBonds = nBonds & 0x000000FF;
- AtomBond = Bond;
-}
-
-void CAtom::GetBonds ( RPSAtomBondI AtomBondI, int & nAtomBonds ) {
-// This GetBonds(..) disposes AtomBondI, if it was not set
-// to NULL, allocates AtomBondI[nAtomBonds] and returns its
-// pointer. AtomBondI MUST BE DISPOSED BY APPLICATION.
-int i;
-
- if (AtomBondI) delete[] AtomBondI;
-
- nAtomBonds = nBonds & 0x000000FF;
-
- if (nAtomBonds<=0)
- AtomBondI = NULL;
- else {
- AtomBondI = new SAtomBondI[nAtomBonds];
- for (i=0;i<nAtomBonds;i++) {
- if (Bond[i].atom)
- AtomBondI[i].index = Bond[i].atom->index;
- else AtomBondI[i].index = -1;
- AtomBondI[i].order = Bond[i].order;
- }
-
- }
-
-}
-
-void CAtom::GetBonds ( PSAtomBondI AtomBondI, int & nAtomBonds,
- int maxlength ) {
-// This GetBonds(..) does not dispose or allocate AtomBond.
-// It is assumed that length of AtomBond is sufficient to
-// accomodate all bonded atoms.
-int i;
-
- nAtomBonds = IMin(maxlength,nBonds & 0x000000FF);
-
- for (i=0;i<nAtomBonds;i++) {
- if (Bond[i].atom)
- AtomBondI[i].index = Bond[i].atom->index;
- else AtomBondI[i].index = -1;
- AtomBondI[i].order = Bond[i].order;
- }
-
-}
-
-
-int CAtom::AddBond ( PCAtom bond_atom, int bond_order,
- int nAdd_bonds ) {
-PSAtomBond B1;
-int i,k,nb,nballoc;
-
- nb = nBonds & 0x000000FF;
- k = -1;
- for (i=0;(i<nb) && (k<0);i++)
- if (Bond[i].atom==bond_atom) k = i;
- if (k>=0) return -k;
-
- nballoc = (nBonds >> 8) & 0x000000FF;
- if (nBonds>=nballoc) {
- nballoc += nAdd_bonds;
- B1 = new SAtomBond[nballoc];
- for (i=0;i<nb;i++) {
- B1[i].atom = Bond[i].atom;
- B1[i].order = Bond[i].order;
- }
- if (Bond) delete[] Bond;
- Bond = B1;
- }
- Bond[nb].atom = bond_atom;
- Bond[nb].order = bond_order;
- nb++;
-
- nBonds = nb | (nballoc << 8);
-
- return nb;
-
-}
-
-void CAtom::SetResidue ( PCResidue res ) {
- residue = res;
-}
-
-void CAtom::StandardPDBOut ( cpstr Record, pstr S ) {
-char N[10];
- strcpy ( S,Record );
- PadSpaces ( S,80 );
- if (serNum>99999) {
- hy36encode ( 5,serNum,N );
- strcpy_n ( &(S[6]),N,5 );
- } else if (serNum>0)
- PutInteger ( &(S[6]),serNum,5 );
- else if (index<=99999)
- PutInteger ( &(S[6]),index,5 );
- else {
- hy36encode ( 5,index,N );
- strcpy_n ( &(S[6]),N,5 );
- }
- if (!Ter) {
- if (altLoc[0]) S[16] = altLoc[0];
- strcpy_n ( &(S[12]),name ,4 );
- strcpy_n ( &(S[72]),segID ,4 );
- strcpy_nr ( &(S[76]),element,2 );
- if (WhatIsSet & ASET_Charge) {
- if (charge>0) sprintf ( N,"%1i+",mround(charge) );
- else if (charge<0) sprintf ( N,"%1i-",mround(-charge) );
- else strcpy ( N," " );
- strcpy_n ( &(S[78]),N,2 );
- } else
- strcpy_n ( &(S[78])," ",2 );
- }
- strcpy_nr ( &(S[17]),residue->name,3 );
- strcpy_nr ( &(S[20]),residue->chain->chainID,2 );
- if (residue->seqNum>MinInt4) {
- if ((-999<=residue->seqNum) && (residue->seqNum<=9999))
- PutIntIns ( &(S[22]),residue->seqNum,4,residue->insCode );
- else {
- hy36encode ( 4,residue->seqNum,N );
- strcpy_n ( &(S[22]),N,4 );
- }
- }
-}
-
-void CAtom::PDBASCIIDump ( RCFile f ) {
-// makes the ASCII PDB ATOM, HETATM, SIGATOM, ANISOU
-// SIGUIJ and TER lines from the class' data
-char S[100];
- if (Ter) {
- if (WhatIsSet & ASET_Coordinates) {
- StandardPDBOut ( pstr("TER"),S );
- f.WriteLine ( S );
- }
- } else {
- if (WhatIsSet & ASET_Coordinates) {
- if (Het) StandardPDBOut ( pstr("HETATM"),S );
- else StandardPDBOut ( pstr("ATOM") ,S );
- PutRealF ( &(S[30]),x,8,3 );
- PutRealF ( &(S[38]),y,8,3 );
- PutRealF ( &(S[46]),z,8,3 );
- if (WhatIsSet & ASET_Occupancy)
- PutRealF ( &(S[54]),occupancy ,6,2 );
- if (WhatIsSet & ASET_tempFactor)
- PutRealF ( &(S[60]),tempFactor,6,2 );
- f.WriteLine ( S );
- }
- if (WhatIsSet & ASET_CoordSigma) {
- StandardPDBOut ( pstr("SIGATM"),S );
- PutRealF ( &(S[30]),sigX,8,3 );
- PutRealF ( &(S[38]),sigY,8,3 );
- PutRealF ( &(S[46]),sigZ,8,3 );
- if ((WhatIsSet & ASET_OccSigma) &&
- (WhatIsSet & ASET_Occupancy))
- PutRealF ( &(S[54]),sigOcc,6,2 );
- if ((WhatIsSet & ASET_tFacSigma) &&
- (WhatIsSet & ASET_tempFactor))
- PutRealF ( &(S[60]),sigTemp,6,2 );
- f.WriteLine ( S );
- }
- if (WhatIsSet & ASET_Anis_tFac) {
- StandardPDBOut ( pstr("ANISOU"),S );
- PutInteger ( &(S[28]),mround(u11*1.0e4),7 );
- PutInteger ( &(S[35]),mround(u22*1.0e4),7 );
- PutInteger ( &(S[42]),mround(u33*1.0e4),7 );
- PutInteger ( &(S[49]),mround(u12*1.0e4),7 );
- PutInteger ( &(S[56]),mround(u13*1.0e4),7 );
- PutInteger ( &(S[63]),mround(u23*1.0e4),7 );
- f.WriteLine ( S );
- if (WhatIsSet & ASET_Anis_tFSigma) {
- StandardPDBOut ( pstr("SIGUIJ"),S );
- PutInteger ( &(S[28]),mround(su11*1.0e4),7 );
- PutInteger ( &(S[35]),mround(su22*1.0e4),7 );
- PutInteger ( &(S[42]),mround(su33*1.0e4),7 );
- PutInteger ( &(S[49]),mround(su12*1.0e4),7 );
- PutInteger ( &(S[56]),mround(su13*1.0e4),7 );
- PutInteger ( &(S[63]),mround(su23*1.0e4),7 );
- f.WriteLine ( S );
- }
- }
- }
-}
-
-void CAtom::MakeCIF ( PCMMCIFData CIF ) {
-PCMMCIFLoop Loop;
-AtomName AtName;
-Element el;
-char N[10];
-int i,j,RC;
-PCChain chain = NULL;
-PCModel model = NULL;
-//Boolean singleModel = True;
-
- if (residue) chain = residue->chain;
- if (chain) model = PCModel(chain->model);
-// if (model) {
-// if (model->manager)
-// singleModel = PCMMDBFile(model->manager)->nModels<=1;
-// }
-
-/*
-
-loop_
-*0 _atom_site.group_PDB
-*1 _atom_site.id
-*2 _atom_site.type_symbol <- chem elem
--3 _atom_site.label_atom_id <- atom name
-*4 _atom_site.label_alt_id <- alt code
-=5 _atom_site.label_comp_id <- res name ???
-=6 _atom_site.label_asym_id <- chain id ???
-=7 _atom_site.label_entity_id < ???
-=8 _atom_site.label_seq_id <- poly seq id
-+9 _atom_site.pdbx_PDB_ins_code <- ins code
--10 _atom_site.segment_id <- segment id
-*11 _atom_site.Cartn_x
-*12 _atom_site.Cartn_y
-*13 _atom_site.Cartn_z
-*14 _atom_site.occupancy
-*15 _atom_site.B_iso_or_equiv
-*16 _atom_site.Cartn_x_esd
-*17 _atom_site.Cartn_y_esd
-*18 _atom_site.Cartn_z_esd
-*19 _atom_site.occupancy_esd
-*20 _atom_site.B_iso_or_equiv_esd
-*21 _atom_site.pdbx_formal_charge
-+22 _atom_site.auth_seq_id <- seq id we want
-+23 _atom_site.auth_comp_id <- res name we want
-+24 _atom_site.auth_asym_id <- ch id we want ?
-*25 _atom_site.auth_atom_id <- atom name we want ?
-+26 _atom_site.pdbx_PDB_model_num <- model no
-
-'+' is read in CMMDBFile::CheckAtomPlace()
-'=' new in residue
-'-' new in atom
-
-
-*/
-
- RC = CIF->AddLoop ( CIFCAT_ATOM_SITE,Loop );
- if (RC!=CIFRC_Ok) {
- // the category was (re)created, provide tags
-
- Loop->AddLoopTag ( CIFTAG_GROUP_PDB ); // ATOM, TER etc.
- Loop->AddLoopTag ( CIFTAG_ID ); // serial number
-
- Loop->AddLoopTag ( CIFTAG_TYPE_SYMBOL ); // element symbol
- Loop->AddLoopTag ( CIFTAG_LABEL_ATOM_ID ); // atom name
- Loop->AddLoopTag ( CIFTAG_LABEL_ALT_ID ); // alt location
- Loop->AddLoopTag ( CIFTAG_LABEL_COMP_ID ); // residue name
- Loop->AddLoopTag ( CIFTAG_LABEL_ASYM_ID ); // chain ID
- Loop->AddLoopTag ( CIFTAG_LABEL_ENTITY_ID ); // entity ID
- Loop->AddLoopTag ( CIFTAG_LABEL_SEQ_ID ); // res seq number
- Loop->AddLoopTag ( CIFTAG_PDBX_PDB_INS_CODE ); // insertion code
- Loop->AddLoopTag ( CIFTAG_SEGMENT_ID ); // segment ID
-
- Loop->AddLoopTag ( CIFTAG_CARTN_X ); // x-coordinate
- Loop->AddLoopTag ( CIFTAG_CARTN_Y ); // y-coordinate
- Loop->AddLoopTag ( CIFTAG_CARTN_Z ); // z-coordinate
- Loop->AddLoopTag ( CIFTAG_OCCUPANCY ); // occupancy
- Loop->AddLoopTag ( CIFTAG_B_ISO_OR_EQUIV ); // temp factor
-
- Loop->AddLoopTag ( CIFTAG_CARTN_X_ESD ); // x-sigma
- Loop->AddLoopTag ( CIFTAG_CARTN_Y_ESD ); // y-sigma
- Loop->AddLoopTag ( CIFTAG_CARTN_Z_ESD ); // z-sigma
- Loop->AddLoopTag ( CIFTAG_OCCUPANCY_ESD ); // occupancy-sigma
- Loop->AddLoopTag ( CIFTAG_B_ISO_OR_EQUIV_ESD ); // t-factor-sigma
-
- Loop->AddLoopTag ( CIFTAG_PDBX_FORMAL_CHARGE ); // charge on atom
-
- Loop->AddLoopTag ( CIFTAG_AUTH_SEQ_ID ); // res seq number
- Loop->AddLoopTag ( CIFTAG_AUTH_COMP_ID ); // residue name
- Loop->AddLoopTag ( CIFTAG_AUTH_ASYM_ID ); // chain id
- Loop->AddLoopTag ( CIFTAG_AUTH_ATOM_ID ); // atom name
-
- Loop->AddLoopTag ( CIFTAG_PDBX_PDB_MODEL_NUM ); // model number
-
- }
-
- if (Ter) { // ter record
-
- if (!(WhatIsSet & ASET_Coordinates))
- return;
-
- // (0)
- Loop->AddString ( pstr("TER") );
- // (1)
- if (serNum>0) Loop->AddInteger ( serNum );
- else Loop->AddInteger ( index );
- // (2,3,4)
- Loop->AddNoData ( CIF_NODATA_QUESTION ); // no element symbol
- Loop->AddNoData ( CIF_NODATA_QUESTION ); // no atom name
- Loop->AddNoData ( CIF_NODATA_QUESTION ); // no alt code
- if (residue) {
- // (5)
- Loop->AddString ( residue->label_comp_id );
- // (6)
- Loop->AddString ( residue->label_asym_id );
- // (7)
- if (residue->label_entity_id>0)
- Loop->AddInteger ( residue->label_entity_id );
- else Loop->AddNoData ( CIF_NODATA_DOT );
- // (8)
- if (residue->label_seq_id>MinInt4)
- Loop->AddInteger ( residue->label_seq_id );
- else Loop->AddNoData ( CIF_NODATA_DOT );
- // (9)
- Loop->AddString ( residue->insCode,True );
- } else {
- // (5,6,7,8,9)
- Loop->AddString ( NULL );
- Loop->AddString ( NULL );
- Loop->AddNoData ( CIF_NODATA_DOT );
- Loop->AddNoData ( CIF_NODATA_DOT );
- Loop->AddNoData ( CIF_NODATA_DOT );
- }
-
- // (10-21)
- for (i=10;i<=21;i++)
- Loop->AddNoData ( CIF_NODATA_QUESTION );
-
- // (22,23)
- if (residue) {
- if (residue->seqNum>MinInt4)
- Loop->AddInteger ( residue->seqNum );
- else Loop->AddNoData ( CIF_NODATA_DOT );
- Loop->AddString ( residue->name );
- } else {
- Loop->AddNoData ( CIF_NODATA_DOT );
- Loop->AddString ( NULL );
- }
-
- // (24)
- if (chain) Loop->AddString ( chain->chainID,True );
- else Loop->AddString ( NULL );
-
- // (25)
- Loop->AddNoData ( CIF_NODATA_QUESTION ); // no atom name
-
- } else if (WhatIsSet & (ASET_Coordinates | ASET_CoordSigma)) {
- // normal atom record
-
- if (!WhatIsSet) return;
-
- // (0)
- if (Het) Loop->AddString ( pstr("HETATM") );
- else Loop->AddString ( pstr("ATOM") );
- // (1)
- if (serNum>0) Loop->AddInteger ( serNum );
- else Loop->AddInteger ( index );
-
-
- if (WhatIsSet & ASET_Coordinates) {
-
- // (2)
- strcpy_css ( el,element );
- Loop->AddString ( el,True );
- // (3)
- Loop->AddString ( label_atom_id ); // assigned atom name
- // (4)
- Loop->AddString ( altLoc,True ); // alt code
-
- if (residue) {
- // (5)
- Loop->AddString ( residue->label_comp_id );
- // (6)
- Loop->AddString ( residue->label_asym_id );
- // (7)
- if (residue->label_entity_id>0)
- Loop->AddInteger ( residue->label_entity_id );
- else Loop->AddNoData ( CIF_NODATA_DOT );
- // (8)
- if (residue->label_seq_id>MinInt4)
- Loop->AddInteger ( residue->label_seq_id );
- else Loop->AddNoData ( CIF_NODATA_DOT );
- // (9)
- Loop->AddString ( residue->insCode,True );
- } else {
- // (5,6,7,8,9)
- Loop->AddString ( NULL );
- Loop->AddString ( NULL );
- Loop->AddNoData ( CIF_NODATA_DOT );
- Loop->AddNoData ( CIF_NODATA_DOT );
- Loop->AddNoData ( CIF_NODATA_DOT );
- }
-
- // (10)
- Loop->AddString ( segID ,True );
- // (11,12,13)
- Loop->AddReal ( x );
- Loop->AddReal ( y );
- Loop->AddReal ( z );
- // (14)
- if (WhatIsSet & ASET_Occupancy)
- Loop->AddReal ( occupancy );
- else Loop->AddNoData ( CIF_NODATA_QUESTION );
- // (15)
- if (WhatIsSet & ASET_tempFactor)
- Loop->AddReal ( tempFactor );
- else Loop->AddNoData ( CIF_NODATA_QUESTION );
-
- // (16,17,18)
- if (WhatIsSet & ASET_CoordSigma) {
- Loop->AddReal ( sigX );
- Loop->AddReal ( sigY );
- Loop->AddReal ( sigZ );
- } else {
- Loop->AddNoData ( CIF_NODATA_QUESTION );
- Loop->AddNoData ( CIF_NODATA_QUESTION );
- Loop->AddNoData ( CIF_NODATA_QUESTION );
- }
- // (19)
- if ((WhatIsSet & ASET_OccSigma) && (WhatIsSet & ASET_Occupancy))
- Loop->AddReal ( sigOcc );
- else Loop->AddNoData ( CIF_NODATA_QUESTION );
- // (20)
- if ((WhatIsSet & ASET_tFacSigma) && (WhatIsSet & ASET_tempFactor))
- Loop->AddReal ( sigTemp );
- else Loop->AddNoData ( CIF_NODATA_QUESTION );
-
- } else
- for (i=0;i<18;i++)
- Loop->AddNoData ( CIF_NODATA_QUESTION );
-
- // (21)
- if (WhatIsSet & ASET_Charge) {
- sprintf ( N,"%+2i",mround(charge) );
- Loop->AddString ( N,True );
- } else
- Loop->AddNoData ( CIF_NODATA_QUESTION );
-
- if (residue) {
- // (22)
- if (residue->seqNum>MinInt4)
- Loop->AddInteger ( residue->seqNum );
- else Loop->AddNoData ( CIF_NODATA_DOT );
- // (23)
- Loop->AddString ( residue->name );
- } else {
- Loop->AddNoData ( CIF_NODATA_DOT );
- Loop->AddNoData ( CIF_NODATA_DOT );
- }
-
- // (24)
- if (chain) Loop->AddString ( chain->chainID,True );
- else Loop->AddNoData ( CIF_NODATA_DOT );
- // (25)
- strcpy_css ( AtName,name );
- Loop->AddString ( AtName ); // atom name
-
- }
-
- // (26)
- if (!model) Loop->AddNoData ( CIF_NODATA_QUESTION );
- else if (model->serNum>0) Loop->AddInteger ( model->serNum );
- else Loop->AddNoData ( CIF_NODATA_QUESTION );
-
-
- if (WhatIsSet & ASET_Anis_tFac) {
-
- RC = CIF->AddLoop ( CIFCAT_ATOM_SITE_ANISOTROP,Loop );
- if (RC!=CIFRC_Ok) {
- // the category was (re)created, provide tags
- Loop->AddLoopTag ( CIFTAG_ID ); // serial number
- Loop->AddLoopTag ( CIFTAG_U11 ); // component u11
- Loop->AddLoopTag ( CIFTAG_U22 ); // component u22
- Loop->AddLoopTag ( CIFTAG_U33 ); // component u33
- Loop->AddLoopTag ( CIFTAG_U12 ); // component u12
- Loop->AddLoopTag ( CIFTAG_U13 ); // component u13
- Loop->AddLoopTag ( CIFTAG_U23 ); // component u23
- Loop->AddLoopTag ( CIFTAG_U11_ESD ); // component u11 sigma
- Loop->AddLoopTag ( CIFTAG_U22_ESD ); // component u22 sigma
- Loop->AddLoopTag ( CIFTAG_U33_ESD ); // component u33 sigma
- Loop->AddLoopTag ( CIFTAG_U12_ESD ); // component u12 sigma
- Loop->AddLoopTag ( CIFTAG_U13_ESD ); // component u13 sigma
- Loop->AddLoopTag ( CIFTAG_U23_ESD ); // component u23 sigma
- for (i=1;i<index;i++) {
- Loop->AddInteger ( i );
- for (j=0;j<12;j++)
- Loop->AddString ( NULL );
- }
- }
-
- if (serNum>0) Loop->AddInteger ( serNum );
- else Loop->AddInteger ( index );
-
- Loop->AddReal ( u11 );
- Loop->AddReal ( u22 );
- Loop->AddReal ( u33 );
- Loop->AddReal ( u12 );
- Loop->AddReal ( u13 );
- Loop->AddReal ( u23 );
- if (WhatIsSet & ASET_Anis_tFSigma) {
- Loop->AddReal ( su11 );
- Loop->AddReal ( su22 );
- Loop->AddReal ( su33 );
- Loop->AddReal ( su12 );
- Loop->AddReal ( su13 );
- Loop->AddReal ( su23 );
- }
-
- }
-
-}
-
-int CAtom::ConvertPDBATOM ( int ix, cpstr S ) {
-// Gets data from the PDB ASCII ATOM record.
-// This function DOES NOT check the "ATOM" keyword and
-// does not decode the chain and residue parameters! These
-// must be treated by calling process, see
-// Chain::ConvertPDBASCII().
-
- index = ix;
-
- if (WhatIsSet & ASET_Coordinates)
- return Error_ATOM_AlreadySet;
-
- if (!(GetReal(x,&(S[30]),8) &&
- GetReal(y,&(S[38]),8) &&
- GetReal(z,&(S[46]),8)))
- return Error_ATOM_Unrecognized;
-
- WhatIsSet |= ASET_Coordinates;
- Het = False;
- Ter = False;
-
- if (GetReal(occupancy ,&(S[54]),6)) WhatIsSet |= ASET_Occupancy;
- if (GetReal(tempFactor,&(S[60]),6)) WhatIsSet |= ASET_tempFactor;
-
- if (WhatIsSet & (ASET_CoordSigma | ASET_Anis_tFac |
- ASET_Anis_tFSigma))
- // something was already submitted. check complience
- return CheckData ( S );
- else
- // first data submission. just take the data
- GetData ( S );
-
- return 0;
-
-}
-
-void CAtom::SetAtomName ( int ix,
- int sN,
- const AtomName aName,
- const AltLoc aLoc,
- const SegID sID,
- const Element eName ) {
- index = ix;
- serNum = sN;
- strcpy ( name ,aName );
- strcpy ( label_atom_id,aName );
- strcpy_css ( altLoc ,pstr(aLoc) );
- strcpy_css ( segID ,pstr(sID) );
- if (!eName[0]) element[0] = char(0);
- else if (!eName[1]) {
- element[0] = ' ';
- strcpy ( &(element[1]),eName );
- } else
- strcpy ( element,eName );
- WhatIsSet = 0;
-}
-
-int CAtom::ConvertPDBSIGATM ( int ix, cpstr S ) {
-// Gets data from the PDB ASCII SIGATM record.
-// This function DOES NOT check the "SIGATM" keyword and
-// does not decode the chain and residue parameters! These
-// must be treated by the calling process, see
-// Chain::ConvertPDBASCII().
-
- index = ix;
-
- if (WhatIsSet & ASET_CoordSigma)
- return Error_ATOM_AlreadySet;
-
- if (!(GetReal(sigX,&(S[30]),8) &&
- GetReal(sigY,&(S[38]),8) &&
- GetReal(sigZ,&(S[46]),8)))
- return Error_ATOM_Unrecognized;
-
- WhatIsSet |= ASET_CoordSigma;
-
- if (GetReal(sigOcc ,&(S[54]),6)) WhatIsSet |= ASET_OccSigma;
- if (GetReal(sigTemp,&(S[60]),6)) WhatIsSet |= ASET_tFacSigma;
-
- if (WhatIsSet & (ASET_Coordinates | ASET_Anis_tFac |
- ASET_Anis_tFSigma))
- // something was already submitted. check complience
- return CheckData ( S );
- else
- // first data submission. just take the data
- GetData ( S );
-
- return 0;
-
-}
-
-int CAtom::ConvertPDBANISOU ( int ix, cpstr S ) {
-// Gets data from the PDB ASCII ANISOU record.
-// This function DOES NOT check the "ANISOU" keyword and
-// does not decode chain and residue parameters! These must
-// be treated by the calling process, see
-// Chain::ConvertPDBASCII().
-
- index = ix;
-
- if (WhatIsSet & ASET_Anis_tFac)
- return Error_ATOM_AlreadySet;
-
- if (!(GetReal(u11,&(S[28]),7) &&
- GetReal(u22,&(S[35]),7) &&
- GetReal(u33,&(S[42]),7) &&
- GetReal(u12,&(S[49]),7) &&
- GetReal(u13,&(S[56]),7) &&
- GetReal(u23,&(S[63]),7)))
- return Error_ATOM_Unrecognized;
-
- u11 /= 1.0e4;
- u22 /= 1.0e4;
- u33 /= 1.0e4;
- u12 /= 1.0e4;
- u13 /= 1.0e4;
- u23 /= 1.0e4;
-
- WhatIsSet |= ASET_Anis_tFac;
-
- if (WhatIsSet & (ASET_Coordinates | ASET_CoordSigma |
- ASET_Anis_tFSigma))
- // something was already submitted. check complience
- return CheckData ( S );
- else
- // first data submission. just take the data
- GetData ( S );
-
- return 0;
-
-}
-
-int CAtom::ConvertPDBSIGUIJ ( int ix, cpstr S ) {
-// Gets data from the PDB ASCII SIGUIJ record.
-// This function DOES NOT check the "SIGUIJ" keyword and
-// does not decode the chain and residue parameters! These
-// must be treated by the calling process, see
-// Chain::ConvertPDBASCII().
-
- index = ix;
-
- if (WhatIsSet & ASET_Anis_tFSigma)
- return Error_ATOM_AlreadySet;
-
- if (!(GetReal(su11,&(S[28]),7) &&
- GetReal(su22,&(S[35]),7) &&
- GetReal(su33,&(S[42]),7) &&
- GetReal(su12,&(S[49]),7) &&
- GetReal(su13,&(S[56]),7) &&
- GetReal(su23,&(S[63]),7)))
- return Error_ATOM_Unrecognized;
-
- su11 /= 1.0e4;
- su22 /= 1.0e4;
- su33 /= 1.0e4;
- su12 /= 1.0e4;
- su13 /= 1.0e4;
- su23 /= 1.0e4;
-
- WhatIsSet |= ASET_Anis_tFSigma;
-
- if (WhatIsSet & (ASET_Coordinates | ASET_CoordSigma |
- ASET_Anis_tFac))
- // something was already submitted. check complience
- return CheckData ( S );
- else
- // first data submission. just take the data
- GetData ( S );
-
- return 0;
-
-}
-
-int CAtom::ConvertPDBTER ( int ix, cpstr S ) {
-// Gets data from the PDB ASCII TER record.
-// This function DOES NOT check the "TER" keyword and
-// does not decode the chain and residue parameters! These
-// must be treated by the calling process, see
-// Chain::ConvertPDBASCII().
-
- index = ix;
-
- if (((S[6]>='0') && (S[6]<='9')) || (S[6]==' ')) {
- // Although against strict PDB format, 'TER' is
- // actually allowed not to have a serial number.
- // This negative value implies that the number is
- // not set.
- if (!(GetInteger(serNum,&(S[6]),5))) serNum = -1;
- } else
- hy36decode ( 5,&(S[6]),5,&serNum );
-
-// if (!(GetInteger(serNum,&(S[6]),5))) serNum = -1;
-
- if (WhatIsSet & ASET_Coordinates)
- return Error_ATOM_AlreadySet;
-
- WhatIsSet |= ASET_Coordinates;
- Het = False;
- Ter = True;
- name[0] = char(0);
- label_atom_id[0] = char(0);
- element[0] = char(0);
-
- return 0;
-
-}
-
-
-int CAtom::GetModelNum() {
- if (residue) {
- if (residue->chain)
- if (residue->chain->model)
- return residue->chain->model->GetSerNum();
- }
- return 0;
-}
-
-pstr CAtom::GetChainID() {
- if (residue) {
- if (residue->chain) return residue->chain->chainID;
- }
- return pstr("");
-}
-
-pstr CAtom::GetLabelAsymID() {
- if (residue) return residue->label_asym_id;
- else return pstr("");
-}
-
-pstr CAtom::GetResName() {
- if (residue) return residue->name;
- else return pstr("");
-}
-
-pstr CAtom::GetLabelCompID() {
- if (residue) return residue->label_comp_id;
- else return pstr("");
-}
-
-int CAtom::GetAASimilarity ( const ResName resName ) {
- if (residue) return ::GetAASimilarity ( pstr(residue->name),
- pstr(resName) );
- else return -3;
-}
-
-int CAtom::GetAASimilarity ( PCAtom A ) {
- if (residue) {
- if (A->residue)
- return ::GetAASimilarity ( pstr(residue->name),
- pstr(A->residue->name) );
- else return -4;
- } else
- return -3;
-}
-
-realtype CAtom::GetAAHydropathy() {
- if (residue) return ::GetAAHydropathy ( pstr(residue->name) );
- else return MaxReal;
-}
-
-realtype CAtom::GetOccupancy() {
- if (WhatIsSet & ASET_Occupancy) return occupancy;
- else return 0.0;
-}
-
-int CAtom::GetSeqNum() {
- if (residue) return residue->seqNum;
- else return ATOM_NoSeqNum;
-}
-
-int CAtom::GetLabelSeqID() {
- if (residue) return residue->label_seq_id;
- else return ATOM_NoSeqNum;
-}
-
-int CAtom::GetLabelEntityID() {
- if (residue) return residue->label_entity_id;
- else return -1;
-}
-
-pstr CAtom::GetInsCode() {
- if (residue) return residue->insCode;
- else return pstr("");
-}
-
-int CAtom::GetSSEType() {
-// works only after SSE calculations
- if (residue) return residue->SSE;
- else return SSE_None;
-}
-
-pstr CAtom::GetAtomCharge ( pstr chrg ) {
- if (WhatIsSet & ASET_Charge) sprintf ( chrg,"%+2i",mround(charge) );
- else strcpy ( chrg," " );
- return chrg;
-}
-
-PCResidue CAtom::GetResidue() {
- return residue;
-}
-
-PCChain CAtom::GetChain() {
- if (residue) return residue->chain;
- else return NULL;
-}
-
-PCModel CAtom::GetModel() {
- if (residue) {
- if (residue->chain) return (PCModel)residue->chain->model;
- }
- return NULL;
-}
-
-int CAtom::GetResidueNo() {
- if (residue) {
- if (residue->chain)
- return residue->chain->GetResidueNo (
- residue->seqNum,residue->insCode );
- else return -2;
- } else
- return -1;
-}
-
-
-void * CAtom::GetCoordHierarchy() {
- if (residue) return residue->GetCoordHierarchy();
- return NULL;
-}
-
-
-void CAtom::GetStat ( realtype v,
- realtype & v_min, realtype & v_max,
- realtype & v_m, realtype & v_m2 ) {
- if (v<v_min) v_min = v;
- if (v>v_max) v_max = v;
- v_m += v;
- v_m2 += v*v;
-}
-
-
-
-void CAtom::GetChainCalphas ( PPCAtom & Calphas, int & nCalphas,
- cpstr altLoc ) {
-// GetChainCalphas(...) is a specialized function for quick
-// access to C-alphas of chain which includes given atom.
-// This function works faster than an equivalent implementation
-// through MMDB's selection procedures.
-// Parameters:
-// Calphas - array to accept pointers on C-alpha atoms
-// If Calphas!=NULL, then the function will
-// delete and re-allocate it. When the array
-// is no longer needed, the application MUST
-// delete it: delete[] Calphas; Deleting
-// Calphas does not delete atoms from MMDB.
-// nCalphas - integer to accept number of C-alpha atoms
-// and the length of Calphas array.
-// altLoc - alternative location indicator. By default
-// (""), maximum-occupancy locations are taken.
-PCChain chain;
-PPCResidue res;
-PPCAtom atom;
-int nResidues, nAtoms, i,j,k;
-
- if (Calphas) {
- delete[] Calphas;
- Calphas = NULL;
- }
- nCalphas = 0;
-
- if (residue) chain = residue->chain;
- else chain = NULL;
-
- if (chain) {
-
- chain->GetResidueTable ( res,nResidues );
-
- if (nResidues>0) {
-
- Calphas = new PCAtom[nResidues];
-
- if ((!altLoc[0]) || (altLoc[0]==' ')) { // main conformation
-
- for (i=0;i<nResidues;i++) {
- nAtoms = res[i]->nAtoms;
- atom = res[i]->atom;
- for (j=0;j<nAtoms;j++)
- if (!strcmp(atom[j]->name," CA ")) {
- Calphas[nCalphas++] = atom[j];
- break;
- }
- }
-
- } else { // specific conformation
-
- for (i=0;i<nResidues;i++) {
- nAtoms = res[i]->nAtoms;
- atom = res[i]->atom;
- k = 0;
- for (j=0;j<nAtoms;j++)
- if (!strcmp(atom[j]->name," CA ")) {
- k = 1;
- if (!atom[j]->altLoc[0]) {
- // take main conformation now as we do not know if
- // the specific one is in the file
- Calphas[nCalphas] = atom[j];
- k = 2;
- } else if (atom[j]->altLoc[0]==altLoc[0]) {
- // get specific conformation and quit
- Calphas[nCalphas] = atom[j];
- k = 2;
- break;
- }
- } else if (k)
- break;
- if (k==2) nCalphas++;
- }
-
- }
-
- }
-
- } else if (residue) { // check just this atom's residue
-
- Calphas = new PCAtom[1]; // can't be more than 1 C-alpha!
-
- nAtoms = residue->nAtoms;
- atom = residue->atom;
-
- if ((!altLoc[0]) || (altLoc[0]==' ')) { // main conformation
-
- for (j=0;j<nAtoms;j++)
- if (!strcmp(atom[j]->name," CA ")) {
- Calphas[nCalphas++] = atom[j];
- break;
- }
-
- } else { // specific conformation
-
- k = 0;
- for (j=0;j<nAtoms;j++)
- if (!strcmp(atom[j]->name," CA ")) {
- k = 1;
- if (!atom[j]->altLoc[0]) {
- Calphas[nCalphas] = atom[j];
- k = 2;
- } else if (atom[j]->altLoc[0]==altLoc[0]) {
- Calphas[nCalphas] = atom[j];
- k = 2;
- break;
- }
- } else if (k)
- break;
- if (k==2) nCalphas++;
-
- }
-
- }
-
- if (Calphas && (!nCalphas)) {
- delete[] Calphas;
- Calphas = NULL;
- }
-
-}
-
-Boolean CAtom::isMetal() {
- return ::isMetal ( element );
-}
-
-Boolean CAtom::isSolvent() {
- if (residue) return residue->isSolvent();
- return False;
-}
-
-Boolean CAtom::isInSelection ( int selHnd ) {
-PCMMDBFile manager = (PCMMDBFile)GetCoordHierarchy();
-PCMask Mask;
- if (manager) {
- Mask = manager->GetSelMask ( selHnd );
- if (Mask) return CheckMask ( Mask );
- }
- return False;
-}
-
-Boolean CAtom::isNTerminus() {
- if (residue) return residue->isNTerminus();
- return False;
-}
-
-Boolean CAtom::isCTerminus() {
- if (residue) return residue->isCTerminus();
- return False;
-}
-
-void CAtom::CalcAtomStatistics ( RSAtomStat AS ) {
-// AS must be initialized. The function only accumulates
-// the statistics.
-
- if (!Ter) {
-
- AS.nAtoms++;
-
- if (AS.WhatIsSet & WhatIsSet & ASET_Coordinates) {
- GetStat ( x,AS.xmin,AS.xmax,AS.xm,AS.xm2 );
- GetStat ( y,AS.ymin,AS.ymax,AS.ym,AS.ym2 );
- GetStat ( z,AS.zmin,AS.zmax,AS.zm,AS.zm2 );
- } else
- AS.WhatIsSet &= ~ASET_Coordinates;
-
- if (AS.WhatIsSet & WhatIsSet & ASET_Occupancy)
- GetStat(occupancy,AS.occ_min,AS.occ_max,AS.occ_m,AS.occ_m2);
- else AS.WhatIsSet &= ~ASET_Occupancy;
-
- if (AS.WhatIsSet & WhatIsSet & ASET_tempFactor)
- GetStat ( tempFactor,AS.tFmin,AS.tFmax,AS.tFm,AS.tFm2 );
- else AS.WhatIsSet &= ~ASET_tempFactor;
-
- if (AS.WhatIsSet & WhatIsSet & ASET_Anis_tFac) {
- GetStat ( u11,AS.u11_min,AS.u11_max,AS.u11_m,AS.u11_m2 );
- GetStat ( u22,AS.u22_min,AS.u22_max,AS.u22_m,AS.u22_m2 );
- GetStat ( u33,AS.u33_min,AS.u33_max,AS.u33_m,AS.u33_m2 );
- GetStat ( u12,AS.u12_min,AS.u12_max,AS.u12_m,AS.u12_m2 );
- GetStat ( u13,AS.u13_min,AS.u13_max,AS.u13_m,AS.u13_m2 );
- GetStat ( u23,AS.u23_min,AS.u23_max,AS.u23_m,AS.u23_m2 );
- } else
- AS.WhatIsSet &= ~ASET_Anis_tFac;
-
- }
-
-}
-
-
-realtype CAtom::GetDist2 ( PCAtom a ) {
-realtype dx,dy,dz;
- dx = a->x - x;
- dy = a->y - y;
- dz = a->z - z;
- return dx*dx + dy*dy + dz*dz;
-}
-
-realtype CAtom::GetDist2 ( PCAtom a, mat44 & tm ) {
-realtype dx,dy,dz;
- dx = tm[0][0]*a->x + tm[0][1]*a->y + tm[0][2]*a->z + tm[0][3] - x;
- dy = tm[1][0]*a->x + tm[1][1]*a->y + tm[1][2]*a->z + tm[1][3] - y;
- dz = tm[2][0]*a->x + tm[2][1]*a->y + tm[2][2]*a->z + tm[2][3] - z;
- return dx*dx + dy*dy + dz*dz;
-}
-
-realtype CAtom::GetDist2 ( PCAtom a, mat33 & r, vect3 & t ) {
-realtype dx,dy,dz;
- dx = r[0][0]*a->x + r[0][1]*a->y + r[0][2]*a->z + t[0] - x;
- dy = r[1][0]*a->x + r[1][1]*a->y + r[1][2]*a->z + t[1] - y;
- dz = r[2][0]*a->x + r[2][1]*a->y + r[2][2]*a->z + t[2] - z;
- return dx*dx + dy*dy + dz*dz;
-}
-
-realtype CAtom::GetDist2 ( realtype ax, realtype ay, realtype az ) {
-realtype dx,dy,dz;
- dx = ax - x;
- dy = ay - y;
- dz = az - z;
- return dx*dx + dy*dy + dz*dz;
-}
-
-realtype CAtom::GetCosine ( PCAtom a1, PCAtom a2 ) {
-// Calculates cosing of angle a1-this-a2, i.e. that between
-// bond [a1,this] and [this,a2].
-realtype dx1,dy1,dz1, dx2,dy2,dz2,r;
-
- dx1 = a1->x - x;
- dy1 = a1->y - y;
- dz1 = a1->z - z;
- r = dx1*dx1 + dy1*dy1 + dz1*dz1;
-
- dx2 = a2->x - x;
- dy2 = a2->y - y;
- dz2 = a2->z - z;
- r *= dx2*dx2 + dy2*dy2 + dz2*dz2;
-
- if (r>0.0) return (dx1*dx2 + dy1*dy2 + dz1*dz2)/sqrt(r);
- else return 0.0;
-
-}
-
-
-void CAtom::MakeTer() {
- WhatIsSet |= ASET_Coordinates;
- Het = False;
- Ter = True;
-}
-
-
-void CAtom::SetAtomName ( const AtomName atomName ) {
- strcpy ( name,atomName );
-}
-
-
-void CAtom::SetElementName ( const Element elName ) {
- strcpy ( element,elName );
- if (!element[0]) strcpy ( element," " );
- else if ((!element[1]) || (element[1]==' ')) {
- element[2] = char(0);
- element[1] = element[0];
- element[0] = ' ';
- }
-}
-
-void CAtom::SetCharge ( cpstr chrg ) {
-pstr p;
- charge = strtod ( chrg,&p );
- if (p!=chrg) {
- WhatIsSet |= ASET_Charge;
- if ((charge>0.0) && (*p=='-'))
- charge = -charge;
- }
-}
-
-void CAtom::SetCharge ( realtype chrg ) {
- if (chrg<MaxReal) {
- charge = chrg;
- WhatIsSet |= ASET_Charge;
- }
-}
-
-void CAtom::SetAtomIndex ( int ix ) {
-// don't use in your applications!
- index = ix;
-}
-
-pstr CAtom::GetAtomID ( pstr AtomID ) {
-char S[50];
- AtomID[0] = char(0);
- if (residue) {
- if (residue->chain) {
- if (residue->chain->model)
- sprintf (AtomID,"/%i/",residue->chain->model->GetSerNum());
- else strcpy ( AtomID,"/-/" );
- strcat ( AtomID,residue->chain->chainID );
- } else
- strcpy ( AtomID,"/-/-" );
- ParamStr ( AtomID,pstr("/"),residue->seqNum );
- if (residue->name[0]) {
- strcat ( AtomID,"(" );
- strcat ( AtomID,residue->name );
- strcat ( AtomID,")" );
- }
- if (residue->insCode[0]) {
- strcat ( AtomID,"." );
- strcat ( AtomID,residue->insCode );
- }
- strcat ( AtomID,"/" );
- } else
- strcpy ( AtomID,"/-/-/-/" );
- strcpy_css ( S,name );
- if (!S[0]) strcpy ( S,"-" );
- strcat ( AtomID,S );
- strcpy_css ( S,element );
- if (S[0]) {
- strcat ( AtomID,"[" );
- strcat ( AtomID,S );
- strcat ( AtomID,"]" );
- }
- if (altLoc[0]) {
- strcat ( AtomID,":" );
- strcat ( AtomID,altLoc );
- }
- return AtomID;
-}
-
-pstr CAtom::GetAtomIDfmt ( pstr AtomID ) {
-int n;
-char S[50];
- AtomID[0] = char(0);
- if (residue) {
- if (residue->chain) {
- if (residue->chain->model) {
- n = residue->chain->model->GetNumberOfModels();
- if (n<10) strcpy ( S,"/%1i/" );
- else if (n<100) strcpy ( S,"/%2i/" );
- else if (n<1000) strcpy ( S,"/%3i/" );
- else strcpy ( S,"/%i/" );
- sprintf ( AtomID,S,residue->chain->model->GetSerNum() );
- } else
- strcpy ( AtomID,"/-/" );
- strcat ( AtomID,residue->chain->chainID );
- } else
- strcpy ( AtomID,"/-/-" );
- if ((-999<=residue->seqNum) && (residue->seqNum<=9999))
- sprintf ( S,"/%4i",residue->seqNum );
- else sprintf ( S,"/%i" ,residue->seqNum );
- strcat ( AtomID,S );
- sprintf ( S,"(%3s).%1s/",residue->name,residue->insCode );
- strcat ( AtomID,S );
- } else
- strcpy ( AtomID,"/-/-/----(---).-/" );
- sprintf ( S,"%4s[%2s]:%1s",name,element,altLoc );
- strcat ( AtomID,S );
- return AtomID;
-}
-
-
-
-int CAtom::ConvertPDBHETATM ( int ix, cpstr S ) {
-// Gets data from the PDB ASCII HETATM record.
-// This function DOES NOT check the "HETATM" keyword and
-// does not decode the chain and residue parameters! These
-// must be treated by the calling process, see
-// Chain::ConvertPDBASCII().
-int RC;
- RC = ConvertPDBATOM ( ix,S );
- Het = True;
- return RC;
-}
-
-void CAtom::GetData ( cpstr S ) {
-pstr p;
-
- if (((S[6]>='0') && (S[6]<='9')) || (S[6]==' ')) {
- // Here we forgive cards with unreadable serial numbers
- // as we always have index (ix) for the card. For the sake
- // of strict PDB syntax we would have to return
- // Error_UnrecognizedInteger here.
- if (!(GetInteger(serNum,&(S[6]),5))) serNum = -1;
- } else
- hy36decode ( 5,&(S[6]),5,&serNum );
-
-// if (!(GetInteger(serNum,&(S[6]),5))) serNum = index;
-
- altLoc[0] = S[16];
- if (altLoc[0]==' ') altLoc[0] = char(0);
- else altLoc[1] = char(0);
- GetString ( name ,&(S[12]),4 );
- strcpy_ncss ( segID ,&(S[72]),4 );
- GetString ( element,&(S[76]),2 );
- charge = strtod ( &(S[78]),&p );
- if ((charge!=0.0) && (p!=&(S[78]))) {
- WhatIsSet |= ASET_Charge;
- if ((charge>0.0) && (*p=='-'))
- charge = -charge;
- }
-
- RestoreElementName();
- strcpy ( label_atom_id,name );
-
-}
-
-int CAtom::CheckData ( cpstr S ) {
-int sN;
-AltLoc aloc;
-SegID sID;
-Element elmnt;
-pstr p;
-realtype achrg;
-
- aloc[0] = S[16];
- if (aloc[0]==' ') aloc[0] = char(0);
- else aloc[1] = char(0);
-
- strcpy_ncss ( sID ,&(S[72]),4 );
- GetString ( elmnt,&(S[76]),2 );
-
- if (ignoreCharge)
- achrg = charge;
- else {
- achrg = strtod ( &(S[78]),&p );
- if ((achrg!=0.0) && (p!=&(S[78]))) {
- if ((achrg>0.0) && (*p=='-'))
- achrg = -achrg;
- }
- }
-
-// if (!(GetInteger(sN,&(S[6]),5)))
-// sN = index;
-
- if (hy36decode(5,&(S[6]),5,&sN))
- sN = index;
-
- if (ignoreSegID) {
- if (segID[0]) strcpy ( sID,segID );
- else strcpy ( segID,sID );
- }
-
- if (ignoreElement) {
- if (element[0]) strcpy ( elmnt,element );
- else strcpy ( element,elmnt );
- }
-
- if (ignoreUnmatch) return 0;
-
- // Here we forgive cards with unreadable serial numbers
- // as we always have index (ix) for the card. For the sake
- // of strict PDB syntax we would have to return
- // Error_UnrecognizedInteger .
- if ((sN!=serNum) ||
- (strcmp (altLoc ,aloc )) ||
- (strncmp(name ,&(S[12]),4)) ||
- (strcmp (segID ,sID )) ||
- (strcmp (element,elmnt )) ||
- (charge!=achrg)) {
- /*
-char name1[100];
-strncpy ( name1,&(S[12]),4 ); name1[4] = char(0);
- printf ( "\n serNum %5i %5i\n"
- " residue '%s' '%s'\n"
- " altLoc '%s' '%s'\n"
- " name '%s' '%s'\n"
- " segId '%s' '%s'\n"
- " element '%s' '%s'\n"
- " charge '%s' '%s'\n",
- sN,serNum, res->name,residue->name,
- altLoc ,aloc, name,name1,
- segID ,sID,
- element,elmnt,
- charge ,achrg );
- if (res!=residue) printf (" it's a residue\n" );
- */
- return Error_ATOM_Unmatch;
- }
-
- return 0;
-
-}
-
-
-int CAtom::GetCIF ( int ix, PCMMCIFLoop Loop,
- PCMMCIFLoop LoopAnis ) {
-char PDBGroup[30];
-int k;
-int RC;
-
- index = ix;
-
- if (WhatIsSet & ASET_Coordinates)
- return Error_ATOM_AlreadySet;
-
-/*
-
-loop_
-*0 _atom_site.group_PDB
-*1 _atom_site.id
-*2 _atom_site.type_symbol <- chem elem
--3 _atom_site.label_atom_id <- atom name
-*4 _atom_site.label_alt_id <- alt code
-=5 _atom_site.label_comp_id <- res name ???
-=6 _atom_site.label_asym_id <- chain id ???
-=7 _atom_site.label_entity_id < ???
-=8 _atom_site.label_seq_id <- poly seq id
-+9 _atom_site.pdbx_PDB_ins_code <- ins code
--10 _atom_site.segment_id <- segment id
-*11 _atom_site.Cartn_x
-*12 _atom_site.Cartn_y
-*13 _atom_site.Cartn_z
-*14 _atom_site.occupancy
-*15 _atom_site.B_iso_or_equiv
-*16 _atom_site.Cartn_x_esd
-*17 _atom_site.Cartn_y_esd
-*18 _atom_site.Cartn_z_esd
-*19 _atom_site.occupancy_esd
-*20 _atom_site.B_iso_or_equiv_esd
-*21 _atom_site.pdbx_formal_charge
-+22 _atom_site.auth_seq_id <- seq id we want
-+23 _atom_site.auth_comp_id <- res name we want
-+24 _atom_site.auth_asym_id <- ch id we want ?
-*25 _atom_site.auth_atom_id <- atom name we want ?
-+26 _atom_site.pdbx_PDB_model_num <- model no
-
-'+' read in CMMDBFile::CheckAtomPlace()
-'=' new in residue, read in CMMDBFile::CheckAtomPlace()
-'-' new in atom
-
-*/
-
-
- // (0)
- k = ix-1;
- CIFGetString ( PDBGroup,Loop,CIFTAG_GROUP_PDB,k,
- sizeof(PDBGroup),pstr("") );
-
- Ter = !strcmp(PDBGroup,pstr("TER") );
- Het = !strcmp(PDBGroup,pstr("HETATM"));
-
- // (1)
- RC = CIFGetInteger1 ( serNum,Loop,CIFTAG_ID,k );
- if (RC) {
- if (Ter) serNum = -1;
- else if (RC==Error_NoData) serNum = index;
- else
- return RC;
- }
-
- if (Ter) {
- Loop->DeleteRow ( k );
- WhatIsSet |= ASET_Coordinates;
- return 0;
- }
-
- // (25)
- CIFGetString ( name,Loop,CIFTAG_AUTH_ATOM_ID,k,
- sizeof(name) ,pstr("") );
- // (3)
- CIFGetString ( label_atom_id,Loop,CIFTAG_LABEL_ATOM_ID,k,
- sizeof(label_atom_id),pstr("") );
- // (4)
- CIFGetString ( altLoc,Loop,CIFTAG_LABEL_ALT_ID ,k,
- sizeof(altLoc),pstr("") );
-
- // (11,12,13)
- RC = CIFGetReal1 ( x,Loop,CIFTAG_CARTN_X,k );
- if (!RC) RC = CIFGetReal1 ( y,Loop,CIFTAG_CARTN_Y,k );
- if (!RC) RC = CIFGetReal1 ( z,Loop,CIFTAG_CARTN_Z,k );
- if (RC) return Error_ATOM_Unrecognized;
- WhatIsSet |= ASET_Coordinates;
-
- // (14)
- if (!CIFGetReal1(occupancy,Loop,CIFTAG_OCCUPANCY,k))
- WhatIsSet |= ASET_Occupancy;
- // (15)
- if (!CIFGetReal1(tempFactor,Loop,CIFTAG_B_ISO_OR_EQUIV,k))
- WhatIsSet |= ASET_tempFactor;
-
- // (10)
- CIFGetString ( segID,Loop,CIFTAG_SEGMENT_ID,k,
- sizeof(segID) ,pstr("") );
- // (21)
- if (!CIFGetReal1(charge,Loop,CIFTAG_PDBX_FORMAL_CHARGE,k))
- WhatIsSet |= ASET_Charge;
- // (2)
- RC = CIFGetString ( element,Loop,CIFTAG_TYPE_SYMBOL,k,
- sizeof(element),pstr(" ") );
- if (RC)
- CIFGetString ( element,Loop,CIFTAG_ATOM_TYPE_SYMBOL,k,
- sizeof(element),pstr(" ") );
-
- RestoreElementName();
- MakePDBAtomName ();
-// printf ( " '%s' '%s'\n",name,element );
-
- // (16,17,18)
- RC = CIFGetReal1 ( sigX,Loop,CIFTAG_CARTN_X_ESD,k );
- if (!RC) RC = CIFGetReal1 ( sigY,Loop,CIFTAG_CARTN_Y_ESD,k );
- if (!RC) RC = CIFGetReal1 ( sigZ,Loop,CIFTAG_CARTN_Z_ESD,k );
- if (RC==Error_UnrecognizedReal)
- return RC;
- if (!RC) WhatIsSet |= ASET_CoordSigma;
-
- // (19)
- if (!CIFGetReal1(sigOcc,Loop,CIFTAG_OCCUPANCY_ESD,k))
- WhatIsSet |= ASET_OccSigma;
- // (20)
- if (!CIFGetReal1(sigTemp,Loop,CIFTAG_B_ISO_OR_EQUIV_ESD,k))
- WhatIsSet |= ASET_tFacSigma;
-
- Loop->DeleteRow ( k );
-
- if (LoopAnis) {
-
- RC = CIFGetReal1 ( u11,LoopAnis,CIFTAG_U11,k );
- if (!RC) RC = CIFGetReal1 ( u22,LoopAnis,CIFTAG_U22,k );
- if (!RC) RC = CIFGetReal1 ( u33,LoopAnis,CIFTAG_U33,k );
- if (!RC) RC = CIFGetReal1 ( u13,LoopAnis,CIFTAG_U13,k );
- if (!RC) RC = CIFGetReal1 ( u12,LoopAnis,CIFTAG_U12,k );
- if (!RC) RC = CIFGetReal1 ( u23,LoopAnis,CIFTAG_U23,k );
- if (RC==Error_UnrecognizedReal)
- return RC;
- if (!RC) WhatIsSet |= ASET_Anis_tFac;
-
- RC = CIFGetReal1 ( su11,LoopAnis,CIFTAG_U11_ESD,k );
- if (!RC) RC = CIFGetReal1 ( su22,LoopAnis,CIFTAG_U22_ESD,k );
- if (!RC) RC = CIFGetReal1 ( su33,LoopAnis,CIFTAG_U33_ESD,k );
- if (!RC) RC = CIFGetReal1 ( su13,LoopAnis,CIFTAG_U13_ESD,k );
- if (!RC) RC = CIFGetReal1 ( su12,LoopAnis,CIFTAG_U12_ESD,k );
- if (!RC) RC = CIFGetReal1 ( su23,LoopAnis,CIFTAG_U23_ESD,k );
- if (RC==Error_UnrecognizedReal)
- return RC;
- if (!RC) WhatIsSet |= ASET_Anis_tFSigma;
-
- LoopAnis->DeleteRow ( k );
-
- }
-
- return 0;
-
-}
-
-Boolean CAtom::RestoreElementName() {
-// This function works only if element name is not given.
- if (Ter) {
- name[0] = char(0);
- element[0] = char(0);
- return False;
- }
- if ((!element[0]) ||
- ((element[0]==' ') && ((!element[1]) || (element[1]==' ')))) {
- if ((name[0]>='A') && (name[0]<='Z')) {
- element[0] = name[0];
- element[1] = name[1];
- } else {
- element[0] = ' ';
- element[1] = name[1];
- }
- element[2] = char(0);
- return False;
- } else if (!element[1]) {
- // not aligned element name, possibly coming from mmCIF
- element[1] = element[0];
- element[0] = ' ';
- element[2] = char(0);
- return False;
- }
- return True;
-}
-
-Boolean CAtom::MakePDBAtomName() {
-int i,k;
- if (Ter) {
- name[0] = char(0);
- element[0] = char(0);
- return False;
- }
- UpperCase ( name );
- UpperCase ( element );
- if ((element[0]==' ') && (element[1]==' ')) {
- // element name not given, make one from the atom name
- if ((name[0]>='A') && (name[0]<='Z')) {
- if (!name[1]) {
- name[4] = char(0);
- name[3] = ' ';
- name[2] = ' ';
- name[1] = name[0];
- name[0] = ' ';
- }
- /* the commented part looks like a wrong inheritance
- from FORTRAN RWBrook. Commented on 04.03.2004,
- to be removed.
- else if ((name[0]=='C') && (name[1]=='A')) {
- name[4] = char(0);
- name[3] = name[2];
- name[2] = name[1];
- name[1] = name[0];
- name[0] = ' ';
- }
- */
- element[0] = name[0];
- element[1] = name[1];
- } else {
- element[0] = ' ';
- element[1] = name[1];
- }
- element[2] = char(0);
- return False;
- } else if ((name[0]>='A') && (name[0]<='Z')) {
- if (!element[1]) {
- element[2] = char(0);
- element[1] = element[0];
- element[0] = ' ';
- k = strlen(name);
- if (k<4) {
- for (i=3;i>0;i--)
- name[i] = name[i-1];
- name[0] = ' ';
- k++;
- while (k<4)
- name[k++] = ' ';
- name[k] = char(0);
- }
- } else if ((element[0]==' ') && (element[1]!=name[1])) {
- for (i=3;i>0;i--)
- name[i] = name[i-1];
- name[0] = ' ';
- k = strlen(name);
- while (k<4)
- name[k++] = ' ';
- name[k] = char(0);
- } else {
- k = strlen(name);
- while (k<4)
- name[k++] = ' ';
- name[k] = char(0);
- }
- }
- return True;
-}
-
-void CAtom::SetCoordinates ( realtype xx, realtype yy, realtype zz,
- realtype occ, realtype tFac ) {
- x = xx;
- y = yy;
- z = zz;
- occupancy = occ;
- tempFactor = tFac;
- WhatIsSet |= ASET_Coordinates | ASET_Occupancy | ASET_tempFactor;
-}
-
-void CAtom::Transform ( mat33 & tm, vect3 & v ) {
-realtype x1,y1,z1;
- x1 = tm[0][0]*x + tm[0][1]*y + tm[0][2]*z + v[0];
- y1 = tm[1][0]*x + tm[1][1]*y + tm[1][2]*z + v[1];
- z1 = tm[2][0]*x + tm[2][1]*y + tm[2][2]*z + v[2];
- x = x1;
- y = y1;
- z = z1;
-}
-
-void CAtom::Transform ( mat44 & tm ) {
-realtype x1,y1,z1;
- x1 = tm[0][0]*x + tm[0][1]*y + tm[0][2]*z + tm[0][3];
- y1 = tm[1][0]*x + tm[1][1]*y + tm[1][2]*z + tm[1][3];
- z1 = tm[2][0]*x + tm[2][1]*y + tm[2][2]*z + tm[2][3];
- x = x1;
- y = y1;
- z = z1;
-}
-
-void CAtom::TransformCopy ( mat44 & tm,
- realtype & xx,
- realtype & yy,
- realtype & zz ) {
- xx = tm[0][0]*x + tm[0][1]*y + tm[0][2]*z + tm[0][3];
- yy = tm[1][0]*x + tm[1][1]*y + tm[1][2]*z + tm[1][3];
- zz = tm[2][0]*x + tm[2][1]*y + tm[2][2]*z + tm[2][3];
-}
-
-void CAtom::TransformSet ( mat44 & tm,
- realtype xx,
- realtype yy,
- realtype zz ) {
- x = tm[0][0]*xx + tm[0][1]*yy + tm[0][2]*zz + tm[0][3];
- y = tm[1][0]*xx + tm[1][1]*yy + tm[1][2]*zz + tm[1][3];
- z = tm[2][0]*xx + tm[2][1]*yy + tm[2][2]*zz + tm[2][3];
-}
-
-
-// ------- user-defined data handlers
-
-int CAtom::PutUDData ( int UDDhandle, int iudd ) {
- if (UDDhandle & UDRF_ATOM)
- return CUDData::putUDData ( UDDhandle,iudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CAtom::PutUDData ( int UDDhandle, realtype rudd ) {
- if (UDDhandle & UDRF_ATOM)
- return CUDData::putUDData ( UDDhandle,rudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CAtom::PutUDData ( int UDDhandle, cpstr sudd ) {
- if (UDDhandle & UDRF_ATOM)
- return CUDData::putUDData ( UDDhandle,sudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CAtom::GetUDData ( int UDDhandle, int & iudd ) {
- if (UDDhandle & UDRF_ATOM)
- return CUDData::getUDData ( UDDhandle,iudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CAtom::GetUDData ( int UDDhandle, realtype & rudd ) {
- if (UDDhandle & UDRF_ATOM)
- return CUDData::getUDData ( UDDhandle,rudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CAtom::GetUDData ( int UDDhandle, pstr sudd, int maxLen ) {
- if (UDDhandle & UDRF_ATOM)
- return CUDData::getUDData ( UDDhandle,sudd,maxLen );
- else return UDDATA_WrongUDRType;
-}
-
-int CAtom::GetUDData ( int UDDhandle, pstr & sudd ) {
- if (UDDhandle & UDRF_ATOM)
- return CUDData::getUDData ( UDDhandle,sudd );
- else return UDDATA_WrongUDRType;
-}
-
-
-void CAtom::Copy ( PCAtom atom ) {
-// this does not make any references in residues and does
-// not change indices!! it does change serial numbers, though.
-
- serNum = atom->serNum;
- x = atom->x;
- y = atom->y;
- z = atom->z;
- occupancy = atom->occupancy;
- tempFactor = atom->tempFactor;
- sigX = atom->sigX;
- sigY = atom->sigY;
- sigZ = atom->sigZ;
- sigOcc = atom->sigOcc;
- sigTemp = atom->sigTemp;
- u11 = atom->u11;
- u22 = atom->u22;
- u33 = atom->u33;
- u12 = atom->u12;
- u13 = atom->u13;
- u23 = atom->u23;
- su11 = atom->su11;
- su22 = atom->su22;
- su33 = atom->su33;
- su12 = atom->su12;
- su13 = atom->su13;
- su23 = atom->su23;
- Het = atom->Het;
- Ter = atom->Ter;
- WhatIsSet = atom->WhatIsSet;
-
- strcpy ( name ,atom->name );
- strcpy ( label_atom_id,atom->label_atom_id );
- strcpy ( altLoc ,atom->altLoc );
- strcpy ( segID ,atom->segID );
- strcpy ( element ,atom->element );
- strcpy ( energyType ,atom->energyType );
- charge = atom->charge;
-
-}
-
-int CAtom::CheckID ( const AtomName aname, const Element elname,
- const AltLoc aloc ) {
-pstr p1,p2;
- if (aname) {
- if (aname[0]!='*') {
- p1 = name;
- while (*p1==' ') p1++;
- p2 = pstr(aname);
- while (*p2==' ') p2++;
- while ((*p2) && (*p1) && (*p1!=' ') && (*p2!=' ')) {
- if (*p1!=*p2) return 0;
- p1++;
- p2++;
- }
- if (*p1!=*p2) {
- if (((*p1) && (*p1!=' ')) ||
- ((*p2) && (*p2!=' '))) return 0;
- }
- }
- }
- if (elname) {
- if (elname[0]!='*') {
- p1 = element;
- while (*p1==' ') p1++;
- p2 = pstr(elname);
- while (*p2==' ') p2++;
- while ((*p2) && (*p1) && (*p1!=' ') && (*p2!=' ')) {
- if (*p1!=*p2) return 0;
- p1++;
- p2++;
- }
- if (*p1!=*p2) return 0;
- }
- }
- if (aloc) {
- if ((aloc[0]!='*') && (strcmp(aloc,altLoc))) return 0;
- }
- return 1;
-}
-
-int CAtom::CheckIDS ( cpstr ID ) {
-AtomName aname;
-Element elname;
-AltLoc aloc;
-pstr p;
- p = strrchr ( ID,'/' );
- if (p) p++;
- else p = pstr(ID);
- ParseAtomID ( p,aname,elname,aloc );
- return CheckID ( aname,elname,aloc );
-}
-
-void CAtom::SetShortBinary() {
- WhatIsSet |= ASET_ShortBinary;
-}
-
-void CAtom::write ( RCFile f ) {
-int i,k;
-byte Version=2;
-byte nb;
-
- f.WriteWord ( &WhatIsSet );
- if (WhatIsSet & ASET_ShortBinary) {
- if (Ter) WhatIsSet |= ASET_ShortTer;
- if (Het) WhatIsSet |= ASET_ShortHet;
- f.WriteInt ( &index );
- f.WriteTerLine ( name ,False );
- f.WriteTerLine ( altLoc ,False );
- f.WriteTerLine ( element,False );
- if (WhatIsSet & ASET_Coordinates) {
- f.WriteFloat ( &x );
- f.WriteFloat ( &y );
- f.WriteFloat ( &z );
- }
- return;
- }
-
- f.WriteByte ( &Version );
-
- CUDData::write ( f );
-
- f.WriteInt ( &serNum );
- f.WriteInt ( &index );
- f.WriteTerLine ( name ,False );
- f.WriteTerLine ( label_atom_id,False );
- f.WriteTerLine ( altLoc ,False );
- f.WriteTerLine ( segID ,False );
- f.WriteTerLine ( element ,False );
- f.WriteTerLine ( energyType ,False );
- f.WriteFloat ( &charge );
- f.WriteBool ( &Het );
- f.WriteBool ( &Ter );
-
- if (WhatIsSet & ASET_Coordinates) {
- f.WriteFloat ( &x );
- f.WriteFloat ( &y );
- f.WriteFloat ( &z );
- if (WhatIsSet & ASET_Occupancy)
- f.WriteFloat ( &occupancy );
- if (WhatIsSet & ASET_tempFactor)
- f.WriteFloat ( &tempFactor );
- }
-
- if (WhatIsSet & ASET_CoordSigma) {
- f.WriteFloat ( &sigX );
- f.WriteFloat ( &sigY );
- f.WriteFloat ( &sigZ );
- if ((WhatIsSet & ASET_Occupancy) &&
- (WhatIsSet & ASET_OccSigma))
- f.WriteFloat ( &sigOcc );
- if ((WhatIsSet & ASET_tempFactor) &&
- (WhatIsSet & ASET_tFacSigma))
- f.WriteFloat ( &sigTemp );
- }
-
- if (WhatIsSet & ASET_Anis_tFac) {
- f.WriteFloat ( &u11 );
- f.WriteFloat ( &u22 );
- f.WriteFloat ( &u33 );
- f.WriteFloat ( &u12 );
- f.WriteFloat ( &u13 );
- f.WriteFloat ( &u23 );
- if (WhatIsSet & ASET_Anis_tFSigma) {
- f.WriteFloat ( &su11 );
- f.WriteFloat ( &su22 );
- f.WriteFloat ( &su33 );
- f.WriteFloat ( &su12 );
- f.WriteFloat ( &su13 );
- f.WriteFloat ( &su23 );
- }
- }
-
- nb = byte(nBonds & 0x000000FF);
- f.WriteByte ( &nb );
- for (i=0;i<nb;i++)
- if (Bond[i].atom) {
- f.WriteInt ( &(Bond[i].atom->index) );
- f.WriteByte ( &(Bond[i].order) );
- } else {
- k = -1;
- f.WriteInt ( &k );
- }
-
-}
-
-void CAtom::read ( RCFile f ) {
-int i,k;
-byte nb,Version;
-
- FreeMemory();
-
- f.ReadWord ( &WhatIsSet );
- if (WhatIsSet & ASET_ShortBinary) {
- f.ReadInt ( &index );
- f.ReadTerLine ( name ,False );
- f.ReadTerLine ( altLoc ,False );
- f.ReadTerLine ( element,False );
- if (WhatIsSet & ASET_Coordinates) {
- f.ReadFloat ( &x );
- f.ReadFloat ( &y );
- f.ReadFloat ( &z );
- }
- serNum = index;
- Ter = WhatIsSet & ASET_ShortTer;
- Het = WhatIsSet & ASET_ShortHet;
- name [4] = char(0);
- altLoc [1] = char(0);
- element[2] = char(0);
- segID [0] = char(0);
- charge = 0.0;
- WhatIsSet &= ASET_All;
- return;
- }
-
- f.ReadByte ( &Version );
-
- CUDData::read ( f );
-
- f.ReadInt ( &serNum );
- f.ReadInt ( &index );
- f.ReadTerLine ( name ,False );
- if (Version>1)
- f.ReadTerLine ( label_atom_id,False );
- f.ReadTerLine ( altLoc ,False );
- f.ReadTerLine ( segID ,False );
- f.ReadTerLine ( element ,False );
- f.ReadTerLine ( energyType,False );
- f.ReadFloat ( &charge );
- f.ReadBool ( &Het );
- f.ReadBool ( &Ter );
-
- if (WhatIsSet & ASET_Coordinates) {
- f.ReadFloat ( &x );
- f.ReadFloat ( &y );
- f.ReadFloat ( &z );
- if (WhatIsSet & ASET_Occupancy) f.ReadFloat ( &occupancy );
- else occupancy = 0.0;
- if (WhatIsSet & ASET_tempFactor) f.ReadFloat ( &tempFactor );
- else tempFactor = 0.0;
- } else {
- x = 0.0;
- y = 0.0;
- z = 0.0;
- occupancy = 0.0;
- tempFactor = 0.0;
- }
-
- if (WhatIsSet & ASET_CoordSigma) {
- f.ReadFloat ( &sigX );
- f.ReadFloat ( &sigY );
- f.ReadFloat ( &sigZ );
- if ((WhatIsSet & ASET_Occupancy) &&
- (WhatIsSet & ASET_OccSigma))
- f.ReadFloat ( &sigOcc );
- else sigOcc = 0.0;
- if ((WhatIsSet & ASET_tempFactor) &&
- (WhatIsSet & ASET_tFacSigma))
- f.ReadFloat ( &sigTemp );
- else sigTemp = 0.0;
- } else {
- sigX = 0.0;
- sigY = 0.0;
- sigZ = 0.0;
- sigOcc = 0.0;
- sigTemp = 0.0;
- }
-
- if (WhatIsSet & ASET_Anis_tFac) {
- f.ReadFloat ( &u11 );
- f.ReadFloat ( &u22 );
- f.ReadFloat ( &u33 );
- f.ReadFloat ( &u12 );
- f.ReadFloat ( &u13 );
- f.ReadFloat ( &u23 );
- if (WhatIsSet & ASET_Anis_tFSigma) {
- f.ReadFloat ( &su11 );
- f.ReadFloat ( &su22 );
- f.ReadFloat ( &su33 );
- f.ReadFloat ( &su12 );
- f.ReadFloat ( &su13 );
- f.ReadFloat ( &su23 );
- } else {
- su11 = 0.0;
- su22 = 0.0;
- su33 = 0.0;
- su12 = 0.0;
- su13 = 0.0;
- su23 = 0.0;
- }
- } else {
- u11 = 0.0;
- u22 = 0.0;
- u33 = 0.0;
- u12 = 0.0;
- u13 = 0.0;
- u23 = 0.0;
- su11 = 0.0;
- su22 = 0.0;
- su33 = 0.0;
- su12 = 0.0;
- su13 = 0.0;
- su23 = 0.0;
- }
-
- f.ReadByte ( &nb );
- if (nb>0) {
- Bond = new SAtomBond[nb];
- for (i=0;i<nb;i++) {
- f.ReadInt ( &k );
- if (k>0) f.ReadByte ( &(Bond[i].order) );
- else Bond[i].order = 0;
- // we place *index* of bonded atom temporary on the place
- // of its pointer, and the pointer will be calculated
- // after CResidue::read calls _setBonds(..).
- memcpy ( &(Bond[i].atom),&k,4 );
- }
- }
- nBonds = nb;
- nBonds = nBonds | (nBonds << 8);
-
-}
-
-void CAtom::_setBonds ( PPCAtom A ) {
-int i,k,nb;
- nb = nBonds & 0x000000FF;
- for (i=0;i<nb;i++) {
- memcpy ( &k,&(Bond[i].atom),4 );
- if (k>0) Bond[i].atom = A[k];
- else Bond[i].atom = NULL;
- }
-}
-
-
-MakeFactoryFunctions(CAtom)
-
-
-
-// =========================== CResidue ===========================
-
-
-void SAtomStat::Init() {
-
- nAtoms = 0;
-
- xmin = MaxReal; xmax = MinReal; xm = 0.0; xm2 = 0.0;
- ymin = MaxReal; ymax = MinReal; ym = 0.0; ym2 = 0.0;
- zmin = MaxReal; zmax = MinReal; zm = 0.0; zm2 = 0.0;
-
- occ_min = MaxReal; occ_max = MinReal; occ_m = 0.0; occ_m2 = 0.0;
- tFmin = MaxReal; tFmax = MinReal; tFm = 0.0; tFm2 = 0.0;
-
- u11_min = MaxReal; u11_max = MinReal; u11_m = 0.0; u11_m2 = 0.0;
- u22_min = MaxReal; u22_max = MinReal; u22_m = 0.0; u22_m2 = 0.0;
- u33_min = MaxReal; u33_max = MinReal; u33_m = 0.0; u33_m2 = 0.0;
- u12_min = MaxReal; u12_max = MinReal; u12_m = 0.0; u12_m2 = 0.0;
- u13_min = MaxReal; u13_max = MinReal; u13_m = 0.0; u13_m2 = 0.0;
- u23_min = MaxReal; u23_max = MinReal; u23_m = 0.0; u23_m2 = 0.0;
-
- WhatIsSet = ASET_All;
-
- finished = False;
-
-}
-
-void SAtomStat::Finish() {
-realtype v;
-
- if (!finished) {
-
- finished = True;
-
- if (nAtoms>0) {
-
- v = nAtoms;
-
- xm /= v; xm2 /= v;
- ym /= v; ym2 /= v;
- zm /= v; zm2 /= v;
-
- occ_m /= v; occ_m2 /= v;
- tFm /= v; tFm2 /= v;
-
- u11_m /= v; u11_m2 /= v;
- u22_m /= v; u22_m2 /= v;
- u33_m /= v; u33_m2 /= v;
- u12_m /= v; u12_m2 /= v;
- u13_m /= v; u13_m2 /= v;
- u23_m /= v; u23_m2 /= v;
- }
- }
-
-}
-
-realtype SAtomStat::GetMaxSize() {
-realtype r;
- r = RMax(xmax-xmin,ymax-ymin);
- r = RMax(r,zmax-zmin);
- return RMax(r,0.0);
-}
-
-
-// ----------------------------------------------------------------
-
-
-CResidue::CResidue() : CUDData() {
- InitResidue();
-}
-
-CResidue::CResidue ( PCChain Chain_Owner ) : CUDData() {
- InitResidue();
- if (Chain_Owner)
- Chain_Owner->AddResidue ( this );
-}
-
-CResidue::CResidue ( PCChain Chain_Owner,
- const ResName resName,
- int sqNum,
- const InsCode ins ) : CUDData() {
- InitResidue();
- seqNum = sqNum;
- strcpy_css ( name,pstr(resName) );
- strcpy_css ( insCode,pstr(ins) );
- if (Chain_Owner)
- Chain_Owner->AddResidue ( this );
-}
-
-CResidue::CResidue ( RPCStream Object ) : CUDData(Object) {
- InitResidue();
-}
-
-CResidue::~CResidue() {
- FreeMemory();
- if (chain) chain->_ExcludeResidue ( name,seqNum,insCode );
-}
-
-
-void CResidue::InitResidue() {
- strcpy ( name ,"---" ); // residue name
- strcpy ( label_comp_id,"---" ); // assigned residue name
- label_asym_id[0] = char(0); // assigned chain Id
- seqNum = -MaxInt; // residue sequence number
- label_seq_id = -MaxInt; // assigned residue sequence number
- label_entity_id = 1; // assigned entity id
- strcpy ( insCode,"" ); // residue insertion code
- chain = NULL; // reference to chain
- index = -1; // undefined index in chain
- nAtoms = 0; // number of atoms in the residue
- AtmLen = 0; // length of atom array
- atom = NULL; // array of atoms
- Exclude = True;
- SSE = SSE_None;
-}
-
-void CResidue::SetChain ( PCChain Chain_Owner ) {
- chain = Chain_Owner;
-}
-
-
-int CResidue::GetResidueNo() {
- if (chain) return chain->GetResidueNo ( seqNum,insCode );
- else return -1;
-}
-
-void CResidue::SetChainID ( const ChainID chID ) {
- if (chain)
- chain->SetChainID ( chID );
-}
-
-
-int CResidue::GetCenter ( realtype & x, realtype & y,
- realtype & z ) {
-int i,k;
- x = 0.0;
- y = 0.0;
- z = 0.0;
- k = 0;
- for (i=0;i<nAtoms;i++)
- if (atom[i]) {
- if (!atom[i]->Ter) {
- x += atom[i]->x;
- y += atom[i]->y;
- z += atom[i]->z;
- k++;
- }
- }
- if (k>0) {
- x /= k;
- y /= k;
- z /= k;
- return 0;
- }
- return 1;
-}
-
-void * CResidue::GetCoordHierarchy() {
- if (chain) return chain->GetCoordHierarchy();
- return NULL;
-}
-
-void CResidue::GetAltLocations ( int & nAltLocs,
- PAltLoc & aLoc,
- rvector & occupancy,
- int & alflag ) {
-int i,j,k, nal,nal1;
-realtype occ1;
-Boolean B;
-PAltLoc aL;
-rvector occ;
-bvector alv;
-
- aLoc = NULL;
- occupancy = NULL;
- nAltLocs = 0;
- alflag = ALF_NoAltCodes;
-
- if (nAtoms>0) {
-
- // temporary array for altcodes
- aL = new AltLoc[nAtoms];
- // temporary array for occupancies
- GetVectorMemory ( occ,nAtoms,0 );
- // temporary array for checking altcodes
- GetVectorMemory ( alv,nAtoms,0 );
- for (i=0;i<nAtoms;i++)
- alv[i] = False;
-
- k = 0; // counts unique alternation codes
- nal = 0;
- for (i=0;i<nAtoms;i++)
- if (atom[i]) {
- if (!atom[i]->Ter) {
- // Find if the alternation code of ith atom is
- // a new one.
- B = False;
- for (j=0;(j<k) && (!B);j++)
- B = !strcmp(atom[i]->altLoc,aL[j]);
- if (!B) {
- // that's a new altcode, get its occupancy
- if (atom[i]->WhatIsSet & ASET_Occupancy)
- occ[k] = atom[i]->occupancy;
- else occ[k] = -1.0;
- // store new altcode in temporary array
- strcpy ( aL[k],atom[i]->altLoc );
- // check consistency of the altcode data if:
- // a) the data was not found wrong so far
- // b) this atom name has not been checked before
- // c) altcode is not the "empty"-altcode
- if ((!(alflag & ALF_Mess)) && (!alv[i]) &&
- (atom[i]->altLoc[0])) {
- B = False; // will be set True if "empty"-altcode
- // is found for current atom name
- nal1 = 0; // counts the number of different altcodes
- // for current atom name
- occ1 = 0.0; // will count the sum of occupancies for
- // current atom name
- for (j=0;j<nAtoms;j++)
- if (atom[j]) {
- if ((!atom[j]->Ter) &&
- (!strcmp(atom[j]->name,atom[i]->name))) {
- if (atom[j]->WhatIsSet & ASET_Occupancy)
- occ1 += atom[j]->occupancy;
- if (!atom[j]->altLoc[0]) B = True;
- alv[j] = True; // mark it as "checked"
- nal1++;
- }
- }
- if (!(alflag & (ALF_EmptyAltLoc | ALF_NoEmptyAltLoc))) {
- if (B) alflag |= ALF_EmptyAltLoc;
- else alflag |= ALF_NoEmptyAltLoc;
- } else if (((alflag & ALF_EmptyAltLoc) && (!B)) ||
- ((alflag & ALF_NoEmptyAltLoc) && (B)))
- alflag |= ALF_Mess;
- if ((occ[k]>=0) && (fabs(1.0-occ1)>0.01))
- alflag |= ALF_Occupancy;
- if (nal==0) // first time just remember the number
- nal = nal1; // of different altcodes
- else if (nal!=nal1) // check if number of different altcodes
- alflag |= ALF_Mess; // is not the same through the residue
- }
- k++;
- }
- }
- }
- if (k>0) {
- aLoc = new AltLoc[k];
- GetVectorMemory ( occupancy,k,0 );
- for (i=0;i<k;i++) {
- strcpy ( aLoc[i],aL[i] );
- occupancy[i] = occ[i];
- }
- nAltLocs = k;
- }
-
- delete[] aL;
- FreeVectorMemory ( occ,0 );
- FreeVectorMemory ( alv,0 );
-
- }
-
-}
-
-int CResidue::GetNofAltLocations() {
-int i,j,k;
-Boolean B;
- k = 0;
- for (i=0;i<nAtoms;i++)
- if (atom[i]) {
- if (!atom[i]->Ter) {
- B = False;
- for (j=0;(j<i) && (!B);j++)
- if (atom[j]) {
- if (!atom[j]->Ter)
- B = !strcmp(atom[i]->altLoc,atom[j]->altLoc);
- }
- if (!B) k++;
- }
- }
- return k;
-}
-
-void CResidue::SetResID ( const ResName resName, int sqNum,
- const InsCode ins ) {
- strcpy_css ( name,pstr(resName) );
- seqNum = sqNum;
- strcpy_css ( insCode,pstr(ins) );
- strcpy (label_comp_id,name );
-}
-
-void CResidue::FreeMemory() {
-// NOTE: individual atoms are disposed here as well!
- DeleteAllAtoms();
- if (atom) delete[] atom;
- atom = NULL;
- nAtoms = 0;
- AtmLen = 0;
-}
-
-void CResidue::ExpandAtomArray ( int nAdd ) {
-int i;
-PPCAtom atom1;
- AtmLen += abs(nAdd);
- atom1 = new PCAtom[AtmLen];
- for (i=0;i<nAtoms;i++)
- atom1[i] = atom[i];
- for (i=nAtoms;i<AtmLen;i++)
- atom1[i] = NULL;
- if (atom) delete[] atom;
- atom = atom1;
-}
-
-int CResidue::_AddAtom ( PCAtom atm ) {
-// Adds atom to the residue
-int i;
- for (i=0;i<nAtoms;i++)
- if (atom[i]==atm) return -i; // this atom is already there
- if (nAtoms>=AtmLen)
- ExpandAtomArray ( nAtoms+10-AtmLen );
- atom[nAtoms] = atm;
- atom[nAtoms]->residue = this;
- nAtoms++;
- return 0;
-}
-
-int CResidue::AddAtom ( PCAtom atm ) {
-// AddAtom(..) adds atom to the residue. If residue is associated
-// with a coordinate hierarchy, and atom 'atm' is not, the latter
-// is checked in automatically. If atom 'atm' belongs to any
-// coordinate hierarchy (even though that of the residue), it is
-// *copied* rather than simply taken over, and is checked in.
-// If residue is not associated with a coordinate hierarchy, all
-// added atoms will be checked in automatically once the residue
-// is checked in.
-PCMMDBFile manager;
-PCResidue res;
-int i;
-
- for (i=0;i<nAtoms;i++)
- if (atom[i]==atm) return -i; // this atom is already there
-
- if (nAtoms>=AtmLen)
- ExpandAtomArray ( nAtoms+10-AtmLen );
-
- if (atm->GetCoordHierarchy()) {
- atom[nAtoms] = newCAtom();
- atom[nAtoms]->Copy ( atm );
- } else {
- res = atm->GetResidue();
- if (res)
- for (i=0;i<res->nAtoms;i++)
- if (res->atom[i]==atm) {
- res->atom[i] = NULL;
- break;
- }
- atom[nAtoms] = atm;
- }
-
- atom[nAtoms]->residue = this;
- manager = PCMMDBFile(GetCoordHierarchy());
- if (manager)
- manager->CheckInAtom ( 0,atom[nAtoms] );
-
- nAtoms++;
-
- return nAtoms;
-
-}
-
-int CResidue::InsertAtom ( PCAtom atm, int position ) {
-// InsertAtom(..) inserts atom into the specified position of
-// the residue. If residue is associated with a coordinate hierarchy,
-// and atom 'atm' is not, the latter is checked in automatically.
-// If atom 'atm' belongs to any coordinate hierarchy (even though
-// that of the residue), it is *copied* rather than simply taken
-// over, and is checked in.
-// If residue is not associated with a coordinate hierarchy, all
-// added atoms will be checked in automatically once the residue
-// is checked in.
-PCMMDBFile manager;
-PCResidue res;
-int i,pos;
-
- for (i=0;i<nAtoms;i++)
- if (atom[i]==atm) return -i; // this atom is already there
-
- if (nAtoms>=AtmLen)
- ExpandAtomArray ( nAtoms+10-AtmLen );
-
- pos = IMin(position,nAtoms);
- for (i=nAtoms;i>pos;i--)
- atom[i] = atom[i-1];
-
- if (atm->GetCoordHierarchy()) {
- atom[pos] = newCAtom();
- atom[pos]->Copy ( atm );
- } else {
- res = atm->GetResidue();
- if (res)
- for (i=0;i<res->nAtoms;i++)
- if (res->atom[i]==atm) {
- res->atom[i] = NULL;
- break;
- }
- atom[pos] = atm;
- }
-
- atom[pos]->residue = this;
- manager = PCMMDBFile(GetCoordHierarchy());
- if (manager)
- manager->CheckInAtom ( 0,atom[pos] );
-
- nAtoms++;
-
- return nAtoms;
-
-}
-
-int CResidue::InsertAtom ( PCAtom atm, const AtomName aname ) {
-// This version inserts before the atom with given name. If such
-// name is not found, the atom is appended to the end.
-int i;
- i = 0;
- while (i<nAtoms)
- if (!atom[i]) i++;
- else if (!strcmp(aname,atom[i]->name)) break;
- else i++;
- return InsertAtom ( atm,i );
-}
-
-
-void CResidue::CheckInAtoms() {
-PCMMDBFile manager;
-int i;
- manager = PCMMDBFile(GetCoordHierarchy());
- if (manager)
- for (i=0;i<nAtoms;i++)
- if (atom[i]) {
- if (atom[i]->index<0)
- manager->CheckInAtom ( 0,atom[i] );
- }
-}
-
-
-int CResidue::_ExcludeAtom ( int kndex ) {
-// deletes atom from the residue
-int i,k;
-
- if (!Exclude) return 0;
-
- k = -1;
- for (i=0;(i<nAtoms) && (k<0);i++)
- if (atom[i]) {
- if (atom[i]->index==kndex) k = i;
- }
-
- if (k>=0) {
- for (i=k+1;i<nAtoms;i++)
- atom[i-1] = atom[i];
- nAtoms--;
- }
-
- if (nAtoms<=0) return 1;
- else return 0;
-
-}
-
-
-void CResidue::PDBASCIIAtomDump ( RCFile f ) {
-int i;
- for (i=0;i<nAtoms;i++)
- if (atom[i])
- atom[i]->PDBASCIIDump ( f );
-}
-
-void CResidue::MakeAtomCIF ( PCMMCIFData CIF ) {
-int i;
- for (i=0;i<nAtoms;i++)
- if (atom[i])
- atom[i]->MakeCIF ( CIF );
-}
-
-
-void CResidue::Copy ( PCResidue res ) {
-//
-// Modify CResidue::Copy and both CResidues::_copy methods
-// simultaneously!
-//
-// This function will nake a copy of residue res in 'this' one.
-// All atoms are copied, none is moved regardless to the association
-// with coordinate hierarchy. If 'this' residue is associated with
-// a coordinate hierarchy, all atoms are checked in.
-PCMMDBFile manager;
-int i;
-
- FreeMemory();
-
- seqNum = res->seqNum;
- label_seq_id = res->label_seq_id;
- label_entity_id = res->label_entity_id;
- index = res->index;
- AtmLen = res->nAtoms;
- SSE = res->SSE;
- strcpy ( name ,res->name );
- strcpy ( label_comp_id,res->label_comp_id );
- strcpy ( label_asym_id,res->label_asym_id );
- strcpy ( insCode ,res->insCode );
-
- if (AtmLen>0) {
- atom = new PCAtom[AtmLen];
- nAtoms = 0;
- for (i=0;i<res->nAtoms;i++)
- if (res->atom[i]) {
- atom[nAtoms] = newCAtom();
- atom[nAtoms]->Copy ( res->atom[i] );
- atom[nAtoms]->SetResidue ( this );
- nAtoms++;
- }
- for (i=nAtoms;i<AtmLen;i++)
- atom[i] = NULL;
- manager = PCMMDBFile(GetCoordHierarchy());
- if (manager)
- manager->CheckInAtoms ( 0,atom,nAtoms );
- }
-
-}
-
-
-void CResidue::_copy ( PCResidue res ) {
-// Modify both CResidue::_copy and CResidue::Copy methods
-// simultaneously!
-//
-// will work properly only if atomic arrays
-// this->chain->model->GetAtom() and
-// res->chain->model->GetAtom() are identical
-//
-int i;
-PPCAtom A;
-
- FreeMemory();
-
- seqNum = res->seqNum;
- label_seq_id = res->label_seq_id;
- label_entity_id = res->label_entity_id;
- index = res->index;
- nAtoms = res->nAtoms;
- SSE = res->SSE;
- strcpy ( name ,res->name );
- strcpy ( label_comp_id,res->label_comp_id );
- strcpy ( label_asym_id,res->label_asym_id );
- strcpy ( insCode ,res->insCode );
-
- AtmLen = nAtoms;
- A = NULL;
- if (chain) {
- if (chain->model)
- A = chain->model->GetAllAtoms();
- }
- if ((nAtoms>0) && (A)) {
- atom = new PCAtom[nAtoms];
- for (i=0;i<nAtoms;i++) {
- atom[i] = A[res->atom[i]->index-1];
- atom[i]->SetResidue ( this );
- }
- } else {
- nAtoms = 0;
- AtmLen = 0;
- }
-
-}
-
-void CResidue::_copy ( PCResidue res, PPCAtom atm,
- int & atom_index ) {
-// modify both CResidue::_copy and CResidue::Copy methods
-// simultaneously!
-//
-// This function physically copies the atoms, creating new atom
-// instances and putting them into array 'atm' sequentially from
-// 'atom_index' position. 'atom_index' is modified (advanced).
-//
-int i;
-
- FreeMemory();
-
- seqNum = res->seqNum;
- label_seq_id = res->label_seq_id;
- label_entity_id = res->label_entity_id;
- index = res->index;
- nAtoms = res->nAtoms;
- SSE = res->SSE;
- strcpy ( name ,res->name );
- strcpy ( label_comp_id,res->label_comp_id );
- strcpy ( label_asym_id,res->label_asym_id );
- strcpy ( insCode ,res->insCode );
-
- AtmLen = nAtoms;
- if (AtmLen>0) {
- atom = new PCAtom[AtmLen];
- for (i=0;i<nAtoms;i++)
- if (res->atom[i]) {
- if (!atm[atom_index]) atm[atom_index] = newCAtom();
- atm[atom_index]->Copy ( res->atom[i] );
- atm[atom_index]->residue = this;
- atm[atom_index]->index = atom_index+1;
- atom[i] = atm[atom_index];
- atom_index++;
- } else
- atom[i] = NULL;
- }
-
-}
-
-
-void CResidue::GetAtomStatistics ( RSAtomStat AS ) {
- AS.Init();
- CalcAtomStatistics ( AS );
- AS.Finish();
-}
-
-void CResidue::CalcAtomStatistics ( RSAtomStat AS ) {
-// AS must be initialized. The function only accumulates
-// the statistics.
-int i;
- for (i=0;i<nAtoms;i++)
- if (atom[i])
- atom[i]->CalcAtomStatistics ( AS );
-}
-
-
-PCChain CResidue::GetChain() {
- return chain;
-}
-
-PCModel CResidue::GetModel() {
- if (chain) return (PCModel)chain->model;
- else return NULL;
-}
-
-
-int CResidue::GetModelNum() {
- if (chain) {
- if (chain->model)
- return chain->model->GetSerNum();
- }
- return 0;
-}
-
-pstr CResidue::GetChainID() {
- if (chain) return chain->chainID;
- return pstr("");
-}
-
-pstr CResidue::GetLabelAsymID() {
- return label_asym_id;
-}
-
-pstr CResidue::GetResName() {
- return name;
-}
-
-pstr CResidue::GetLabelCompID() {
- return label_comp_id;
-}
-
-int CResidue::GetAASimilarity ( const ResName resName ) {
- return ::GetAASimilarity ( pstr(name),pstr(resName) );
-}
-
-int CResidue::GetAASimilarity ( PCResidue res ) {
- return ::GetAASimilarity ( name,res->name );
-}
-
-realtype CResidue::GetAAHydropathy() {
- return ::GetAAHydropathy ( name );
-}
-
-void CResidue::SetResName ( const ResName resName ) {
- strcpy ( name,resName );
-}
-
-int CResidue::GetSeqNum() {
- return seqNum;
-}
-
-int CResidue::GetLabelSeqID() {
- return label_seq_id;
-}
-
-int CResidue::GetLabelEntityID() {
- return label_entity_id;
-}
-
-pstr CResidue::GetInsCode() {
- return insCode;
-}
-
-Boolean CResidue::isAminoacid () {
- return ::isAminoacid ( name );
-}
-
-Boolean CResidue::isNucleotide() {
- return ::isNucleotide ( name );
-}
-
-int CResidue::isDNARNA() {
- return ::isDNARNA ( name );
-}
-
-Boolean CResidue::isSugar() {
- return ::isSugar ( name );
-}
-
-Boolean CResidue::isSolvent() {
- return ::isSolvent ( name );
-}
-
-Boolean CResidue::isModRes() {
-PCChain chn;
-PCModRes modRes;
-int nModRes,i;
- chn = GetChain();
- if (chn) {
- nModRes = chn->GetNofModResidues();
- for (i=0;i<nModRes;i++) {
- modRes = chn->GetModResidue ( i );
- if (modRes) {
- if ((!strcmp(modRes->resName,name)) &&
- (modRes->seqNum==seqNum) &&
- (!strcmp(modRes->insCode,insCode)))
- return True;
- }
- }
-
- }
- return False;
-}
-
-Boolean CResidue::isInSelection ( int selHnd ) {
-PCMMDBFile manager = (PCMMDBFile)GetCoordHierarchy();
-PCMask Mask;
- if (manager) {
- Mask = manager->GetSelMask ( selHnd );
- if (Mask) return CheckMask ( Mask );
- }
- return False;
-}
-
-
-Boolean CResidue::isNTerminus() {
-PPCResidue Res;
-int i,j,nRes;
- if (chain) {
- chain->GetResidueTable ( Res,nRes );
- i = 0;
- j = -1;
- while ((i<nRes) && (j<0)) {
- if (Res[i]) j = i;
- i++;
- }
- if (j>=0)
- return (Res[j]->index==index);
- }
- return False;
-}
-
-Boolean CResidue::isCTerminus() {
-PPCResidue Res;
-int i,j,nRes;
- if (chain) {
- chain->GetResidueTable ( Res,nRes );
- i = nRes-1;
- j = -1;
- while ((i>=0) && (j<0)) {
- if (Res[i]) j = i;
- i--;
- }
- if (j>=0)
- return (Res[j]->index==index);
- }
- return False;
-}
-
-
-pstr CResidue::GetResidueID ( pstr ResidueID ) {
- ResidueID[0] = char(0);
- if (chain) {
- if (chain->model)
- sprintf ( ResidueID,"/%i/",chain->model->GetSerNum() );
- else strcpy ( ResidueID,"/-/" );
- strcat ( ResidueID,chain->chainID );
- } else
- strcpy ( ResidueID,"/-/-" );
- ParamStr ( ResidueID,pstr("/"),seqNum );
- strcat ( ResidueID,"(" );
- strcat ( ResidueID,name );
- strcat ( ResidueID,")" );
- if (insCode[0]) {
- strcat ( ResidueID,"." );
- strcat ( ResidueID,insCode );
- }
- return ResidueID;
-}
-
-
-int CResidue::CheckID ( int * snum,
- const InsCode inscode,
- const ResName resname ) {
- if (snum) {
- if (*snum!=seqNum) return 0;
- }
- if (inscode) {
- if ((inscode[0]!='*') && (strcmp(inscode,insCode))) return 0;
- }
- if (!resname) return 1;
- if ((resname[0]!='*') && (strcmp(resname,name))) return 0;
- return 1;
-}
-
-int CResidue::CheckIDS ( cpstr CID ) {
-ChainID chn;
-InsCode inscode;
-ResName resname;
-AtomName atm;
-Element elm;
-AltLoc aloc;
-pstr p1,p2;
-int mdl,sn,rc;
-
- rc = ParseAtomPath ( CID,mdl,chn,sn,inscode,resname,
- atm,elm,aloc,NULL );
- // rc = ParseResID ( CID,sn,inscode,resname );
-
- if (rc>=0) {
- p1 = NULL;
- p2 = NULL;
- if (inscode[0]!='*') p1 = inscode;
- if (resname[0]!='*') p2 = resname;
- if (!rc) return CheckID ( &sn ,p1,p2 );
- else return CheckID ( NULL,p1,p2 );
- }
- return 0;
-
-}
-
-
-// -------------------- Extracting atoms -------------------------
-
-int CResidue::GetNumberOfAtoms() {
- return nAtoms;
-}
-
-int CResidue::GetNumberOfAtoms ( Boolean countTers ) {
-int i,na;
- na = 0;
- for (i=0;i<nAtoms;i++)
- if (atom[i]) {
- if (countTers || (!atom[i]->Ter)) na++;
- }
- return na;
-}
-
-PCAtom CResidue::GetAtom ( const AtomName aname,
- const Element elname,
- const AltLoc aloc ) {
-int i;
- for (i=0;i<nAtoms;i++)
- if (atom[i]) {
- if (atom[i]->CheckID(aname,elname,aloc))
- return atom[i];
- }
- return NULL;
-}
-
-PCAtom CResidue::GetAtom ( int atomNo ) {
- if ((0<=atomNo) && (atomNo<nAtoms))
- return atom[atomNo];
- return NULL;
-}
-
-void CResidue::GetAtomTable ( PPCAtom & atomTable, int & NumberOfAtoms ) {
- atomTable = atom;
- NumberOfAtoms = nAtoms;
-}
-
-void CResidue::GetAtomTable1 ( PPCAtom & atomTable, int & NumberOfAtoms ) {
-int i,j;
- if (atomTable) delete[] atomTable;
- if (nAtoms>0) {
- atomTable = new PCAtom[nAtoms];
- j = 0;
- for (i=0;i<nAtoms;i++)
- if (atom[i]) {
- if (!atom[i]->Ter)
- atomTable[j++] = atom[i];
- }
- NumberOfAtoms = j;
- } else {
- atomTable = NULL;
- NumberOfAtoms = 0;
- }
-}
-
-void CResidue::TrimAtomTable() {
-int i,j;
- j = 0;
- for (i=0;i<nAtoms;i++)
- if (atom[i]) {
- if (j<i) {
- atom[j] = atom[i];
- atom[i] = NULL;
- }
- j++;
- }
- nAtoms = j;
-}
-
-
-// --------------------- Deleting atoms --------------------------
-
-int CResidue::DeleteAtom ( const AtomName aname,
- const Element elname,
- const AltLoc aloc ) {
-// apply CMMDBFile::FinishStructEdit() after all editings are done!
-// returns number of deleted atoms
-int i,k,nA,kndex;
-PPCAtom A;
-
- A = NULL;
- nA = 0;
- if (chain) {
- if (chain->model) {
- A = chain->model->GetAllAtoms();
- nA = chain->model->GetNumberOfAllAtoms();
- }
- }
-
- k = 0;
- for (i=0;i<nAtoms;i++)
- if (atom[i]) {
- if (atom[i]->CheckID(aname,elname,aloc)) {
- k++;
- kndex = atom[i]->index;
- if ((0<kndex) && (kndex<=nA)) A[kndex-1] = NULL;
- Exclude = False;
- delete atom[i];
- atom[i] = NULL;
- Exclude = True;
- }
- }
-
- return k;
-
-}
-
-int CResidue::DeleteAtom ( int atomNo ) {
-// apply CMMDBFile::FinishStructEdit() after all editings are done!
-// returns number of deleted atoms
-int kndex,nA;
-PPCAtom A;
-
- if ((0<=atomNo) && (atomNo<nAtoms)) {
- if (atom[atomNo]) {
- A = NULL;
- nA = 0;
- if (chain) {
- if (chain->model) {
- A = chain->model->GetAllAtoms();
- nA = chain->model->GetNumberOfAllAtoms();
- }
- }
- kndex = atom[atomNo]->index;
- if ((0<kndex) && (kndex<=nA)) A[kndex-1] = NULL;
- Exclude = False;
- delete atom[atomNo];
- atom[atomNo] = NULL;
- Exclude = True;
- return 1;
- }
- }
-
- return 0;
-
-}
-
-
-int CResidue::DeleteAllAtoms() {
-int i,k,nA,kndex;
-PPCAtom A;
-
- Exclude = False;
-
- A = NULL;
- nA = 0;
- if (chain) {
- if (chain->model) {
- A = chain->model->GetAllAtoms();
- nA = chain->model->GetNumberOfAllAtoms();
- }
- }
-
- k = 0;
- for (i=0;i<nAtoms;i++)
- if (atom[i]) {
- k++;
- kndex = atom[i]->index;
- if ((0<kndex) && (kndex<=nA)) A[kndex-1] = NULL;
- delete atom[i];
- atom[i] = NULL;
- }
- nAtoms = 0;
-
- Exclude = True;
-
- return k;
-
-}
-
-
-int CResidue::DeleteAltLocs() {
-// This function leaves only alternative location with maximal
-// occupancy, if those are equal or unspecified, the one with
-// "least" alternative location indicator.
-// The function returns the number of deleted atoms. The atom
-// table remains untrimmed, so that nAtoms are wrong until that
-// is done. Tables are trimmed by FinishStructEdit() or
-// explicitely.
-PPCAtom A;
-AtomName aname;
-AltLoc aLoc,aL;
-realtype occupancy,occ;
-int nA,i,i1,i2,j,k,n,kndex;
-
- A = NULL;
- nA = 0;
- if (chain) {
- if (chain->model) {
- A = chain->model->GetAllAtoms();
- nA = chain->model->GetNumberOfAllAtoms();
- }
- }
- Exclude = False;
-
- n = 0;
- for (i=0;i<nAtoms;i++)
-
- if (atom[i]) {
- if (!atom[i]->Ter) {
- occupancy = atom[i]->GetOccupancy();
- strcpy ( aname,atom[i]->name );
- strcpy ( aLoc ,atom[i]->altLoc );
- i1 = -1;
- i2 = i;
- k = 0;
- for (j=i+1;j<nAtoms;j++)
- if (atom[j]) {
- if ((!atom[j]->Ter) && (!strcmp(atom[j]->name,aname))) {
- k++;
- occ = atom[j]->GetOccupancy();
- if (occ>occupancy) {
- occupancy = occ;
- i1 = j;
- }
- if (aLoc[0]) {
- strcpy ( aL,atom[j]->altLoc );
- if (!aL[0]) {
- aLoc[0] = char(0);
- i2 = j;
- } else if (strcmp(aL,aLoc)<0) {
- strcpy ( aLoc,aL );
- i2 = j;
- }
- }
- }
- }
- if (k>0) {
- if (i1<0) {
- if (atom[i]->WhatIsSet & ASET_Occupancy) i1 = i;
- else i1 = i2;
- }
- for (j=i;j<nAtoms;j++)
- if ((j!=i1) && atom[j]) {
- if ((!atom[j]->Ter) && (!strcmp(atom[j]->name,aname))) {
- n++;
- kndex = atom[j]->index;
- if ((0<kndex) && (kndex<=nA)) A[kndex-1] = NULL;
- delete atom[j];
- atom[j] = NULL;
- }
- }
- }
- }
- }
-
- Exclude = True;
-
- return n;
-
-}
-
-void CResidue::ApplyTransform ( mat44 & TMatrix ) {
-// transforms all coordinates by multiplying with matrix TMatrix
-int i;
- for (i=0;i<nAtoms;i++)
- if (atom[i]) {
- if (!atom[i]->Ter)
- atom[i]->Transform ( TMatrix );
- }
-}
-
-
-
-// -----------------------------------------------------------------
-
-
-void CResidue::MaskAtoms ( PCMask Mask ) {
-int i;
- for (i=0;i<nAtoms;i++)
- if (atom[i]) atom[i]->SetMask ( Mask );
-}
-
-void CResidue::UnmaskAtoms ( PCMask Mask ) {
-int i;
- for (i=0;i<nAtoms;i++)
- if (atom[i]) atom[i]->RemoveMask ( Mask );
-}
-
-
-
-// ------- user-defined data handlers
-
-int CResidue::PutUDData ( int UDDhandle, int iudd ) {
- if (UDDhandle & UDRF_RESIDUE)
- return CUDData::putUDData ( UDDhandle,iudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CResidue::PutUDData ( int UDDhandle, realtype rudd ) {
- if (UDDhandle & UDRF_RESIDUE)
- return CUDData::putUDData ( UDDhandle,rudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CResidue::PutUDData ( int UDDhandle, cpstr sudd ) {
- if (UDDhandle & UDRF_RESIDUE)
- return CUDData::putUDData ( UDDhandle,sudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CResidue::GetUDData ( int UDDhandle, int & iudd ) {
- if (UDDhandle & UDRF_RESIDUE)
- return CUDData::getUDData ( UDDhandle,iudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CResidue::GetUDData ( int UDDhandle, realtype & rudd ) {
- if (UDDhandle & UDRF_RESIDUE)
- return CUDData::getUDData ( UDDhandle,rudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CResidue::GetUDData ( int UDDhandle, pstr sudd, int maxLen ) {
- if (UDDhandle & UDRF_RESIDUE)
- return CUDData::getUDData ( UDDhandle,sudd,maxLen );
- else return UDDATA_WrongUDRType;
-}
-
-int CResidue::GetUDData ( int UDDhandle, pstr & sudd ) {
- if (UDDhandle & UDRF_RESIDUE)
- return CUDData::getUDData ( UDDhandle,sudd );
- else return UDDATA_WrongUDRType;
-}
-
-
-#define NOmaxdist2 12.25
-
-Boolean CResidue::isMainchainHBond ( PCResidue res ) {
-// Test if there is main chain Hbond between PCRes1 (donor) and
-// PCRes2 (acceptor).
-// As defined Kabsch & Sanders
-// This probably needs the option of supporting alternative criteria
-PCAtom NAtom,OAtom,CAtom;
-realtype abx,aby,abz;
-realtype acx,acy,acz;
-realtype bcx,bcy,bcz;
-realtype absq,acsq,bcsq;
-
- NAtom = GetAtom ( "N" );
- OAtom = res->GetAtom ( "O" );
- CAtom = res->GetAtom ( "C" );
-
- if (NAtom && OAtom && CAtom) {
-
- abx = OAtom->x - NAtom->x;
- aby = OAtom->y - NAtom->y;
- abz = OAtom->z - NAtom->z;
- absq = abx*abx + aby*aby + abz*abz;
-
-
- if (absq<=NOmaxdist2) {
-
- acx = NAtom->x - CAtom->x;
- acy = NAtom->y - CAtom->y;
- acz = NAtom->z - CAtom->z;
-
- bcx = CAtom->x - OAtom->x;
- bcy = CAtom->y - OAtom->y;
- bcz = CAtom->z - OAtom->z;
-
- acsq = acx*acx + acy*acy + acz*acz;
- bcsq = bcx*bcx + bcy*bcy + bcz*bcz;
-
- return (acos((bcsq+absq-acsq)/(2.0*sqrt(bcsq*absq)))>=Pi/2.0);
-
- }
-
- }
-
- return False;
-
-}
-
-
-void CResidue::write ( RCFile f ) {
-int i;
-byte Version=2;
-
- CUDData::write ( f );
-
- f.WriteByte ( &Version );
- f.WriteInt ( &seqNum );
- f.WriteInt ( &label_seq_id );
- f.WriteInt ( &label_entity_id );
- f.WriteInt ( &index );
- f.WriteInt ( &nAtoms );
- f.WriteByte ( &SSE );
- f.WriteTerLine ( name ,False );
- f.WriteTerLine ( label_comp_id,False );
- f.WriteTerLine ( label_asym_id,False );
- f.WriteTerLine ( insCode ,False );
- for (i=0;i<nAtoms;i++)
- f.WriteInt ( &(atom[i]->index) );
-
-}
-
-void CResidue::read ( RCFile f ) {
-// IMPORTANT: array Atom in CMMDBFile class should be
-// read prior calling this function!
-PPCAtom A;
-int i,k;
-byte Version;
-
- FreeMemory ();
-
- CUDData::read ( f );
-
- f.ReadByte ( &Version );
- f.ReadInt ( &seqNum );
- if (Version>1) {
- f.ReadInt ( &label_seq_id );
- f.ReadInt ( &label_entity_id );
- }
- f.ReadInt ( &index );
- f.ReadInt ( &nAtoms );
- f.ReadByte ( &SSE );
- f.ReadTerLine ( name,False );
- if (Version>1) {
- f.ReadTerLine ( label_comp_id,False );
- f.ReadTerLine ( label_asym_id,False );
- }
- f.ReadTerLine ( insCode,False );
- AtmLen = nAtoms;
- A = NULL;
- if (chain) {
- if (chain->model)
- A = chain->model->GetAllAtoms();
- }
- if ((nAtoms>0) && (A)) {
- atom = new PCAtom[nAtoms];
- for (i=0;i<nAtoms;i++) {
- f.ReadInt ( &k );
- atom[i] = A[k-1];
- atom[i]->SetResidue ( this );
- atom[i]->_setBonds ( A );
- }
- } else {
- for (i=0;i<nAtoms;i++)
- f.ReadInt ( &k );
- nAtoms = 0;
- AtmLen = 0;
- }
-}
-
-
-MakeFactoryFunctions(CResidue)
-
diff --git a/mmdb/mmdb_atom.h b/mmdb/mmdb_atom.h
deleted file mode 100755
index 66cab38..0000000
--- a/mmdb/mmdb_atom.h
+++ /dev/null
@@ -1,739 +0,0 @@
-// $Id: mmdb_atom.h,v 1.30 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 06.02.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_Atom <interface>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CAtom ( atom class )
-// ~~~~~~~~~ CResidue ( residue class )
-// **** Functions: BondAngle
-// ~~~~~~~~~~
-//
-// Copyright (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-#ifndef __MMDB_Atom__
-#define __MMDB_Atom__
-
-
-#ifndef __Stream__
-#include "stream_.h"
-#endif
-
-#ifndef __MMDB_Defs__
-#include "mmdb_defs.h"
-#endif
-
-#ifndef __MMDB_UDData__
-#include "mmdb_uddata.h"
-#endif
-
-#ifndef __MMDB_Utils__
-#include "mmdb_utils.h"
-#endif
-
-
-// ====================== CAtom ==========================
-
-
-// constants for the WhatIsSet field
-#define ASET_Coordinates 0x00000001
-#define ASET_Occupancy 0x00000002
-#define ASET_tempFactor 0x00000004
-#define ASET_CoordSigma 0x00000010
-#define ASET_OccSigma 0x00000020
-#define ASET_tFacSigma 0x00000040
-#define ASET_Anis_tFac 0x00000100
-#define ASET_Anis_tFSigma 0x00001000
-#define ASET_Charge 0x00000080
-#define ASET_All 0x000FFFFF
-
-
-#define ATOM_NoSeqNum MinInt4
-
-extern Boolean ignoreSegID;
-extern Boolean ignoreElement;
-extern Boolean ignoreCharge;
-extern Boolean ignoreNonCoorPDBErrors;
-extern Boolean ignoreUnmatch;
-
-
-DefineStructure(SAtomStat)
-
-struct SAtomStat {
-
- public :
- int nAtoms; // number of atoms in statistics
-
- realtype xmin,ymin,zmin; // minimums of coordinates
- realtype xmax,ymax,zmax; // maximums of coordinates
- realtype xm ,ym ,zm; // mediums of coordinates
- realtype xm2 ,ym2 ,zm2; // square mediums of coordinates
-
- realtype occ_min,occ_max; // minimum/maximum occupancy
- realtype occ_m ,occ_m2; // medium and square medium occupancy
-
- realtype tFmin,tFmax; // minimum/maximum temperature factor
- realtype tFm ,tFm2; // medium and sq. med. temp. factor
-
- realtype u11_min,u11_max; // minimums and
- realtype u22_min,u22_max; // maximums of
- realtype u33_min,u33_max; // anisotropic
- realtype u12_min,u12_max; // temperature
- realtype u13_min,u13_max; // factors
- realtype u23_min,u23_max;
-
- realtype u11_m,u11_m2; // mediums and
- realtype u22_m,u22_m2; // square mediums of
- realtype u33_m,u33_m2; // anisotropic
- realtype u12_m,u12_m2; // temperature
- realtype u13_m,u13_m2; // factors
- realtype u23_m,u23_m2;
-
- word WhatIsSet; // mask field
-
- void Init ();
- void Finish();
-
- realtype GetMaxSize();
-
- private :
- Boolean finished;
-
-};
-
-
-DefineStructure(SAtomBondI)
-
-struct SAtomBondI {
- int index; //!< bonded atom index
- byte order; //!< bond order
-};
-
-
-DefineStructure(SAtomBond)
-
-struct SAtomBond {
- PCAtom atom; //!< bonded atom pointer
- byte order; //!< bond order
-};
-
-
-DefineFactoryFunctions(CAtom)
-
-class CAtom : public CUDData {
-
- friend class CResidue;
- friend class CModel;
- friend class CMMDBFile;
- friend class CMMDBCoorManager;
- friend class CMMDBSelManager;
-
- public :
-
- int serNum; //!< serial number
- AtomName name; //!< atom name (ALIGNED)
- AtomName label_atom_id; //!< assigned atom name (not aligned)
- AltLoc altLoc; //!< alternative location indicator ("" for none)
- SegID segID; //!< segment identifier
- Element element; //!< element symbol (ALIGNED TO RIGHT)
- EnergyType energyType; //!< energy type (without spaces)
- PCResidue residue; //!< reference to residue
- realtype x,y,z; //!< orthogonal coordinates in angstroms
- realtype occupancy; //!< occupancy
- realtype tempFactor; //!< temperature factor
- realtype charge; //!< charge on the atom
- realtype sigX,sigY,sigZ; //!< standard deviations of the coords
- realtype sigOcc; //!< standard deviation of occupancy
- realtype sigTemp; //!< standard deviation of temp. factor
- realtype u11,u22,u33; //!< anisotropic temperature
- realtype u12,u13,u23; /// factors
- realtype su11,su22,su33; //!< standard deviations of
- realtype su12,su13,su23; /// anisotropic temperature factors
- Boolean Het; //!< indicator of het atom
- Boolean Ter; //!< chain terminator
-
- word WhatIsSet; //!< mask field
- /// 0x0001 atomic coordinates
- /// 0x0002 occupancy
- /// 0x0004 temperature factor
- /// 0x0010 coordinate standard deviations
- /// 0x0020 deviation of occupancy
- /// 0x0040 deviation of temperature factor
- /// 0x0100 anisotropic temperature factors
- /// 0x1000 anis. temp. fact-s st-d deviations
-
- CAtom ();
- CAtom ( PCResidue res );
- CAtom ( RPCStream Object );
- ~CAtom();
-
- void SetResidue ( PCResidue res );
- void PDBASCIIDump ( RCFile f );
- void MakeCIF ( PCMMCIFData CIF );
-
- // AddBond(...) adds a bond to the atom, that is a pointer
- // to the bonded atom and the bond order. nAdd_bonds allows
- // one to minimize the memory reallocations, if number of
- // bonds is known apriori: CAtom adds space for nAdd_bonds
- // if currently allocated space is exchausted.
- // Return: <=0 - error: bond_atom is already "bonded"
- // >0 - Ok, returns current number of bonds
- int AddBond ( PCAtom bond_atom, int bond_order,
- int nAdd_bonds=1 );
- int GetNBonds();
-
- // This GetBonds(..) returns pointer to the CAtom's
- // internal Bond structure, IT MUST NOT BE DISPOSED.
- void GetBonds ( RPSAtomBond AtomBond, int & nAtomBonds );
- void FreeBonds();
-
- // This GetBonds(..) disposes AtomBondI, if it was not set
- // to NULL, allocates AtomBondI[nAtomBonds] and returns its
- // pointer. AtomBondI MUST BE DISPOSED BY APPLICATION.
- void GetBonds ( RPSAtomBondI AtomBondI, int & nAtomBonds );
-
- // This GetBonds(..) does not dispose or allocate AtomBondI.
- // It is assumed that length of AtomBondI is sufficient to
- // accomodate all bonded atoms.
- void GetBonds ( PSAtomBondI AtomBondI, int & nAtomBonds,
- int maxlength );
-
-
- // ConvertPDBxxxxxx() gets data from the PDB ASCII xxxxxx
- // record (xxxxxx stands for ATOM, SIGATM, ANISOU, SIGUIJ,
- // TER or HETATM).
- // These functions DO NOT check the xxxxxx keyword and
- // do not decode the chain and residue parameters! These
- // must be treated by the calling process, see
- // CMMDBFile::ReadPDBAtom().
- // The atom reference is updated in the corresponding
- // residue.
- int ConvertPDBATOM ( int ix, cpstr S );
- int ConvertPDBSIGATM ( int ix, cpstr S );
- int ConvertPDBANISOU ( int ix, cpstr S );
- int ConvertPDBSIGUIJ ( int ix, cpstr S );
- int ConvertPDBTER ( int ix, cpstr S );
- int ConvertPDBHETATM ( int ix, cpstr S );
-
- int GetCIF ( int ix, PCMMCIFLoop Loop,
- PCMMCIFLoop LoopAnis );
-
- Boolean RestoreElementName();
- Boolean MakePDBAtomName();
-
- void SetAtomName ( int ix, // index
- int sN, // serial number
- const AtomName aName, // atom name
- const AltLoc aLoc, // alternative location
- const SegID sID, // segment ID
- const Element eName ); // element name
-
- // This only renames the atom
- void SetAtomName ( const AtomName atomName );
- void SetElementName ( const Element elName );
- void SetCharge ( cpstr chrg );
- void SetCharge ( realtype chrg );
-
- void SetAtomIndex ( int ix ); // don't use in your applications!
-
- void MakeTer(); // converts atom into 'ter'
-
- void SetCoordinates ( realtype xx, realtype yy, realtype zz,
- realtype occ, realtype tFac );
-
- int GetModelNum ();
- pstr GetChainID ();
- pstr GetLabelAsymID ();
- pstr GetResName ();
- pstr GetLabelCompID ();
- int GetAASimilarity ( const ResName resName );
- int GetAASimilarity ( PCAtom A );
- realtype GetAAHydropathy();
- realtype GetOccupancy ();
- int GetSeqNum ();
- int GetLabelSeqID ();
- int GetLabelEntityID ();
- pstr GetInsCode ();
- int GetSSEType (); // works only after SSE calculations
- pstr GetAtomName () { return name; }
- pstr GetElementName () { return element; }
- pstr GetAtomCharge ( pstr chrg );
-
- // GetChainCalphas(...) is a specialized function for quick
- // access to C-alphas of chain which includes given atom.
- // This function works faster than an equivalent implementation
- // through MMDB's selection procedures.
- // Parameters:
- // Calphas - array to accept pointers on C-alpha atoms
- // If Calphas!=NULL, then the function will
- // delete and re-allocate it. When the array
- // is no longer needed, the application MUST
- // delete it: delete[] Calphas; Deleting
- // Calphas does not delete atoms from MMDB.
- // nCalphas - integer to accept number of C-alpha atoms
- // and the length of Calphas array.
- // altLoc - alternative location indicator. By default
- // (""), maximum-occupancy locations are taken.
- void GetChainCalphas ( PPCAtom & Calphas, int & nCalphas,
- cpstr altLoc = "" );
-
- Boolean isTer () { return Ter; }
- Boolean isMetal ();
- Boolean isSolvent (); // works only for atom in a residue!
- Boolean isInSelection ( int selHnd );
- Boolean isNTerminus ();
- Boolean isCTerminus ();
-
- void CalcAtomStatistics ( RSAtomStat AS );
-
- realtype GetDist2 ( PCAtom a );
- realtype GetDist2 ( PCAtom a, mat44 & tm ); // tm applies to A
- realtype GetDist2 ( PCAtom a, mat33 & r, vect3 & t );// tm applies to A
- realtype GetDist2 ( realtype ax, realtype ay, realtype az );
-
- // GetCosine(a1,a2) calculates cosine of angle a1-this-a2,
- // i.e. that between vectors [a1,this] and [this,a2].
- realtype GetCosine ( PCAtom a1, PCAtom a2 );
-
- PCResidue GetResidue ();
- PCChain GetChain ();
- PCModel GetModel ();
- int GetResidueNo();
- void * GetCoordHierarchy(); // PCMMDBFile
-
- // GetAtomID(..) generates atom ID in the form
- // /m/c/r(rn).i/n[e]:a
- // where m - model number
- // c - chain ID
- // r - residue sequence number
- // rn - residue name
- // i - insertion code
- // n - atom name
- // e - chemical element specification
- // a - alternate location indicator
- // If any of the fields is undefined, it is replaced by
- // hyphen '-'.
- // No checks on the sufficiency of string buffer AtomID
- // is made.
- // GetAtomID returns AtomID.
- pstr GetAtomID ( pstr AtomID );
-
- pstr GetAtomIDfmt ( pstr AtomID );
-
- // ------- checking atom ID
- // CheckID(..) returns 1 if atom is identified, and 0 otherwise.
- // Parameters:
- // aname - atom name. It may or may not be aligned (as in
- // a PDB file), only first word of the name will
- // be taken ("CA", " CA" and " CA B" are all
- // considered as "CA"). aname may be set to NULL
- // or '*', then this parameter is ignored.
- // elname - element code. It will work only if element code
- // is supplied (which might not be the case if
- // the atom was created in a tricky way). elname
- // should be used to distinguih between, e.g.
- // "Ca" and "C_alpha"). elname may be set to NULL,
- // or '*', then this parameter is ignored.
- // aloc - the alternate location code. aloc may be set to
- // NULL or '*', then this parameter is ignored.
- // IMPORTANT: comparison is case-sensitive.
- // The atom is considered as identified, if all non-NULL
- // parameters do match. If all parameters are set NULL, any atom
- // is identified.
- // DEFAULT values correspond to 'any element' and
- // 'no alternate location code'
- // NOTE that " " is not an empty item.
- int CheckID ( const AtomName aname, const Element elname=NULL,
- const AltLoc aloc=pstr("") );
-
- // CheckIDS(..) works exactly like CheckID(..), but it takes
- // the only parameter, the atom ID, which is of the form:
- // {name} {[element]} {:altcode}
- // Here {} means that the item may be omitted. Any item may be
- // represented by a wildcard '*', which means 'any value'. Just
- // absence of an item means 'empty', which makes sense only for
- // alternate location code. Missing name or element therefore
- // mean 'any name' or 'any element', correspondingly (same as a
- // wildcard). There should be no spaces in ID except for leading
- // spaces; any following space will terminate parsing.
- // The followings are perfectly valid IDs:
- // CA[C]:A (carbon C_alpha in location A)
- // CA[*]:A (either C_alpha or Ca in location A)
- // CA:A (same as above)
- // CA (either C_alpha or Ca with no location indicator)
- // CA[] (same as above)
- // CA[C]: (C_alpha with no location indicator)
- // [C] (any carbon with no location indicator)
- // [C]:* (any carbon with any location indicator)
- // *[C]:* (same as above)
- // :A (any atom in location A)
- // *[*]:A (same as above)
- // *[*]:* (any atom)
- // * (any atom with no alternate location indicator)
- int CheckIDS ( cpstr ID );
-
-
- // ------- transform coordinates: x := m*x + v
- void Transform ( mat33 & tm, vect3 & v );
- void Transform ( mat44 & tm );
- void TransformCopy ( mat44 & tm,
- realtype & xx, realtype & yy, realtype & zz );
- void TransformSet ( mat44 & tm,
- realtype xx, realtype yy, realtype zz );
-
-
- // ------- user-defined data handlers
- int PutUDData ( int UDDhandle, int iudd );
- int PutUDData ( int UDDhandle, realtype rudd );
- int PutUDData ( int UDDhandle, cpstr sudd );
-
- int GetUDData ( int UDDhandle, int & iudd );
- int GetUDData ( int UDDhandle, realtype & rudd );
- int GetUDData ( int UDDhandle, pstr sudd, int maxLen );
- int GetUDData ( int UDDhandle, pstr & sudd );
-
-
- int GetIndex() { return index; }
-
- virtual void Copy ( PCAtom atom ); // without references in
- // residues
-
- void SetShortBinary(); // leaves only coordinates in binary files
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
- int index; // index in the file
- int nBonds; // number of bonds in the lowest byte (!)
- PSAtomBond Bond; // atom bonds
-
- void InitAtom ();
- void FreeMemory ();
- void StandardPDBOut ( cpstr Record, pstr S );
- void GetData ( cpstr S );
- int CheckData ( cpstr S );
- void GetStat ( realtype v,
- realtype & v_min, realtype & v_max,
- realtype & v_m, realtype & v_m2 );
- void _setBonds ( PPCAtom A ); // used only in CResidue
-
-};
-
-
-// ====================== CResidue ==========================
-
-#define ALF_NoAltCodes 0x00000000
-#define ALF_EmptyAltLoc 0x00000001
-#define ALF_NoEmptyAltLoc 0x00000002
-#define ALF_Mess 0x00000004
-#define ALF_Occupancy 0x00000008
-
-#define SSE_None 0
-#define SSE_Strand 1
-#define SSE_Bulge 2
-#define SSE_3Turn 3
-#define SSE_4Turn 4
-#define SSE_5Turn 5
-#define SSE_Helix 6
-
-
-DefineFactoryFunctions(CResidue)
-
-class CResidue : public CUDData {
-
- friend class CAtom;
- friend class CChain;
- friend class CMMDBFile;
-
- public :
-
- ResName name; //!< residue name - all spaces cut
- ResName label_comp_id; //!< assigned residue name
- ChainID label_asym_id; //!< assigned chain Id
- InsCode insCode; //!< residue insertion code
- PCChain chain; //!< reference to chain
- PPCAtom atom; //!< array of atoms
- int seqNum; //!< residue sequence number
- int label_seq_id; //!< assigned residue sequence number
- int label_entity_id; //!< assigned entity id
- int index; //!< index in the chain
- int nAtoms; //!< number of atoms in the residue
- byte SSE; //!< SSE type
-
- CResidue ();
- CResidue ( PCChain Chain_Owner );
- CResidue ( PCChain Chain_Owner, const ResName resName,
- int sqNum, const InsCode ins );
- CResidue ( RPCStream Object );
- ~CResidue();
-
- void SetChain ( PCChain Chain_Owner );
- void SetResID ( const ResName resName, int sqNum,
- const InsCode ins );
- void SetChainID ( const ChainID chID );
-
- void PDBASCIIAtomDump ( RCFile f );
- void MakeAtomCIF ( PCMMCIFData CIF );
-
- PCChain GetChain();
- PCModel GetModel();
-
- int GetModelNum ();
- pstr GetChainID ();
- pstr GetLabelAsymID();
- pstr GetResName ();
- pstr GetLabelCompID();
- int GetAASimilarity ( const ResName resName );
- int GetAASimilarity ( PCResidue res );
- realtype GetAAHydropathy();
- void SetResName ( const ResName resName );
- int GetSeqNum ();
- int GetLabelSeqID ();
- int GetLabelEntityID();
- pstr GetInsCode ();
- int GetResidueNo ();
- int GetCenter ( realtype & x, realtype & y, realtype & z );
- void * GetCoordHierarchy(); // PCMMDBFile
-
- void GetAtomStatistics ( RSAtomStat AS );
- void CalcAtomStatistics ( RSAtomStat AS );
-
- pstr GetResidueID ( pstr ResidueID );
-
- // GetAltLocations(..) returns the number of different
- // alternative locations in nAltLocs, the locations themselves
- // - in aLoc and the corresponding occupancies - in occupancy.
- // aLoc and occupancy are allocated dynamically; it is
- // responsibility of the application to deallocate aLoc prior
- // calling GetAltLocations(..) if they were previously allocated.
- // Either, the application is responsible for deallocating aLoc and
- // occupancy after use.
- // occupancy[i] may return -1.0 if occupancies were not read
- // from coordinate file.
- // alflag returns ALF_NoAltCodes if no alt codes was found,
- // otherwise the output is decoded according to bits:
- // ALF_EmptyAltLoc alternative locations include the
- // "no alt loc indicator" ("" for
- // CAtom::altLoc).
- // This means that each atom that has alt locs
- // different of "", also includes one marked as
- // "".
- // ALF_NoEmptyAltLoc alternative locations do not include the
- // "no alt loc indicator" ("" for
- // CAtom::altLoc).
- // This means that each atom has either ""
- // alt loc or at least two alt locs different
- // of "".
- // ALF_Mess incorrect residue: it mixes both
- // ""-including and not-""-including schemes
- // ALF_Occupancy warning that sum of occupancies for alt
- // located atoms differ from 1.0 by more
- // than 0.01.
- void GetAltLocations ( int & nAltLocs, PAltLoc & aLoc,
- rvector & occupancy, int & alflag );
- int GetNofAltLocations();
-
- Boolean isAminoacid ();
- Boolean isNucleotide ();
- int isDNARNA (); // 0(neither),1(DNA),2(RNA)
- Boolean isSugar ();
- Boolean isSolvent ();
- Boolean isModRes ();
- Boolean isInSelection ( int selHnd );
- Boolean isNTerminus ();
- Boolean isCTerminus ();
-
- // ------- checking residue ID
- // CheckID(..) returns 1 if residue is identified, and 0 otherwise.
- // Parameters:
- // sname - pointer to sequence number; if NULL then ignored.
- // inscode - insertion code; if NULL or '*' then ignored.
- // resname - residue name; if NULL or '*' then ignored.
- // IMPORTANT: comparison is case-sensitive.
- // The residue is considered as identified, if all non-NULL
- // parameters do match. If all parameters are set NULL, any
- // residue is identified.
- // DEFAULT values correspond to 'any residue name' and
- // 'no insertion code'
- // NOTE that " " is not an empty item.
- int CheckID ( int * snum, const InsCode inscode=pstr(""),
- const ResName resname=NULL );
-
- // CheckIDS(..) works exactly like CheckID(..), but it takes
- // the only parameter, the residue ID, which is of the form:
- // {seqnum} {(name)} {.inscode}
- // Here {} means that the item may be omitted. Any item may be
- // represented by a wildcard '*', which means 'any value'. Just
- // absence of a value means 'empty', which is meaningful only for
- // the insertion code. Missing sequence number or residue name
- // therefore mean 'any sequence number' or 'any residue name',
- // correspondingly (same as a wildcard). There should be no
- // spaces in ID except for leading spaces; any following space will
- // terminate parsing. The followings are perfectly valid IDs:
- // 27(ALA).A (residue 27A ALA)
- // 27().A (residue 27A)
- // 27(*).A (same as above)
- // 27.A (same as above)
- // 27 (residue 27)
- // 27(). (same as above)
- // (ALA) (any ALA without insertion code)
- // (ALA). (same as above)
- // (ALA).* (any ALA)
- // *(ALA).* (any ALA)
- // .A (any residue with insertion code A)
- // *(*).A (same as above)
- // *(*).* (any residue)
- // * (any residue with no insertion code)
- int CheckIDS ( cpstr ID );
-
-
- // -------------------- Extracting atoms ----------------------
-
- int GetNumberOfAtoms ();
- int GetNumberOfAtoms ( Boolean countTers );
-
- PCAtom GetAtom ( const AtomName aname, const Element elname=NULL,
- const AltLoc aloc=cpstr("") );
- PCAtom GetAtom ( int atomNo );
-
- void GetAtomTable ( PPCAtom & atomTable, int & NumberOfAtoms );
-
- // GetAtomTable1(..) returns atom table without TER atoms and
- // without NULL atom pointers. NumberOfAtoms returns the actual
- // number of atom pointers in atomTable.
- // atomTable is allocated withing the function. If it was
- // not set to NULL before calling the function, the latter will
- // attempt to deallocate it first.
- // The application is responsible for deleting atomTable,
- // however it must not touch atom pointers, i.e. use simply
- // "delete[] atomTable;". Never pass atomTable from GetAtomTable()
- // into this function, unless you set it to NULL before doing that.
- void GetAtomTable1 ( PPCAtom & atomTable, int & NumberOfAtoms );
-
-
- // --------------------- Deleting atoms -----------------------
-
- int DeleteAtom ( const AtomName aname, const Element elname=NULL,
- const AltLoc aloc=cpstr("") );
- int DeleteAtom ( int atomNo );
- int DeleteAllAtoms();
-
- // DeleteAltLocs() leaves only alternative location with maximal
- // occupancy, if those are equal or unspecified, the one with
- // "least" alternative location indicator.
- // The function returns the number of deleted atoms. The atom
- // table remains untrimmed, so that nAtoms are wrong until that
- // is done. Tables are trimmed by FinishStructEdit() or
- // explicitely.
- int DeleteAltLocs ();
-
- void TrimAtomTable ();
-
- // ---------------------- Adding atoms ------------------------
-
- // AddAtom(..) adds atom to the residue. If residue is associated
- // with a coordinate hierarchy, and atom 'atm' is not, the latter
- // is checked in automatically. If atom 'atm' belongs to any
- // coordinate hierarchy (even though that of the residue), it is
- // *copied* rather than simply taken over, and is checked in.
- // If residue is not associated with a coordinate hierarchy, all
- // added atoms will be checked in automatically once the residue
- // is checked in.
- int AddAtom ( PCAtom atm );
-
- // InsertAtom(..) inserts atom into the specified position of
- // the residue. If residue is associated with a coordinate
- // hierarchy, and atom 'atm' is not, the latter is checked in
- // automatically. If atom 'atm' belongs to any coordinate
- // hierarchy (even though that of the residue), it is *copied*
- // rather than simply taken over, and is checked in.
- // If residue is not associated with a coordinate hierarchy, all
- // added atoms will be checked in automatically once the residue
- // is checked in.
- int InsertAtom ( PCAtom atm, int position );
-
- // This version inserts before the atom with given name. If such
- // name is not found, the atom is appended to the end.
- int InsertAtom ( PCAtom atm, const AtomName aname );
-
- // --------------------------------------------------------------
-
- void ApplyTransform ( mat44 & TMatrix ); // transforms all
- // coordinates by
- // multiplying with
- // matrix TMatrix
-
- void MaskAtoms ( PCMask Mask );
- void UnmaskAtoms ( PCMask Mask );
-
-
- // ------- user-defined data handlers
- int PutUDData ( int UDDhandle, int iudd );
- int PutUDData ( int UDDhandle, realtype rudd );
- int PutUDData ( int UDDhandle, cpstr sudd );
-
- int GetUDData ( int UDDhandle, int & iudd );
- int GetUDData ( int UDDhandle, realtype & rudd );
- int GetUDData ( int UDDhandle, pstr sudd, int maxLen );
- int GetUDData ( int UDDhandle, pstr & sudd );
-
-
- Boolean isMainchainHBond ( PCResidue res );
-
- void Copy ( PCResidue res );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- int AtmLen; // length of atom array
- Boolean Exclude; // used internally
-
- void InitResidue ();
- void FreeMemory ();
- int _AddAtom ( PCAtom atm );
- int _ExcludeAtom ( int kndex ); // 1: residue gets empty,
- // 0 otherwise
- void _copy ( PCResidue res );
- void _copy ( PCResidue res, PPCAtom atm, int & atom_index );
- void ExpandAtomArray ( int nAdd );
- void CheckInAtoms ();
-
-};
-
-
-extern realtype BondAngle ( PCAtom A, PCAtom B, PCAtom C );
-
-
-#endif
-
diff --git a/mmdb/mmdb_bondmngr.cpp b/mmdb/mmdb_bondmngr.cpp
deleted file mode 100755
index 69afa73..0000000
--- a/mmdb/mmdb_bondmngr.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-// $Id: mmdb_bondmngr.cpp,v 1.21 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 29.01.10 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : mmdb_bondmngr <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CMMDBBondManager ( MMDB bonds maker )
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2010
-//
-// =================================================================
-//
-
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __MMDB_BondMngr__
-#include "mmdb_bondmngr.h"
-#endif
-
-#ifndef __MMDB_Graph__
-#include "mmdb_graph.h"
-#endif
-
-
-// ===================== CMMDBBondManager =====================
-
-CMMDBBondManager::CMMDBBondManager() : CMMDBSelManager() {
-}
-
-CMMDBBondManager::CMMDBBondManager ( RPCStream Object )
- : CMMDBSelManager(Object) {
-}
-
-CMMDBBondManager::~CMMDBBondManager() {}
-
-void CMMDBBondManager::MakeBonds ( Boolean calc_only ) {
-UNUSED_ARGUMENT(calc_only);
-PCModel model;
-PCChain chain;
-PCResidue res;
-CGraph graph;
-PPCVertex V;
-PPCEdge E;
-int i, im,ic,ir, nV,nE, k1,k2;
-
- RemoveBonds();
-
- for (im=0;im<nModels;im++) {
- model = Model[im];
- if (model)
- for (ic=0;ic<model->nChains;ic++) {
- chain = model->Chain[ic];
- if (chain)
- for (ir=0;ir<chain->nResidues;ir++) {
- res = chain->Residue[ir];
- if (res) {
- graph.MakeGraph ( res,NULL );
- graph.GetVertices ( V,nV );
- graph.GetEdges ( E,nE );
- for (i=0;i<nE;i++) {
- k1 = V[E[i]->GetVertex1()]->GetUserID();
- k2 = V[E[i]->GetVertex2()]->GetUserID();
- res->atom[k1]->AddBond ( res->atom[k2],E[i]->GetType() );
- res->atom[k2]->AddBond ( res->atom[k1],E[i]->GetType() );
- }
- }
- }
- }
- }
-
-}
-
-void CMMDBBondManager::RemoveBonds() {
-int i;
- for (i=0;i<nAtoms;i++)
- if (Atom[i])
- Atom[i]->FreeBonds();
-}
-
-// ------------------- Stream functions ----------------------
-
-void CMMDBBondManager::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- CMMDBSelManager::write ( f );
-}
-
-void CMMDBBondManager::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- CMMDBSelManager::read ( f );
-}
-
-
-MakeStreamFunctions(CMMDBBondManager)
diff --git a/mmdb/mmdb_chain.cpp b/mmdb/mmdb_chain.cpp
deleted file mode 100755
index 137b5ce..0000000
--- a/mmdb/mmdb_chain.cpp
+++ /dev/null
@@ -1,2568 +0,0 @@
-// $Id: mmdb_chain.cpp,v 1.25 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 14.06.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_Chain <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CChainContainer ( container for in-chain classes )
-// ~~~~~~~~~ CContainerChain ( chain containered class template)
-// CDBReference ( DBREF records )
-// CSeqAdv ( SEQADV records )
-// CSeqRes ( SEQRES records )
-// CModRes ( MODRES records )
-// CHetRec ( HET records )
-// CChain ( MMDB chain class )
-//
-// Copyright (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifndef __MMDB_Chain__
-#include "mmdb_chain.h"
-#endif
-
-#ifndef __MMDB_Model__
-#include "mmdb_model.h"
-#endif
-
-#ifndef __MMDB_File__
-#include "mmdb_file.h"
-#endif
-
-#ifndef __MMDB_CIFDefs__
-#include "mmdb_cifdefs.h"
-#endif
-
-// ================== CProModel ======================
-
-MakeStreamFunctions(CProModel)
-
-// ============== CChainContainer ====================
-
-PCContainerClass CChainContainer::MakeContainerClass ( int ClassID ) {
- switch (ClassID) {
- default :
- case ClassID_Template : return
- CClassContainer::MakeContainerClass(ClassID);
- case ClassID_DBReference : return new CDBReference ( Chain );
- case ClassID_SeqAdv : return new CSeqAdv ( Chain );
- case ClassID_ModRes : return new CModRes ( Chain );
- case ClassID_Het : return new CHetRec ( Chain );
- }
-}
-
-void CChainContainer::SetChain ( PCChain Chain_Owner ) {
-int i;
- Chain = Chain_Owner;
- for (i=0;i<length;i++)
- if (Container[i])
- (void)PCContainerChain(Container[i])->SetChain ( Chain );
-}
-
-cpstr CChainContainer::Get1stChainID() {
-int i;
- i = 0;
- if (Container) {
- while ((i<length-1) && (!Container[i])) i++;
- if (Container[i])
- return PCContainerChain(Container[i])->chainID;
- else return NULL;
- } else
- return NULL;
-}
-
-void CChainContainer::MoveByChainID ( const ChainID chainID,
- PCChainContainer ChainContainer ) {
-int i;
- for (i=0;i<length;i++)
- if (Container[i]) {
- if (!strcmp(PCContainerChain(Container[i])->chainID,chainID)) {
- ChainContainer->AddData ( Container[i] );
- Container[i] = NULL;
- }
- }
-}
-
-
-MakeStreamFunctions(CChainContainer)
-
-
-// ================ CContainerChain ===================
-
-CContainerChain::CContainerChain ()
- : CContainerClass() {
- Chain = NULL;
- chainID[0] = char(0);
-}
-
-CContainerChain::CContainerChain ( PCChain Chain_Owner)
- : CContainerClass() {
- Chain = Chain_Owner;
- if (Chain) strcpy ( chainID,Chain->GetChainID() );
- else chainID[0] = char(0);
-}
-
-void CContainerChain::SetChain ( PCChain Chain_Owner ) {
- Chain = Chain_Owner;
- if (Chain) strcpy ( chainID,Chain->GetChainID() );
- else strcpy ( chainID,"" );
-}
-
-MakeStreamFunctions(CContainerChain)
-
-
-// ================ CDBReference ===================
-
-CDBReference::CDBReference() : CContainerChain() {
- InitDBReference();
-}
-
-CDBReference::CDBReference( PCChain Chain_Owner )
- : CContainerChain(Chain_Owner) {
- InitDBReference();
-}
-
-CDBReference::CDBReference ( PCChain Chain_Owner, cpstr S )
- : CContainerChain(Chain_Owner) {
- InitDBReference();
- ConvertPDBASCII ( S );
-}
-
-CDBReference::CDBReference ( RPCStream Object )
- : CContainerChain(Object) {
- InitDBReference();
-}
-
-CDBReference::~CDBReference() {}
-
-void CDBReference::InitDBReference() {
- seqBeg = 0;
- strcpy ( insBeg ,"-" );
- seqEnd = 0;
- strcpy ( insEnd ,"-" );
- strcpy ( database ,"------" );
- strcpy ( dbAccession,"--------" );
- strcpy ( dbIdCode ,"------------" );
- dbseqBeg = 0;
- strcpy ( dbinsBeg,"-" );
- dbseqEnd = 0;
- strcpy ( dbinsEnd,"-" );
-}
-
-void CDBReference::PDBASCIIDump ( pstr S, int N ) {
-UNUSED_ARGUMENT(N);
-// makes the ASCII PDB DBREF line number N
-// from the class' data
- strcpy ( S,"DBREF" );
- PadSpaces ( S,80 );
- strcpy_n ( &(S[7]),Chain->GetEntryID(),4 );
- if (Chain->chainID[0]) S[12] = Chain->chainID[0];
- PutIntIns ( &(S[14]),seqBeg,4,insBeg );
- PutIntIns ( &(S[20]),seqEnd,4,insEnd );
- strcpy_n ( &(S[26]),database ,6 );
- strcpy_n ( &(S[33]),dbAccession,8 );
- strcpy_n ( &(S[42]),dbIdCode ,12 );
- PutIntIns ( &(S[55]),dbseqBeg,5,dbinsBeg );
- PutIntIns ( &(S[62]),dbseqEnd,5,dbinsEnd );
-}
-
-void CDBReference::MakeCIF ( PCMMCIFData CIF, int N ) {
-UNUSED_ARGUMENT(N);
-PCMMCIFLoop Loop1,Loop2;
-int RC1,RC2;
-
- RC1 = CIF->AddLoop ( CIFCAT_STRUCT_REF_SEQ,Loop1 );
- RC2 = CIF->AddLoop ( CIFCAT_STRUCT_REF ,Loop2 );
-
- if ((RC1!=CIFRC_Ok) || (RC2!=CIFRC_Ok)) {
- // the category was (re)created, provide tags
- Loop1->AddLoopTag ( CIFTAG_NDB_PDB_ID_CODE );
- Loop1->AddLoopTag ( CIFTAG_NDB_CHAIN_ID );
- Loop1->AddLoopTag ( CIFTAG_SEQ_ALIGN_BEG );
- Loop1->AddLoopTag ( CIFTAG_NDB_SEQ_ALIGN_BEG_INS_CODE );
- Loop1->AddLoopTag ( CIFTAG_SEQ_ALIGN_END );
- Loop1->AddLoopTag ( CIFTAG_NDB_SEQ_ALIGN_END_INS_CODE );
- Loop1->AddLoopTag ( CIFTAG_NDB_DB_ACCESSION );
- Loop1->AddLoopTag ( CIFTAG_DB_ALIGN_BEG );
- Loop1->AddLoopTag ( CIFTAG_NDB_DB_ALIGN_BEG_INS_CODE );
- Loop1->AddLoopTag ( CIFTAG_DB_ALIGN_END );
- Loop1->AddLoopTag ( CIFTAG_NDB_DB_ALIGN_END_INS_CODE );
- Loop2->AddLoopTag ( CIFTAG_DB_NAME );
- Loop2->AddLoopTag ( CIFTAG_DB_CODE );
- }
-
- Loop1->AddString ( Chain->GetEntryID(),True );
- Loop1->AddString ( Chain->chainID ,True );
- Loop1->AddInteger ( seqBeg );
- Loop1->AddString ( insBeg ,True );
- Loop1->AddInteger ( seqEnd );
- Loop1->AddString ( insEnd ,True );
- Loop1->AddString ( dbAccession ,True );
- Loop1->AddInteger ( dbseqBeg );
- Loop1->AddString ( dbinsBeg ,True );
- Loop1->AddInteger ( dbseqEnd );
- Loop1->AddString ( dbinsEnd ,True );
-
- Loop2->AddString ( database,True );
- Loop2->AddString ( dbIdCode,True );
-
-}
-
-void CDBReference::GetCIF ( PCMMCIFData CIF, int & Signal ) {
-// GetCIF(..) must be always run without reference to Chain,
-// see CModel::GetCIF(..).
-PCMMCIFLoop Loop1,Loop2;
-PCMMCIFStruct Struct2;
-pstr F;
-int RC,CIFMode,ref_id1,ref_id2;
-
- Loop1 = CIF->GetLoop ( CIFCAT_STRUCT_REF_SEQ );
-
- if (!Loop1) {
- Signal = -1;
- return;
- }
-
- if (Signal>=Loop1->GetLoopLength()) {
- Signal = -1;
- return;
- }
-
-
- // Determine the ChainID first and store it locally. It will
- // be used by CModel for generating chains and placing the
- // primary structure data BEFORE reading the coordinate section.
- CIFMode = CIF_NDB;
- F = Loop1->GetString ( CIFName(TAG_CHAIN_ID,CIFMode),Signal,RC );
- if ((RC) || (!F)) {
- CIFMode = CIF_PDBX;
- F = Loop1->GetString ( CIFName(TAG_CHAIN_ID,CIFMode),Signal,RC );
- }
- if ((!RC) && F) {
- strcpy_n0 ( chainID,F,sizeof(ChainID)-1 );
- Loop1->DeleteField ( CIFName(TAG_CHAIN_ID,CIFMode),Signal );
- } else
- strcpy ( chainID,"" );
-
-
- if (CIFGetInteger(seqBeg,Loop1,CIFName(TAG_SEQ_ALIGN_BEG,CIFMode),
- Signal)) return;
- CIFGetString ( insBeg,Loop1,CIFName(TAG_SEQ_ALIGN_BEG_INS_CODE,CIFMode),
- Signal,sizeof(InsCode),pstr(" ") );
-
- if (CIFGetInteger(seqEnd,Loop1,CIFName(TAG_SEQ_ALIGN_END,CIFMode),
- Signal)) return;
- CIFGetString ( insEnd,Loop1,CIFName(TAG_SEQ_ALIGN_END_INS_CODE,CIFMode),
- Signal,sizeof(InsCode),pstr(" ") );
- CIFGetString ( dbAccession,Loop1,CIFName(TAG_DB_ACCESSION,CIFMode),
- Signal,sizeof(DBAcCode),pstr(" ") );
-
- if (CIFGetInteger(dbseqBeg,Loop1,CIFName(TAG_DB_ALIGN_BEG,CIFMode),
- Signal)) return;
- CIFGetString ( dbinsBeg,Loop1,CIFName(TAG_DB_ALIGN_BEG_INS_CODE,CIFMode),
- Signal,sizeof(InsCode),pstr(" ") );
-
- if (CIFGetInteger(dbseqEnd,Loop1,CIFName(TAG_DB_ALIGN_END,CIFMode),
- Signal)) return;
- CIFGetString ( dbinsEnd,Loop1,CIFName(TAG_DB_ALIGN_END_INS_CODE,CIFMode),
- Signal,sizeof(InsCode),pstr(" ") );
-
- Loop2 = CIF->GetLoop ( CIFCAT_STRUCT_REF );
- if (Loop2) {
- CIFGetString ( database,Loop2,CIFTAG_DB_NAME,Signal,
- sizeof(DBName) ,pstr(" ") );
- CIFGetString ( dbIdCode,Loop2,CIFTAG_DB_CODE,Signal,
- sizeof(DBIdCode),pstr(" ") );
- } else if (CIFMode==CIF_PDBX) {
- Struct2 = CIF->GetStructure ( CIFCAT_STRUCT_REF );
- if (Struct2 &&
- (!CIFGetInteger(ref_id1,Loop1,CIFTAG_REF_ID,Signal)) &&
- (!CIFGetInteger(ref_id2,Struct2,CIFTAG_ID,False))) {
- if (ref_id1==ref_id2) {
- CIFGetString ( database,Struct2,CIFTAG_DB_NAME,
- sizeof(DBName) ,pstr(" ") ,False );
- CIFGetString ( dbIdCode,Struct2,CIFTAG_DB_CODE,
- sizeof(DBIdCode),pstr(" "),False );
- }
- }
- }
-
- Signal++;
-
-}
-
-
-int CDBReference::ConvertPDBASCII ( cpstr S ) {
-IDCode idCode;
- if (Chain->chainID[0]) {
- if (S[12]!=Chain->chainID[0])
- return Error_WrongChainID;
- } else if (S[12]!=' ') {
- Chain->chainID[0] = S[12];
- Chain->chainID[1] = char(0);
- } else
- Chain->chainID[0] = char(0);
- strcpy ( idCode,Chain->GetEntryID() );
- if (idCode[0]) {
- if (strncmp(&(S[7]),idCode,4) && (!ignoreNonCoorPDBErrors))
- return Error_WrongEntryID;
- } else {
- GetString ( idCode,&(S[7]),4 );
- Chain->SetEntryID ( idCode );
- }
- GetIntIns ( seqBeg,insBeg,&(S[14]),4 );
- GetIntIns ( seqEnd,insEnd,&(S[20]),4 );
- strcpy_ncs ( database ,&(S[26]),6 );
- strcpy_ncs ( dbAccession ,&(S[33]),8 );
- strcpy_ncs ( dbIdCode ,&(S[42]),12 );
- GetIntIns ( dbseqBeg,dbinsBeg,&(S[55]),5 );
- GetIntIns ( dbseqEnd,dbinsEnd,&(S[62]),5 );
- return 0;
-}
-
-void CDBReference::Copy ( PCContainerClass DBRef ) {
-
- CContainerChain::Copy ( DBRef );
-
- seqBeg = PCDBReference(DBRef)->seqBeg;
- seqEnd = PCDBReference(DBRef)->seqEnd;
- dbseqBeg = PCDBReference(DBRef)->dbseqBeg;
- dbseqEnd = PCDBReference(DBRef)->dbseqEnd;
- strcpy ( insBeg ,PCDBReference(DBRef)->insBeg );
- strcpy ( insEnd ,PCDBReference(DBRef)->insEnd );
- strcpy ( database ,PCDBReference(DBRef)->database );
- strcpy ( dbAccession,PCDBReference(DBRef)->dbAccession );
- strcpy ( dbIdCode ,PCDBReference(DBRef)->dbIdCode );
- strcpy ( dbinsBeg ,PCDBReference(DBRef)->dbinsBeg );
- strcpy ( dbinsEnd ,PCDBReference(DBRef)->dbinsEnd );
-
-}
-
-void CDBReference::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &seqBeg );
- f.WriteInt ( &seqEnd );
- f.WriteInt ( &dbseqBeg );
- f.WriteInt ( &dbseqEnd );
- f.WriteTerLine ( insBeg ,False );
- f.WriteTerLine ( insEnd ,False );
- f.WriteTerLine ( database ,False );
- f.WriteTerLine ( dbAccession,False );
- f.WriteTerLine ( dbIdCode ,False );
- f.WriteTerLine ( dbinsBeg ,False );
- f.WriteTerLine ( dbinsEnd ,False );
-}
-
-void CDBReference::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- f.ReadInt ( &seqBeg );
- f.ReadInt ( &seqEnd );
- f.ReadInt ( &dbseqBeg );
- f.ReadInt ( &dbseqEnd );
- f.ReadTerLine ( insBeg ,False );
- f.ReadTerLine ( insEnd ,False );
- f.ReadTerLine ( database ,False );
- f.ReadTerLine ( dbAccession,False );
- f.ReadTerLine ( dbIdCode ,False );
- f.ReadTerLine ( dbinsBeg ,False );
- f.ReadTerLine ( dbinsEnd ,False );
-}
-
-MakeStreamFunctions(CDBReference)
-
-
-
-// ================ CSeqAdv ===================
-
-CSeqAdv::CSeqAdv() : CContainerChain() {
- InitSeqAdv();
-}
-
-CSeqAdv::CSeqAdv ( PCChain Chain_Owner )
- : CContainerChain(Chain_Owner) {
- InitSeqAdv();
-}
-
-CSeqAdv::CSeqAdv ( PCChain Chain_Owner, cpstr S )
- : CContainerChain(Chain_Owner) {
- InitSeqAdv();
- ConvertPDBASCII ( S );
-}
-
-CSeqAdv::CSeqAdv ( RPCStream Object ) : CContainerChain(Object) {
- InitSeqAdv();
-}
-
-CSeqAdv::~CSeqAdv() {
- if (conflict) delete[] conflict;
-}
-
-void CSeqAdv::InitSeqAdv() {
- strcpy ( resName ,"---" );
- seqNum = 0;
- strcpy ( insCode ,"-" );
- strcpy ( database ,"------" );
- strcpy ( dbAccession,"---------" );
- strcpy ( dbRes ,"---" );
- dbSeq = 0;
- conflict = NULL;
- CreateCopy ( conflict,pstr(" ") );
-}
-
-void CSeqAdv::PDBASCIIDump ( pstr S, int N ) {
-UNUSED_ARGUMENT(N);
-// makes the ASCII PDB SEQADV line number N
-// from the class' data
- strcpy ( S,"SEQADV" );
- PadSpaces ( S,80 );
- strcpy_n ( &(S[7]) ,Chain->GetEntryID(),4 );
- strcpy_n ( &(S[12]),resName ,3 );
- if (Chain->chainID[0]) S[16] = Chain->chainID[0];
- PutIntIns ( &(S[18]),seqNum,4,insCode );
- strcpy_n ( &(S[24]),database ,4 );
- strcpy_n ( &(S[29]),dbAccession,9 );
- strcpy_n ( &(S[39]),dbRes ,3 );
- PutInteger ( &(S[43]),dbSeq ,5 );
- strcpy_n ( &(S[49]),conflict,IMin(strlen(conflict),21) );
-}
-
-int CSeqAdv::ConvertPDBASCII ( cpstr S ) {
-IDCode idCode;
- if (Chain->chainID[0]) {
- if (S[16]!=Chain->chainID[0])
- return Error_WrongChainID;
- } else if (S[16]!=' ') {
- Chain->chainID[0] = S[16];
- Chain->chainID[1] = char(0);
- } else
- Chain->chainID[0] = char(0);
- strcpy ( idCode,Chain->GetEntryID() );
- if (idCode[0]) {
- if (strncmp(&(S[7]),idCode,4) && (!ignoreNonCoorPDBErrors))
- return Error_WrongEntryID;
- } else {
- GetString ( idCode,&(S[7]),4 );
- Chain->SetEntryID ( idCode );
- }
- strcpy_ncs ( resName ,&(S[12]),3 );
- GetIntIns ( seqNum,insCode,&(S[18]),4 );
- strcpy_ncs ( database ,&(S[24]),4 );
- strcpy_ncs ( dbAccession ,&(S[29]),9 );
- strcpy_ncs ( dbRes ,&(S[39]),3 );
- GetInteger ( dbSeq,&(S[43]),5 );
- CreateCopy ( conflict,&(S[49]) );
- CutSpaces ( conflict,SCUTKEY_END );
- return 0;
-}
-
-
-void CSeqAdv::MakeCIF ( PCMMCIFData CIF, int N ) {
-UNUSED_ARGUMENT(N);
-PCMMCIFLoop Loop;
-int RC;
-
- RC = CIF->AddLoop ( CIFCAT_STRUCT_REF_SEQ_DIF,Loop );
-
- if (RC!=CIFRC_Ok) {
- // the category was (re)created, provide tags
- Loop->AddLoopTag ( CIFTAG_NDB_PDB_ID_CODE );
- Loop->AddLoopTag ( CIFTAG_MON_ID );
- Loop->AddLoopTag ( CIFTAG_NDB_PDB_CHAIN_ID );
- Loop->AddLoopTag ( CIFTAG_SEQ_NUM );
- Loop->AddLoopTag ( CIFTAG_NDB_PDB_INS_CODE );
- Loop->AddLoopTag ( CIFTAG_NDB_SEQ_DB_NAME );
- Loop->AddLoopTag ( CIFTAG_NDB_SEQ_DB_ACCESSION_CODE );
- Loop->AddLoopTag ( CIFTAG_DB_MON_ID );
- Loop->AddLoopTag ( CIFTAG_NDB_SEQ_DB_SEQ_NUM );
- Loop->AddLoopTag ( CIFTAG_DETAILS );
- }
-
- Loop->AddString ( Chain->GetEntryID(),True );
- Loop->AddString ( resName ,True );
- Loop->AddString ( Chain->chainID ,True );
- Loop->AddInteger ( seqNum );
- Loop->AddString ( insCode ,True );
- Loop->AddString ( database ,True );
- Loop->AddString ( dbAccession ,True );
- Loop->AddString ( dbRes ,True );
- Loop->AddInteger ( dbSeq );
- Loop->AddString ( conflict ,True );
-
-}
-
-void CSeqAdv::GetCIF ( PCMMCIFData CIF, int & Signal ) {
-// GetCIF(..) must be always run without reference to Chain,
-// see CModel::GetCIF(..).
-PCMMCIFLoop Loop;
-pstr F;
-int RC;
-
- Loop = CIF->GetLoop ( CIFCAT_STRUCT_REF_SEQ_DIF );
- if (!Loop) {
- Signal = -1;
- return;
- }
-
- if (Signal>=Loop->GetLoopLength()) {
- Signal = -1;
- return;
- }
-
- // Determine the ChainID first and store it locally. It will
- // be used by CModel for generating chains and placing the
- // primary structure data BEFORE reading the coordinate section.
-
- F = Loop->GetString ( CIFTAG_NDB_PDB_CHAIN_ID,Signal,RC );
- if ((!RC) && F) {
- strcpy_n0 ( chainID,F,sizeof(ChainID)-1 );
- Loop->DeleteField ( CIFTAG_NDB_PDB_CHAIN_ID,Signal );
- } else
- strcpy ( chainID,"" );
-
- CIFGetString ( resName,Loop,CIFTAG_MON_ID,Signal,sizeof(ResName),
- pstr("UNK") );
-
- CIFGetIntegerD ( seqNum,Loop,CIFTAG_SEQ_NUM );
-
- CIFGetString ( insCode,Loop,CIFTAG_NDB_PDB_INS_CODE,
- Signal,sizeof(InsCode),pstr(" ") );
-
- CIFGetString ( database,Loop,CIFTAG_NDB_SEQ_DB_NAME,Signal,
- sizeof(DBName),pstr(" ") );
-
- CIFGetString ( dbAccession,Loop,CIFTAG_NDB_SEQ_DB_ACCESSION_CODE,
- Signal,sizeof(DBAcCode),pstr(" ") );
-
- CIFGetString ( dbRes,Loop,CIFTAG_DB_MON_ID,Signal,sizeof(ResName),
- pstr(" ") );
-
- CIFGetIntegerD ( dbSeq,Loop,CIFTAG_NDB_SEQ_DB_SEQ_NUM );
-// if (CIFGetInteger1(dbSeq,Loop,CIFTAG_NDB_SEQ_DB_SEQ_NUM,Signal))
-// dbSeq = MinInt4;
-
- F = Loop->GetString ( CIFTAG_DETAILS,Signal,RC );
- if ((!RC) && F) {
- CreateCopy ( conflict,F );
- Loop->DeleteField ( CIFTAG_DETAILS,Signal );
- } else
- CreateCopy ( conflict,pstr(" ") );
-
- Signal++;
-
-}
-
-void CSeqAdv::Copy ( PCContainerClass SeqAdv ) {
-
- CContainerClass::Copy ( SeqAdv );
-
- seqNum = PCSeqAdv(SeqAdv)->seqNum;
- dbSeq = PCSeqAdv(SeqAdv)->dbSeq;
- strcpy ( resName ,PCSeqAdv(SeqAdv)->resName );
- strcpy ( insCode ,PCSeqAdv(SeqAdv)->insCode );
- strcpy ( database ,PCSeqAdv(SeqAdv)->database );
- strcpy ( dbAccession,PCSeqAdv(SeqAdv)->dbAccession );
- strcpy ( dbRes ,PCSeqAdv(SeqAdv)->dbRes );
- CreateCopy ( conflict,PCSeqAdv(SeqAdv)->conflict );
-
-}
-
-void CSeqAdv::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &seqNum );
- f.WriteInt ( &dbSeq );
- f.WriteTerLine ( resName ,False );
- f.WriteTerLine ( insCode ,False );
- f.WriteTerLine ( database ,False );
- f.WriteTerLine ( dbAccession,False );
- f.WriteTerLine ( dbRes ,False );
- f.CreateWrite ( conflict );
-}
-
-void CSeqAdv::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- f.ReadInt ( &seqNum );
- f.ReadInt ( &dbSeq );
- f.ReadTerLine ( resName ,False );
- f.ReadTerLine ( insCode ,False );
- f.ReadTerLine ( database ,False );
- f.ReadTerLine ( dbAccession,False );
- f.ReadTerLine ( dbRes ,False );
- f.CreateRead ( conflict );
-}
-
-MakeStreamFunctions(CSeqAdv)
-
-
-
-// ================ CSeqRes ===================
-
-CSeqRes::CSeqRes() : CStream() {
- InitSeqRes();
-}
-
-CSeqRes::CSeqRes ( RPCStream Object ) : CStream(Object) {
- InitSeqRes();
-}
-
-CSeqRes::~CSeqRes() {
- FreeMemory();
-}
-
-void CSeqRes::SetChain ( PCChain Chain_Owner ) {
- Chain = Chain_Owner;
- if (Chain) strcpy ( chainID,Chain->chainID );
- else strcpy ( chainID,"" );
-}
-
-void CSeqRes::InitSeqRes() {
- Chain = NULL;
- numRes = -1;
- resName = NULL;
- serNum = 0;
- strcpy ( chainID,"" );
-}
-
-void CSeqRes::FreeMemory() {
- if (resName) delete[] resName;
- resName = NULL;
- numRes = -1;
- serNum = 0;
-}
-
-void CSeqRes::PDBASCIIDump ( RCFile f ) {
-// writes the ASCII PDB SEQRES lines into file f
-char S[100];
-int i,k,sN;
- if (numRes<0) return;
- strcpy ( S,"SEQRES" );
- PadSpaces ( S,80 );
- if (Chain->chainID[0])
- S[11] = Chain->chainID[0];
- PutInteger ( &(S[13]),numRes,4 );
- if (resName) {
- i = 0;
- sN = 1;
- while (i<numRes) {
- PutInteger ( &(S[8]),sN,2 );
- k = 19;
- while ((i<numRes) && (k<70)) {
- if (resName[i][0])
- strcpy_n ( &(S[k]),resName[i],3 );
- else strcpy_n ( &(S[k]),pstr(" "),3 );
- i++;
- k += 4;
- }
- while (k<70) {
- strcpy_n ( &(S[k]),pstr(" "),3 );
- k += 4;
- }
- f.WriteLine ( S );
- sN++;
- }
- } else {
- S[9] = '0';
- strcpy_n ( &(S[19]),pstr("UNK"),3 );
- f.WriteLine ( S );
- }
-}
-
-int CSeqRes::ConvertPDBASCII ( cpstr S ) {
-int i,k,sN,nR;
- if (Chain->chainID[0]) {
- if (S[11]!=Chain->chainID[0])
- return Error_WrongChainID;
- } else if (S[11]!=' ') {
- Chain->chainID[0] = S[11];
- Chain->chainID[1] = char(0);
- } else
- Chain->chainID[0] = char(0);
- GetInteger ( sN,&(S[8]) ,2 );
- GetInteger ( nR,&(S[13]),4 );
- if (sN==0) {
- FreeMemory();
- numRes = nR;
- } else {
- serNum++;
- if (sN!=serNum)
- return Error_SEQRES_serNum;
- if (sN==1) {
- FreeMemory();
- resName = new ResName[nR];
- for (i=0;i<nR;i++)
- resName[i][0] = char(0);
- numRes = nR;
- serNum = sN;
- } else if (nR!=numRes)
- return Error_SEQRES_numRes;
- i = 0;
- while ((i<nR) && (resName[i][0])) i++;
- if (i>=nR)
- return Error_SEQRES_extraRes;
- k = 19;
- while ((i<nR) && (k<70)) {
- GetString ( resName[i],&(S[k]),3 );
- if (!strcmp(resName[i]," ")) resName[i][0] = char(0);
- else i++;
- k += 4;
- }
- }
- return 0;
-}
-
-
-void CSeqRes::MakeCIF ( PCMMCIFData CIF ) {
-// Note that CSeqRes only adds sequence to the CIF loop common
-// to all chains. Therefore this loop should be wiped off from
-// CIF structure before putting first sequence into it.
-PCMMCIFLoop Loop;
-int RC,i;
-
- if (numRes<0) return;
-
- RC = CIF->AddLoop ( CIFCAT_NDB_POLY_SEQ_SCHEME,Loop );
- if (RC!=CIFRC_Ok) {
- // the category was (re)created, provide tags
- Loop->AddLoopTag ( CIFTAG_ID );
- Loop->AddLoopTag ( CIFTAG_MON_ID );
- }
-
- if (resName)
- for (i=0;i<numRes;i++) {
- Loop->AddString ( Chain->chainID,True );
- Loop->AddString ( resName[i] ,True );
- }
- else
- for (i=0;i<numRes;i++) {
- Loop->AddString ( Chain->GetEntryID(),True );
- Loop->AddString ( pstr("UNK") ,True );
- }
-
-}
-
-int CSeqRes::GetCIF ( PCMMCIFData CIF ) {
-// Tries to get sequence from the CIF structure. A sequence
-// for first met chain is extracted and then removed from
-// the CIF structure, so that sequential calls will extract
-// all sequencies. Chain ID is stored locally in chainID;
-// reference to parent chain is neither used nor checked.
-// Returns 0 if sequence was extracted and 1 otherwise.
-PCMMCIFLoop Loop;
-ResName * rN;
-ChainID chID;
-pstr F,CHAIN_ID;
-int RC,CIFMode,i,l;
-Boolean isMon;
-
- FreeMemory();
-
- CIFMode = CIF_NDB;
- Loop = CIF->GetLoop ( CIFName(CAT_POLY_SEQ_SCHEME,CIFMode) );
- if (!Loop) {
- CIFMode = CIF_PDBX;
- Loop = CIF->GetLoop ( CIFName(CAT_POLY_SEQ_SCHEME,CIFMode) );
- if (!Loop) return 1;
- }
-
- l = Loop->GetLoopLength();
- if (l<=0) return 1;
-
- rN = new ResName[l];
- chainID[0] = char(1);
- numRes = 0;
- isMon = False;
- CHAIN_ID = CIFName(TAG_SEQ_CHAIN_ID,CIFMode);
- for (i=0;i<l;i++) {
- F = Loop->GetString ( CHAIN_ID,i,RC );
- if (!RC) {
- if (F) strcpy ( chID,F );
- else chID[0] = char(0);
- if (chainID[0]==char(1)) strcpy ( chainID,chID );
- if (!strcmp(chainID,chID)) {
- CIFGetString ( rN[numRes],Loop,CIFTAG_MON_ID,i,
- sizeof(ResName),pstr("UNK") );
- Loop->DeleteField ( CHAIN_ID,i );
- if (strcmp(rN[numRes],"UNK")) isMon = True;
- numRes++;
- }
- }
- }
-
- if (numRes==0) {
- numRes = -1;
- delete[] rN;
- return 1;
- }
-
- if (isMon) {
- resName = new ResName[numRes];
- for (i=0;i<numRes;i++)
- strcpy ( resName[i],rN[i] );
- }
-
- delete[] rN;
-
- return 0;
-
-}
-
-void CSeqRes::Copy ( PCSeqRes SeqRes ) {
-int i;
-
- FreeMemory();
-
- numRes = SeqRes->numRes;
- serNum = SeqRes->serNum;
-
- if (SeqRes->resName) {
- resName = new ResName[numRes];
- for (i=0;i<numRes;i++)
- strcpy ( resName[i],SeqRes->resName[i] );
- }
-
-}
-
-void CSeqRes::write ( RCFile f ) {
-int i;
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &numRes );
- f.WriteInt ( &serNum );
- if (resName) i = 1;
- else i = 0;
- f.WriteInt ( &i );
- if (resName)
- for (i=0;i<numRes;i++)
- f.WriteTerLine ( resName[i],False );
-}
-
-void CSeqRes::read ( RCFile f ) {
-int i;
-byte Version;
- FreeMemory();
- f.ReadByte ( &Version );
- f.ReadInt ( &numRes );
- f.ReadInt ( &serNum );
- f.ReadInt ( &i );
- if (i) {
- resName = new ResName[numRes];
- for (i=0;i<numRes;i++)
- f.ReadTerLine ( resName[i],False );
- }
-}
-
-
-MakeStreamFunctions(CSeqRes)
-
-
-
-// ================ CModRes ===================
-
-CModRes::CModRes() : CContainerChain() {
- InitModRes();
-}
-
-CModRes::CModRes ( PCChain Chain_Owner )
- : CContainerChain(Chain_Owner) {
- InitModRes();
-}
-
-CModRes::CModRes ( PCChain Chain_Owner, cpstr S )
- : CContainerChain(Chain_Owner) {
- InitModRes();
- ConvertPDBASCII ( S );
-}
-
-CModRes::CModRes ( RPCStream Object ) : CContainerChain(Object) {
- InitModRes();
-}
-
-CModRes::~CModRes() {
- if (comment) delete[] comment;
-}
-
-void CModRes::InitModRes() {
- strcpy ( resName,"---" );
- seqNum = 0;
- strcpy ( insCode,"-" );
- comment = NULL;
- CreateCopy ( comment,pstr(" ") );
- strcpy ( stdRes ,"---" );
-}
-
-void CModRes::PDBASCIIDump ( pstr S, int N ) {
-UNUSED_ARGUMENT(N);
-// makes the ASCII PDB MODRES line number N
-// from the class' data
- strcpy ( S,"MODRES" );
- PadSpaces ( S,80 );
- strcpy_n ( &(S[7]) ,Chain->GetEntryID(),4 );
- strcpy_n ( &(S[12]),resName ,3 );
- if (Chain->chainID[0]) S[16] = Chain->chainID[0];
- PutIntIns ( &(S[18]),seqNum,4,insCode );
- strcpy_n ( &(S[24]),stdRes ,3 );
- strcpy_n ( &(S[29]),comment,IMin(strlen(comment),41) );
-}
-
-int CModRes::ConvertPDBASCII ( cpstr S ) {
-IDCode idCode;
- if (Chain->chainID[0]) {
- if (S[16]!=Chain->chainID[0])
- return Error_WrongChainID;
- } else if (S[16]!=' ') {
- Chain->chainID[0] = S[16];
- Chain->chainID[1] = char(0);
- } else
- Chain->chainID[0] = char(0);
- strcpy ( idCode,Chain->GetEntryID() );
- if (idCode[0]) {
- if (strncmp(&(S[7]),idCode,4) && (!ignoreNonCoorPDBErrors))
- return Error_WrongEntryID;
- } else {
- GetString ( idCode,&(S[7]),4 );
- Chain->SetEntryID ( idCode );
- }
- GetString ( resName ,&(S[12]),3 );
- GetIntIns ( seqNum,insCode,&(S[18]),4 );
- GetString ( stdRes ,&(S[24]),3 );
- CreateCopy ( comment ,&(S[29]) );
- CutSpaces ( comment,SCUTKEY_END );
- return 0;
-}
-
-void CModRes::MakeCIF ( PCMMCIFData CIF, int N ) {
-UNUSED_ARGUMENT(CIF);
-UNUSED_ARGUMENT(N);
-/* -- apparently wrong use of _struct_conn, to be revised
-PCMMCIFLoop Loop;
-int RC;
-
- RC = CIF->AddLoop ( CIFCAT_STRUCT_CONN,Loop );
-
- if (RC!=CIFRC_Ok) {
- // the category was (re)created, provide tags
- Loop->AddLoopTag ( CIFTAG_CONN_TYPE_ID );
- Loop->AddLoopTag ( CIFTAG_NDB_PDB_ID );
- Loop->AddLoopTag ( CIFTAG_PTNR1_LABEL_COMP_ID );
- Loop->AddLoopTag ( CIFTAG_PTNR1_LABEL_ASYM_ID );
- Loop->AddLoopTag ( CIFTAG_PTNR1_LABEL_SEQ_ID );
- Loop->AddLoopTag ( CIFTAG_NDB_PTNR1_LABEL_INS_CODE );
- Loop->AddLoopTag ( CIFTAG_NDB_PTNR1_STANDARD_COMP_ID );
- Loop->AddLoopTag ( CIFTAG_DETAILS );
- }
-
- Loop->AddString ( pstr("MODRES") );
- Loop->AddString ( Chain->GetEntryID(),True );
- Loop->AddString ( resName ,True );
- Loop->AddString ( Chain->chainID ,True );
- Loop->AddInteger ( seqNum );
- Loop->AddString ( insCode ,True );
- Loop->AddString ( stdRes ,True );
- Loop->AddString ( comment ,True );
-
-*/
-
-}
-
-void CModRes::GetCIF ( PCMMCIFData CIF, int & Signal ) {
-UNUSED_ARGUMENT(CIF);
-// GetCIF(..) must be always run without reference to Chain,
-// see CModel::GetCIF(..).
-
-/* -- apparently wrong use of _struct_conn, to be revised
-PCMMCIFLoop Loop;
-pstr F;
-int l,RC;
-
- Loop = CIF->GetLoop ( CIFCAT_STRUCT_CONN );
- if (!Loop) {
- Signal = -1;
- return;
- }
-
- l = Loop->GetLoopLength();
- while (Signal<l) {
- F = Loop->GetString ( CIFTAG_CONN_TYPE_ID,Signal,RC );
- if ((!RC) && F) {
- if (!strcmp(F,"MODRES")) break;
- }
- Signal++;
- }
- if (Signal>=l) {
- Signal = -1;
- return;
- }
-
- Loop->DeleteField ( CIFTAG_CONN_TYPE_ID,Signal );
-
- // Determine the ChainID first and store it locally. It will
- // be used by CModel for generating chains and placing the
- // primary structure data BEFORE reading the coordinate section.
- F = Loop->GetString ( CIFTAG_PTNR1_LABEL_ASYM_ID,Signal,RC );
- if ((!RC) && F) {
- strcpy_n0 ( chainID,F,sizeof(ChainID)-1 );
- Loop->DeleteField ( CIFTAG_PTNR1_LABEL_ASYM_ID,Signal );
- } else
- strcpy ( chainID,"" );
-
-
- CIFGetString ( resName,Loop,CIFTAG_PTNR1_LABEL_COMP_ID,Signal,
- sizeof(ResName),pstr("UNK") );
-
- if (CIFGetInteger(seqNum,Loop,CIFTAG_PTNR1_LABEL_SEQ_ID,Signal))
- return;
-
- CIFGetString ( insCode,Loop,CIFTAG_NDB_PTNR1_LABEL_INS_CODE,
- Signal,sizeof(InsCode),pstr(" ") );
-
- CIFGetString ( stdRes,Loop,CIFTAG_NDB_PTNR1_STANDARD_COMP_ID,Signal,
- sizeof(ResName),pstr("UNK") );
-
- F = Loop->GetString ( CIFTAG_DETAILS,Signal,RC );
- if ((!RC) && F) {
- CreateCopy ( comment,F );
- Loop->DeleteField ( CIFTAG_DETAILS,Signal );
- } else
- CreateCopy ( comment,pstr(" ") );
-
- Signal++;
-
-*/
-
- Signal = -1;
-
-}
-
-void CModRes::Copy ( PCContainerClass ModRes ) {
- seqNum = PCModRes(ModRes)->seqNum;
- strcpy ( resName,PCModRes(ModRes)->resName );
- strcpy ( insCode,PCModRes(ModRes)->insCode );
- strcpy ( stdRes ,PCModRes(ModRes)->stdRes );
- CreateCopy ( comment,PCModRes(ModRes)->comment );
-}
-
-void CModRes::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &seqNum );
- f.WriteTerLine ( resName,False );
- f.WriteTerLine ( insCode,False );
- f.WriteTerLine ( stdRes ,False );
- f.CreateWrite ( comment );
-}
-
-void CModRes::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- f.ReadInt ( &seqNum );
- f.ReadTerLine ( resName,False );
- f.ReadTerLine ( insCode,False );
- f.ReadTerLine ( stdRes ,False );
- f.CreateRead ( comment );
-}
-
-MakeStreamFunctions(CModRes)
-
-
-
-// ================ CHetRec ======================
-
-CHetRec::CHetRec() : CContainerChain() {
- InitHetRec();
-}
-
-CHetRec::CHetRec ( PCChain Chain_Owner )
- : CContainerChain(Chain_Owner) {
- InitHetRec();
-}
-
-CHetRec::CHetRec ( PCChain Chain_Owner, cpstr S )
- : CContainerChain(Chain_Owner) {
- InitHetRec();
- ConvertPDBASCII ( S );
-}
-
-CHetRec::CHetRec ( RPCStream Object ) : CContainerChain(Object) {
- InitHetRec();
-}
-
-CHetRec::~CHetRec() {
- if (comment) delete[] comment;
-}
-
-void CHetRec::InitHetRec() {
- strcpy ( hetID ,"---" );
- strcpy ( insCode,"-" );
- seqNum = 0;
- numHetAtoms = 0;
- comment = NULL;
- CreateCopy ( comment,pstr(" ") );
-}
-
-void CHetRec::PDBASCIIDump ( pstr S, int N ) {
-UNUSED_ARGUMENT(N);
-// makes the ASCII PDB MODRES line number N
-// from the class' data
- strcpy ( S,"HET" );
- PadSpaces ( S,80 );
- strcpy_n ( &(S[7]) ,hetID,3 );
- if (Chain->chainID[0]) S[12] = Chain->chainID[0];
- PutIntIns ( &(S[13]),seqNum,4,insCode );
- PutInteger ( &(S[20]),numHetAtoms,5 );
- strcpy_n ( &(S[30]),comment,IMin(strlen(comment),40) );
-}
-
-int CHetRec::ConvertPDBASCII ( cpstr S ) {
- if (Chain->chainID[0]) {
- if (S[12]!=Chain->chainID[0])
- return Error_WrongChainID;
- } else if (S[12]!=' ') {
- Chain->chainID[0] = S[12];
- Chain->chainID[1] = char(0);
- } else
- Chain->chainID[0] = char(0);
- GetString ( hetID ,&(S[7]) ,3 );
- GetIntIns ( seqNum,insCode,&(S[13]),4 );
- GetInteger ( numHetAtoms ,&(S[20]),5 );
- CreateCopy ( comment ,&(S[30]) );
- CutSpaces ( comment,SCUTKEY_END );
- return 0;
-}
-
-void CHetRec::MakeCIF ( PCMMCIFData CIF, int N ) {
-UNUSED_ARGUMENT(N);
-PCMMCIFLoop Loop;
-int RC;
-
- RC = CIF->AddLoop ( CIFCAT_NDB_NONSTANDARD_LIST,Loop );
-
- if (RC!=CIFRC_Ok) {
- // the category was (re)created, provide tags
- Loop->AddLoopTag ( CIFTAG_ID );
- Loop->AddLoopTag ( CIFTAG_AUTH_ASYM_ID );
- Loop->AddLoopTag ( CIFTAG_AUTH_SEQ_ID );
- Loop->AddLoopTag ( CIFTAG_INS_CODE );
- Loop->AddLoopTag ( CIFTAG_NUMBER_ATOMS_NH );
- Loop->AddLoopTag ( CIFTAG_DETAILS );
- }
-
- Loop->AddString ( hetID ,True );
- Loop->AddString ( Chain->chainID,True );
- Loop->AddInteger ( seqNum );
- Loop->AddString ( insCode ,True );
- Loop->AddInteger ( numHetAtoms );
- Loop->AddString ( comment ,True );
-
-}
-
-void CHetRec::GetCIF ( PCMMCIFData CIF, int & Signal ) {
-// GetCIF(..) must be always run without reference to Chain,
-// see CModel::GetCIF(..).
-PCMMCIFLoop Loop;
-pstr F;
-int RC;
-
- Loop = CIF->GetLoop ( CIFCAT_NDB_NONSTANDARD_LIST );
- if (!Loop) {
- Signal = -1;
- return;
- }
-
- if (Signal>=Loop->GetLoopLength()) {
- Signal = -1;
- return;
- }
-
- // Determine the ChainID first and store it locally. It will
- // be used by CModel for generating chains and placing the
- // primary structure data BEFORE reading the coordinate section.
- F = Loop->GetString ( CIFTAG_AUTH_ASYM_ID,Signal,RC );
- if ((!RC) && F) {
- strcpy_n0 ( chainID,F,sizeof(ChainID)-1 );
- Loop->DeleteField ( CIFTAG_AUTH_ASYM_ID,Signal );
- } else
- strcpy ( chainID,"" );
-
-
- CIFGetString ( hetID,Loop,CIFTAG_ID,Signal,sizeof(ResName),
- pstr("UNK") );
-
- if (CIFGetInteger(seqNum,Loop,CIFTAG_AUTH_SEQ_ID,Signal)) return;
-
- CIFGetString ( insCode,Loop,CIFTAG_INS_CODE,Signal,sizeof(InsCode),
- pstr(" ") );
-
- if (CIFGetInteger(numHetAtoms,Loop,CIFTAG_NUMBER_ATOMS_NH,Signal))
- return;
-
- F = Loop->GetString ( CIFTAG_DETAILS,Signal,RC );
- if ((!RC) && F) {
- CreateCopy ( comment,F );
- Loop->DeleteField ( CIFTAG_DETAILS,Signal );
- } else
- CreateCopy ( comment,pstr(" ") );
-
- Signal++;
-
-}
-
-void CHetRec::Copy ( PCContainerClass Het ) {
- seqNum = PCHetRec(Het)->seqNum;
- numHetAtoms = PCHetRec(Het)->numHetAtoms;
- strcpy ( hetID ,PCHetRec(Het)->hetID );
- strcpy ( insCode,PCHetRec(Het)->insCode );
- CreateCopy ( comment,PCHetRec(Het)->comment );
-}
-
-void CHetRec::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &seqNum );
- f.WriteInt ( &numHetAtoms );
- f.WriteTerLine ( hetID ,False );
- f.WriteTerLine ( insCode,False );
- f.CreateWrite ( comment );
-}
-
-void CHetRec::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- f.ReadInt ( &seqNum );
- f.ReadInt ( &numHetAtoms );
- f.ReadTerLine ( hetID ,False );
- f.ReadTerLine ( insCode,False );
- f.CreateRead ( comment );
-}
-
-MakeStreamFunctions(CHetRec)
-
-
-
-// ===================== CChain =======================
-
-CChain::CChain() : CUDData() {
- InitChain();
- SetChain ( pstr("") );
-}
-
-CChain::CChain ( PCProModel Model, const ChainID chID ) : CUDData() {
- InitChain();
- SetChain ( chID );
- if (Model) Model->AddChain ( this );
-}
-
-CChain::CChain ( RPCStream Object ) : CUDData(Object) {
- InitChain();
- SetChain ( pstr("") );
-}
-
-void CChain::InitChain() {
- nResidues = 0;
- ResLen = 0;
- Residue = NULL;
- model = NULL;
- chainID[0] = char(0);
- prevChainID[0] = char(0);
- nWeights = 0;
- Weight = 0.0;
- Exclude = True;
-}
-
-void CChain::SetChain ( const ChainID chID ) {
- strcpy ( chainID,chID );
- if (chID[0]==' ') chainID[0] = char(0);
- DBReference.SetChain ( this );
- SeqAdv .SetChain ( this );
- SeqRes .SetChain ( this );
- ModRes .SetChain ( this );
- Het .SetChain ( this );
-}
-
-void CChain::SetChainID ( const ChainID chID ) {
- strcpy ( chainID,chID );
- if (chID[0]==' ') chainID[0] = char(0);
-}
-
-CChain::~CChain() {
- FreeMemory();
- if (model) model->_ExcludeChain ( chainID );
-}
-
-void CChain::FreeMemory() {
- DeleteAllResidues();
- if (Residue) delete[] Residue;
- ResLen = 0;
- nResidues = 0;
- Residue = NULL;
- FreeAnnotations();
-}
-
-void CChain::FreeAnnotations() {
- DBReference.FreeContainer();
- SeqAdv .FreeContainer();
- SeqRes .FreeMemory ();
- ModRes .FreeContainer();
- Het .FreeContainer();
-}
-
-void CChain::SetModel ( PCProModel Model ) {
- model = Model;
-}
-
-PCMMDBManager CChain::GetCoordHierarchy() {
- if (model) return model->GetCoordHierarchy();
- return NULL;
-}
-
-void CChain::CheckInAtoms() {
-int i;
- if (GetCoordHierarchy())
- for (i=0;i<nResidues;i++)
- if (Residue[i])
- Residue[i]->CheckInAtoms();
-}
-
-int CChain::ConvertDBREF ( cpstr PDBString ) {
-int RC;
-PCContainerChain ContainerChain;
- ContainerChain = new CDBReference(this);
- RC = ContainerChain->ConvertPDBASCII ( PDBString );
- if (RC) {
- delete ContainerChain;
- return RC;
- }
- DBReference.AddData ( ContainerChain );
- return 0;
-}
-
-int CChain::ConvertSEQADV ( cpstr PDBString ) {
-int RC;
-PCContainerChain ContainerChain;
- ContainerChain = new CSeqAdv(this);
- RC = ContainerChain->ConvertPDBASCII ( PDBString );
- if (RC) {
- delete ContainerChain;
- return RC;
- }
- SeqAdv.AddData ( ContainerChain );
- return 0;
-}
-
-int CChain::ConvertSEQRES ( cpstr PDBString ) {
- return SeqRes.ConvertPDBASCII ( PDBString );
-}
-
-int CChain::ConvertMODRES ( cpstr PDBString ) {
-int RC;
-PCContainerChain ContainerChain;
- ContainerChain = new CModRes(this);
- RC = ContainerChain->ConvertPDBASCII ( PDBString );
- if (RC) {
- delete ContainerChain;
- return RC;
- }
- ModRes.AddData ( ContainerChain );
- return 0;
-}
-
-int CChain::ConvertHET ( cpstr PDBString ) {
-int RC;
-PCContainerChain ContainerChain;
- ContainerChain = new CHetRec(this);
- RC = ContainerChain->ConvertPDBASCII ( PDBString );
- if (RC) {
- delete ContainerChain;
- return RC;
- }
- Het.AddData ( ContainerChain );
- return 0;
-}
-
-
-void CChain::PDBASCIIDump ( RCFile f ) {
-// this function was for test purposes and is not used
-// for normal function of MMDB
- DBReference.PDBASCIIDump ( f );
- SeqAdv .PDBASCIIDump ( f );
- SeqRes .PDBASCIIDump ( f );
- ModRes .PDBASCIIDump ( f );
- Het .PDBASCIIDump ( f );
-}
-
-void CChain::PDBASCIIAtomDump ( RCFile f ) {
-int i;
- for (i=0;i<nResidues;i++)
- if (Residue[i])
- Residue[i]->PDBASCIIAtomDump ( f );
-}
-
-void CChain::MakeAtomCIF ( PCMMCIFData CIF ) {
-int i;
- for (i=0;i<nResidues;i++)
- if (Residue[i])
- Residue[i]->MakeAtomCIF ( CIF );
-}
-
-
-int CChain::GetNumberOfResidues() {
- return nResidues;
-}
-
-PCResidue CChain::GetResidue ( int resNo ) {
- if ((0<=resNo) && (resNo<nResidues))
- return Residue[resNo];
- else return NULL;
-}
-
-
-PCResidue CChain::GetResidueCreate ( const ResName resName,
- int seqNum,
- const InsCode insCode,
- Boolean Enforce ) {
-// Returns pointer on residue, whose name, sequence number and
-// insert code are given in resName, seqNum and insCode, respectively.
-// If such a residue is absent in the chain, one is created at
-// the end of the chain.
-int i;
-
- // check if such a residue is already in the chain
- if (insCode[0]) {
- for (i=0;i<nResidues;i++)
- if (Residue[i]) {
- if ((seqNum==Residue[i]->seqNum) &&
- (!strcmp(insCode,Residue[i]->insCode))) {
- if (!strcmp(resName,Residue[i]->name))
- return Residue[i]; // it is there; just return the pointer
- else if (!Enforce)
- return NULL; // duplicate seqNum and insCode!
- }
- }
- } else {
- for (i=0;i<nResidues;i++)
- if (Residue[i]) {
- if ((seqNum==Residue[i]->seqNum) &&
- (!Residue[i]->insCode[0])) {
- if (!strcmp(resName,Residue[i]->name))
- return Residue[i]; // it is there; just return the pointer
- else if (!Enforce)
- return NULL; // duplicate seqNum and insCode!
- }
- }
- }
-
- // expand the residue array, if necessary
- if (nResidues>=ResLen)
- ExpandResidueArray ( 100 );
-
- // create new residue
- Residue[nResidues] = newCResidue();
- Residue[nResidues]->SetChain ( this );
- Residue[nResidues]->SetResID ( resName,seqNum,insCode );
- Residue[nResidues]->index = nResidues;
- nResidues++;
-
- return Residue[nResidues-1];
-
-}
-
-void CChain::ExpandResidueArray ( int inc ) {
-PPCResidue Residue1;
-int i;
- ResLen += inc;
- Residue1 = new PCResidue[ResLen];
- for (i=0;i<nResidues;i++)
- Residue1[i] = Residue[i];
- if (Residue) delete[] Residue;
- Residue = Residue1;
- for (i=nResidues;i<ResLen;i++)
- Residue[i] = NULL;
-}
-
-PCResidue CChain::GetResidue ( int seqNum, const InsCode insCode ) {
-// Returns pointer on residue, whose sequence number and
-// insert code are given in seqNum and insCode, respectively.
-// If such a residue is absent in the chain, returns NULL.
-int i;
-Boolean isInsCode;
- if (insCode) isInsCode = insCode[0]!=char(0);
- else isInsCode = False;
- if (isInsCode) {
- for (i=0;i<nResidues;i++)
- if (Residue[i]) {
- if ((seqNum==Residue[i]->seqNum) &&
- (!strcmp(insCode,Residue[i]->insCode)))
- return Residue[i];
- }
- } else {
- for (i=0;i<nResidues;i++)
- if (Residue[i]) {
- if ((seqNum==Residue[i]->seqNum) && (!Residue[i]->insCode[0]))
- return Residue[i];
- }
- }
- return NULL;
-}
-
-int CChain::GetResidueNo ( int seqNum, const InsCode insCode ) {
-// GetResidueNo(..) returns the residue number in the chain's
-// residues table. Residues are numbered as 0..nres-1 as they appear
-// in the coordinate file.
-// If residue is not found, the function returns -1.
-int i;
-Boolean isInsCode;
- if (insCode) isInsCode = insCode[0]!=char(0);
- else isInsCode = False;
- if (isInsCode) {
- for (i=0;i<nResidues;i++)
- if (Residue[i]) {
- if ((seqNum==Residue[i]->seqNum) &&
- (!strcmp(insCode,Residue[i]->insCode)))
- return i;
- }
- } else {
- for (i=0;i<nResidues;i++)
- if (Residue[i]) {
- if ((seqNum==Residue[i]->seqNum) && (!Residue[i]->insCode[0]))
- return i;
- }
- }
- return -1;
-}
-
-void CChain::GetResidueTable ( PPCResidue & resTable,
- int & NumberOfResidues ) {
- resTable = Residue;
- NumberOfResidues = nResidues;
-}
-
-int CChain::_ExcludeResidue ( const ResName resName, int seqNum,
- const InsCode insCode ) {
-// ExcludeResidue(..) excludes (but does not dispose!) a residue
-// from the chain. Returns 1 if the chain gets empty and 0 otherwise.
-int i,k;
-
- if (!Exclude) return 0;
-
- // find the residue
- k = -1;
- for (i=0;(i<nResidues) && (k<0);i++)
- if ((seqNum==Residue[i]->seqNum) &&
- (!strcmp(insCode,Residue[i]->insCode)) &&
- (!strcmp(resName,Residue[i]->name)))
- k = i;
-
- if (k>=0) {
- for (i=k+1;i<nResidues;i++) {
- Residue[i-1] = Residue[i];
- if (Residue[i-1])
- Residue[i-1]->index = i-1;
- }
- nResidues--;
- Residue[nResidues] = NULL;
- }
-
- if (nResidues<=0) return 1;
- else return 0;
-
-}
-
-
-
-// ------------------ Deleting residues --------------------------
-
-int CChain::DeleteResidue ( int resNo ) {
- if ((0<=resNo) && (resNo<nResidues)) {
- if (Residue[resNo]) {
- Exclude = False;
- delete Residue[resNo];
- Residue[resNo] = NULL;
- Exclude = True;
- return 1;
- }
- }
- return 0;
-}
-
-int CChain::DeleteResidue ( int seqNum, const InsCode insCode ) {
-int i;
- if (insCode[0]) {
- for (i=0;i<nResidues;i++)
- if (Residue[i]) {
- if ((seqNum==Residue[i]->seqNum) &&
- (!strcmp(insCode,Residue[i]->insCode))) {
- Exclude = False;
- delete Residue[i];
- Residue[i] = NULL;
- Exclude = True;
- return 1;
- }
- }
- } else {
- for (i=0;i<nResidues;i++)
- if (Residue[i]) {
- if ((seqNum==Residue[i]->seqNum) && (!Residue[i]->insCode[0])) {
- Exclude = False;
- delete Residue[i];
- Residue[i] = NULL;
- Exclude = True;
- return 1;
- }
- }
- }
- return 0;
-}
-
-
-int CChain::DeleteAllResidues() {
-int i,k;
- Exclude = False;
- k = 0;
- for (i=0;i<nResidues;i++)
- if (Residue[i]) {
- delete Residue[i];
- Residue[i] = NULL;
- k++;
- }
- nResidues = 0;
- Exclude = True;
- return k;
-}
-
-
-int CChain::DeleteSolvent() {
-int i,k;
- Exclude = False;
- k = 0;
- for (i=0;i<nResidues;i++)
- if (Residue[i]) {
- if (Residue[i]->isSolvent()) {
- delete Residue[i];
- Residue[i] = NULL;
- k++;
- }
- }
- Exclude = True;
- return k;
-}
-
-
-void CChain::TrimResidueTable() {
-int i,j;
- Exclude = False;
- j = 0;
- for (i=0;i<nResidues;i++)
- if (Residue[i]) {
- if (Residue[i]->nAtoms>0) {
- if (j<i) {
- Residue[j] = Residue[i];
- Residue[j]->index = j;
- Residue[i] = NULL;
- }
- j++;
- } else {
- delete Residue[i];
- Residue[i] = NULL;
- }
- }
- nResidues = j;
- Exclude = True;
-}
-
-int CChain::AddResidue ( PCResidue res ) {
-// modify both CModel::Copy methods simultaneously!
-//
-// Copy(PCModel,PPCAtom,int&) copies atoms into array 'atom'
-// starting from position atom_index. 'atom' should be able to
-// accept all new atoms - no checks on the length of 'atom'
-// is being made. This function should not be used in applications.
- return InsResidue ( res,nResidues );
-}
-
-/*
-PCMMDBFile mmdbfile;
-PCChain chain1;
-int i;
-
- for (i=0;i<nResidues;i++)
- if (Residue[i]==res) return -i; // this residue is already there
-
- if (res) {
-
- mmdbfile = PCMMDBFile(GetCoordHierarchy());
-
- // get space for new residue
- if (nResidues>=ResLen)
- ExpandResidueArray ( 100 );
-
- if (res->GetCoordHierarchy()) {
- Residue[nResidues] = newCResidue();
- Residue[nResidues]->SetChain ( this );
- Residue[nResidues]->SetResID ( res->name,res->seqNum,res->insCode );
- if (mmdbfile) {
- // get space for new atoms
- mmdbfile->AddAtomArray ( res->GetNumberOfAtoms(True) );
- Residue[nResidues]->Copy ( res,mmdbfile->Atom,mmdbfile->nAtoms );
- } else {
- for (i=0;i<res->nAtoms;i++)
- Residue[nResidues]->AddAtom ( res->atom[i] );
- }
- } else {
- Residue[nResidues] = res;
- chain1 = res->GetChain();
- if (chain1)
- for (i=0;i<chain1->nResidues;i++)
- if (chain1->Residue[i]==res) {
- chain1->Residue[i] = NULL;
- break;
- }
- Residue[nResidues]->SetChain ( this );
- if (mmdbfile)
- Residue[nResidues]->CheckInAtoms();
- }
- nResidues++;
-
- }
-
- return nResidues;
-
-}
-*/
-
-int CChain::InsResidue ( PCResidue res, int seqNum,
- const InsCode insCode ) {
- return InsResidue ( res,GetResidueNo(seqNum,insCode) );
-}
-
-int CChain::InsResidue ( PCResidue res, int pos ) {
-// Inserts residue res onto position pos of the chain,
-// pos=0..nResidues-1 . Residues pos..nResidues-1 are
-// shifted up the chain.
-// The function places new atoms on the top of atom
-// index. It is advisable to call
-// CMMDBFile::PDBCleanup ( PDBCLEAN_INDEX ) after all
-// insertions are done.
-PCMMDBFile mmdbfile;
-PCChain chain1;
-int i,pp;
-
- pp = IMax ( 0,IMin(nResidues,pos) );
-
- for (i=0;i<nResidues;i++)
- if (Residue[i]==res) return -i; // this residue is already there
-
- if (res) {
-
- mmdbfile = PCMMDBFile(GetCoordHierarchy());
-
- // get space for new residue
- if (nResidues>=ResLen)
- ExpandResidueArray ( 100 );
-
- // shift residues to the end of the chain as necessary
- for (i=nResidues;i>pp;i--)
- Residue[i] = Residue[i-1];
-
- // insert the new residue
- if (res->GetCoordHierarchy()) {
- Residue[pp] = newCResidue();
- Residue[pp]->SetChain ( this );
- Residue[pp]->SetResID ( res->name,res->seqNum,res->insCode );
- if (mmdbfile) {
- // get space for new atoms
- mmdbfile->AddAtomArray ( res->GetNumberOfAtoms(True) );
- Residue[pp]->_copy ( res,mmdbfile->Atom,mmdbfile->nAtoms );
- } else {
- for (i=0;i<res->nAtoms;i++)
- Residue[pp]->AddAtom ( res->atom[i] );
- }
- } else {
- Residue[pp] = res;
- chain1 = res->GetChain();
- if (chain1)
- for (i=0;i<chain1->nResidues;i++)
- if (chain1->Residue[i]==res) {
- chain1->Residue[i] = NULL;
- break;
- }
- Residue[pp]->SetChain ( this );
- if (mmdbfile)
- Residue[pp]->CheckInAtoms();
- }
- nResidues++;
-
- }
-
- return nResidues;
-
-}
-
-
-// -------------------- Extracting atoms -----------------------
-
-int CChain::GetNumberOfAtoms ( Boolean countTers ) {
-int i,na;
- na = 0;
- for (i=0;i<nResidues;i++)
- if (Residue[i]) na += Residue[i]->GetNumberOfAtoms ( countTers );
- return na;
-}
-
-int CChain::GetNumberOfAtoms ( int seqNo, const InsCode insCode ) {
-PCResidue res;
- res = GetResidue ( seqNo,insCode );
- if (res) return res->nAtoms;
- return 0;
-}
-
-int CChain::GetNumberOfAtoms ( int resNo ) {
- if ((0<=resNo) && (resNo<nResidues)) {
- if (Residue[resNo]) return Residue[resNo]->nAtoms;
- }
- return 0;
-}
-
-PCAtom CChain::GetAtom ( int seqNo,
- const InsCode insCode,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc ) {
-PCResidue res;
- res = GetResidue ( seqNo,insCode );
- if (res) return res->GetAtom ( aname,elmnt,aloc );
- return NULL;
-}
-
-PCAtom CChain::GetAtom ( int seqNo, const InsCode insCode,
- int atomNo ) {
-PCResidue res;
- res = GetResidue ( seqNo,insCode );
- if (res) {
- if ((0<=atomNo) && (atomNo<res->nAtoms))
- return res->atom[atomNo];
- }
- return NULL;
-}
-
-PCAtom CChain::GetAtom ( int resNo,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc ) {
- if ((0<=resNo) && (resNo<nResidues)) {
- if (Residue[resNo])
- return Residue[resNo]->GetAtom ( aname,elmnt,aloc );
- }
- return NULL;
-}
-
-PCAtom CChain::GetAtom ( int resNo, int atomNo ) {
-PCResidue res;
- if ((0<=resNo) && (resNo<nResidues)) {
- res = Residue[resNo];
- if (res) {
- if ((0<=atomNo) && (atomNo<res->nAtoms))
- return res->atom[atomNo];
- }
- }
- return NULL;
-}
-
-void CChain::GetAtomTable ( int seqNo, const InsCode insCode,
- PPCAtom & atomTable, int & NumberOfAtoms ) {
-PCResidue res;
- atomTable = NULL;
- NumberOfAtoms = 0;
- res = GetResidue ( seqNo,insCode );
- if (res) {
- atomTable = res->atom;
- NumberOfAtoms = res->nAtoms;
- }
-}
-
-void CChain::GetAtomTable ( int resNo, PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- atomTable = NULL;
- NumberOfAtoms = 0;
- if ((0<=resNo) && (resNo<nResidues)) {
- res = Residue[resNo];
- if (res) {
- atomTable = res->atom;
- NumberOfAtoms = res->nAtoms;
- }
- }
-}
-
-
-void CChain::GetAtomTable1 ( int seqNo, const InsCode insCode,
- PPCAtom & atomTable, int & NumberOfAtoms ) {
-PCResidue res;
- res = GetResidue ( seqNo,insCode );
- if (res)
- res->GetAtomTable1 ( atomTable,NumberOfAtoms );
- else {
- if (atomTable) delete[] atomTable;
- atomTable = NULL;
- NumberOfAtoms = 0;
- }
-}
-
-void CChain::GetAtomTable1 ( int resNo, PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- if ((0<=resNo) && (resNo<nResidues))
- res = Residue[resNo];
- else res = NULL;
- if (res)
- res->GetAtomTable1 ( atomTable,NumberOfAtoms );
- else {
- if (atomTable) delete[] atomTable;
- atomTable = NULL;
- NumberOfAtoms = 0;
- }
-}
-
-int CChain::DeleteAtom ( int seqNo,
- const InsCode insCode,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc ) {
-PCResidue res;
- res = GetResidue ( seqNo,insCode );
- if (res) return res->DeleteAtom ( aname,elmnt,aloc );
- return 0;
-}
-
-int CChain::DeleteAtom ( int seqNo, const InsCode insCode,
- int atomNo ) {
-PCResidue res;
- res = GetResidue ( seqNo,insCode );
- if (res) return res->DeleteAtom ( atomNo );
- return 0;
-}
-
-int CChain::DeleteAtom ( int resNo,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc ) {
- if ((0<=resNo) && (resNo<nResidues)) {
- if (Residue[resNo])
- return Residue[resNo]->DeleteAtom ( aname,elmnt,aloc );
- }
- return 0;
-}
-
-int CChain::DeleteAtom ( int resNo, int atomNo ) {
- if ((0<=resNo) && (resNo<nResidues)) {
- if (Residue[resNo])
- return Residue[resNo]->DeleteAtom ( atomNo );
- }
- return 0;
-}
-
-
-int CChain::DeleteAllAtoms ( int seqNo, const InsCode insCode ) {
-PCResidue res;
- res = GetResidue ( seqNo,insCode );
- if (res) return res->DeleteAllAtoms();
- return 0;
-}
-
-int CChain::DeleteAllAtoms ( int resNo ) {
- if ((0<=resNo) && (resNo<nResidues)) {
- if (Residue[resNo])
- return Residue[resNo]->DeleteAllAtoms();
- }
- return 0;
-}
-
-int CChain::DeleteAllAtoms() {
-int i,k;
- k = 0;
- for (i=0;i<nResidues;i++)
- if (Residue[i])
- k += Residue[i]->DeleteAllAtoms();
- return k;
-}
-
-int CChain::DeleteAltLocs() {
-// This function leaves only alternative location with maximal
-// occupancy, if those are equal or unspecified, the one with
-// "least" alternative location indicator.
-// The function returns the number of deleted. All tables remain
-// untrimmed, so that explicit trimming or calling FinishStructEdit()
-// is required.
-int i,n;
-
- n = 0;
- for (i=0;i<nResidues;i++)
- if (Residue[i]) n += Residue[i]->DeleteAltLocs();
-
- return n;
-
-}
-
-
-int CChain::AddAtom ( int seqNo, const InsCode insCode,
- PCAtom atom ) {
-PCResidue res;
- res = GetResidue ( seqNo,insCode );
- if (res) return res->AddAtom ( atom );
- return 0;
-}
-
-int CChain::AddAtom ( int resNo, PCAtom atom ) {
- if ((0<=resNo) && (resNo<nResidues)) {
- if (Residue[resNo])
- return Residue[resNo]->AddAtom ( atom );
- }
- return 0;
-}
-
-
-void CChain::Copy ( PCChain Chain ) {
-// modify both CChain::_copy and CChain::Copy methods simultaneously!
-int i;
-
- FreeMemory();
-
- if (Chain) {
-
- CopyAnnotations ( Chain );
-
- nResidues = Chain->nResidues;
- ResLen = nResidues;
- if (nResidues>0) {
- Residue = new PCResidue[nResidues];
- for (i=0;i<nResidues;i++) {
- Residue[i] = newCResidue();
- Residue[i]->SetChain ( this );
- Residue[i]->Copy ( Chain->Residue[i] );
- }
- }
-
- }
-
-}
-
-void CChain::CopyAnnotations ( PCChain Chain ) {
- if (Chain) {
- strcpy ( chainID ,Chain->chainID );
- strcpy ( prevChainID,Chain->prevChainID );
- DBReference.Copy ( &(Chain->DBReference) );
- SeqAdv .Copy ( &(Chain->SeqAdv) ); // SEQADV records
- SeqRes .Copy ( &(Chain->SeqRes) ); // SEQRES data
- ModRes .Copy ( &(Chain->ModRes) ); // MODRES records
- Het .Copy ( &(Chain->Het) ); // HET records
- }
-}
-
-
-void CChain::_copy ( PCChain Chain ) {
-// modify both CChain::_copy and CChain::Copy methods simultaneously!
-int i;
-
- FreeMemory();
-
- strcpy ( chainID ,Chain->chainID );
- strcpy ( prevChainID,Chain->prevChainID );
-
- DBReference.Copy ( &(Chain->DBReference) );
- SeqAdv .Copy ( &(Chain->SeqAdv) ); // SEQADV records
- SeqRes .Copy ( &(Chain->SeqRes) ); // SEQRES data
- ModRes .Copy ( &(Chain->ModRes) ); // MODRES records
- Het .Copy ( &(Chain->Het) ); // HET records
-
- nResidues = Chain->nResidues;
- ResLen = nResidues;
- if (nResidues>0) {
- Residue = new PCResidue[nResidues];
- for (i=0;i<nResidues;i++) {
- Residue[i] = newCResidue();
- Residue[i]->SetChain ( this );
- Residue[i]->_copy ( Chain->Residue[i] );
- }
- }
-
-}
-
-void CChain::_copy ( PCChain Chain, PPCAtom atom, int & atom_index ) {
-// modify both CChain::_copy and CChain::Copy methods simultaneously!
-int i;
-
- FreeMemory();
-
- strcpy ( chainID ,Chain->chainID );
- strcpy ( prevChainID,Chain->prevChainID );
-
- DBReference.Copy ( &(Chain->DBReference) );
- SeqAdv .Copy ( &(Chain->SeqAdv) ); // SEQADV records
- SeqRes .Copy ( &(Chain->SeqRes) ); // SEQRES data
- ModRes .Copy ( &(Chain->ModRes) ); // MODRES records
- Het .Copy ( &(Chain->Het) ); // HET records
-
- nResidues = Chain->nResidues;
- ResLen = nResidues;
- if (nResidues>0) {
- Residue = new PCResidue[nResidues];
- for (i=0;i<nResidues;i++)
- if (Chain->Residue[i]) {
- Residue[i] = newCResidue();
- Residue[i]->SetChain ( this );
- Residue[i]->_copy ( Chain->Residue[i],atom,atom_index );
- } else
- Residue[i] = NULL;
- }
-
-}
-
-/*
-void CChain::Duplicate ( PCChain Chain ) {
-int i;
-
- FreeMemory();
-
- strcpy ( chainID ,Chain->chainID );
- strcpy ( prevChainID,Chain->prevChainID );
-
- DBReference.Copy ( &(Chain->DBReference) );
- SeqAdv .Copy ( &(Chain->SeqAdv) ); // SEQADV records
- SeqRes .Copy ( &(Chain->SeqRes) ); // SEQRES data
- ModRes .Copy ( &(Chain->ModRes) ); // MODRES records
- Het .Copy ( &(Chain->Het) ); // HET records
-
- nResidues = Chain->nResidues;
- ResLen = nResidues;
- if (nResidues>0) {
- Residue = new PCResidue[nResidues];
- for (i=0;i<nResidues;i++) {
- Residue[i] = newCResidue();
- Residue[i]->SetChain ( this );
- Residue[i]->Duplicate ( Chain->Residue[i] );
- }
- }
-
-}
-*/
-
-cpstr CChain::GetEntryID() {
- if (model) return model->GetEntryID();
- else return pstr("");
-}
-
-void CChain::SetEntryID ( const IDCode idCode ) {
- if (model) model->SetEntryID ( idCode );
-}
-
-int CChain::GetModelNum() {
- if (model) return model->GetSerNum();
- return 0;
-}
-
-cpstr CChain::GetChainID ( pstr ChID ) {
- ChID[0] = char(0);
- if (model)
- sprintf ( ChID,"/%i/",model->GetSerNum() );
- else strcpy ( ChID,"/-/" );
- strcat ( ChID,chainID );
- return ChID;
-}
-
-
-void CChain::GetAtomStatistics ( RSAtomStat AS ) {
- AS.Init();
- CalcAtomStatistics ( AS );
- AS.Finish();
-}
-
-void CChain::CalcAtomStatistics ( RSAtomStat AS ) {
-int i;
- for (i=0;i<nResidues;i++)
- if (Residue[i])
- Residue[i]->CalcAtomStatistics ( AS );
-}
-
-void CChain::ApplyTransform ( mat44 & TMatrix ) {
-// transforms all coordinates by multiplying with matrix TMatrix
-int i;
- for (i=0;i<nResidues;i++)
- if (Residue[i]) Residue[i]->ApplyTransform ( TMatrix );
-}
-
-Boolean CChain::isSolventChain() {
-// returns True if chain contains only solvent molecules
-Boolean B,P;
-int i;
- B = True;
- P = False;
- for (i=0;(i<nResidues) && B;i++)
- if (Residue[i]) {
- P = True;
- B = Residue[i]->isSolvent();
- }
- return (B && P);
-}
-
-Boolean CChain::isInSelection ( int selHnd ) {
-PCMMDBFile mmdbfile = (PCMMDBFile)GetCoordHierarchy();
-PCMask Mask;
- if (mmdbfile) {
- Mask = mmdbfile->GetSelMask ( selHnd );
- if (Mask) return CheckMask ( Mask );
- }
- return False;
-}
-
-Boolean CChain::isAminoacidChain() {
-// returns True if chain contains at least one aminoacid residue
-Boolean B,P;
-int i;
- B = False;
- P = False;
- for (i=0;(i<nResidues) && (!B);i++)
- if (Residue[i]) {
- P = True;
- B = Residue[i]->isAminoacid();
- }
- return (B && P);
-}
-
-Boolean CChain::isNucleotideChain() {
-// returns True if chain contains at least one nucleotide residue
-Boolean B,P;
-int i;
- B = False;
- P = False;
- for (i=0;(i<nResidues) && (!B);i++)
- if (Residue[i]) {
- P = True;
- B = Residue[i]->isNucleotide();
- }
- return (B && P);
-}
-
-int CChain::CheckID ( const ChainID chID ) {
- if (chID) {
- if (!strcmp(chID,chainID)) return 1;
- }
- return 0;
-}
-
-int CChain::CheckIDS ( cpstr CID ) {
-ChainID chn;
-InsCode inscode;
-ResName resname;
-AtomName atm;
-Element elm;
-AltLoc aloc;
-int mdl,sn,rc;
-
- rc = ParseAtomPath ( CID,mdl,chn,sn,inscode,resname,
- atm,elm,aloc,NULL );
- if (rc>=0) {
- if (!strcmp(chn,chainID)) return 1;
- }
- return 0;
-
-}
-
-int CChain::GetNumberOfDBRefs() {
- return DBReference.Length();
-}
-
-PCDBReference CChain::GetDBRef ( int dbRefNo ) {
- return (PCDBReference)DBReference.GetContainerClass ( dbRefNo );
-}
-
-
-void CChain::MaskAtoms ( PCMask Mask ) {
-int i;
- for (i=0;i<nResidues;i++)
- if (Residue[i]) Residue[i]->MaskAtoms ( Mask );
-}
-
-void CChain::MaskResidues ( PCMask Mask ) {
-int i;
- for (i=0;i<nResidues;i++)
- if (Residue[i]) Residue[i]->SetMask ( Mask );
-}
-
-void CChain::UnmaskAtoms ( PCMask Mask ) {
-int i;
- for (i=0;i<nResidues;i++)
- if (Residue[i]) Residue[i]->UnmaskAtoms ( Mask );
-}
-
-void CChain::UnmaskResidues ( PCMask Mask ) {
-int i;
- for (i=0;i<nResidues;i++)
- if (Residue[i]) Residue[i]->RemoveMask ( Mask );
-}
-
-
-
-
-// ------- user-defined data handlers
-
-int CChain::PutUDData ( int UDDhandle, int iudd ) {
- if (UDDhandle & UDRF_CHAIN)
- return CUDData::putUDData ( UDDhandle,iudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CChain::PutUDData ( int UDDhandle, realtype rudd ) {
- if (UDDhandle & UDRF_CHAIN)
- return CUDData::putUDData ( UDDhandle,rudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CChain::PutUDData ( int UDDhandle, cpstr sudd ) {
- if (UDDhandle & UDRF_CHAIN)
- return CUDData::putUDData ( UDDhandle,sudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CChain::GetUDData ( int UDDhandle, int & iudd ) {
- if (UDDhandle & UDRF_CHAIN)
- return CUDData::getUDData ( UDDhandle,iudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CChain::GetUDData ( int UDDhandle, realtype & rudd ) {
- if (UDDhandle & UDRF_CHAIN)
- return CUDData::getUDData ( UDDhandle,rudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CChain::GetUDData ( int UDDhandle, pstr sudd, int maxLen ) {
- if (UDDhandle & UDRF_CHAIN)
- return CUDData::getUDData ( UDDhandle,sudd,maxLen );
- else return UDDATA_WrongUDRType;
-}
-
-int CChain::GetUDData ( int UDDhandle, pstr & sudd ) {
- if (UDDhandle & UDRF_CHAIN)
- return CUDData::getUDData ( UDDhandle,sudd );
- else return UDDATA_WrongUDRType;
-}
-
-
-// -------------------------------------------------------------------
-
-DefineClass(CSortResidues)
-
-class CSortResidues : public CQuickSort {
- public :
- CSortResidues() : CQuickSort() {}
- int Compare ( int i, int j );
- void Swap ( int i, int j );
- void Sort ( PPCResidue res, int nresidues );
-};
-
-int CSortResidues::Compare ( int i, int j ) {
-int diff;
- diff = ((PPCResidue)data)[i]->seqNum - ((PPCResidue)data)[j]->seqNum;
- if (diff==0)
- diff = strcmp( (PPCResidue(data))[i]->insCode,
- (PPCResidue(data))[j]->insCode );
- if (diff>0) return 1;
- if (diff<0) return -1;
- return 0;
-}
-
-void CSortResidues::Swap ( int i, int j ) {
-PCResidue res;
- res = ((PPCResidue)data)[i];
- ((PPCResidue)data)[i] = ((PPCResidue)data)[j];
- ((PPCResidue)data)[j] = res;
-}
-
-void CSortResidues::Sort ( PPCResidue res, int nresidues ) {
- CQuickSort::Sort ( &(res[0]),nresidues );
-}
-
-void CChain::SortResidues() {
-CSortResidues SR;
- TrimResidueTable();
- SR.Sort ( Residue,nResidues );
-}
-
-int CChain::GetNofModResidues() {
- return ModRes.Length();
-}
-
-PCModRes CChain::GetModResidue ( int modResNo ) {
- return PCModRes(ModRes.GetContainerClass(modResNo));
-}
-
-void CChain::write ( RCFile f ) {
-int i;
-byte Version=1;
-
- f.WriteByte ( &Version );
-
- CUDData::write ( f );
-
- f.WriteTerLine ( chainID ,False );
- f.WriteTerLine ( prevChainID,False );
-
- DBReference.write ( f ); // Database reference
- SeqAdv .write ( f ); // SEQADV records
- SeqRes .write ( f ); // SEQRES data
- ModRes .write ( f ); // MODRES records
- Het .write ( f ); // HET records
-
- f.WriteInt ( &nResidues );
- for (i=0;i<nResidues;i++)
- Residue[i]->write ( f );
-
-}
-
-void CChain::read ( RCFile f ) {
-// The Atom array in CMMDBFile must be already read
-// prior to calling this function!
-int i;
-byte Version;
-
- FreeMemory();
-
- f.ReadByte ( &Version );
-
- CUDData::read ( f );
-
- f.ReadTerLine ( chainID ,False );
- f.ReadTerLine ( prevChainID,False );
-
- DBReference.read ( f ); // Database reference
- SeqAdv .read ( f ); // SEQADV records
- SeqRes .read ( f ); // SEQRES data
- ModRes .read ( f ); // MODRES records
- Het .read ( f ); // HET records
-
- SetChain ( chainID );
-
- f.ReadInt ( &nResidues );
- ResLen = nResidues;
- if (nResidues>0) {
- Residue = new PCResidue[nResidues];
- for (i=0;i<nResidues;i++) {
- Residue[i] = newCResidue();
- Residue[i]->SetChain ( this );
- Residue[i]->read ( f );
- }
- }
-
-}
-
-
-MakeFactoryFunctions(CChain)
-
-
-
-// ===================================================================
-
- /*
-void TestChain() {
-// reads from 'in.chain', writes into
-// 'out.chain' and 'abin.chain'
-CFile f;
-char S[81];
-PCChain Chain;
-
- Chain = newCChain();
-
- f.assign ( "in.chain",True );
- if (f.reset()) {
- while (!f.FileEnd()) {
- f.ReadLine ( S,sizeof(S) );
- Chain->ConvertPDBString ( S );
- }
- f.shut();
- } else {
- printf ( " Can't open input file 'in.chain' \n" );
- delete Chain;
- return;
- }
-
- f.assign ( "out.chain",True );
- if (f.rewrite()) {
- Chain->PDBASCIIDump ( f );
- f.shut();
- } else {
- printf ( " Can't open output file 'out.chain' \n" );
- delete Chain;
- return;
- }
-
-
- f.assign ( "mmdb.chain.bin",False );
- if (f.rewrite()) {
- Chain->write ( f );
- f.shut();
- } else {
- printf ( " Can't open binary chain file for writing.\n" );
- delete Chain;
- return;
- }
-
- delete Chain;
- printf ( " Chain deleted.\n" );
-
- Chain = newCChain();
- if (f.reset()) {
- Chain->read ( f );
- f.shut();
- } else {
- printf ( " Can't open binary chain file for reading.\n" );
- delete Chain;
- return;
- }
-
- f.assign ( "abin.chain",True );
- if (f.rewrite()) {
- Chain->PDBASCIIDump ( f );
- f.shut();
- } else
- printf ( " Can't open output file 'abin.chain' \n" );
-
- delete Chain;
-
-}
- */
diff --git a/mmdb/mmdb_chain.h b/mmdb/mmdb_chain.h
deleted file mode 100755
index bd095d8..0000000
--- a/mmdb/mmdb_chain.h
+++ /dev/null
@@ -1,674 +0,0 @@
-// $Id: mmdb_chain.h,v 1.22 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 29.01.10 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_Chain <interface>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CProModel ( a virtue of CModel )
-// ~~~~~~~~~ CChainContainer ( container of in-chain classes )
-// CContainerChain ( chain containered class template)
-// CDBReference ( DBREF records )
-// CSeqAdv ( SEQADV records )
-// CSeqRes ( SEQRES records )
-// CModRes ( MODRES records )
-// CHetRec ( HET records )
-// CChain ( chain class )
-//
-// Copyright (C) E. Krissinel 2000-2010
-//
-// =================================================================
-//
-
-#ifndef __MMDB_Chain__
-#define __MMDB_Chain__
-
-
-#ifndef __Stream__
-#include "stream_.h"
-#endif
-
-#ifndef __MMDB_Defs__
-#include "mmdb_defs.h"
-#endif
-
-#ifndef __MMDB_Utils__
-#include "mmdb_utils.h"
-#endif
-
-#ifndef __MMDB_Atom__
-#include "mmdb_atom.h"
-#endif
-
-
-// ==================== CProModel ======================
-
-// This class is a virtue needed only for defining certain
-// functions of CModel, which are used by CChain and
-// CResidue
-
-DefineClass(CProModel);
-DefineStreamFunctions(CProModel);
-
-DefineClass(CMMDBManager);
-
-class CProModel : public CUDData {
-
- friend class CChain;
-
- public :
-
- CProModel () : CUDData () {}
- CProModel ( RPCStream Object ) : CUDData ( Object ) {}
- ~CProModel () {}
-
- virtual cpstr GetEntryID () { return ""; }
- virtual void SetEntryID ( const IDCode ) {}
-
- virtual int AddChain ( PCChain ) { return 0; }
-
- // returns pointer to CMMDBFile
- virtual PCMMDBManager GetCoordHierarchy() { return NULL; }
-
- // GetNumberOfModels() returns TOTAL number of models
- virtual int GetNumberOfModels() { return 0; }
-
- // GetNumberOfAllAtoms() returns TOTAL number of atoms in
- // all models
- virtual int GetNumberOfAllAtoms() { return 0; }
-
- // returns pointer to the general Atom array
- virtual PPCAtom GetAllAtoms() { return NULL; }
-
- virtual int GetSerNum () { return 0; }
-
- virtual void ExpandAtomArray ( int ) {}
- virtual void AddAtomArray ( int ) {}
-
- protected :
-
- virtual int _ExcludeChain ( const ChainID ) { return 0; }
-
-};
-
-
-
-// ==================== CChainContainer ======================
-
-DefineClass(CChainContainer);
-DefineStreamFunctions(CChainContainer);
-
-class CChainContainer : public CClassContainer {
-
- public :
-
- CChainContainer () : CClassContainer () {}
- CChainContainer ( RPCStream Object )
- : CClassContainer ( Object ) {}
- ~CChainContainer () {}
-
- PCContainerClass MakeContainerClass ( int ClassID );
-
- void SetChain ( PCChain Chain_Owner ); // must be set before using
- // the Container
-
- // special functions used in CModel::GetCIF(..)
- cpstr Get1stChainID ();
- void MoveByChainID ( const ChainID chainID,
- PCChainContainer ChainContainer );
-
- protected :
- PCChain Chain;
-
-};
-
-
-// ================== CContainerChain =====================
-
-DefineClass(CContainerChain);
-DefineStreamFunctions(CContainerChain);
-
-class CContainerChain : public CContainerClass {
-
- friend class CChainContainer;
-
- public :
-
- CContainerChain ();
- CContainerChain ( PCChain Chain_Owner );
- CContainerChain ( RPCStream Object ) : CContainerClass(Object){}
-
- void SetChain ( PCChain Chain_Owner );
-
- protected :
- PCChain Chain;
- ChainID chainID; // just a copy of Chain->chainID
-
-};
-
-
-// ================== CDBReference ========================
-
-DefineClass(CDBReference);
-DefineStreamFunctions(CDBReference);
-
-class CDBReference : public CContainerChain {
-
- public :
-
- int seqBeg; // initial seq num of the PDB seq-ce segment
- InsCode insBeg; // initial ins code of the PDB seq-ce segm-t
- int seqEnd; // ending seq number of the PDB seq-ce segm-t
- InsCode insEnd; // ending ins code of the PDB seq-ce segment
- DBName database; // sequence database name
- DBAcCode dbAccession; // sequence database accession code
- DBIdCode dbIdCode; // sequence database identification code
- int dbseqBeg; // initial seq number of the database segment
- InsCode dbinsBeg; // ins code of initial residue of the segment
- int dbseqEnd; // ending seq number of the database segment
- InsCode dbinsEnd; // ins code of the ending residue of the seg-t
-
- CDBReference ();
- CDBReference ( PCChain Chain_Owner );
- CDBReference ( PCChain Chain_Owner, cpstr S );
- CDBReference ( RPCStream Object );
- ~CDBReference();
-
- void PDBASCIIDump ( pstr S, int N );
- void MakeCIF ( PCMMCIFData CIF, int N );
- int ConvertPDBASCII ( cpstr S );
- void GetCIF ( PCMMCIFData CIF, int & Signal );
- int GetClassID () { return ClassID_DBReference; }
-
- void Copy ( PCContainerClass DBRef );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitDBReference();
-
-};
-
-
-// ==================== CSeqAdv ===========================
-
-DefineClass(CSeqAdv);
-DefineStreamFunctions(CSeqAdv);
-
-class CSeqAdv : public CContainerChain {
-
- public :
-
- ResName resName; // residue name in conflict
- int seqNum; // residue sequence number
- InsCode insCode; // residue insertion code
- DBName database; // sequence database name
- DBAcCode dbAccession; // sequence database accession code
- ResName dbRes; // sequence database residue name
- int dbSeq; // sequence database sequence number
- pstr conflict; // conflict comment
-
- CSeqAdv ();
- CSeqAdv ( PCChain Chain_Owner );
- CSeqAdv ( PCChain Chain_Owner, cpstr S );
- CSeqAdv ( RPCStream Object );
- ~CSeqAdv();
-
- void PDBASCIIDump ( pstr S, int N );
- int ConvertPDBASCII ( cpstr S );
-
- void MakeCIF ( PCMMCIFData CIF, int N );
- void GetCIF ( PCMMCIFData CIF, int & Signal );
-
- int GetClassID () { return ClassID_SeqAdv; }
-
- void Copy ( PCContainerClass SeqAdv );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitSeqAdv();
-
-};
-
-
-// ================== CSeqRes ========================
-
-DefineClass(CSeqRes);
-DefineStreamFunctions(CSeqRes);
-
-class CSeqRes : public CStream {
-
- friend class CModel;
- friend class CChain;
-
- public :
-
- int numRes; // number of residues in the chain
- PResName resName; // residue names
-
- CSeqRes ();
- CSeqRes ( RPCStream Object );
- ~CSeqRes();
-
- void SetChain ( PCChain Chain_Owner );
- void PDBASCIIDump ( RCFile f );
- int ConvertPDBASCII ( cpstr S );
-
- void MakeCIF ( PCMMCIFData CIF );
- int GetCIF ( PCMMCIFData CIF );
-
- void Copy ( PCSeqRes SeqRes );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
- PCChain Chain;
- ChainID chainID;
- int serNum;
-
- void InitSeqRes();
- void FreeMemory();
-
-};
-
-
-// ================== CModRes ========================
-
-DefineClass(CModRes);
-DefineStreamFunctions(CModRes);
-
-class CModRes : public CContainerChain {
-
- public :
-
- ResName resName; // residue name used
- int seqNum; // residue sequence number
- InsCode insCode; // residue insertion code
- ResName stdRes; // standard residue name
- pstr comment; // description of the residue modification
-
- CModRes ();
- CModRes ( PCChain Chain_Owner );
- CModRes ( PCChain Chain_Owner, cpstr S );
- CModRes ( RPCStream Object );
- ~CModRes();
-
- void PDBASCIIDump ( pstr S, int N );
- void MakeCIF ( PCMMCIFData CIF, int N );
- int ConvertPDBASCII ( cpstr S );
- void GetCIF ( PCMMCIFData CIF, int & Signal );
- int GetClassID () { return ClassID_ModRes; }
-
- void Copy ( PCContainerClass ModRes );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitModRes();
-
-};
-
-
-// ================== CHetRec ===========================
-
-DefineClass(CHetRec);
-DefineStreamFunctions(CHetRec);
-
-class CHetRec : public CContainerChain {
-
- public :
-
- ResName hetID; // Het identifier (right-justified)
- int seqNum; // sequence number
- InsCode insCode; // insertion code
- int numHetAtoms; // number of HETATM records for the
- // group present in the entry
- pstr comment; // text describing Het group
-
- CHetRec ();
- CHetRec ( PCChain Chain_Owner );
- CHetRec ( PCChain Chain_Owner, cpstr S );
- CHetRec ( RPCStream Object );
- ~CHetRec();
-
- void PDBASCIIDump ( pstr S, int N );
- void MakeCIF ( PCMMCIFData CIF, int N );
- int ConvertPDBASCII ( cpstr S );
- void GetCIF ( PCMMCIFData CIF, int & Signal );
- int GetClassID () { return ClassID_Het; }
-
- void Copy ( PCContainerClass Het );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitHetRec();
-
-};
-
-
-// ================= CChain =======================
-
-DefineFactoryFunctions(CChain);
-
-class CChain : public CUDData {
-
- friend class CDBReference;
- friend class CSeqAdv;
- friend class CSeqRes;
- friend class CModRes;
- friend class CHetRec;
- friend class CResidue;
- friend class CAtom;
- friend class CModel;
- friend class CMMDBFile;
- friend class CMMDBSelManager;
- friend class CMMDBBondManager;
- friend class CMMDBCoorManager;
- friend class CMMDBManager;
-
- public :
-
- CChainContainer DBReference; // database reference
- CChainContainer SeqAdv; // SEQADV records
- CSeqRes SeqRes; // Sequence residues, SEQRES records
- CChainContainer ModRes; // modification descriptions
- CChainContainer Het; // non-standard residues descriptions
-
- CChain (); // SetModel() MUST be used after this constructor!
- CChain ( PCProModel Model, const ChainID chID );
- CChain ( RPCStream Object );
- ~CChain();
-
- void FreeAnnotations();
-
- void SetModel ( PCProModel Model );
- void SetChain ( const ChainID chID );
-
- PCMMDBManager GetCoordHierarchy(); // PCMMDBFile
-
- // ConvertXXXXX(..) functions do not check for record name
- // and assume that PDBString is at least 81 symbols long
- // (including the terminating null).
- int ConvertDBREF ( cpstr PDBString );
- int ConvertSEQADV ( cpstr PDBString );
- int ConvertSEQRES ( cpstr PDBString );
- int ConvertMODRES ( cpstr PDBString );
- int ConvertHET ( cpstr PDBString );
-
- // This function should be used for testing purposes only.
- // A full PDB ASCII dump for all models and chains involved
- // is done by CMMDBFile class.
- void PDBASCIIDump ( RCFile f );
-
- void PDBASCIIAtomDump ( RCFile f );
- void MakeAtomCIF ( PCMMCIFData CIF );
-
-
- // ----------------- Extracting residues -------------------------
-
- int GetNumberOfResidues(); // returns number of res-s in the chain
- PCResidue GetResidue ( int resNo ); // returns resNo-th residue
- // in the chain;
- // 0<=resNo<nResidues
-
- // GetResidue(..) returns pointer on residue, whose sequence
- // number and insert code are given in seqNum and insCode,
- // respectively. If such a residue is absent in the chain,
- // returns NULL.
- PCResidue GetResidue ( int seqNum, const InsCode insCode );
-
- // GetResidueNo(..) returns the residue number in the chain's
- // residues table. Residues are numbered as 0..nres-1 as they
- // appear in the coordinate file.
- // If residue is not found, the function returns -1.
- int GetResidueNo ( int seqNum, const InsCode insCode );
-
- void GetResidueTable ( PPCResidue & resTable,
- int & NumberOfResidues );
-
- // GetResidueCreate(..) returns pointer on residue, whose name,
- // sequence number and insertion code are given by resName, seqNum
- // and insCode, respectively. If such a residue is absent in the
- // chain, one is created at the end of chain.
- // If a residue with given sequence number and insertion code
- // is present in the chain but has a different name, the function
- // returns NULL unless Enforce is set True. In the latter case,
- // a new residue is still created at the end of chain, but there
- // is no guarantee that any function operating on the sequence
- // number and insertion code will work properly.
- PCResidue GetResidueCreate ( const ResName resName, int seqNum,
- const InsCode insCode, Boolean Enforce );
-
-
- // ------------------ Deleting residues ----------------------
-
- int DeleteResidue ( int resNo ); // returns num of deleted res-s
- int DeleteResidue ( int seqNum, const InsCode insCode );
- int DeleteAllResidues();
- int DeleteSolvent ();
- void TrimResidueTable (); // do not forget to call after all dels
-
- // ------------------- Adding residues -----------------------
-
- // AddResidue(..) adds residue to the chain, InsResidue inserts
- // the residue on the specified position of the chain (other
- // residues are shifted up to the end of chain). Position in the
- // chain may be specified by a serial number (that is position in
- // the residue table) or by seqNum and insCode of one of the
- // chain's residues (the new residue is then inserted before that
- // one). If the chain is associated with a coordinate hierarchy,
- // and residue 'res' is not, the latter is checked in
- // automatically. If residue 'res' belongs to any coordinate
- // hierarchy (even though that of the residue), it is *copied*
- // rather than simply taken over, and is checked in.
- // If the chain is not associated with a coordinate hierarchy,
- // all added residues will be checked in automatically once the
- // chain is checked in.
- int AddResidue ( PCResidue res );
- int InsResidue ( PCResidue res, int pos );
- int InsResidue ( PCResidue res, int seqNum,
- const InsCode insCode );
-
- // -------------------- Extracting atoms ---------------------
-
- int GetNumberOfAtoms ( Boolean countTers );
- int GetNumberOfAtoms ( int seqNo, const InsCode insCode );
- int GetNumberOfAtoms ( int resNo );
-
- PCAtom GetAtom ( int seqNo,
- const InsCode insCode,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc );
- PCAtom GetAtom ( int seqNo, const InsCode insCode, int atomNo );
- PCAtom GetAtom ( int resNo,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc );
- PCAtom GetAtom ( int resNo, int atomNo );
-
- void GetAtomTable ( int seqNo, const InsCode insCode,
- PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable ( int resNo,
- PPCAtom & atomTable, int & NumberOfAtoms );
-
- // GetAtomTable1(..) returns atom table without TER atoms and
- // without NULL atom pointers. NumberOfAtoms returns the actual
- // number of atom pointers in atomTable.
- // atomTable is allocated withing the function. If it was
- // not set to NULL before calling the function, the latter will
- // attempt to deallocate it first.
- // The application is responsible for deleting atomTable,
- // however it must not touch atom pointers, i.e. use simply
- // "delete[] atomTable;". Never pass atomTable from
- // GetAtomTable(..) into this function, unless you set it to NULL
- // before doing that.
- void GetAtomTable1 ( int seqNo, const InsCode insCode,
- PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable1 ( int resNo,
- PPCAtom & atomTable, int & NumberOfAtoms );
-
- // --------------------- Deleting atoms ----------------------
-
- int DeleteAtom ( int seqNo,
- const InsCode insCode,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc );
- int DeleteAtom ( int seqNo,
- const InsCode insCode,
- int atomNo );
- int DeleteAtom ( int resNo,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc );
- int DeleteAtom ( int resNo, int atomNo );
-
- int DeleteAllAtoms ( int seqNo, const InsCode insCode );
- int DeleteAllAtoms ( int resNo );
- int DeleteAllAtoms ();
-
- // DeleteAltLocs() leaves only alternative location with maximal
- // occupancy, if those are equal or unspecified, the one with
- // "least" alternative location indicator.
- // The function returns the number of deleted. All tables remain
- // untrimmed, so that explicit trimming or calling
- // FinishStructEdit() is required.
- int DeleteAltLocs();
-
- // ---------------------- Adding atoms -----------------------
-
- int AddAtom ( int seqNo, const InsCode insCode, PCAtom atom );
- int AddAtom ( int resNo, PCAtom atom );
-
- // -------------------------------------------------------------
-
- void ApplyTransform ( mat44 & TMatrix ); // transforms all
- // coordinates by multiplying
- // with matrix TMatrix
-
- int GetModelNum();
- PCModel GetModel () { return (PCModel)model; }
- cpstr GetChainID () { return chainID; }
- void SetChainID ( const ChainID chID );
- cpstr GetChainID ( pstr ChID ); // returns /m/c
-
- void GetAtomStatistics ( RSAtomStat AS );
- void CalcAtomStatistics ( RSAtomStat AS );
-
- int CheckID ( const ChainID chID );
- int CheckIDS ( cpstr CID );
-
- cpstr GetEntryID ();
- void SetEntryID ( const IDCode idCode );
-
- int GetNumberOfDBRefs ();
- PCDBReference GetDBRef ( int dbRefNo ); // 0..nDBRefs-1
-
- void MaskAtoms ( PCMask Mask );
- void MaskResidues ( PCMask Mask );
- void UnmaskAtoms ( PCMask Mask );
- void UnmaskResidues ( PCMask Mask );
-
- void SortResidues ();
-
- int GetNofModResidues();
- PCModRes GetModResidue ( int modResNo ); // 0.. on
-
- Boolean isSolventChain ();
- Boolean isInSelection ( int selHnd );
- Boolean isAminoacidChain ();
- Boolean isNucleotideChain();
-
-
- // ------- user-defined data handlers
- int PutUDData ( int UDDhandle, int iudd );
- int PutUDData ( int UDDhandle, realtype rudd );
- int PutUDData ( int UDDhandle, cpstr sudd );
-
- int GetUDData ( int UDDhandle, int & iudd );
- int GetUDData ( int UDDhandle, realtype & rudd );
- int GetUDData ( int UDDhandle, pstr sudd, int maxLen );
- int GetUDData ( int UDDhandle, pstr & sudd );
-
- void Copy ( PCChain Chain );
- void CopyAnnotations ( PCChain Chain );
-
- void write ( RCFile f ); // writes header to PDB binary file
- void read ( RCFile f ); // reads header from PDB binary file
-
- protected :
-
- ChainID chainID; // chain ID
- ChainID prevChainID; // if chain is renamed, its original
- // name may be saved here.
- PCProModel model; // pointer to model class
-
- int nWeights; // used externally for sorting
- realtype Weight; // chains
-
- int nResidues; // number of residues
- PPCResidue Residue; // array of residues
-
- Boolean Exclude; // used internally
-
- void InitChain ();
- void FreeMemory();
-
- void ExpandResidueArray ( int inc );
- // _ExcludeResidue(..) excludes (but does not dispose!) a residue
- // from the chain. Returns 1 if the chain gets empty and 0
- // otherwise.
- int _ExcludeResidue ( const ResName resName, int seqNum,
- const InsCode insCode );
- void _copy ( PCChain Chain );
- void _copy ( PCChain Chain, PPCAtom atom, int & atom_index );
- void CheckInAtoms();
-
- private :
- int ResLen; // length of Residue array
-
-};
-
-
-extern void TestChain(); // reads from 'in.chain', writes into
- // 'out.chain' and 'abin.chain'
-
-#endif
-
diff --git a/mmdb/mmdb_cifdefs.cpp b/mmdb/mmdb_cifdefs.cpp
deleted file mode 100755
index 48ed20f..0000000
--- a/mmdb/mmdb_cifdefs.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-// $Id: mmdb_cifdefs.cpp,v 1.19 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 08.12.00 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDBF_Defs <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-//
-// CIF Definitions
-//
-// (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-#ifndef __MMDB_CIFDefs__
-#include "mmdb_cifdefs.h"
-#endif
-
-
-// ------------------------------------------------------------------
-
-pstr CIFName ( int NameID, int Mode ) {
-// Gives CIF name according to CIF Mode.
-
- switch (Mode) {
-
- case CIF_NDB :
-
- switch (NameID) {
- case CAT_POLY_SEQ_SCHEME :
- return CIFCAT_NDB_POLY_SEQ_SCHEME;
- case TAG_ID_CODE :
- return CIFTAG_NDB_PDB_ID_CODE;
- case TAG_CHAIN_ID :
- return CIFTAG_NDB_CHAIN_ID;
- case TAG_SEQ_ALIGN_BEG :
- return CIFTAG_SEQ_ALIGN_BEG;
- case TAG_SEQ_ALIGN_BEG_INS_CODE :
- return CIFTAG_NDB_SEQ_ALIGN_BEG_INS_CODE;
- case TAG_SEQ_ALIGN_END :
- return CIFTAG_SEQ_ALIGN_END;
- case TAG_SEQ_ALIGN_END_INS_CODE :
- return CIFTAG_NDB_SEQ_ALIGN_END_INS_CODE;
- case TAG_DB_ACCESSION :
- return CIFTAG_NDB_DB_ACCESSION;
- case TAG_DB_ALIGN_BEG :
- return CIFTAG_DB_ALIGN_BEG;
- case TAG_DB_ALIGN_BEG_INS_CODE :
- return CIFTAG_NDB_DB_ALIGN_BEG_INS_CODE;
- case TAG_DB_ALIGN_END :
- return CIFTAG_DB_ALIGN_END;
- case TAG_DB_ALIGN_END_INS_CODE :
- return CIFTAG_NDB_DB_ALIGN_END_INS_CODE;
- case TAG_SEQ_CHAIN_ID :
- return CIFTAG_ID;
- default : return pstr("ERROR_IN_CIF_NAME_1");
- }
-
- case CIF_PDBX :
-
- switch (NameID) {
- case CAT_POLY_SEQ_SCHEME :
- return CIFCAT_PDBX_POLY_SEQ_SCHEME;
- case TAG_ID_CODE :
- return CIFTAG_PDBX_PDB_ID_CODE;
- case TAG_CHAIN_ID :
- return CIFTAG_PDBX_STRAND_ID;
- case TAG_SEQ_ALIGN_BEG :
- return CIFTAG_SEQ_ALIGN_BEG;
- case TAG_SEQ_ALIGN_BEG_INS_CODE :
- return CIFTAG_PDBX_SEQ_ALIGN_BEG_INS_CODE;
- case TAG_SEQ_ALIGN_END :
- return CIFTAG_SEQ_ALIGN_END;
- case TAG_SEQ_ALIGN_END_INS_CODE :
- return CIFTAG_PDBX_SEQ_ALIGN_END_INS_CODE;
- case TAG_DB_ACCESSION :
- return CIFTAG_PDBX_DB_ACCESSION;
- case TAG_DB_ALIGN_BEG :
- return CIFTAG_DB_ALIGN_BEG;
- case TAG_DB_ALIGN_BEG_INS_CODE :
- return CIFTAG_PDBX_DB_ALIGN_BEG_INS_CODE;
- case TAG_DB_ALIGN_END :
- return CIFTAG_DB_ALIGN_END;
- case TAG_DB_ALIGN_END_INS_CODE :
- return CIFTAG_PDBX_DB_ALIGN_END_INS_CODE;
- case TAG_SEQ_CHAIN_ID :
- return CIFTAG_ASYM_ID;
- default : return pstr("ERROR_IN_CIF_NAME_2");
- }
-
- default : return pstr("ERROR_IN_CIF_NAME_3");
-
- }
-
-}
-
diff --git a/mmdb/mmdb_cifdefs.h b/mmdb/mmdb_cifdefs.h
deleted file mode 100755
index 045ee77..0000000
--- a/mmdb/mmdb_cifdefs.h
+++ /dev/null
@@ -1,327 +0,0 @@
-// $Id: mmdb_cifdefs.h,v 1.21 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 06.02.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDBF_Defs <interface>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-//
-// CIF Definitions
-//
-// (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-#ifndef __MMDB_CIFDefs__
-#define __MMDB_CIFDefs__
-
-#ifndef __MatType__
-#include "mattype_.h"
-#endif
-
-// ------------------------------------------------------------------
-
-// Mode IDs
-
-#define CIF_NDB 0
-#define CIF_PDBX 1
-
-
-// CIF IDs for mode-dependent CIF names
-
-
-#define CAT_POLY_SEQ_SCHEME 1
-
-#define TAG_CHAIN_ID 101
-#define TAG_DB_ACCESSION 102
-#define TAG_DB_ALIGN_BEG 103
-#define TAG_DB_ALIGN_BEG_INS_CODE 104
-#define TAG_DB_ALIGN_END 105
-#define TAG_DB_ALIGN_END_INS_CODE 106
-#define TAG_ID_CODE 107
-#define TAG_SEQ_CHAIN_ID 108
-#define TAG_SEQ_ALIGN_BEG 109
-#define TAG_SEQ_ALIGN_BEG_INS_CODE 110
-#define TAG_SEQ_ALIGN_END 111
-#define TAG_SEQ_ALIGN_END_INS_CODE 112
-
-// CIFName(..) gives CIF name according to CIF Mode.
-extern pstr CIFName ( int NameID, int Mode );
-
-// ------------------------------------------------------------------
-
-
-#define CIFCAT_ATOM_SITE pstr("_atom_site")
-#define CIFCAT_ATOM_SITE_ANISOTROP pstr("_atom_site_anisotrop")
-#define CIFCAT_ATOM_SITES pstr("_atom_sites")
-#define CIFCAT_AUDIT_AUTHOR pstr("_audit_author")
-#define CIFCAT_CELL pstr("_cell")
-#define CIFCAT_CHEM_COMP pstr("_chem_comp")
-#define CIFCAT_CITATION pstr("_citation")
-#define CIFCAT_DATABASE pstr("_database")
-#define CIFCAT_DATABASE_PDB_CAVEAT pstr("_database_pdb_caveat")
-#define CIFCAT_DATABASE_PDB_MATRIX pstr("_database_pdb_matrix")
-#define CIFCAT_DATABASE_PDB_REV pstr("_database_pdb_rev")
-#define CIFCAT_DATABASE_PDB_TVECT pstr("_database_pdb_tvect")
-#define CIFCAT_ENTITY pstr("_entity")
-#define CIFCAT_EXPTL pstr("_exptl")
-#define CIFCAT_NDB_DATABASE_REMARK pstr("_ndb_database_remark")
-#define CIFCAT_NDB_NONSTANDARD_LIST pstr("_ndb_nonstandard_list")
-#define CIFCAT_NDB_POLY_SEQ_SCHEME pstr("_ndb_poly_seq_scheme")
-#define CIFCAT_PDBX_POLY_SEQ_SCHEME pstr("_pdbx_poly_seq_scheme")
-#define CIFCAT_SPRSDE pstr("_ndb_database_pdb_obs_spr")
-#define CIFCAT_STRUCT pstr("_struct")
-#define CIFCAT_STRUCT_ASYM pstr("_struct_asym")
-#define CIFCAT_STRUCT_CONF pstr("_struct_conf")
-#define CIFCAT_STRUCT_CONN pstr("_struct_conn")
-#define CIFCAT_STRUCT_LINKR cpstr("_struct_linkr")
-#define CIFCAT_STRUCT_KEYWORDS pstr("_struct_keywords")
-#define CIFCAT_STRUCT_NCS_OPER pstr("_struct_ncs_oper")
-#define CIFCAT_STRUCT_REF pstr("_struct_ref")
-#define CIFCAT_STRUCT_REF_SEQ pstr("_struct_ref_seq")
-#define CIFCAT_STRUCT_REF_SEQ_DIF pstr("_struct_ref_seq_dif")
-#define CIFCAT_STRUCT_SHEET pstr("_struct_sheet")
-#define CIFCAT_STRUCT_SHEET_RANGE pstr("_struct_sheet_range")
-#define CIFCAT_STRUCT_SHEET_ORDER pstr("_struct_sheet_order")
-#define CIFCAT_STRUCT_SHEET_HBOND pstr("_struct_sheet_hbond")
-#define CIFCAT_SYMMETRY pstr("_symmetry")
-#define CIFCAT_OBSLTE pstr("_ndb_database_pdb_obs_spr")
-
-
-#define CIFTAG_ANGLE_ALPHA pstr("angle_alpha")
-#define CIFTAG_ANGLE_BETA pstr("angle_beta")
-#define CIFTAG_ANGLE_GAMMA pstr("angle_gamma")
-#define CIFTAG_ASYM_ID pstr("asym_id")
-#define CIFTAG_ATOM_TYPE_SYMBOL pstr("atom_type_symbol")
-#define CIFTAG_AUTH_ASYM_ID pstr("auth_asym_id")
-#define CIFTAG_AUTH_ATOM_ID pstr("auth_atom_id")
-#define CIFTAG_AUTH_COMP_ID pstr("auth_comp_id")
-#define CIFTAG_AUTH_SEQ_ID pstr("auth_seq_id")
-#define CIFTAG_B_ISO_OR_EQUIV pstr("B_iso_or_equiv")
-#define CIFTAG_B_ISO_OR_EQUIV_ESD pstr("B_iso_or_equiv_esd")
-#define CIFTAG_BEG_LABEL_ASYM_ID pstr("beg_label_asym_id")
-#define CIFTAG_BEG_LABEL_COMP_ID pstr("beg_label_comp_id")
-#define CIFTAG_BEG_LABEL_SEQ_ID pstr("beg_label_seq_id")
-#define CIFTAG_CARTN_X pstr("cartn_x")
-#define CIFTAG_CARTN_X_ESD pstr("cartn_x_esd")
-#define CIFTAG_CARTN_Y pstr("cartn_y")
-#define CIFTAG_CARTN_Y_ESD pstr("cartn_y_esd")
-#define CIFTAG_CARTN_Z pstr("cartn_z")
-#define CIFTAG_CARTN_Z_ESD pstr("cartn_z_esd")
-#define CIFTAG_PDBX_FORMAL_CHARGE pstr("pdbx_formal_charge")
-#define CIFTAG_CODE pstr("code")
-#define CIFTAG_CODE_NDB pstr("code_NDB")
-#define CIFTAG_CODE_PDB pstr("code_PDB")
-#define CIFTAG_CONF_TYPE_ID pstr("conf_type_id")
-#define CIFTAG_CONN_TYPE_ID pstr("conn_type_id")
-#define CIFTAG_DATE pstr("date")
-#define CIFTAG_DATE_ORIGINAL pstr("date_original")
-#define CIFTAG_DB_ALIGN_BEG pstr("db_align_beg")
-#define CIFTAG_DB_ALIGN_END pstr("db_align_end")
-#define CIFTAG_DB_CODE pstr("db_code")
-#define CIFTAG_DB_MON_ID pstr("db_mon_id")
-#define CIFTAG_DB_NAME pstr("db_name")
-#define CIFTAG_DETAILS pstr("details")
-#define CIFTAG_END_LABEL_ASYM_ID pstr("end_label_asym_id")
-#define CIFTAG_END_LABEL_COMP_ID pstr("end_label_comp_id")
-#define CIFTAG_END_LABEL_SEQ_ID pstr("end_label_seq_id")
-#define CIFTAG_ENTITY_ID pstr("entity_id")
-#define CIFTAG_ENTRY_ID pstr("entry_id")
-#define CIFTAG_FORMULA pstr("formula")
-#define CIFTAG_FRACT_TRANSF_MATRIX11 pstr("fract_transf_matrix[1][1]")
-#define CIFTAG_FRACT_TRANSF_MATRIX12 pstr("fract_transf_matrix[1][2]")
-#define CIFTAG_FRACT_TRANSF_MATRIX13 pstr("fract_transf_matrix[1][3]")
-#define CIFTAG_FRACT_TRANSF_MATRIX21 pstr("fract_transf_matrix[2][1]")
-#define CIFTAG_FRACT_TRANSF_MATRIX22 pstr("fract_transf_matrix[2][2]")
-#define CIFTAG_FRACT_TRANSF_MATRIX23 pstr("fract_transf_matrix[2][3]")
-#define CIFTAG_FRACT_TRANSF_MATRIX31 pstr("fract_transf_matrix[3][1]")
-#define CIFTAG_FRACT_TRANSF_MATRIX32 pstr("fract_transf_matrix[3][2]")
-#define CIFTAG_FRACT_TRANSF_MATRIX33 pstr("fract_transf_matrix[3][3]")
-#define CIFTAG_FRACT_TRANSF_VECTOR1 pstr("fract_transf_vector[1]")
-#define CIFTAG_FRACT_TRANSF_VECTOR2 pstr("fract_transf_vector[2]")
-#define CIFTAG_FRACT_TRANSF_VECTOR3 pstr("fract_transf_vector[3]")
-#define CIFTAG_GROUP_PDB pstr("group_PDB" )
-#define CIFTAG_ID pstr("id")
-#define CIFTAG_INS_CODE pstr("ins_code")
-#define CIFTAG_LABEL_ALT_ID pstr("label_alt_id")
-#define CIFTAG_LABEL_ATOM_ID pstr("label_atom_id")
-#define CIFTAG_LABEL_ASYM_ID pstr("label_asym_id")
-#define CIFTAG_LABEL_COMP_ID pstr("label_comp_id")
-#define CIFTAG_LABEL_ENTITY_ID pstr("label_entity_id")
-#define CIFTAG_LABEL_SEQ_ID pstr("label_seq_id")
-#define CIFTAG_LENGTH_A pstr("length_a")
-#define CIFTAG_LENGTH_B pstr("length_b")
-#define CIFTAG_LENGTH_C pstr("length_c")
-#define CIFTAG_MATRIX11 pstr("matrix[1][1]")
-#define CIFTAG_MATRIX12 pstr("matrix[1][2]")
-#define CIFTAG_MATRIX13 pstr("matrix[1][3]")
-#define CIFTAG_MATRIX21 pstr("matrix[2][1]")
-#define CIFTAG_MATRIX22 pstr("matrix[2][2]")
-#define CIFTAG_MATRIX23 pstr("matrix[2][3]")
-#define CIFTAG_MATRIX31 pstr("matrix[3][1]")
-#define CIFTAG_MATRIX32 pstr("matrix[3][2]")
-#define CIFTAG_MATRIX33 pstr("matrix[3][3]")
-#define CIFTAG_METHOD pstr("method")
-#define CIFTAG_MOD_TYPE pstr("mod_type")
-#define CIFTAG_MON_ID pstr("mon_id")
-#define CIFTAG_NAME pstr("name")
-#define CIFTAG_NDB_BEG_LABEL_INS_CODE_PDB pstr("ndb_beg_label_ins_code_pdb")
-#define CIFTAG_NDB_CHAIN_ID pstr("ndb_chain_id")
-#define CIFTAG_NDB_COMPONENT_NO pstr("ndb_component_no")
-#define CIFTAG_NDB_DESCRIPTOR pstr("ndb_descriptor")
-#define CIFTAG_NDB_DB_ACCESSION pstr("ndb_db_accession")
-#define CIFTAG_NDB_DB_ALIGN_BEG_INS_CODE pstr("ndb_db_align_beg_ins_code")
-#define CIFTAG_NDB_DB_ALIGN_END_INS_CODE pstr("ndb_db_align_end_ins_code")
-#define CIFTAG_NDB_END_LABEL_INS_CODE_PDB pstr("ndb_end_label_ins_code_pdb")
-//#define CIFTAG_NDB_INS_CODE pstr("ndb_ins_code")
-#define CIFTAG_PDBX_PDB_INS_CODE pstr("pdbx_PDB_ins_code")
-#define CIFTAG_NDB_HELIX_CLASS_PDB pstr("ndb_helix_class_pdb")
-#define CIFTAG_NDB_KEYWORDS pstr("ndb_keywords")
-#define CIFTAG_NDB_LABEL_ALT_ID pstr("ndb_label_alt_id")
-#define CIFTAG_NDB_LABEL_ATOM_ID pstr("ndb_label_atom_id")
-#define CIFTAG_NDB_LABEL_ASYM_ID pstr("ndb_label_asym_id")
-#define CIFTAG_NDB_LABEL_COMP_ID pstr("ndb_label_comp_id")
-#define CIFTAG_NDB_LABEL_INS_CODE pstr("ndb_label_ins_code")
-#define CIFTAG_NDB_LABEL_SEQ_NUM pstr("ndb_label_seq_num")
-#define CIFTAG_NDB_LENGTH pstr("ndb_length")
-#define CIFTAG_NDB_MODEL pstr("ndb_model")
-#define CIFTAG_NDB_PDB_CHAIN_ID pstr("ndb_pdb_chain_id")
-#define CIFTAG_NDB_PDB_ID pstr("ndb_pdb_id")
-#define CIFTAG_NDB_PDB_ID_CODE pstr("ndb_pdb_id_code")
-#define CIFTAG_NDB_PDB_INS_CODE pstr("ndb_pdb_ins_code")
-#define CIFTAG_NDB_PTNR1_LABEL_INS_CODE pstr("ndb_ptnr1_label_ins_code")
-#define CIFTAG_NDB_PTNR1_STANDARD_COMP_ID pstr("ndb_ptnr1_standard_comp_id")
-#define CIFTAG_NDB_RANGE_1_BEG_LABEL_COMP_ID pstr("ndb_range_1_beg_label_comp_id")
-#define CIFTAG_NDB_RANGE_1_BEG_LABEL_ASYM_ID pstr("ndb_range_1_beg_label_asym_id")
-#define CIFTAG_NDB_RANGE_1_BEG_LABEL_INS_CODE pstr("ndb_range_1_beg_label_ins_code")
-#define CIFTAG_NDB_RANGE_1_END_LABEL_COMP_ID pstr("ndb_range_1_end_label_comp_id")
-#define CIFTAG_NDB_RANGE_1_END_LABEL_ASYM_ID pstr("ndb_range_1_end_label_asym_id")
-#define CIFTAG_NDB_RANGE_1_END_LABEL_INS_CODE pstr("ndb_range_1_end_label_ins_code")
-#define CIFTAG_NDB_SEQ_ALIGN_BEG pstr("ndb_seq_align_beg")
-#define CIFTAG_NDB_SEQ_ALIGN_BEG_INS_CODE pstr("ndb_seq_align_beg_ins_code")
-#define CIFTAG_NDB_SEQ_ALIGN_END pstr("ndb_seq_align_end")
-#define CIFTAG_NDB_SEQ_ALIGN_END_INS_CODE pstr("ndb_seq_align_end_ins_code")
-#define CIFTAG_NDB_SEQ_DB_NAME pstr("ndb_seq_db_name")
-#define CIFTAG_NDB_SEQ_DB_ACCESSION_CODE pstr("ndb_seq_db_accession_code")
-#define CIFTAG_NDB_SEQ_DB_SEQ_NUM pstr("ndb_seq_db_seq_num")
-#define CIFTAG_NDB_SYNONYMS pstr("ndb_synonyms")
-#define CIFTAG_NUM pstr("num")
-#define CIFTAG_NUMBER_ATOMS_NH pstr("number_atoms_nh")
-#define CIFTAG_NUMBER_STRANDS pstr("number_strands")
-#define CIFTAG_OCCUPANCY pstr("occupancy")
-#define CIFTAG_OCCUPANCY_ESD pstr("occupancy_esd")
-#define CIFTAG_ORIGX11 pstr("origx[1][1]")
-#define CIFTAG_ORIGX12 pstr("origx[1][2]")
-#define CIFTAG_ORIGX13 pstr("origx[1][3]")
-#define CIFTAG_ORIGX21 pstr("origx[2][1]")
-#define CIFTAG_ORIGX22 pstr("origx[2][2]")
-#define CIFTAG_ORIGX23 pstr("origx[2][3]")
-#define CIFTAG_ORIGX31 pstr("origx[3][1]")
-#define CIFTAG_ORIGX32 pstr("origx[3][2]")
-#define CIFTAG_ORIGX33 pstr("origx[3][3]")
-#define CIFTAG_ORIGX_VECTOR1 pstr("origx_vector[1]")
-#define CIFTAG_ORIGX_VECTOR2 pstr("origx_vector[2]")
-#define CIFTAG_ORIGX_VECTOR3 pstr("origx_vector[3]")
-#define CIFTAG_PDB_ID pstr("pdb_id")
-#define CIFTAG_PDB_MON_ID pstr("pdb_mon_id")
-#define CIFTAG_PDB_STRAND_ID pstr("pdb_strand_id")
-#define CIFTAG_PDBX_DB_ACCESSION pstr("pdbx_db_accession")
-#define CIFTAG_PDBX_DB_ALIGN_BEG_INS_CODE pstr("pdbx_db_align_beg_ins_code")
-#define CIFTAG_PDBX_DB_ALIGN_END_INS_CODE pstr("pdbx_db_align_end_ins_code")
-#define CIFTAG_PDBX_PDB_ID_CODE pstr("pdbx_PDB_id_code")
-#define CIFTAG_PDBX_PDB_INS_CODE pstr("pdbx_PDB_ins_code")
-#define CIFTAG_PDBX_PDB_MODEL_NUM pstr("pdbx_PDB_model_num")
-#define CIFTAG_PDBX_STRAND_ID pstr("pdbx_strand_id")
-#define CIFTAG_RANGE_1_BEG_LABEL_ATOM_ID pstr("range_1_beg_label_atom_id")
-#define CIFTAG_RANGE_1_BEG_LABEL_SEQ_ID pstr("range_1_beg_label_seq_id")
-#define CIFTAG_RANGE_1_END_LABEL_ATOM_ID pstr("range_1_end_label_atom_id")
-#define CIFTAG_RANGE_1_END_LABEL_SEQ_ID pstr("range_1_end_label_seq_id")
-#define CIFTAG_RANGE_ID_1 pstr("range_id_1")
-#define CIFTAG_RANGE_ID_2 pstr("range_id_2")
-#define CIFTAG_RCSB_RECORD_REVISED_1 pstr("rcsb_record_revised_1")
-#define CIFTAG_RCSB_RECORD_REVISED_2 pstr("rcsb_record_revised_2")
-#define CIFTAG_RCSB_RECORD_REVISED_3 pstr("rcsb_record_revised_3")
-#define CIFTAG_RCSB_RECORD_REVISED_4 pstr("rcsb_record_revised_4")
-#define CIFTAG_PDBX_SEQ_ALIGN_BEG_INS_CODE pstr("pdbx_seq_align_beg_ins_code")
-#define CIFTAG_PDBX_SEQ_ALIGN_END_INS_CODE pstr("pdbx_seq_align_end_ins_code")
-#define CIFTAG_PTNR1_LABEL_ASYM_ID pstr("ptnr1_label_asym_id")
-#define CIFTAG_PTNR1_LABEL_COMP_ID pstr("ptnr1_label_comp_id")
-#define CIFTAG_PTNR1_LABEL_SEQ_ID pstr("ptnr1_label_seq_id")
-#define CIFTAG_REF_ID pstr("ref_id")
-#define CIFTAG_REPLACES pstr("replaces")
-#define CIFTAG_REPLACE_PDB_ID pstr("replace_pdb_id")
-#define CIFTAG_SEGMENT_ID pstr("segment_id")
-#define CIFTAG_SEQ_ALIGN_BEG pstr("seq_align_beg")
-#define CIFTAG_SEQ_ALIGN_END pstr("seq_align_end")
-#define CIFTAG_SEQ_NUM pstr("seq_num")
-#define CIFTAG_SENSE pstr("sense")
-#define CIFTAG_SHEET_ID pstr("sheet_id")
-#define CIFTAG_SOURCE pstr("source")
-#define CIFTAG_SPACE_GROUP_NAME_H_M pstr("space_group_name_H-M")
-#define CIFTAG_TEXT pstr("text")
-#define CIFTAG_TITLE pstr("title")
-#define CIFTAG_TYPE pstr("type")
-#define CIFTAG_TYPE_SYMBOL pstr("type_symbol")
-#define CIFTAG_VECTOR1 pstr("vector[1]")
-#define CIFTAG_VECTOR2 pstr("vector[2]")
-#define CIFTAG_VECTOR3 pstr("vector[3]")
-#define CIFTAG_U11 pstr("u[1][1]")
-#define CIFTAG_U11_ESD pstr("u[1][1]_esd")
-#define CIFTAG_U12 pstr("u[1][2]")
-#define CIFTAG_U12_ESD pstr("u[1][2]_esd")
-#define CIFTAG_U13 pstr("u[1][3]")
-#define CIFTAG_U13_ESD pstr("u[1][3]_esd")
-#define CIFTAG_U22 pstr("u[2][2]")
-#define CIFTAG_U22_ESD pstr("u[2][2]_esd")
-#define CIFTAG_U23 pstr("u[2][3]")
-#define CIFTAG_U23_ESD pstr("u[2][3]_esd")
-#define CIFTAG_U33 pstr("u[3][3]")
-#define CIFTAG_U33_ESD pstr("u[3][3]_esd")
-#define CIFTAG_Z_PDB pstr("z_pdb")
-
-#define CIFTAG_CONN_PTNR1_AUTH_ATOM_ID pstr("ptnr1_auth_atom_id")
-#define CIFTAG_CONN_PDBX_PTNR1_AUTH_ALT_ID pstr("pdbx_ptnr1_auth_alt_id")
-#define CIFTAG_CONN_PTNR1_AUTH_COMP_ID pstr("ptnr1_auth_comp_id")
-#define CIFTAG_CONN_PTNR1_AUTH_ASYM_ID pstr("ptnr1_auth_asym_id")
-#define CIFTAG_CONN_PTNR1_AUTH_SEQ_ID pstr("ptnr1_auth_seq_id")
-#define CIFTAG_CONN_PDBX_PTNR1_PDB_INS_CODE pstr("pdbx_ptnr1_PDB_ins_code")
-#define CIFTAG_CONN_DIST pstr("link_dist")
-#define CIFTAG_CONN_PTNR2_AUTH_ATOM_ID pstr("ptnr2_auth_atom_id")
-#define CIFTAG_CONN_PDBX_PTNR2_AUTH_ALT_ID pstr("pdbx_ptnr2_auth_alt_id")
-#define CIFTAG_CONN_PTNR2_AUTH_COMP_ID pstr("ptnr2_auth_comp_id")
-#define CIFTAG_CONN_PTNR2_AUTH_ASYM_ID pstr("ptnr2_auth_asym_id")
-#define CIFTAG_CONN_PTNR2_AUTH_SEQ_ID pstr("ptnr2_auth_seq_id")
-#define CIFTAG_CONN_PDBX_PTNR2_PDB_INS_CODE pstr("pdbx_ptnr2_PDB_ins_code")
-#define CIFTAG_CONN_PTNR1_SYMMETRY pstr("ptnr1_symmetry")
-#define CIFTAG_CONN_PTNR2_SYMMETRY pstr("ptnr2_symmetry")
-#define CIFTAG_CONN_NAME pstr("link_name")
-
-
-#endif
-
diff --git a/mmdb/mmdb_coormngr.cpp b/mmdb/mmdb_coormngr.cpp
deleted file mode 100755
index 8ec1900..0000000
--- a/mmdb/mmdb_coormngr.cpp
+++ /dev/null
@@ -1,4360 +0,0 @@
-// $Id: mmdb_coormngr.cpp,v 1.28 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 26.01.09 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : mmdb_coormngr <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CBrick ( space brick )
-// ~~~~~~~~~ CMBrick ( "multiple" space brick )
-// CMMDBCoorManager ( MMDB atom coordinate manager )
-//
-// Copyright (C) E. Krissinel 2000-2009
-//
-// =================================================================
-//
-
-#ifndef __MATH_H
-#include <math.h>
-#endif
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __LinAlg__
-#include "linalg_.h"
-#endif
-
-#ifndef __MMDB_CoorMngr__
-#include "mmdb_coormngr.h"
-#endif
-
-#ifndef __MMDB_Tables__
-#include "mmdb_tables.h"
-#endif
-
-
-// =========================== CBrick ==============================
-
-CBrick::CBrick() {
- InitBrick();
-}
-
-CBrick::~CBrick() {
- Clear();
-}
-
-void CBrick::InitBrick() {
- Atom = NULL;
- id = NULL;
- nAtoms = 0;
- nAllocAtoms = 0;
-}
-
-void CBrick::Clear() {
- if (Atom) delete[] Atom;
- FreeVectorMemory ( id,0 );
- Atom = NULL;
- nAtoms = 0;
- nAllocAtoms = 0;
-}
-
-void CBrick::AddAtom ( PCAtom A, int atomid ) {
-int i;
-PPCAtom Atom1;
-ivector id1;
- if (nAtoms>=nAllocAtoms) {
- nAllocAtoms = nAtoms+10;
- Atom1 = new PCAtom[nAllocAtoms];
- GetVectorMemory ( id1,nAllocAtoms,0 );
- for (i=0;i<nAtoms;i++) {
- Atom1[i] = Atom[i];
- id1 [i] = id [i];
- }
- for (i=nAtoms;i<nAllocAtoms;i++) {
- Atom1[i] = NULL;
- id1 [i] = -1;
- }
- if (Atom) delete[] Atom;
- FreeVectorMemory ( id,0 );
- Atom = Atom1;
- id = id1;
- }
- Atom[nAtoms] = A;
- id [nAtoms] = atomid;
- nAtoms++;
-}
-
-
-// =========================== CMBrick =============================
-
-CMBrick::CMBrick ( int nStructures ) {
- InitMBrick ( nStructures );
-}
-
-CMBrick::~CMBrick() {
- Clear();
-}
-
-void CMBrick::InitMBrick ( int nStructures ) {
-int i;
- nStruct = nStructures;
- Atom = new PPCAtom[nStruct];
- id = new ivector[nStruct];
- GetVectorMemory ( nAtoms,nStruct,0 );
- GetVectorMemory ( nAllocAtoms,nStruct,0 );
- for (i=0;i<nStruct;i++) {
- Atom [i] = NULL;
- id [i] = NULL;
- nAtoms [i] = 0;
- nAllocAtoms[i] = 0;
- }
-}
-
-void CMBrick::Clear() {
-int i;
- if (Atom) {
- for (i=0;i<nStruct;i++)
- if (Atom[i]) delete[] Atom[i];
- delete[] Atom;
- Atom = NULL;
- }
- FreeMatrixMemory ( id,nStruct,0,0 );
- FreeVectorMemory ( nAtoms,0 );
- FreeVectorMemory ( nAllocAtoms,0 );
- nStruct = 0;
-}
-
-void CMBrick::AddAtom ( PCAtom A, int structNo, int atomid ) {
-int i,natoms,nalloc;
-PPCAtom Atom0,Atom1;
-ivector id0,id1;
- natoms = nAtoms [structNo];
- nalloc = nAllocAtoms[structNo];
- Atom0 = Atom [structNo];
- id0 = id [structNo];
- if (natoms>=nalloc) {
- nalloc = natoms+10;
- Atom1 = new PCAtom[nalloc];
- GetVectorMemory ( id1,nalloc,0 );
- for (i=0;i<natoms;i++) {
- Atom1[i] = Atom0[i];
- id1 [i] = id0 [i];
- }
- for (i=natoms;i<nalloc;i++) {
- Atom1[i] = NULL;
- id1 [i] = -1;
- }
- if (Atom0) delete[] Atom0;
- FreeVectorMemory ( id0,0 );
- Atom[structNo] = Atom1;
- id [structNo] = id1;
- nAllocAtoms[structNo] = nalloc;
- Atom0 = Atom1;
- id0 = id1;
- }
- Atom0 [natoms] = A;
- id0 [natoms] = atomid;
- nAtoms[structNo] = natoms+1;
-}
-
-
-
-// ==================== CGenSym ========================
-
-CGenSym::CGenSym() : CSymOps() {
- InitGenSym();
-}
-
-CGenSym::CGenSym ( RPCStream Object ) : CSymOps(Object) {
- InitGenSym();
-}
-
-CGenSym::~CGenSym() {} // virtual FreeMmeory is called by ~CSymOps()
-
-void CGenSym::InitGenSym() {
- chID1 = NULL;
- chID2 = NULL;
- nChains = NULL;
- nOpAlloc = 0;
-}
-
-void CGenSym::FreeMemory() {
-int i;
- for (i=0;i<nOpAlloc;i++) {
- if (chID1[i]) delete[] chID1[i];
- if (chID2[i]) delete[] chID2[i];
- }
- if (chID1) delete[] chID1;
- if (chID2) delete[] chID2;
- FreeVectorMemory ( nChains,0 );
- nOpAlloc = 0;
- CSymOps::FreeMemory();
-}
-
-int CGenSym::AddSymOp ( cpstr XYZOperation ) {
-int RC,i;
-PChainID * ch1ID;
-PChainID * ch2ID;
-ivector nChains1;
-
- RC = CSymOps::AddSymOp ( XYZOperation );
- if (Nops>nOpAlloc) {
- ch1ID = new PChainID[Nops];
- ch2ID = new PChainID[Nops];
- GetVectorMemory ( nChains1,Nops,0 );
- for (i=0;i<nOpAlloc;i++) {
- ch1ID[i] = chID1[i];
- ch2ID[i] = chID2[i];
- nChains1[i] = nChains[i];
- }
- for (i=nOpAlloc;i<Nops;i++) {
- ch1ID[i] = NULL;
- ch2ID[i] = NULL;
- nChains1[i] = 0;
- }
- if (chID1) delete[] chID1;
- if (chID2) delete[] chID2;
- FreeVectorMemory ( nChains,0 );
- chID1 = ch1ID;
- chID2 = ch2ID;
- nChains = nChains1;
- nOpAlloc = Nops;
- }
- return RC;
-}
-
-int CGenSym::AddRenChain ( int Nop, const ChainID ch1,
- const ChainID ch2 ) {
-int i;
-PChainID c1,c2;
- if ((0<=Nop) && (Nop<Nops)) {
- c1 = new ChainID[nChains[Nop]+1];
- c2 = new ChainID[nChains[Nop]+1];
- for (i=0;i<nChains[Nop];i++) {
- strcpy ( c1[i],chID1[Nop][i] );
- strcpy ( c2[i],chID2[Nop][i] );
- }
- strcpy ( c1[nChains[Nop]],ch1 );
- strcpy ( c2[nChains[Nop]],ch2 );
- if (chID1[Nop]) delete[] chID1[Nop];
- if (chID2[Nop]) delete[] chID2[Nop];
- chID1[Nop] = c1;
- chID2[Nop] = c2;
- nChains[Nop]++;
- return SYMOP_Ok;
- } else
- return SYMOP_NoSymOps;
-}
-
-void CGenSym::Copy ( PCSymOps GenSym ) {
-int i,j;
- CSymOps::Copy ( GenSym );
- if (Nops>0) {
- nOpAlloc = Nops;
- chID1 = new PChainID[Nops];
- chID2 = new PChainID[Nops];
- GetVectorMemory ( nChains,Nops,0 );
- for (i=0;i<Nops;i++) {
- nChains[i] = PCGenSym(GenSym)->nChains[i];
- if (nChains[i]<=0) {
- chID1[i] = NULL;
- chID2[i] = NULL;
- } else {
- chID1[i] = new ChainID[nChains[i]];
- chID2[i] = new ChainID[nChains[i]];
- for (j=0;j<nChains[i];j++) {
- strcpy ( chID1[i][j],PCGenSym(GenSym)->chID1[i][j] );
- strcpy ( chID2[i][j],PCGenSym(GenSym)->chID2[i][j] );
- }
- }
- }
- }
-}
-
-void CGenSym::write ( RCFile f ) {
-int i,j;
-byte Version=1;
- f.WriteByte ( &Version );
- CSymOps::write ( f );
- f.WriteInt ( &nOpAlloc );
- for (i=0;i<nOpAlloc;i++) {
- f.WriteInt ( &(nChains[i]) );
- for (j=0;j<nChains[i];j++) {
- f.WriteTerLine ( chID1[i][j],False );
- f.WriteTerLine ( chID2[i][j],False );
- }
- }
-}
-
-void CGenSym::read ( RCFile f ) {
-int i,j;
-byte Version;
- f.ReadByte ( &Version );
- CSymOps::read ( f );
- f.ReadInt ( &nOpAlloc );
- if (nOpAlloc>0) {
- chID1 = new PChainID[nOpAlloc];
- chID2 = new PChainID[nOpAlloc];
- GetVectorMemory ( nChains,nOpAlloc,0 );
- for (i=0;i<nOpAlloc;i++) {
- f.ReadInt ( &(nChains[i]) );
- if (nChains[i]>0) {
- chID1[i] = new ChainID[nChains[i]];
- chID2[i] = new ChainID[nChains[i]];
- for (j=0;j<nChains[i];j++) {
- f.ReadTerLine ( chID1[i][j],False );
- f.ReadTerLine ( chID2[i][j],False );
- }
- } else {
- chID1[i] = NULL;
- chID2[i] = NULL;
- }
- }
- }
-}
-
-
-MakeStreamFunctions(CGenSym)
-
-
-
-// ======================= CContactIndex ==========================
-
-void SContact::Copy ( RSContact c ) {
- id1 = c.id1;
- id2 = c.id2;
- group = c.group;
- dist = c.dist;
-}
-
-void SContact::Swap ( RSContact c ) {
-int ib;
-long lb;
-realtype rb;
- ib = id1; id1 = c.id1; c.id1 = ib;
- ib = id2; id2 = c.id2; c.id2 = ib;
- lb = group; group = c.group; c.group = lb;
- rb = dist; dist = c.dist; c.dist = rb;
-}
-
-DefineClass(CContactIndex)
-
-class CContactIndex {
-
- friend class CMMDBSelManager;
-
- public :
-
- CContactIndex ( PSContact contact,
- int maxlen,
- int ncontacts,
- int max_alloc );
- ~CContactIndex();
-
- void AddContact ( int id1, int id2, realtype dist, int group );
- void GetIndex ( RPSContact contact, int & ncontacts );
-
- protected :
-
- PSContact contact_index; // contact index
- int max_index; // if <=0 then dynamical index
- // otherwise fixed by max_index
- int n_contacts; // number of contacts
- int alloc_index; // physical length of contact_index
- // when dynamical
- int alloc_max; // physical limit on allocation
-
-};
-
-
-CContactIndex::CContactIndex ( PSContact contact,
- int maxlen,
- int ncontacts,
- int max_alloc ) {
- contact_index = contact;
- max_index = maxlen;
- if (!contact_index) n_contacts = 0;
- else n_contacts = IMax(0,ncontacts);
- alloc_index = n_contacts;
- alloc_max = n_contacts + max_alloc;
-}
-
-CContactIndex::~CContactIndex() {
- if (contact_index) delete[] contact_index;
- contact_index = NULL;
- n_contacts = 0;
- alloc_index = 0;
-}
-
-void CContactIndex::AddContact ( int id1, int id2, realtype dist,
- int group ) {
-PSContact cont1;
-int i;
-
- if ((alloc_max<=0) || (n_contacts<alloc_max)) {
- if (max_index>0) {
- if (n_contacts<max_index) {
- contact_index[n_contacts].id1 = id1;
- contact_index[n_contacts].id2 = id2;
- contact_index[n_contacts].dist = dist;
- contact_index[n_contacts].group = group;
- }
- } else {
- if (n_contacts>=alloc_index) {
- alloc_index = n_contacts+IMax(alloc_index/4+10,10);
- if ((alloc_max>0) && (alloc_index>alloc_max))
- alloc_index = alloc_max;
- cont1 = new SContact[alloc_index];
- for (i=0;i<n_contacts;i++)
- cont1[i].Copy ( contact_index[i] );
- if (contact_index) delete[] contact_index;
- contact_index = cont1;
- }
- contact_index[n_contacts].id1 = id1;
- contact_index[n_contacts].id2 = id2;
- contact_index[n_contacts].dist = dist;
- contact_index[n_contacts].group = group;
- }
- n_contacts++;
- }
-}
-
-void CContactIndex::GetIndex ( RPSContact contact, int & ncontacts ) {
- contact = contact_index;
- ncontacts = n_contacts;
- contact_index = NULL;
- n_contacts = 0;
- alloc_index = 0;
-}
-
-
-// ======================== CMContact =============================
-
-CMContact::CMContact ( int nStructures ) {
-int i;
- nStruct = nStructures;
- if (nStruct>0) {
- Atom = new PPCAtom[nStruct];
- id = new ivector[nStruct];
- GetVectorMemory ( nAtoms,nStruct,0 );
- GetVectorMemory ( nAlloc,nStruct,0 );
- for (i=0;i<nStruct;i++) {
- Atom [i] = NULL;
- id [i] = NULL;
- nAtoms[i] = 0;
- nAlloc[i] = 0;
- }
- } else {
- Atom = NULL;
- nAtoms = NULL;
- nAlloc = NULL;
- }
-}
-
-CMContact::~CMContact() {
-int i;
- if (Atom) {
- for (i=0;i<nStruct;i++)
- if (Atom[i]) delete[] Atom[i];
- delete[] Atom;
- Atom = NULL;
- }
- FreeMatrixMemory ( id,nStruct,0,0 );
- FreeVectorMemory ( nAtoms,0 );
- FreeVectorMemory ( nAlloc,0 );
- nStruct = 0;
-}
-
-void CMContact::AddContact ( PCAtom A, int structNo, int atomid ) {
-PPCAtom A1,A2;
-ivector id1,id2;
-int nat,nal,i;
- A1 = Atom [structNo];
- id1 = id [structNo];
- nat = nAtoms[structNo];
- nal = nAlloc[structNo];
- if (nat>=nal) {
- nal = nat+10;
- A2 = new PCAtom[nal];
- GetVectorMemory ( id2,nal,0 );
- for (i=0;i<nat;i++) {
- A2 [i] = A1 [i];
- id2[i] = id1[i];
- }
- for (i=nat;i<nal;i++) {
- A2 [i] = NULL;
- id2[i] = 0;
- }
- if (A1) delete[] A1;
- FreeVectorMemory ( id1,0 );
- Atom[structNo] = A2;
- id [structNo] = id2;
- A1 = A2;
- id1 = id2;
- nAlloc[structNo] = nal;
- }
- A1 [nat] = A;
- id1[nat] = atomid;
- nAtoms[structNo] = nat+1;
-}
-
-
-void DeleteMContacts ( PPCMContact & mcontact, int nContacts ) {
-int i;
- if (mcontact) {
- for (i=0;i<nContacts;i++)
- if (mcontact[i]) delete mcontact[i];
- delete[] mcontact;
- mcontact = NULL;
- }
-}
-
-
-// ==================== CMMDBCoorManager =====================
-
-CMMDBCoorManager::CMMDBCoorManager() : CMMDBFile() {
- InitMMDBCoorManager();
-}
-
-CMMDBCoorManager::CMMDBCoorManager ( RPCStream Object )
- : CMMDBFile(Object) {
- InitMMDBCoorManager();
-}
-
-CMMDBCoorManager::~CMMDBCoorManager() {
- RemoveBricks ();
- RemoveMBricks();
-}
-
-void CMMDBCoorManager::ResetManager() {
- CMMDBFile::ResetManager();
- RemoveBricks ();
- RemoveMBricks ();
- InitMMDBCoorManager();
-}
-
-void CMMDBCoorManager::InitMMDBCoorManager() {
-
- CoorIDCode = CID_Ok;
-
- brick_size = 6.0; // angstroms
- xbrick_0 = 0.0;
- ybrick_0 = 0.0;
- zbrick_0 = 0.0;
- nbrick_x = 0;
- nbrick_y = 0;
- nbrick_z = 0;
- Brick = NULL;
-
- mbrick_size = 6.0; // angstroms
- xmbrick_0 = 0.0;
- ymbrick_0 = 0.0;
- zmbrick_0 = 0.0;
- nmbrick_x = 0;
- nmbrick_y = 0;
- nmbrick_z = 0;
- MBrick = NULL;
-
-}
-
-
-int CMMDBCoorManager::SetDefaultCoorID ( cpstr CID ) {
- return DefPath.SetPath ( CID );
-}
-
-PCModel CMMDBCoorManager::GetFirstDefinedModel() {
-PCModel mdl;
-int i;
- mdl = NULL;
- for (i=0;(i<nModels) && (!mdl);i++)
- mdl = Model[i];
- return mdl;
-}
-
-int CMMDBCoorManager::GetFirstModelNum() {
-PCModel mdl;
-int i;
- mdl = NULL;
- for (i=0;(i<nModels) && (!mdl);i++)
- mdl = Model[i];
- if (mdl) return mdl->GetSerNum();
- return 1;
-}
-
-
-PCModel CMMDBCoorManager::GetModel ( int modelNo ) {
- if ((modelNo>=1) && (modelNo<=nModels))
- return Model[modelNo-1];
- else return NULL;
-}
-
-PCModel CMMDBCoorManager::GetModel ( cpstr CID ) {
-int modno,sn,rc;
-ChainID chname;
-InsCode ic;
-ResName resname;
-AtomName aname;
-Element elname;
-AltLoc aloc;
-
- CoorIDCode = CID_Ok;
- rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
- aname,elname,aloc,&DefPath );
- if ((rc<0) || (rc & APATH_WC_ModelNo)) {
- CoorIDCode = CID_WrongPath;
- return NULL;
- }
-
- if ((modno>=1) && (modno<=nModels))
- return Model[modno-1];
- else return NULL;
-
-}
-
-void CMMDBCoorManager::GetModelTable ( PPCModel & modelTable,
- int & NumberOfModels ) {
- NumberOfModels = nModels;
- modelTable = Model;
-}
-
-int CMMDBCoorManager::DeleteModel ( int modelNo ) {
- if ((modelNo>=1) && (modelNo<=nModels)) {
- if (Model[modelNo-1]) {
- Exclude = False;
- delete Model[modelNo-1];
- Model[modelNo-1] = NULL;
- Exclude = True;
- return 1;
- }
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteModel ( cpstr CID ) {
-int modno,sn,rc;
-ChainID chname;
-InsCode ic;
-ResName resname;
-AtomName aname;
-Element elname;
-AltLoc aloc;
-
- CoorIDCode = CID_Ok;
- rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
- aname,elname,aloc,&DefPath );
- if ((rc<0) || (rc & APATH_WC_ModelNo)) {
- CoorIDCode = CID_WrongPath;
- return 0;
- }
-
- if ((modno>=1) && (modno<=nModels)) {
- if (Model[modno-1]) {
- Exclude = False;
- delete Model[modno-1];
- Model[modno-1] = NULL;
- Exclude = True;
- return 1;
- }
- }
-
- return 0;
-
-}
-
-
-int CMMDBCoorManager::DeleteSolvent() {
-int i,k;
- Exclude = False;
- k = 0;
- for (i=0;i<nModels;i++)
- if (Model[i]) {
- k += Model[i]->DeleteSolvent();
- Model[i]->TrimChainTable();
- if (Model[i]->nChains<=0) {
- delete Model[i];
- Model[i] = NULL;
- }
- }
- Exclude = True;
- return k;
-}
-
-
-// ---------------- Adding/Inserting models ---------------
-
-int CMMDBCoorManager::AddModel ( PCModel model ) {
-PPCModel model1;
-int i,nnat,nat1;
-
- for (i=0;i<nModels;i++)
- if (Model[i]==model) return -i;
-
- nnat = model->GetNumberOfAtoms ( True );
- AddAtomArray ( nnat ); // get space for new atoms
-
- if (model->GetCoordHierarchy()) {
- SwitchModel ( nModels+1 ); // get one more model at the end
- nat1 = nAtoms;
- Model[nModels-1]->_copy ( model,Atom,nat1 );
- Model[nModels-1]->serNum = nModels;
- nAtoms = nat1;
- } else {
- model1 = new PCModel[nModels+1];
- for (i=0;i<nModels;i++)
- model1[i] = Model[i];
- if (Model) delete[] Model;
- Model = model1;
- Model[nModels] = model;
- Model[nModels]->SetMMDBManager ( PCMMDBManager(this),nModels+1 );
- Model[nModels]->CheckInAtoms();
- nModels++;
- }
-
- return nModels;
-
-}
-
-int CMMDBCoorManager::InsModel ( PCModel model, int modelNo ) {
- AddModel ( model );
- RotateModels ( modelNo,nModels,1 );
- return nModels;
-}
-
-void CMMDBCoorManager::RotateModels ( int modelNo1, int modelNo2,
- int rotdir ) {
-PCModel model;
-PPCAtom A;
-int m1,m2,i11,i12,i21,i22,nat,i,k;
-
- m1 = IMax ( 0,modelNo1-1 );
- m2 = IMin ( nModels,modelNo2) - 1;
- if (m1>m2) ISwap ( m1,m2 );
-
- if (m1!=m2) {
-
- if (Model[m1] && Model[m2]) {
- Model[m1]->GetAIndexRange ( i11,i12 );
- Model[m2]->GetAIndexRange ( i21,i22 );
- if ((i11<i12) && (i21<i22) && (i12<i22)) {
- i11--; i12--;
- i21--; i22--;
- if (rotdir<0) {
- // rotate anticlockwise
- nat = i12-i11+1;
- A = new PCAtom[nat];
- k = 0;
- for (i=i11;i<=i12;i++)
- A[k++] = Atom[i];
- k = i11;
- for (i=i12+1;i<=i22;i++) {
- Atom[k] = Atom[i];
- if (Atom[k]) Atom[k]->index = k+1;
- k++;
- }
- for (i=0;i<nat;i++) {
- Atom[k] = A[i];
- if (Atom[k]) Atom[k]->index = k+1;
- k++;
- }
- } else {
- // rotate anticlockwise
- nat = i22-i21+1;
- A = new PCAtom[nat];
- k = 0;
- for (i=i21;i<=i22;i++)
- A[k++] = Atom[i];
- k = i22;
- for (i=i21-1;i>=i11;i--) {
- Atom[k] = Atom[i];
- if (Atom[k]) Atom[k]->index = k+1;
- k--;
- }
- for (i=nat-1;i>=0;i--) {
- Atom[k] = A[i];
- if (Atom[k]) Atom[k]->index = k+1;
- k--;
- }
- }
- delete[] A;
- }
- }
-
- if (rotdir<0) {
- // rotate anticlockwise
- model = Model[m1];
- for (i=m1;i<m2;i++) {
- Model[i] = Model[i+1];
- Model[i]->serNum = i+1;
- }
- Model[m2] = model;
- Model[m2]->serNum = m2+1;
- } else {
- // rotate clockwise
- model = Model[m2];
- for (i=m2;i>m1;i--) {
- Model[i] = Model[i-1];
- Model[i]->serNum = i+1;
- }
- Model[m1] = model;
- Model[m1]->serNum = m1+1;
- }
-
- }
-
-}
-
-
-void CMMDBCoorManager::SwapModels ( int modelNo1, int modelNo2 ) {
-PCModel model;
-PPCAtom A;
-int m1,m2,i11,i12,i21,i22,i,k,n;
-
- n = 0; // tp depress "uninitialized" warning
-
- m1 = IMax ( 0,modelNo1-1 );
- m2 = IMin ( nModels,modelNo2) - 1;
- if (m1>m2) ISwap ( m1,m2 );
-
- if (m1!=m2) {
-
- if (Model[m1])
- Model[m1]->GetAIndexRange ( i11,i12 );
- else {
- n = m1;
- while ((!Model[n]) && (n<m2)) n++;
- if (n<m2) {
- Model[n]->GetAIndexRange ( i11,i12 );
- i12 = i11-1;
- } else
- n = -1;
- }
-
- if (n>=0) {
- if (Model[m2])
- Model[m2]->GetAIndexRange ( i21,i22 );
- else {
- n = m2;
- while ((!Model[n]) && (m1<n)) n--;
- if (m1<n) {
- Model[n]->GetAIndexRange ( i21,i22 );
- i22 = i21-1;
- } else
- n = -1;
- }
- }
-
- if (n>=0) {
-
- i11--; i12--;
- i21--; i22--;
-
- A = new PCAtom[AtmLen];
- k = 0;
-
- for (i=0 ;i<i11 ;i++) A[k++] = Atom[i];
- for (i=i21 ;i<=i22 ;i++) A[k++] = Atom[i];
- for (i=i12+1 ;i<i21 ;i++) A[k++] = Atom[i];
- for (i=i11 ;i<=i12 ;i++) A[k++] = Atom[i];
-
- for (i=0 ;i<nAtoms;i++) if (A[i]) A[i]->index = i+1;
- for (i=nAtoms;i<AtmLen;i++) A[i] = NULL;
-
- if (Atom) delete[] Atom;
- Atom = A;
-
- }
-
- model = Model[m2];
- Model[m2] = Model[m1];
- Model[m1] = model;
-
- Model[m1]->serNum = m1+1;
- Model[m2]->serNum = m2+1;
-
- }
-
-}
-
-
-
-
-PCChain CMMDBCoorManager::GetChain ( int modelNo, const ChainID chainID ) {
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->GetChain ( chainID );
- }
- return NULL;
-}
-
-PCChain CMMDBCoorManager::GetChain ( int modelNo, int chainNo ) {
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->GetChain ( chainNo );
- }
- return NULL;
-}
-
-PCChain CMMDBCoorManager::GetChain ( cpstr CID ) {
-int modno,sn,rc;
-ChainID chname;
-InsCode ic;
-ResName resname;
-AtomName aname;
-Element elname;
-AltLoc aloc;
-
- CoorIDCode = CID_Ok;
- rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
- aname,elname,aloc,&DefPath );
- if ((rc<0) || (rc & (APATH_WC_ModelNo | APATH_WC_ChainID))) {
- CoorIDCode = CID_WrongPath;
- return NULL;
- }
- return GetChain ( modno,chname );
-
-}
-
-void CMMDBCoorManager::GetChainTable ( int modelNo,
- PPCChain & chainTable,
- int & NumberOfChains ) {
- chainTable = NULL;
- NumberOfChains = 0;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1]) {
- chainTable = Model[modelNo-1]->Chain;
- NumberOfChains = Model[modelNo-1]->nChains;
- }
- }
-}
-
-void CMMDBCoorManager::GetChainTable ( cpstr CID,
- PPCChain & chainTable,
- int & NumberOfChains ) {
-int modno,sn,rc;
-ChainID chname;
-InsCode ic;
-ResName resname;
-AtomName aname;
-Element elname;
-AltLoc aloc;
-
- chainTable = NULL;
- NumberOfChains = 0;
- CoorIDCode = CID_Ok;
-
- rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
- aname,elname,aloc,&DefPath );
- if ((rc<0) || (rc & APATH_WC_ModelNo)) {
- CoorIDCode = CID_WrongPath;
- return;
- }
-
- if ((0<modno) && (modno<=nModels)) {
- if (Model[modno-1]) {
- chainTable = Model[modno-1]->Chain;
- NumberOfChains = Model[modno-1]->nChains;
- }
- }
-}
-
-
-int CMMDBCoorManager::DeleteChain ( int modelNo, const ChainID chID ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteChain ( chID );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteChain ( int modelNo, int chainNo ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteChain ( chainNo );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAllChains ( int modelNo ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAllChains();
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAllChains() {
-int i,k;
- k = 0;
- for (i=0;i<nModels;i++)
- if (Model[i]) k += Model[i]->DeleteAllChains();
- return k;
-}
-
-int CMMDBCoorManager::AddChain ( int modelNo, PCChain chain ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->AddChain ( chain );
- }
- return 0;
-}
-
-
-PCResidue CMMDBCoorManager::GetResidue ( int modelNo,
- const ChainID chainID,
- int seqNo,
- const InsCode insCode ) {
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->GetResidue ( chainID,seqNo,insCode );
- }
- return NULL;
-}
-
-PCResidue CMMDBCoorManager::GetResidue ( int modelNo, int chainNo,
- int seqNo,
- const InsCode insCode ) {
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->GetResidue ( chainNo,seqNo,insCode );
- }
- return NULL;
-}
-
-PCResidue CMMDBCoorManager::GetResidue ( int modelNo,
- const ChainID chainID,
- int resNo ) {
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->GetResidue ( chainID,resNo );
- }
- return NULL;
-}
-
-PCResidue CMMDBCoorManager::GetResidue ( int modelNo, int chainNo,
- int resNo ) {
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->GetResidue ( chainNo,resNo );
- }
- return NULL;
-}
-
-PCResidue CMMDBCoorManager::GetResidue ( cpstr CID ) {
-int modno,sn,rc;
-ChainID chname;
-InsCode ic;
-ResName resname;
-AtomName aname;
-Element elname;
-AltLoc aloc;
-
- CoorIDCode = CID_Ok;
- rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
- aname,elname,aloc,&DefPath );
- if ((rc<0) || (rc & (APATH_WC_ModelNo | APATH_WC_ChainID |
- APATH_WC_SeqNum | APATH_WC_InsCode))) {
- CoorIDCode = CID_WrongPath;
- return NULL;
- }
- return GetResidue ( modno,chname,sn,ic );
-
-}
-
-
-int CMMDBCoorManager::GetResidueNo ( int modelNo,
- const ChainID chainID,
- int seqNo,
- const InsCode insCode ) {
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->GetResidueNo ( chainID,seqNo,insCode );
- }
- return -3;
-}
-
-int CMMDBCoorManager::GetResidueNo ( int modelNo, int chainNo,
- int seqNo,
- const InsCode insCode ) {
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->GetResidueNo ( chainNo,seqNo,insCode );
- }
- return -3;
-}
-
-void CMMDBCoorManager::GetResidueTable ( PPCResidue & resTable,
- int & NumberOfResidues ) {
-// resTable has to be NULL or it will be reallocated. The
-// application is responsible for deallocating the resTable (but not
-// of its residues!). This does not apply to other GetResidueTable
-// functions.
-PPCChain chain;
-PPCResidue res;
-int i,j,k,n,nChains,nResidues;
-
- if (resTable) {
- delete[] resTable;
- resTable = NULL;
- }
-
- NumberOfResidues = 0;
- for (i=0;i<nModels;i++)
- if (Model[i]) {
- Model[i]->GetChainTable ( chain,nChains );
- for (j=0;j<Model[i]->nChains;j++)
- if (chain[j]) {
- chain[j]->GetResidueTable ( res,nResidues );
- NumberOfResidues += nResidues;
- }
- }
-
- if (NumberOfResidues>0) {
- resTable = new PCResidue[NumberOfResidues];
- k = 0;
- for (i=0;i<nModels;i++)
- if (Model[i]) {
- Model[i]->GetChainTable ( chain,nChains );
- for (j=0;j<Model[i]->nChains;j++)
- if (chain[j]) {
- chain[j]->GetResidueTable ( res,nResidues );
- for (n=0;n<nResidues;n++)
- if (res[n]) resTable[k++] = res[n];
- }
- }
- NumberOfResidues = k;
- }
-
-}
-
-void CMMDBCoorManager::GetResidueTable ( int modelNo,
- const ChainID chainID,
- PPCResidue & resTable,
- int & NumberOfResidues ) {
-PCChain chain;
- resTable = NULL;
- NumberOfResidues = 0;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1]) {
- chain = Model[modelNo-1]->GetChain ( chainID );
- if (chain) {
- resTable = chain->Residue;
- NumberOfResidues = chain->nResidues;
- }
- }
- }
-}
-
-void CMMDBCoorManager::GetResidueTable ( int modelNo, int chainNo,
- PPCResidue & resTable,
- int & NumberOfResidues ) {
-PCChain chain;
- resTable = NULL;
- NumberOfResidues = 0;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1]) {
- chain = Model[modelNo-1]->GetChain ( chainNo );
- if (chain) {
- resTable = chain->Residue;
- NumberOfResidues = chain->nResidues;
- }
- }
- }
-}
-
-void CMMDBCoorManager::GetResidueTable ( cpstr CID,
- PPCResidue & resTable,
- int & NumberOfResidues ) {
-int modno,sn,rc;
-ChainID chname;
-InsCode ic;
-ResName resname;
-AtomName aname;
-Element elname;
-AltLoc aloc;
-PCChain chain;
-
- resTable = NULL;
- NumberOfResidues = 0;
- CoorIDCode = CID_Ok;
-
- rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
- aname,elname,aloc,&DefPath );
- if ((rc<0) || (rc & (APATH_WC_ModelNo | APATH_WC_ChainID))) {
- CoorIDCode = CID_WrongPath;
- return;
- }
-
- if ((0<modno) && (modno<=nModels)) {
- if (Model[modno-1]) {
- chain = Model[modno-1]->GetChain ( chname );
- if (chain) {
- resTable = chain->Residue;
- NumberOfResidues = chain->nResidues;
- }
- }
- }
-
-}
-
-
-int CMMDBCoorManager::DeleteResidue ( int modelNo,
- const ChainID chainID,
- int seqNo,
- const InsCode insCode ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteResidue ( chainID,seqNo,insCode );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteResidue ( int modelNo,
- const ChainID chainID,
- int resNo ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteResidue ( chainID,resNo );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteResidue ( int modelNo, int chainNo,
- int seqNo,
- const InsCode insCode ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteResidue ( chainNo,seqNo,insCode );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteResidue ( int modelNo, int chainNo,
- int resNo ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteResidue ( chainNo,resNo );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAllResidues ( int modelNo,
- const ChainID chainID ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAllResidues ( chainID );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAllResidues ( int modelNo, int chainNo ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAllResidues ( chainNo );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAllResidues ( int modelNo ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAllResidues();
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAllResidues() {
-int i,k;
- k = 0;
- for (i=0;i<nModels;i++)
- if (Model[i]) k += Model[i]->DeleteAllResidues();
- return k;
-}
-
-int CMMDBCoorManager::AddResidue ( int modelNo, const ChainID chainID,
- PCResidue res ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->AddResidue ( chainID,res );
- }
- return 0;
-}
-
-int CMMDBCoorManager::AddResidue ( int modelNo, int chainNo,
- PCResidue res ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->AddResidue ( chainNo,res );
- }
- return 0;
-}
-
-
-
-int CMMDBCoorManager::GetNumberOfChains ( int modelNo ) {
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->nChains;
- }
- return 0;
-}
-
-int CMMDBCoorManager::GetNumberOfChains ( cpstr CID ) {
-int modno,sn,rc;
-ChainID chname;
-InsCode ic;
-ResName resname;
-AtomName aname;
-Element elname;
-AltLoc aloc;
-
- CoorIDCode = CID_Ok;
- rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
- aname,elname,aloc,&DefPath );
- if ((rc<0) || (rc & APATH_WC_ModelNo)) {
- CoorIDCode = CID_WrongPath;
- return 0;
- }
-
- if ((0<modno) && (modno<=nModels)) {
- if (Model[modno-1])
- return Model[modno-1]->nChains;
- }
-
- return 0;
-
-}
-
-int CMMDBCoorManager::GetNumberOfResidues ( int modelNo,
- const ChainID chainID ) {
-PCChain chain;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1]) {
- chain = Model[modelNo-1]->GetChain ( chainID );
- if (chain) return chain->nResidues;
- }
- }
- return 0;
-}
-
-int CMMDBCoorManager::GetNumberOfResidues ( int modelNo, int chainNo ) {
-PCChain chain;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1]) {
- if ((0<=chainNo) && (chainNo<Model[modelNo-1]->nChains)) {
- chain = Model[modelNo-1]->Chain[chainNo];
- if (chain) return chain->nResidues;
- }
- }
- }
- return 0;
-}
-
-int CMMDBCoorManager::GetNumberOfResidues ( cpstr CID ) {
-int modno,sn,rc;
-ChainID chname;
-InsCode ic;
-ResName resname;
-AtomName aname;
-Element elname;
-AltLoc aloc;
-PCChain chain;
-
- CoorIDCode = CID_Ok;
- rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
- aname,elname,aloc,&DefPath );
- if ((rc<0) || (rc & (APATH_WC_ModelNo | APATH_WC_ChainID))) {
- CoorIDCode = CID_WrongPath;
- return 0;
- }
-
- if ((0<modno) && (modno<=nModels)) {
- if (Model[modno-1]) {
- chain = Model[modno-1]->GetChain ( chname );
- if (chain) return chain->nResidues;
- }
- }
-
- return 0;
-
-}
-
-
-int CMMDBCoorManager::GetNumberOfAtoms ( int modelNo,
- const ChainID chainID,
- int seqNo,
- const InsCode insCode ) {
-PCChain chain;
-PCResidue res;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1]) {
- chain = Model[modelNo-1]->GetChain ( chainID );
- if (chain) {
- res = chain->GetResidue ( seqNo,insCode );
- if (res) return res->nAtoms;
- }
- }
- }
- return 0;
-}
-
-int CMMDBCoorManager::GetNumberOfAtoms ( int modelNo, int chainNo,
- int seqNo,
- const InsCode insCode ) {
-PCChain chain;
-PCResidue res;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1]) {
- if ((0<=chainNo) && (chainNo<Model[modelNo-1]->nChains)) {
- chain = Model[modelNo-1]->Chain[chainNo];
- if (chain) {
- res = chain->GetResidue ( seqNo,insCode );
- if (res) return res->nAtoms;
- }
- }
- }
- }
- return 0;
-}
-
-int CMMDBCoorManager::GetNumberOfAtoms ( int modelNo,
- const ChainID chainID,
- int resNo ) {
-PCChain chain;
-PCResidue res;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1]) {
- chain = Model[modelNo-1]->GetChain ( chainID );
- if (chain) {
- if ((0<=resNo) && (resNo<chain->nResidues)) {
- res = chain->Residue[resNo];
- if (res) return res->nAtoms;
- }
- }
- }
- }
- return 0;
-}
-
-int CMMDBCoorManager::GetNumberOfAtoms ( int modelNo, int chainNo,
- int resNo ) {
-PCChain chain;
-PCResidue res;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1]) {
- if ((0<=chainNo) && (chainNo<Model[modelNo-1]->nChains)) {
- chain = Model[modelNo-1]->Chain[chainNo];
- if (chain) {
- if ((0<=resNo) && (resNo<chain->nResidues)) {
- res = chain->Residue[resNo];
- if (res) return res->nAtoms;
- }
- }
- }
- }
- }
- return 0;
-}
-
-int CMMDBCoorManager::GetNumberOfAtoms ( cpstr CID ) {
-// returns number of atoms in residues identified by CID
-int modno,sn,rc;
-ChainID chname;
-InsCode ic;
-ResName resname;
-AtomName aname;
-Element elname;
-AltLoc aloc;
-PCChain chain;
-PCResidue res;
-
- CoorIDCode = CID_Ok;
- rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
- aname,elname,aloc,&DefPath );
- if ((rc<0) || (rc & (APATH_WC_ModelNo | APATH_WC_ChainID |
- APATH_WC_SeqNum | APATH_WC_InsCode))) {
- CoorIDCode = CID_WrongPath;
- return 0;
- }
-
- if ((0<modno) && (modno<=nModels)) {
- if (Model[modno-1]) {
- chain = Model[modno-1]->GetChain ( chname );
- if (chain) {
- res = chain->GetResidue ( sn,ic );
- if (res) return res->nAtoms;
- }
- }
- }
-
- return 0;
-
-}
-
-
-// -------------------- Extracting atoms -----------------------
-
-PCAtom CMMDBCoorManager::GetAtom (
- int modelNo, // model serial number 1...
- const ChainID chID, // chain ID
- int seqNo, // residue sequence number
- const InsCode insCode, // residue insertion code
- const AtomName aname, // atom name
- const Element elmnt, // chemical element code or '*'
- const AltLoc aloc // alternate location indicator
- ) {
-PCModel mdl;
-PCChain chn;
-PCResidue res;
-PCAtom atm;
-
- if ((1<=modelNo) && (modelNo<=nModels))
- mdl = Model[modelNo-1];
- else mdl = NULL;
- if (!mdl) {
- CoorIDCode = CID_NoModel;
- return NULL;
- }
-
- chn = mdl->GetChain ( chID );
- if (!chn) {
- CoorIDCode = CID_NoChain;
- return NULL;
- }
-
- res = chn->GetResidue ( seqNo,insCode );
- if (!res) {
- CoorIDCode = CID_NoResidue;
- return NULL;
- }
-
- atm = res->GetAtom ( aname,elmnt,aloc );
- if (!atm) CoorIDCode = CID_NoAtom;
- else CoorIDCode = CID_Ok;
-
- return atm;
-
-}
-
-PCAtom CMMDBCoorManager::GetAtom (
- int modelNo, // model serial number 1...
- const ChainID chID, // chain ID
- int seqNo, // residue sequence number
- const InsCode insCode, // residue insertion code
- int atomNo // atom number 0..
- ) {
-PCModel mdl;
-PCChain chn;
-PCResidue res;
-PCAtom atm;
-
- if ((1<=modelNo) && (modelNo<=nModels))
- mdl = Model[modelNo-1];
- else mdl = NULL;
- if (!mdl) {
- CoorIDCode = CID_NoModel;
- return NULL;
- }
-
- chn = mdl->GetChain ( chID );
- if (!chn) {
- CoorIDCode = CID_NoChain;
- return NULL;
- }
-
- res = chn->GetResidue ( seqNo,insCode );
- if (!res) {
- CoorIDCode = CID_NoResidue;
- return NULL;
- }
-
- if ((0<=atomNo) && (atomNo<res->nAtoms))
- atm = res->atom[atomNo];
- else atm = NULL;
- if (!atm) CoorIDCode = CID_NoAtom;
- else CoorIDCode = CID_Ok;
-
- return atm;
-
-}
-
-PCAtom CMMDBCoorManager::GetAtom (
- int modelNo, // model serial number 1...
- const ChainID chID, // chain ID
- int resNo, // residue number 0..
- const AtomName aname, // atom name
- const Element elmnt, // chemical element code or '*'
- const AltLoc aloc // alternate location indicator
- ) {
-PCModel mdl;
-PCChain chn;
-PCResidue res;
-PCAtom atm;
-
- if ((1<=modelNo) && (modelNo<=nModels))
- mdl = Model[modelNo-1];
- else mdl = NULL;
- if (!mdl) {
- CoorIDCode = CID_NoModel;
- return NULL;
- }
-
- chn = mdl->GetChain ( chID );
- if (!chn) {
- CoorIDCode = CID_NoChain;
- return NULL;
- }
-
- if ((0<=resNo) && (resNo<chn->nResidues))
- res = chn->Residue[resNo];
- else res = NULL;
- if (!res) {
- CoorIDCode = CID_NoResidue;
- return NULL;
- }
-
- atm = res->GetAtom ( aname,elmnt,aloc );
- if (!atm) CoorIDCode = CID_NoAtom;
- else CoorIDCode = CID_Ok;
-
- return atm;
-
-}
-
-PCAtom CMMDBCoorManager::GetAtom (
- int modelNo, // model serial number 1...
- const ChainID chID, // chain ID
- int resNo, // residue number 0..
- int atomNo // atom number 0..
- ) {
-PCModel mdl;
-PCChain chn;
-PCResidue res;
-PCAtom atm;
-
- if ((1<=modelNo) && (modelNo<=nModels))
- mdl = Model[modelNo-1];
- else mdl = NULL;
- if (!mdl) {
- CoorIDCode = CID_NoModel;
- return NULL;
- }
-
- chn = mdl->GetChain ( chID );
- if (!chn) {
- CoorIDCode = CID_NoChain;
- return NULL;
- }
-
- if ((0<=resNo) && (resNo<chn->nResidues))
- res = chn->Residue[resNo];
- else res = NULL;
- if (!res) {
- CoorIDCode = CID_NoResidue;
- return NULL;
- }
-
- if ((0<=atomNo) && (atomNo<res->nAtoms))
- atm = res->atom[atomNo];
- else atm = NULL;
- if (!atm) CoorIDCode = CID_NoAtom;
- else CoorIDCode = CID_Ok;
-
- return atm;
-
-}
-
-PCAtom CMMDBCoorManager::GetAtom (
- int modelNo, // model serial number 1...
- int chNo, // chain number 0..
- int seqNo, // residue sequence number
- const InsCode insCode, // residue insertion code
- const AtomName aname, // atom name
- const Element elmnt, // chemical element code or '*'
- const AltLoc aloc // alternate location indicator
- ) {
-PCModel mdl;
-PCChain chn;
-PCResidue res;
-PCAtom atm;
-
- if ((1<=modelNo) && (modelNo<=nModels))
- mdl = Model[modelNo-1];
- else mdl = NULL;
- if (!mdl) {
- CoorIDCode = CID_NoModel;
- return NULL;
- }
-
- if ((0<=chNo) && (chNo<mdl->nChains))
- chn = mdl->Chain[chNo];
- else chn = NULL;
- if (!chn) {
- CoorIDCode = CID_NoChain;
- return NULL;
- }
-
- res = chn->GetResidue ( seqNo,insCode );
- if (!res) {
- CoorIDCode = CID_NoResidue;
- return NULL;
- }
-
- atm = res->GetAtom ( aname,elmnt,aloc );
- if (!atm) CoorIDCode = CID_NoAtom;
- else CoorIDCode = CID_Ok;
-
- return atm;
-
-}
-
-PCAtom CMMDBCoorManager::GetAtom (
- int modelNo, // model serial number 1...
- int chNo, // chain number 0...
- int seqNo, // residue sequence number
- const InsCode insCode, // residue insertion code
- int atomNo // atom number 0...
- ) {
-PCModel mdl;
-PCChain chn;
-PCResidue res;
-PCAtom atm;
-
- if ((1<=modelNo) && (modelNo<=nModels))
- mdl = Model[modelNo-1];
- else mdl = NULL;
- if (!mdl) {
- CoorIDCode = CID_NoModel;
- return NULL;
- }
-
- if ((0<=chNo) && (chNo<mdl->nChains))
- chn = mdl->Chain[chNo];
- else chn = NULL;
- if (!chn) {
- CoorIDCode = CID_NoChain;
- return NULL;
- }
-
- res = chn->GetResidue ( seqNo,insCode );
- if (!res) {
- CoorIDCode = CID_NoResidue;
- return NULL;
- }
-
- if ((0<=atomNo) && (atomNo<res->nAtoms))
- atm = res->atom[atomNo];
- else atm = NULL;
- if (!atm) CoorIDCode = CID_NoAtom;
- else CoorIDCode = CID_Ok;
-
- return atm;
-
-}
-
-PCAtom CMMDBCoorManager::GetAtom (
- int modelNo, // model serial number 1...
- int chNo, // chain number 0...
- int resNo, // residue number 0...
- const AtomName aname, // atom name
- const Element elmnt, // chemical element code or '*'
- const AltLoc aloc // alternate location indicator
- ) {
-PCModel mdl;
-PCChain chn;
-PCResidue res;
-PCAtom atm;
-
- if ((1<=modelNo) && (modelNo<=nModels))
- mdl = Model[modelNo-1];
- else mdl = NULL;
- if (!mdl) {
- CoorIDCode = CID_NoModel;
- return NULL;
- }
-
- if ((0<=chNo) && (chNo<mdl->nChains))
- chn = mdl->Chain[chNo];
- else chn = NULL;
- if (!chn) {
- CoorIDCode = CID_NoChain;
- return NULL;
- }
-
- if ((0<=resNo) && (resNo<chn->nResidues))
- res = chn->Residue[resNo];
- else res = NULL;
- if (!res) {
- CoorIDCode = CID_NoResidue;
- return NULL;
- }
-
- atm = res->GetAtom ( aname,elmnt,aloc );
- if (!atm) CoorIDCode = CID_NoAtom;
- else CoorIDCode = CID_Ok;
-
- return atm;
-
-}
-
-PCAtom CMMDBCoorManager::GetAtom (
- int modelNo, // model serial number 1...
- int chNo, // chain number 0...
- int resNo, // residue number 0...
- int atomNo // atom number 0...
- ) {
-PCModel mdl;
-PCChain chn;
-PCResidue res;
-PCAtom atm;
-
- if ((1<=modelNo) && (modelNo<=nModels))
- mdl = Model[modelNo-1];
- else mdl = NULL;
- if (!mdl) {
- CoorIDCode = CID_NoModel;
- return NULL;
- }
-
- if ((0<=chNo) && (chNo<mdl->nChains))
- chn = mdl->Chain[chNo];
- else chn = NULL;
- if (!chn) {
- CoorIDCode = CID_NoChain;
- return NULL;
- }
-
- if ((0<=resNo) && (resNo<chn->nResidues))
- res = chn->Residue[resNo];
- else res = NULL;
- if (!res) {
- CoorIDCode = CID_NoResidue;
- return NULL;
- }
-
- if ((0<=atomNo) && (atomNo<res->nAtoms))
- atm = res->atom[atomNo];
- else atm = NULL;
- if (!atm) CoorIDCode = CID_NoAtom;
- else CoorIDCode = CID_Ok;
-
- return atm;
-
-}
-
-
-PCAtom CMMDBCoorManager::GetAtom ( cpstr CID ) {
-int modno,sn,rc;
-ChainID chname;
-InsCode ic;
-ResName resname;
-AtomName aname;
-Element elname;
-AltLoc aloc;
-
- CoorIDCode = CID_Ok;
- rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
- aname,elname,aloc,&DefPath );
- if ((rc<0) || (rc & APATH_Incomplete)) {
- CoorIDCode = CID_WrongPath;
- return NULL;
- }
-
- return GetAtom ( modno,chname,sn,ic,aname,elname,aloc );
-
-}
-
-
-void CMMDBCoorManager::GetAtomTable ( PPCAtom & atomTable,
- int & NumberOfAtoms ) {
- atomTable = Atom;
- NumberOfAtoms = nAtoms;
-}
-
-void CMMDBCoorManager::GetAtomTable ( int modelNo,
- const ChainID chainID,
- int seqNo,
- const InsCode insCode,
- PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- atomTable = NULL;
- NumberOfAtoms = 0;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1]) {
- res = Model[modelNo-1]->GetResidue ( chainID,seqNo,insCode );
- if (res) {
- atomTable = res->atom;
- NumberOfAtoms = res->nAtoms;
- }
- }
- }
-}
-
-void CMMDBCoorManager::GetAtomTable ( int modelNo,
- int chainNo,
- int seqNo,
- const InsCode insCode,
- PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- atomTable = NULL;
- NumberOfAtoms = 0;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1]) {
- res = Model[modelNo-1]->GetResidue ( chainNo,seqNo,insCode );
- if (res) {
- atomTable = res->atom;
- NumberOfAtoms = res->nAtoms;
- }
- }
- }
-}
-
-void CMMDBCoorManager::GetAtomTable ( int modelNo,
- const ChainID chainID,
- int resNo,
- PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- atomTable = NULL;
- NumberOfAtoms = 0;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1]) {
- res = Model[modelNo-1]->GetResidue ( chainID,resNo );
- if (res) {
- atomTable = res->atom;
- NumberOfAtoms = res->nAtoms;
- }
- }
- }
-}
-
-void CMMDBCoorManager::GetAtomTable ( int modelNo, int chainNo,
- int resNo, PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- atomTable = NULL;
- NumberOfAtoms = 0;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1]) {
- res = Model[modelNo-1]->GetResidue ( chainNo,resNo );
- if (res) {
- atomTable = res->atom;
- NumberOfAtoms = res->nAtoms;
- }
- }
- }
-}
-
-void CMMDBCoorManager::GetAtomTable ( cpstr CID,
- PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-int modno,sn,rc;
-ChainID chname;
-InsCode ic;
-ResName resname;
-AtomName aname;
-Element elname;
-AltLoc aloc;
-PCResidue res;
-
- atomTable = NULL;
- NumberOfAtoms = 0;
-
- CoorIDCode = CID_Ok;
- rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
- aname,elname,aloc,&DefPath );
- if ((rc<0) || (rc & (APATH_WC_ModelNo | APATH_WC_ChainID |
- APATH_WC_SeqNum | APATH_WC_InsCode))) {
- CoorIDCode = CID_WrongPath;
- return;
- }
-
- res = GetResidue ( modno,chname,sn,ic );
- if (res) {
- atomTable = res->atom;
- NumberOfAtoms = res->nAtoms;
- }
-
-}
-
-
-void CMMDBCoorManager::GetAtomTable1 ( PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-int i,j;
- if (atomTable) delete[] atomTable;
- if (nAtoms>0) {
- atomTable = new PCAtom[nAtoms];
- j = 0;
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- if (!Atom[i]->Ter)
- atomTable[j++] = Atom[i];
- }
- NumberOfAtoms = j;
- } else {
- atomTable = NULL;
- NumberOfAtoms = 0;
- }
-}
-
-void CMMDBCoorManager::GetAtomTable1 ( int modelNo,
- const ChainID chainID,
- int seqNo,
- const InsCode insCode,
- PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- res = NULL;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- res = Model[modelNo-1]->GetResidue ( chainID,seqNo,insCode );
- }
- if (res)
- res->GetAtomTable1 ( atomTable,NumberOfAtoms );
- else {
- if (atomTable) delete[] atomTable;
- atomTable = NULL;
- NumberOfAtoms = 0;
- }
-}
-
-void CMMDBCoorManager::GetAtomTable1 ( int modelNo,
- int chainNo,
- int seqNo,
- const InsCode insCode,
- PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- res = NULL;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- res = Model[modelNo-1]->GetResidue ( chainNo,seqNo,insCode );
- }
- if (res)
- res->GetAtomTable1 ( atomTable,NumberOfAtoms );
- else {
- if (atomTable) delete[] atomTable;
- atomTable = NULL;
- NumberOfAtoms = 0;
- }
-}
-
-void CMMDBCoorManager::GetAtomTable1 ( int modelNo,
- const ChainID chainID,
- int resNo,
- PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- res = NULL;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- res = Model[modelNo-1]->GetResidue ( chainID,resNo );
- }
- if (res)
- res->GetAtomTable1 ( atomTable,NumberOfAtoms );
- else {
- if (atomTable) delete[] atomTable;
- atomTable = NULL;
- NumberOfAtoms = 0;
- }
-}
-
-void CMMDBCoorManager::GetAtomTable1 ( int modelNo, int chainNo,
- int resNo,
- PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- res = NULL;
- if ((0<modelNo) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- res = Model[modelNo-1]->GetResidue ( chainNo,resNo );
- }
- if (res)
- res->GetAtomTable1 ( atomTable,NumberOfAtoms );
- else {
- if (atomTable) delete[] atomTable;
- atomTable = NULL;
- NumberOfAtoms = 0;
- }
-}
-
-void CMMDBCoorManager::GetAtomTable1 ( cpstr CID, PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-int modno,sn,rc;
-ChainID chname;
-InsCode ic;
-ResName resname;
-AtomName aname;
-Element elname;
-AltLoc aloc;
-PCResidue res;
-
- atomTable = NULL;
- NumberOfAtoms = 0;
-
- CoorIDCode = CID_Ok;
- rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
- aname,elname,aloc,&DefPath );
- if ((rc<0) || (rc & (APATH_WC_ModelNo | APATH_WC_ChainID |
- APATH_WC_SeqNum | APATH_WC_InsCode))) {
- CoorIDCode = CID_WrongPath;
- return;
- }
-
- res = GetResidue ( modno,chname,sn,ic );
- if (res)
- res->GetAtomTable1 ( atomTable,NumberOfAtoms );
- else {
- if (atomTable) delete[] atomTable;
- atomTable = NULL;
- NumberOfAtoms = 0;
- }
-
-}
-
-
-
-int CMMDBCoorManager::DeleteAtom ( int modelNo,
- const ChainID chID,
- int seqNo,
- const InsCode insCode,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAtom ( chID,seqNo,insCode,
- aname,elmnt,aloc );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAtom ( int modelNo,
- const ChainID chID,
- int seqNo,
- const InsCode insCode,
- int atomNo ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAtom ( chID,seqNo,insCode,atomNo );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAtom ( int modelNo,
- const ChainID chID,
- int resNo,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAtom ( chID,resNo,
- aname,elmnt,aloc );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAtom ( int modelNo,
- const ChainID chID,
- int resNo,
- int atomNo ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAtom ( chID,resNo,atomNo );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAtom ( int modelNo, int chNo, int seqNo,
- const InsCode insCode,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAtom ( chNo,seqNo,insCode,
- aname,elmnt,aloc );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAtom ( int modelNo, int chNo, int seqNo,
- const InsCode insCode, int atomNo ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAtom ( chNo,seqNo,insCode,atomNo );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAtom ( int modelNo, int chNo, int resNo,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAtom ( chNo,resNo,
- aname,elmnt,aloc );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAtom ( int modelNo, int chNo, int resNo,
- int atomNo ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAtom ( chNo,resNo,atomNo );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAllAtoms ( int modelNo,
- const ChainID chID,
- int seqNo,
- const InsCode insCode ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAllAtoms ( chID,seqNo,insCode );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAllAtoms ( int modelNo, const ChainID chID,
- int resNo ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAllAtoms ( chID,resNo );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAllAtoms ( int modelNo, const ChainID chID ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAllAtoms ( chID );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAllAtoms ( int modelNo, int chNo, int seqNo,
- const InsCode insCode ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAllAtoms ( chNo,seqNo,insCode );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAllAtoms ( int modelNo, int chNo,
- int resNo ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAllAtoms ( chNo,resNo );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAllAtoms ( int modelNo, int chNo ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAllAtoms ( chNo );
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAllAtoms ( int modelNo ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->DeleteAllAtoms();
- }
- return 0;
-}
-
-int CMMDBCoorManager::DeleteAllAtoms() {
-int i,k;
- k = 0;
- for (i=0;i<nModels;i++)
- if (Model[i]) k += Model[i]->DeleteAllAtoms();
- return k;
-}
-
-
-/*
-int CMMDBCoorManager::DeleteAltLocs() {
-// This function leaves only alternative location with maximal
-// occupancy, if those are equal or unspecified, the one with
-// "least" alternative location indicator.
-// The function returns the number of deleted atoms and optimizes
-// the atom index.
-ChainID chID;
-ResName rName;
-InsCode iCode;
-AtomName aname;
-AltLoc aLoc,aL;
-realtype occupancy,occ;
-int seqNum;
-int i,j,k,i1,i2,n;
-
- k = 0;
- n = 0;
- i = 0;
- while (i<nAtoms) {
-
- if (Atom[i]) {
- seqNum = Atom[i]->GetSeqNum ();
- occupancy = Atom[i]->GetOccupancy();
- strcpy ( chID ,Atom[i]->GetChainID() );
- strcpy ( rName,Atom[i]->GetResName() );
- strcpy ( iCode,Atom[i]->GetInsCode() );
- strcpy ( aname,Atom[i]->name );
- strcpy ( aLoc ,Atom[i]->altLoc );
- j = i+1;
- i1 = -1;
- i2 = i;
- while (j<nAtoms)
- if (Atom[j]) {
- if ((Atom[j]->GetSeqNum()==seqNum) &&
- (!strcmp(Atom[j]->name,aname)) &&
- (!strcmp(Atom[j]->GetInsCode(),iCode)) &&
- (!strcmp(Atom[j]->GetResName(),rName)) &&
- (!strcmp(Atom[j]->GetChainID(),chID ))) {
- occ = Atom[j]->GetOccupancy();
- if (occ>occupancy) {
- occupancy = occ;
- i1 = j;
- }
- if (aLoc[0]) {
- strcpy ( aL,Atom[j]->altLoc );
- if (!aL[0]) {
- aLoc[0] = char(0);
- i2 = j;
- } else if (strcmp(aL,aLoc)<0) {
- strcpy ( aLoc,aL );
- i2 = j;
- }
- }
- j++;
- } else
- break;
- } else
- j++;
- if (i1<0) {
- if (Atom[i]->WhatIsSet & ASET_Occupancy) i1 = i;
- else i1 = i2;
- }
- while (i<j) {
- if (Atom[i]) {
- if (i!=i1) {
- delete Atom[i];
- Atom[i] = NULL;
- n++;
- } else {
- if (k<i) {
- Atom[k] = Atom[i];
- Atom[k]->index = k+1;
- }
- k++;
- }
- }
- i++;
- }
-
- } else
- i++;
-
- }
-
- nAtoms = k;
- return n;
-
-}
-*/
-
-int CMMDBCoorManager::DeleteAltLocs() {
-// This function leaves only alternative location with maximal
-// occupancy, if those are equal or unspecified, the one with
-// "least" alternative location indicator.
-// The function returns the number of deleted atoms. All tables
-// remain untrimmed, so that explicit trimming or calling
-// FinishStructEdit() at some point is required.
-int i,n;
-
- n = 0;
- for (i=0;i<nModels;i++)
- if (Model[i]) n += Model[i]->DeleteAltLocs();
-
- return n;
-
-}
-
-int CMMDBCoorManager::AddAtom ( int modelNo,
- const ChainID chID,
- int seqNo,
- const InsCode insCode,
- PCAtom atom ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->AddAtom ( chID,seqNo,insCode,atom );
- }
- return 0;
-}
-
-int CMMDBCoorManager::AddAtom ( int modelNo, const ChainID chID,
- int resNo, PCAtom atom ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->AddAtom ( chID,resNo,atom );
- }
- return 0;
-}
-
-int CMMDBCoorManager::AddAtom ( int modelNo, int chNo,
- int seqNo, const InsCode insCode,
- PCAtom atom ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->AddAtom ( chNo,seqNo,insCode,atom );
- }
- return 0;
-}
-
-int CMMDBCoorManager::AddAtom ( int modelNo, int chNo,
- int resNo, PCAtom atom ) {
- if ((modelNo>0) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->AddAtom ( chNo,resNo,atom );
- }
- return 0;
-}
-
-
-void CMMDBCoorManager::RemoveBricks() {
-int i,j,k;
- if (Brick) {
- for (i=0;i<nbrick_x;i++)
- if (Brick[i]) {
- for (j=0;j<nbrick_y;j++)
- if (Brick[i][j]) {
- for (k=0;k<nbrick_z;k++)
- if (Brick[i][j][k]) delete Brick[i][j][k];
- delete[] Brick[i][j];
- }
- delete[] Brick[i];
- }
- delete[] Brick;
- }
- Brick = NULL;
- nbrick_x = 0;
- nbrick_y = 0;
- nbrick_z = 0;
-}
-
-void CMMDBCoorManager::GetBrickCoor ( PCAtom A,
- int & nx, int & ny, int & nz ) {
- nx = (int)floor((A->x-xbrick_0)/brick_size);
- ny = (int)floor((A->y-ybrick_0)/brick_size);
- nz = (int)floor((A->z-zbrick_0)/brick_size);
- if ((ny<0) || (nz<0) || (nx>=nbrick_x) ||
- (ny>=nbrick_y) || (nz>=nbrick_z)) nx = -1;
-}
-
-void CMMDBCoorManager::GetBrickCoor ( realtype x, realtype y,
- realtype z, int & nx,
- int & ny, int & nz ) {
- nx = (int)floor((x-xbrick_0)/brick_size);
- ny = (int)floor((y-ybrick_0)/brick_size);
- nz = (int)floor((z-zbrick_0)/brick_size);
- if ((ny<0) || (nz<0) || (nx>=nbrick_x) ||
- (ny>=nbrick_y) || (nz>=nbrick_z)) nx = -1;
-}
-
-void CMMDBCoorManager::GetBrickDimension (
- int & nxmax, int & nymax, int & nzmax ) {
- if (!Brick) {
- nxmax = 0; nymax = 0; nzmax = 0;
- } else {
- nxmax = nbrick_x;
- nymax = nbrick_y;
- nzmax = nbrick_z;
- }
-}
-
-PCBrick CMMDBCoorManager::GetBrick ( int nx, int ny, int nz ) {
- if (!Brick) return NULL;
- if ((nx>=0) && (nx<nbrick_x) &&
- (ny>=0) && (ny<nbrick_y) &&
- (nz>=0) && (nz<nbrick_z)) {
- if (!Brick[nx]) return NULL;
- if (!Brick[nx][ny]) return NULL;
- return Brick[nx][ny][nz];
- }
- return NULL;
-}
-
-void CMMDBCoorManager::MakeBricks ( PPCAtom atmvec, int avlen,
- realtype Margin,
- realtype BrickSize ) {
-// Makes bricking for atoms contained in vector atmvec of length
-// avlen, with brick size BrickSize (in angstroms). The previous
-// bricking, if there was any, is removed.
-int i,j, nx,ny,nz, alen;
-realtype x1,x2, y1,y2, z1,z2, dx,dy,dz;
-PPCAtom A;
-
- RemoveBricks();
-
- brick_size = BrickSize;
-
- if (atmvec) {
- A = atmvec;
- alen = avlen;
- } else {
- A = Atom;
- alen = nAtoms;
- }
-
- if (alen>0) {
- // find the range of coordinates
- x1 = MaxReal;
- x2 = -x1;
- y1 = MaxReal;
- y2 = -y1;
- z1 = MaxReal;
- z2 = -z1;
- for (i=0;i<alen;i++)
- if (A[i]) {
- if ((!A[i]->Ter) && (A[i]->WhatIsSet & ASET_Coordinates)) {
- if (A[i]->x<x1) x1 = A[i]->x;
- if (A[i]->x>x2) x2 = A[i]->x;
- if (A[i]->y<y1) y1 = A[i]->y;
- if (A[i]->y>y2) y2 = A[i]->y;
- if (A[i]->z<z1) z1 = A[i]->z;
- if (A[i]->z>z2) z2 = A[i]->z;
- }
- }
- if (x1<MaxReal) {
- x1 -= Margin; x2 += Margin;
- y1 -= Margin; y2 += Margin;
- z1 -= Margin; z2 += Margin;
- dx = x2-x1; nbrick_x = mround(dx/brick_size+0.0001)+1;
- dy = y2-y1; nbrick_y = mround(dy/brick_size+0.0001)+1;
- dz = z2-z1; nbrick_z = mround(dz/brick_size+0.0001)+1;
- xbrick_0 = x1 - (nbrick_x*brick_size-dx)/2.0;
- ybrick_0 = y1 - (nbrick_y*brick_size-dy)/2.0;
- zbrick_0 = z1 - (nbrick_z*brick_size-dz)/2.0;
- for (i=0;i<alen;i++)
- if (A[i]) {
- if ((!A[i]->Ter) && (A[i]->WhatIsSet & ASET_Coordinates)) {
- GetBrickCoor ( A[i],nx,ny,nz );
- if (nx>=0) {
- if (!Brick) {
- Brick = new PPPCBrick[nbrick_x];
- for (j=0;j<nbrick_x;j++)
- Brick[j] = NULL;
- }
- if (!Brick[nx]) {
- Brick[nx] = new PPCBrick[nbrick_y];
- for (j=0;j<nbrick_y;j++)
- Brick[nx][j] = NULL;
- }
- if (!Brick[nx][ny]) {
- Brick[nx][ny] = new PCBrick[nbrick_z];
- for (j=0;j<nbrick_z;j++)
- Brick[nx][ny][j] = NULL;
- }
- if (!Brick[nx][ny][nz])
- Brick[nx][ny][nz] = new CBrick();
- Brick[nx][ny][nz]->AddAtom ( A[i],i );
- } else
- printf ( " error in "
- "CMMDBCoorManager::MakeBricks!!!\n" );
- }
- }
- }
- }
-
-}
-
-
-void CMMDBCoorManager::RemoveMBricks() {
-int i,j,k;
- if (MBrick) {
- for (i=0;i<nmbrick_x;i++)
- if (MBrick[i]) {
- for (j=0;j<nmbrick_y;j++)
- if (MBrick[i][j]) {
- for (k=0;k<nmbrick_z;k++)
- if (MBrick[i][j][k]) delete MBrick[i][j][k];
- delete[] MBrick[i][j];
- }
- delete[] MBrick[i];
- }
- delete[] MBrick;
- }
- MBrick = NULL;
- nmbrick_x = 0;
- nmbrick_y = 0;
- nmbrick_z = 0;
-}
-
-void CMMDBCoorManager::GetMBrickCoor ( PCAtom A,
- int & nx, int & ny, int & nz ) {
- nx = (int)floor((A->x-xmbrick_0)/mbrick_size);
- ny = (int)floor((A->y-ymbrick_0)/mbrick_size);
- nz = (int)floor((A->z-zmbrick_0)/mbrick_size);
- if ((ny<0) || (nz<0) || (nx>=nmbrick_x) ||
- (ny>=nmbrick_y) || (nz>=nmbrick_z)) nx = -nx-1;
-}
-
-void CMMDBCoorManager::GetMBrickCoor (
- realtype x, realtype y, realtype z,
- int & nx, int & ny, int & nz ) {
- nx = (int)floor((x-xmbrick_0)/mbrick_size);
- ny = (int)floor((y-ymbrick_0)/mbrick_size);
- nz = (int)floor((z-zmbrick_0)/mbrick_size);
- if ((ny<0) || (nz<0) || (nx>=nmbrick_x) ||
- (ny>=nmbrick_y) || (nz>=nmbrick_z)) nx = -nx-1;
-}
-
-void CMMDBCoorManager::GetMBrickDimension (
- int & nxmax, int & nymax, int & nzmax ) {
- if (!Brick) {
- nxmax = 0; nymax = 0; nzmax = 0;
- } else {
- nxmax = nmbrick_x;
- nymax = nmbrick_y;
- nzmax = nmbrick_z;
- }
-}
-
-PCMBrick CMMDBCoorManager::GetMBrick ( int nx, int ny, int nz ) {
- if (!MBrick) return NULL;
- if ((nx>=0) && (nx<nmbrick_x) &&
- (ny>=0) && (ny<nmbrick_y) &&
- (nz>=0) && (nz<nmbrick_z)) {
- if (!MBrick[nx]) return NULL;
- if (!MBrick[nx][ny]) return NULL;
- return MBrick[nx][ny][nz];
- }
- return NULL;
-}
-
-void CMMDBCoorManager::MakeMBricks ( PPCAtom * atmvec, ivector avlen,
- int nStructures, realtype Margin,
- realtype BrickSize ) {
-// Makes bricking for atoms contained in vectors atmvec with lengths
-// given in avlen, with brick size BrickSize (in angstroms).
-// The previous bricking, if there was any, is removed.
-int i,j,k, nx,ny,nz;
-realtype x1,x2, y1,y2, z1,z2, dx,dy,dz;
-PCAtom A;
-
- RemoveMBricks();
-
- mbrick_size = BrickSize;
-
- // find the range of coordinates
- x1 = MaxReal;
- x2 = -x1;
- y1 = MaxReal;
- y2 = -y1;
- z1 = MaxReal;
- z2 = -z1;
- for (i=0;i<nStructures;i++)
- for (j=0;j<avlen[i];j++) {
- A = atmvec[i][j];
- if (A) {
- if ((!A->Ter) && (A->WhatIsSet & ASET_Coordinates)) {
- if (A->x<x1) x1 = A->x;
- if (A->x>x2) x2 = A->x;
- if (A->y<y1) y1 = A->y;
- if (A->y>y2) y2 = A->y;
- if (A->z<z1) z1 = A->z;
- if (A->z>z2) z2 = A->z;
- }
- }
- }
- if (x1<MaxReal) {
- x1 -= Margin; x2 += Margin;
- y1 -= Margin; y2 += Margin;
- z1 -= Margin; z2 += Margin;
- dx = x2-x1; nmbrick_x = mround(dx/mbrick_size+0.0001)+1;
- dy = y2-y1; nmbrick_y = mround(dy/mbrick_size+0.0001)+1;
- dz = z2-z1; nmbrick_z = mround(dz/mbrick_size+0.0001)+1;
- xmbrick_0 = x1 - (nmbrick_x*mbrick_size-dx)/2.0;
- ymbrick_0 = y1 - (nmbrick_y*mbrick_size-dy)/2.0;
- zmbrick_0 = z1 - (nmbrick_z*mbrick_size-dz)/2.0;
- /*
- MBrick = new PPPCMBrick[nmbrick_x];
- for (i=0;i<nmbrick_x;i++) {
- MBrick[i] = new PPCMBrick[nmbrick_y];
- for (j=0;j<nmbrick_y;j++) {
- MBrick[i][j] = new PCMBrick[nmbrick_z];
- for (k=0;k<nmbrick_z;k++)
- MBrick[i][j][k] = new CMBrick(nStructures);
- }
- }
- */
- for (i=0;i<nStructures;i++)
- for (j=0;j<avlen[i];j++) {
- A = atmvec[i][j];
- if (A) {
- if ((!A->Ter) && (A->WhatIsSet & ASET_Coordinates)) {
- GetMBrickCoor ( A,nx,ny,nz );
- if (nx>=0) {
- if (!MBrick) {
- MBrick = new PPPCMBrick[nmbrick_x];
- for (k=0;k<nmbrick_x;k++)
- MBrick[k] = NULL;
- }
- if (!MBrick[nx]) {
- MBrick[nx] = new PPCMBrick[nmbrick_y];
- for (k=0;k<nmbrick_y;k++)
- MBrick[nx][k] = NULL;
- }
- if (!MBrick[nx][ny]) {
- MBrick[nx][ny] = new PCMBrick[nmbrick_z];
- for (k=0;k<nmbrick_z;k++)
- MBrick[nx][ny][k] = NULL;
- }
- if (!MBrick[nx][ny][nz])
- MBrick[nx][ny][nz] = new CMBrick(nStructures);
- MBrick[nx][ny][nz]->AddAtom ( A,i,j );
- } else
- printf ( " error in "
- "CMMDBCoorManager::MakeMBricks!!!\n" );
- }
- }
- }
- }
-
-}
-
-
-int CMMDBCoorManager::GenerateSymMates ( PCGenSym GenSym ) {
-//
-// The function generates symmetry mates according to symmetry
-// operations found in GenSym. Results of first symmetry operation
-// (number 0) always replaces the existing set of atoms, others
-// are added as additional sets.
-// If GenSym is set to NULL, the function generates all
-// symmetry mates for the unit cell taking the symmetry information
-// from Cryst.SymOps.
-// The newly generated chains are added to each model. These
-// chains have many-character chain names, composed as 'x_n',
-// where 'x' is the original name and 'n' is a unique number, which
-// coincides with the symmetry operation (order) number; number '_0'
-// (for the very first symmetry operatyion) is missing. Another
-// side effect is the disorder in atoms' serial numbers.
-// The hierarchy should therefore be cleaned after
-// generating the symmetry mates. An appropriate way to do
-// that is to issue the following call:
-//
-// PDBCleanup ( PDBCLEAN_TER | PDBCLEAN_ALTCODE_STRONG |
-// PDBCLEAN_CHAIN_STRONG | PDBCLEAN_SERIAL );
-//
-PPCMMDBCoorManager Mate;
-int i,j,k,n,nMates,nMates1,nAtoms1;
-PPCAtom Atom1;
-PPCModel Model1;
-
- if (GenSym) nMates = GenSym->GetNofSymOps();
- else nMates = Cryst.GetNumberOfSymOps();
- if (nMates<=0) return GSM_NoSymOps;
-
- if (!Cryst.areMatrices()) return GSM_NoTransfMatrices;
- if (!Cryst.isCellParameters()) return GSM_NoCell;
-
- nMates1 = nMates-1;
- if (nMates1>0) {
-
- // Generate symmetry mates in parallel hierarchies
- Mate = new PCMMDBCoorManager[nMates1];
- for (i=0;i<nMates1;i++) {
- Mate[i] = new CMMDBCoorManager();
- Mate[i]->Copy ( this );
- Mate[i]->ApplySymTransform ( i+1,GenSym );
- }
-
- // apply 1st symmetry operation:
- if (GenSym) ApplySymTransform ( 0,GenSym );
-
- // Gather all symmetry mates in 'this' hierarchy
- nAtoms1 = nMates*nAtoms; // new number of atoms
- Atom1 = new PCAtom[nAtoms1]; // new array of atoms
-
- if (nModels>0) Model1 = new PCModel[nModels]; // new array of
- else Model1 = NULL; // models
-
- k = 0; // index of collected atoms
- for (i=0;i<nModels;i++)
- if (Model[i]) {
- Model1[i] = newCModel();
- Model1[i]->SetMMDBManager ( PCMMDBManager(this),i+1 );
- for (j=0;j<Model[i]->nChains;j++)
- Model1[i]->MoveChain ( Model[i]->Chain[j],Atom,Atom1,k,0 );
- for (n=0;n<nMates1;n++)
- for (j=0;j<Model[i]->nChains;j++)
- Model1[i]->MoveChain ( Mate[n]->Model[i]->Chain[j],
- Mate[n]->Atom,Atom1,k,n+1 );
- } else
- Model1[i] = NULL;
-
- if (Model) delete[] Model;
- Model = Model1;
-
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) delete Atom[i]; // should never happen
- if (Atom) delete[] Atom;
- Atom = Atom1;
- AtmLen = nAtoms1; // length of Atom array
- nAtoms = k;
-
- // Dispose parallel hierarchies
- for (i=0;i<nMates1;i++)
- delete Mate[i];
- delete[] Mate;
-
- } else {
- // just apply the only symmetry operation:
- if (GenSym) ApplySymTransform ( 0,GenSym );
- }
-
- return GSM_Ok;
-
-}
-
-void CMMDBCoorManager::ApplyTransform ( mat44 & TMatrix ) {
-// simply transforms all coordinates by multiplying with matrix TMatrix
-int i;
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- if (!Atom[i]->Ter) Atom[i]->Transform ( TMatrix );
- }
-}
-
-void CMMDBCoorManager::ApplySymTransform ( int SymOpNo,
- PCGenSym GenSym ) {
-// This procedure applies the symmetry operation number SymOpNo
-// (starting from 0 on) and renames chains as specified in
-// GenSym.
-// The chains don't have to be renamed. The number of chains
-// to be renamed is obtained as GenSym->nChains[SymOpNo], their
-// old names - as GenSym->chID1[SymOpNo][j], and their new names
-// - as GenSym->chID2[SymOpNo][j], 0<=j<GenSym->nChains[SymOpNo].
-mat44 tmat;
-int i,j,k,nChn;
-PPCChain chain;
- if (Cryst.GetTMatrix(tmat,SymOpNo,0,0,0,PCSymOps(GenSym))
- ==SYMOP_Ok) {
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- if (!Atom[i]->Ter) Atom[i]->Transform ( tmat );
- }
- if (GenSym)
- for (i=0;i<nModels;i++)
- if (Model[i]) {
- Model[i]->GetChainTable ( chain,nChn );
- for (j=0;j<GenSym->nChains[SymOpNo];j++)
- for (k=0;k<nChn;k++)
- if (!strcmp(chain[k]->chainID,GenSym->chID1[SymOpNo][j]))
- chain[k]->SetChainID ( GenSym->chID2[SymOpNo][j] );
- }
- }
-}
-
-
-void GetEulerRotMatrix ( mat33 & erm,
- realtype alpha,
- realtype beta,
- realtype gamma ) {
-// Calculates the Euler rotation matrix for rotation:
-// 1) about z-axis by angle alpha (0..2*Pi)
-// 2) about new y-axis by angle beta (0..Pi)
-// 3) about new z-axis by angle gamma (0..2*Pi)
-realtype ca,cb,cg, sa,sb,sg;
-
- ca = cos(alpha);
- sa = sin(alpha);
- cb = cos(beta);
- sb = sin(beta);
- cg = cos(gamma);
- sg = sin(gamma);
-
- erm[0][0] = ca*cb*cg - sa*sg;
- erm[0][1] = cb*cg*sa + ca*sg;
- erm[0][2] = -cg*sb;
-
- erm[1][0] = -cg*sa - ca*cb*sg;
- erm[1][1] = ca*cg - cb*sa*sg;
- erm[1][2] = sb*sg;
-
- erm[2][0] = ca*sb;
- erm[2][1] = sa*sb;
- erm[2][2] = cb;
-
-}
-
-
-
-void GetEulerTMatrix ( mat44 & erm,
- realtype alpha,
- realtype beta,
- realtype gamma,
- realtype x0,
- realtype y0,
- realtype z0 ) {
-// Calculates the Euler rotation-translation matrix for rotation:
-// 1) about z-axis by angle alpha
-// 2) about new y-axis by angle beta
-// 3) about new z-axis by angle gamma
-// Point (x0,y0,z0) is the center of rotation.
-mat33 m;
-
- m[0][0] = 1.0;
- GetEulerRotMatrix ( m,alpha,beta,gamma );
-
- erm[0][0] = m[0][0]; erm[0][1] = m[0][1]; erm[0][2] = m[0][2];
- erm[1][0] = m[1][0]; erm[1][1] = m[1][1]; erm[1][2] = m[1][2];
- erm[2][0] = m[2][0]; erm[2][1] = m[2][1]; erm[2][2] = m[2][2];
- erm[3][0] = 0.0; erm[3][1] = 0.0; erm[3][2] = 0.0;
-
- erm[3][3] = 1.0;
-
- erm[0][3] = x0 - m[0][0]*x0 - m[0][1]*y0 - m[0][2]*z0;
- erm[1][3] = y0 - m[1][0]*x0 - m[1][1]*y0 - m[1][2]*z0;
- erm[2][3] = z0 - m[2][0]*x0 - m[2][1]*y0 - m[2][2]*z0;
-
-}
-
-
-void EulerRotation ( PPCAtom A,
- int nA,
- realtype alpha,
- realtype beta,
- realtype gamma,
- realtype x0,
- realtype y0,
- realtype z0 ) {
-// Euler rotation: 1) about z-axis by angle alpha
-// 2) about new y-axis by angle beta
-// 3) about new z-axis by angle gamma
-// Point (x0,y0,z0) is the center of rotation.
-mat33 m;
-realtype x,y,z;
-int i;
-
- m[0][0] = 1.0;
- GetEulerRotMatrix ( m,alpha,beta,gamma );
-
- for (i=0;i<nA;i++)
- if (A[i]) {
- if ((!A[i]->Ter) && (A[i]->WhatIsSet & ASET_Coordinates)) {
- x = A[i]->x - x0;
- y = A[i]->y - y0;
- z = A[i]->z - z0;
- A[i]->x = m[0][0]*x + m[0][1]*y + m[0][2]*z + x0;
- A[i]->y = m[1][0]*x + m[1][1]*y + m[1][2]*z + y0;
- A[i]->z = m[2][0]*x + m[2][1]*y + m[2][2]*z + z0;
- }
- }
-
-}
-
-
-void GetVecRotMatrix ( mat33 & vrm,
- realtype alpha,
- realtype vx,
- realtype vy,
- realtype vz ) {
-// Calculates the rotation matrix for rotation by angle alpha about
-// arbitrary vector directed as (vx,vy,vz) = (vx2-vx1,vy2-vy1,vz2-vz1).
-realtype ca,sa, rx,ry,rz, vl;
-
- ca = cos(alpha);
- sa = sin(alpha);
-
- vl = sqrt ( vx*vx + vy*vy + vz*vz );
- if (vl<=0.0) return;
- rx = vx/vl;
- ry = vy/vl;
- rz = vz/vl;
-
- vrm[0][0] = rx*rx*(1.0-ca) + ca;
- vrm[0][1] = rx*ry*(1.0-ca) - rz*sa;
- vrm[0][2] = rx*rz*(1.0-ca) + ry*sa;
-
- vrm[1][0] = ry*rx*(1.0-ca) + rz*sa;
- vrm[1][1] = ry*ry*(1.0-ca) + ca;
- vrm[1][2] = ry*rz*(1.0-ca) - rx*sa;
-
- vrm[2][0] = rz*rx*(1.0-ca) - ry*sa;
- vrm[2][1] = rz*ry*(1.0-ca) + rx*sa;
- vrm[2][2] = rz*rz*(1.0-ca) + ca;
-
-}
-
-
-void GetRotParameters ( mat33 & vrm,
- realtype & alpha,
- realtype & vx,
- realtype & vy,
- realtype & vz ) {
-// Given the rotation matrix vrm, GetRotParameters(..)
-// returns the rotation angle alpha and the normalized
-// rotation axis vector (vx,vy,vz).
-// The rotation angle and vector are determined up to
-// their sign (however correlated, so that being substituted
-// into GetVecRotMatrix(..) they yield the same rotation
-// matrix).
-// The function does not check for vrm to be a valid
-// rotation matrix.
-realtype ca,sa,vl;
- ca = (vrm[0][0]+vrm[1][1]+vrm[2][2]-1.0)/2.0;
- if (ca<-1.0) ca = -1.0; // does not work if rotation
- if (ca>1.0) ca = 1.0; // matrix is correct
- sa = sqrt(1.0-ca*ca);
- if (sa>0.0) {
- alpha = acos(ca);
- // coefficient of 2 is corrected by normalization below
- vx = (vrm[2][1]-vrm[1][2])/sa;
- vy = (vrm[0][2]-vrm[2][0])/sa;
- vz = (vrm[1][0]-vrm[0][1])/sa;
- // the following code is formally redundant if rotation
- // matrix is correct, however it eliminates the round-offs
- vl = sqrt(vx*vx+vy*vy+vz*vz);
- vx /= vl;
- vy /= vl;
- vz /= vl;
- } else {
- // zero rotation, arbitrary axis would do
- alpha = 0.0;
- vx = 1.0;
- vy = 0.0;
- vz = 0.0;
- }
-}
-
-
-void GetVecTMatrix ( mat44 & vrm,
- realtype alpha,
- realtype vx,
- realtype vy,
- realtype vz,
- realtype x0,
- realtype y0,
- realtype z0 ) {
-// Calculates the rotation-translation matrix for rotation by angle
-// alpha about arbitrary vector directed as (vx,vy,vz) =
-// (vx2-vx1,vy2-vy1,vz2-vz1). Point (x0,y0,z0) is the center of
-// rotation -- actually a point belonging to the rotation axis.
-mat33 m;
-
- GetVecRotMatrix ( m,alpha,vx,vy,vz );
-
- vrm[0][0] = m[0][0]; vrm[0][1] = m[0][1]; vrm[0][2] = m[0][2];
- vrm[1][0] = m[1][0]; vrm[1][1] = m[1][1]; vrm[1][2] = m[1][2];
- vrm[2][0] = m[2][0]; vrm[2][1] = m[2][1]; vrm[2][2] = m[2][2];
- vrm[3][0] = 0.0; vrm[3][1] = 0.0; vrm[3][2] = 0.0;
-
- vrm[3][3] = 1.0;
-
- vrm[0][3] = x0 - m[0][0]*x0 - m[0][1]*y0 - m[0][2]*z0;
- vrm[1][3] = y0 - m[1][0]*x0 - m[1][1]*y0 - m[1][2]*z0;
- vrm[2][3] = z0 - m[2][0]*x0 - m[2][1]*y0 - m[2][2]*z0;
-
-}
-
-
-void VectorRotation ( PPCAtom A,
- int nA,
- realtype alpha,
- realtype vx,
- realtype vy,
- realtype vz,
- realtype x0,
- realtype y0,
- realtype z0 ) {
-// Vector rotation is rotation by angle alpha about arbitrary
-// vector directed as (vx,vy,vz) = (vx2-vx1,vy2-vy1,vz2-vz1).
-// Point (x0,y0,z0) is the center of rotation -- actually
-// a point belonging to the rotation axis.
-mat33 m;
-realtype x,y,z;
-int i;
-
- GetVecRotMatrix ( m, alpha,vx,vy,vz );
-
- for (i=0;i<nA;i++)
- if (A[i]) {
- if ((!A[i]->Ter) && (A[i]->WhatIsSet & ASET_Coordinates)) {
- x = A[i]->x - x0;
- y = A[i]->y - y0;
- z = A[i]->z - z0;
- A[i]->x = m[0][0]*x + m[0][1]*y + m[0][2]*z + x0;
- A[i]->y = m[1][0]*x + m[1][1]*y + m[1][2]*z + y0;
- A[i]->z = m[2][0]*x + m[2][1]*y + m[2][2]*z + z0;
- }
- }
-
-}
-
-
-void GetMassCenter ( PPCAtom A, int nA,
- realtype & xmc, realtype & ymc,
- realtype & zmc ) {
-realtype w,mass;
-int i,k;
-
- xmc = 0.0;
- ymc = 0.0;
- zmc = 0.0;
- mass = 0.0;
-
- for (i=0;i<nA;i++)
- if (A[i]) {
- if ((!A[i]->Ter) && (A[i]->WhatIsSet & ASET_Coordinates)) {
- k = getElementNo ( A[i]->element );
- if (k>=0) w = MolecWeight[k];
- else w = 1.0;
- xmc += w*A[i]->x;
- ymc += w*A[i]->y;
- zmc += w*A[i]->z;
- mass += w;
- }
- }
-
- if (mass>0.0) {
- xmc /= mass;
- ymc /= mass;
- zmc /= mass;
- }
-
-}
-
-int CMMDBCoorManager::BringToUnitCell() {
-// brings all chains into 0th unit cell
-PCChain chain;
-PPCAtom atom;
-realtype x0,y0,z0, x,y,z, xf,yf,zf, sx,sy,sz;
-realtype dx,dy,dz, d,d0;
-int nAtoms;
-int i,j,k,n,m,nt, ic,jc,kc, is,js,ks;
-
- if (!Cryst.areMatrices()) return -1;
-
- is = 0; // this is only
- js = 0; // to depress
- ks = 0; // "uninitialized" worning
-
- Cryst.Frac2Orth ( 0.5,0.5,0.5, x0,y0,z0 );
-
- nt = 0;
- for (i=0;i<nModels;i++)
- if (Model[i]) {
- for (j=0;j<Model[i]->nChains;j++) {
- chain = Model[i]->Chain[j];
- if (chain) {
-
- x = 0.0;
- y = 0.0;
- z = 0.0;
- m = 0;
- for (k=0;k<chain->nResidues;k++)
- if (chain->Residue[k]) {
- chain->Residue[k]->GetAtomTable ( atom,nAtoms );
- for (n=0;n<nAtoms;n++)
- if (atom[n]) {
- if (!atom[n]->Ter) {
- x += atom[n]->x;
- y += atom[n]->y;
- z += atom[n]->z;
- m++;
- }
- }
- }
- x /= m;
- y /= m;
- z /= m;
-
- Cryst.Orth2Frac ( x,y,z, xf,yf,zf );
- sx = frac ( xf );
- sy = frac ( yf );
- sz = frac ( zf );
- d0 = MaxReal;
- for (ic=-3;ic<3;ic++)
- for (jc=-3;jc<3;jc++)
- for (kc=-3;kc<3;kc++) {
- Cryst.Frac2Orth ( sx+ic,sy+jc,sz+kc, dx,dy,dz );
- dx -= x0;
- dy -= y0;
- dz -= z0;
- d = dx*dx + dy*dy + dz*dz;
- if (d<d0) {
- d0 = d;
- is = ic;
- js = jc;
- ks = kc;
- }
- }
-
- sx = xf - (sx+is);
- sy = yf - (sy+js);
- sz = zf - (sz+ks);
-
- if ((fabs(sx)>1.0e-10) || (fabs(sy)>1.0e-10)
- || (fabs(sz)>1.0e-10)) {
- nt++;
- for (k=0;k<chain->nResidues;k++)
- if (chain->Residue[k]) {
- chain->Residue[k]->GetAtomTable ( atom,nAtoms );
- for (n=0;n<nAtoms;n++)
- if (atom[n]) {
- if (!atom[n]->Ter) {
- Cryst.Orth2Frac ( atom[n]->x,atom[n]->y,
- atom[n]->z,
- xf,yf,zf );
- Cryst.Frac2Orth ( xf-sx,yf-sy,zf-sz,
- atom[n]->x,atom[n]->y,
- atom[n]->z );
- }
- }
- }
- }
-
- }
- }
- }
-
- return nt; // number of converted chains
-
-}
-
-
-Boolean CMMDBCoorManager::Frac2Orth (
- realtype xfrac, realtype yfrac, realtype zfrac,
- realtype & xorth, realtype & yorth, realtype & zorth ) {
- return Cryst.Frac2Orth ( xfrac,yfrac,zfrac, xorth,yorth,zorth );
-}
-
-Boolean CMMDBCoorManager::Orth2Frac (
- realtype xorth, realtype yorth, realtype zorth,
- realtype & xfrac, realtype & yfrac, realtype & zfrac ) {
- return Cryst.Orth2Frac ( xorth,yorth,zorth, xfrac,yfrac,zfrac );
-}
-
-
-Boolean CMMDBCoorManager::Frac2Orth ( mat44 & F, mat44 & T ) {
- return Cryst.Frac2Orth ( F,T );
-}
-
-Boolean CMMDBCoorManager::Orth2Frac ( mat44 & T, mat44 & F ) {
- return Cryst.Orth2Frac ( T,F );
-}
-
-
-
-// ------------------------ Contacts -------------------------------
-
-
-#define CA_CA_Dist2 16.0
-
-void CMMDBCoorManager::FindSeqSection ( PCAtom atom, int seqDist,
- int & seq1, int & seq2 ) {
-PCAtom a;
-PCResidue res;
-PCChain chain;
-realtype x0,y0,z0, x,y,z, dx,dy,dz, d2;
-int i1;
-Boolean B0,B;
-
- x = 0.0;
- y = 0.0;
- z = 0.0;
- x0 = 0.0;
- y0 = 0.0;
- z0 = 0.0;
-
- res = atom->residue;
- if ((!res) || (seqDist<=0)) {
- seq1 = MaxInt4;
- seq2 = MinInt4;
- return;
- }
-
- chain = res->chain;
- if (!chain) {
- seq1 = MaxInt4;
- seq2 = MinInt4;
- return;
- }
-
- if (seqDist==1) {
- seq1 = res->index;
- seq2 = seq1;
- return;
- }
-
- a = res->GetAtom ( pstr("CA"),pstr("C"),NULL );
- if (a) {
- x0 = a->x;
- y0 = a->y;
- z0 = a->z;
- B0 = True;
- } else
- B0 = False;
- if (B0) {
- x = x0;
- y = y0;
- z = z0;
- }
-
- B = B0;
- seq2 = res->index;
- i1 = IMin(chain->nResidues,seq2+seqDist)-1;
- while (seq2<i1) {
- seq2++;
- if (chain->Residue[seq2]) {
- a = chain->Residue[seq2]->GetAtom ( pstr("CA"),pstr("C"),NULL );
- if (a && B) {
- dx = x-a->x;
- dy = y-a->y;
- dz = z-a->z;
- d2 = dx*dx + dy*dy + dz*dz;
- if (d2>CA_CA_Dist2) {
- seq2--;
- break;
- }
- }
- if (a) {
- x = a->x;
- y = a->y;
- z = a->z;
- B = True;
- } else
- B = False;
- }
- }
-
- if (B0) {
- x = x0;
- y = y0;
- z = z0;
- }
- B = B0;
- seq1 = res->index;
- i1 = IMax(0,seq1-seqDist+1);
- while (seq1>i1) {
- seq1--;
- if (chain->Residue[seq1]) {
- a = chain->Residue[seq1]->GetAtom ( pstr("CA"),pstr("C"),NULL );
- if (a && B) {
- dx = x-a->x;
- dy = y-a->y;
- dz = z-a->z;
- d2 = dx*dx + dy*dy + dz*dz;
- if (d2>CA_CA_Dist2) {
- seq1++;
- break;
- }
- }
- if (a) {
- x = a->x;
- y = a->y;
- z = a->z;
- B = True;
- } else
- B = False;
- }
- }
-
-}
-
-
-Boolean CMMDBCoorManager::isContact ( PCAtom a1, PCAtom a2,
- int seq1, int seq2,
- realtype dd, realtype d12,
- realtype d22, realtype & d2 ) {
-// seq1..seq2 is forbidden region for residue sequence numbers
-PCResidue res1,res2;
-PCChain chain1,chain2;
-realtype dx,dy,dz;
-
- if (a2->Ter) return False;
-
- dx = fabs(a2->x-a1->x);
- if (dx<=dd) {
- dy = fabs(a2->y-a1->y);
- if (dy<=dd) {
- dz = fabs(a2->z-a1->z);
- if (dz<=dd) {
- d2 = dx*dx + dy*dy + dz*dz;
- if ((d12<=d2) && (d2<=d22)) {
- if (seq1<=seq2) {
- res1 = a1->residue;
- res2 = a2->residue;
- if (res1 && res2) {
- chain1 = res1->chain;
- chain2 = res2->chain;
- if (chain1 && chain2) {
- if (!strcmp(chain1->chainID,chain2->chainID)) {
- if ((seq1<=res2->index) && (res2->index<=seq2))
- return False;
- }
- }
- }
- }
- return True;
- }
- }
- }
- }
-
- return False;
-
-}
-
-Boolean CMMDBCoorManager::isContact ( realtype x, realtype y,
- realtype z, PCAtom a2,
- realtype dd, realtype d12,
- realtype d22, realtype & d2 ) {
-realtype dx,dy,dz;
-
- if (a2->Ter) return False;
-
- dx = fabs(a2->x-x);
- if (dx<=dd) {
- dy = fabs(a2->y-y);
- if (dy<=dd) {
- dz = fabs(a2->z-z);
- if (dz<=dd) {
- d2 = dx*dx + dy*dy + dz*dz;
- if ((d12<=d2) && (d2<=d22)) return True;
- }
- }
- }
-
- return False;
-
-}
-
-
-void CMMDBCoorManager::SeekContacts ( PPCAtom AIndex,
- int ilen,
- int atomNum,
- realtype dist1,
- realtype dist2,
- int seqDist,
- RPSContact contact,
- int & ncontacts,
- int maxlen,
- long group ) {
-PCContactIndex ContactIndex;
-realtype d12,d22,d2;
-int i,seq1,seq2;
-
- if (!AIndex) return;
- if (dist2<dist1) return;
- if (!AIndex[atomNum]) return;
- if (AIndex[atomNum]->Ter) return;
-
- ContactIndex = new CContactIndex ( contact,maxlen,ncontacts,ilen );
-
- FindSeqSection ( AIndex[atomNum],seqDist,seq1,seq2 );
-
- d12 = dist1*dist1;
- d22 = dist2*dist2;
-
- for (i=0;i<ilen;i++)
- if ((i!=atomNum) && AIndex[i]) {
- if (isContact(AIndex[atomNum],AIndex[i],seq1,seq2,dist2,
- d12,d22,d2))
- ContactIndex->AddContact ( atomNum,i,sqrt(d2),group );
- }
-
- ContactIndex->GetIndex ( contact,ncontacts );
-
- delete ContactIndex;
-
-}
-
-
-void CMMDBCoorManager::SeekContacts ( PCAtom A,
- PPCAtom AIndex,
- int ilen,
- realtype dist1,
- realtype dist2,
- int seqDist,
- RPSContact contact,
- int & ncontacts,
- int maxlen,
- long group
- ) {
-PCContactIndex ContactIndex;
-realtype d12,d22,d2;
-int i,seq1,seq2;
-
- if (!AIndex) return;
- if (dist2<dist1) return;
- if (!A) return;
- if (A->Ter) return;
-
- ContactIndex = new CContactIndex ( contact,maxlen,ncontacts,ilen );
-
- FindSeqSection ( A,seqDist,seq1,seq2 );
-
- d12 = dist1*dist1;
- d22 = dist2*dist2;
-
- for (i=0;i<ilen;i++)
- if ((AIndex[i]!=A) && AIndex[i]) {
- if (isContact(A,AIndex[i],seq1,seq2,dist2,d12,d22,d2))
- ContactIndex->AddContact ( -1,i,sqrt(d2),group );
- }
-
- ContactIndex->GetIndex ( contact,ncontacts );
-
- delete ContactIndex;
-
-}
-
-
-void CMMDBCoorManager::SeekContacts ( PPCAtom AIndex1,
- int ilen1,
- PPCAtom AIndex2,
- int ilen2,
- realtype dist1,
- realtype dist2,
- int seqDist,
- RPSContact contact,
- int & ncontacts,
- int maxlen,
- mat44 * TMatrix,
- long group,
- int bricking,
- Boolean doSqrt
- ) {
-// It is Ok to have NULL pointers in AIndex1 and AIndex2
-PCContactIndex ContactIndex;
-PPCAtom A1,A2;
-rvector sx0,sy0,sz0;
-rvector dx0,dy0,dz0;
-realtype d12,d22,d2, eps;
-int l1,l2, i,j, nx,ny,nz, dn;
-int ix1,ix2, iy1,iy2, iz1,iz2, ix,iy,iz;
-int seq1,seq2;
-PCBrick B;
-Boolean swap,UnitT;
-
- if ((dist2<dist1) || (!AIndex1) || (!AIndex2)) return;
-
- ContactIndex = new CContactIndex ( contact,maxlen,ncontacts,
- ilen1*ilen2 );
-
- sx0 = NULL;
- sy0 = NULL;
- sz0 = NULL;
- dx0 = NULL;
- dy0 = NULL;
- dz0 = NULL;
- UnitT = True;
- if (TMatrix) {
- // Transformation matrix is given. Check that that is not
- // the unit one.
- eps = 1.0e-6;
- for (i=0;(i<3) && UnitT;i++)
- for (j=0;(j<4) && UnitT;j++)
- if (i==j) UnitT = fabs(1.0-(*TMatrix)[i][j])<eps;
- else UnitT = fabs((*TMatrix)[i][j])<eps;
- if (!UnitT) {
- // A non-unit transformation to AIndex2 is required.
- // As AIndex1 and AIndex2 may overlap, we have to save
- // the original AIndex1 coordinates
- GetVectorMemory ( sx0,ilen1,0 );
- GetVectorMemory ( sy0,ilen1,0 );
- GetVectorMemory ( sz0,ilen1,0 );
- for (i=0;i<ilen1;i++)
- if (AIndex1[i]) {
- sx0[i] = AIndex1[i]->x;
- sy0[i] = AIndex1[i]->y;
- sz0[i] = AIndex1[i]->z;
- }
- // Save original AIndex2 coordinates and modify the index
- GetVectorMemory ( dx0,ilen2,0 );
- GetVectorMemory ( dy0,ilen2,0 );
- GetVectorMemory ( dz0,ilen2,0 );
- for (i=0;i<ilen2;i++)
- if (AIndex2[i]) {
- dx0[i] = AIndex2[i]->x;
- dy0[i] = AIndex2[i]->y;
- dz0[i] = AIndex2[i]->z;
- AIndex2[i]->Transform ( *TMatrix );
- }
- }
- }
-
- // choose A2 as the largest atom set convenient for
- // bricking (bricking on larger set is more efficient)
- if (bricking & BRICK_ON_1) {
- A1 = AIndex2;
- A2 = AIndex1;
- l1 = ilen2;
- l2 = ilen1;
- swap = True;
- } else if (bricking & BRICK_ON_2) {
- A1 = AIndex1;
- A2 = AIndex2;
- l1 = ilen1;
- l2 = ilen2;
- swap = False;
- } else if (ilen1<=ilen2) {
- A1 = AIndex1;
- A2 = AIndex2;
- l1 = ilen1;
- l2 = ilen2;
- swap = False;
- } else {
- A1 = AIndex2;
- A2 = AIndex1;
- l1 = ilen2;
- l2 = ilen1;
- swap = True;
- }
-
- d12 = dist1*dist1;
- d22 = dist2*dist2;
-
- if (((bricking & BRICK_READY)==0) || (!Brick))
- MakeBricks ( A2,l2,dist2*1.5 );
-
- dn = mround(dist2/brick_size)+1;
-
- if (Brick)
- for (i=0;i<l1;i++)
- if (A1[i]) {
- if (!A1[i]->Ter) {
- if (UnitT) {
- // No transformation -- AIndex1 and AIndex2 are unmodified.
- // Calculate the forbidden sequence region
- FindSeqSection ( A1[i],seqDist,seq1,seq2 );
- // And the brick location
- GetBrickCoor ( A1[i],nx,ny,nz );
- } else {
- // AIndex2 and AIndex1 are modified, but the sequence
- // distance does not apply to physically different chains
- // (meaning that transformation of A2 effectively makes
- // a different chain). Use unmodified atom coordinates
- // of 1st set for calculating the brick location.
- if (swap) GetBrickCoor ( A1[i],nx,ny,nz ); // A1 is AIndex2
- else GetBrickCoor ( sx0[i],sy0[i],sz0[i],nx,ny,nz );
- }
- if (nx>=0) {
- ix1 = IMax ( 0,nx-dn );
- iy1 = IMax ( 0,ny-dn );
- iz1 = IMax ( 0,nz-dn );
- ix2 = IMin ( nbrick_x,nx+dn+1 );
- iy2 = IMin ( nbrick_y,ny+dn+1 );
- iz2 = IMin ( nbrick_z,nz+dn+1 );
- if (UnitT) {
- // AIndex1 unmodified, use it
- for (ix=ix1;ix<ix2;ix++)
- if (Brick[ix])
- for (iy=iy1;iy<iy2;iy++)
- if (Brick[ix][iy])
- for (iz=iz1;iz<iz2;iz++) {
- B = Brick[ix][iy][iz];
- if (B)
- for (j=0;j<B->nAtoms;j++)
- if (B->Atom[j]!=A1[i]) {
- if (isContact(A1[i],B->Atom[j],seq1,seq2,
- dist2,d12,d22,d2)) {
- if (doSqrt) d2 = sqrt(d2);
- if (swap) ContactIndex->AddContact (
- B->id[j],i,d2,group );
- else ContactIndex->AddContact (
- i,B->id[j],d2,group );
- }
- }
- }
- } else if (swap) {
- // A1 stands for AIndex2, it is modified and we need to use
- // the modified coordinates
- for (ix=ix1;ix<ix2;ix++)
- if (Brick[ix])
- for (iy=iy1;iy<iy2;iy++)
- if (Brick[ix][iy])
- for (iz=iz1;iz<iz2;iz++) {
- B = Brick[ix][iy][iz];
- if (B)
- for (j=0;j<B->nAtoms;j++)
- if (isContact(A1[i]->x,A1[i]->y,A1[i]->z,
- B->Atom[j], dist2,d12,d22,d2)) {
- if (doSqrt) d2 = sqrt(d2);
- ContactIndex->AddContact ( B->id[j],i,d2,group );
- }
- }
- } else {
- // A1 stands for AIndex1, it may be modified (if AIndex1
- // and AIndex2 overlap) -- use its unmodified coordinates
- // instead.
- for (ix=ix1;ix<ix2;ix++)
- if (Brick[ix])
- for (iy=iy1;iy<iy2;iy++)
- if (Brick[ix][iy])
- for (iz=iz1;iz<iz2;iz++) {
- B = Brick[ix][iy][iz];
- if (B)
- for (j=0;j<B->nAtoms;j++)
- if (isContact(sx0[i],sy0[i],sz0[i],
- B->Atom[j],dist2,d12,d22,d2)) {
- if (doSqrt) d2 = sqrt(d2);
- ContactIndex->AddContact ( i,B->id[j],d2,group );
- }
- }
- }
- }
- }
- }
-
-
- if (!UnitT) {
- // restore original coordinates
- for (i=0;i<ilen1;i++)
- if (AIndex1[i]) {
- AIndex1[i]->x = sx0[i];
- AIndex1[i]->y = sy0[i];
- AIndex1[i]->z = sz0[i];
- }
- for (i=0;i<ilen2;i++)
- if (AIndex2[i]) {
- AIndex2[i]->x = dx0[i];
- AIndex2[i]->y = dy0[i];
- AIndex2[i]->z = dz0[i];
- }
- FreeVectorMemory ( sx0,0 );
- FreeVectorMemory ( sy0,0 );
- FreeVectorMemory ( sz0,0 );
- FreeVectorMemory ( dx0,0 );
- FreeVectorMemory ( dy0,0 );
- FreeVectorMemory ( dz0,0 );
- }
-
- ContactIndex->GetIndex ( contact,ncontacts );
-
- delete ContactIndex;
-
-}
-
-
-void CMMDBCoorManager::SeekContacts ( PPCAtom AIndex1,
- int ilen1,
- PPCAtom AIndex2,
- int ilen2,
- realtype contDist,
- PSContact contact,
- int & ncontacts,
- int bricking
- ) {
-// Simplified optimized for speed version:
-// - no NULL pointers and Ters in AIndex1 and AIndex2
-// - no checks for identity atoms in AIndex1 and AIndex2
-// - contact must be pre-allocated with at least ilen1*ilen2 elements
-// - contact returns square distances
-// - ncontacts is always reset
-PPCAtom A1,A2;
-realtype contDist2, dx,dy,dz, d2;
-int l1,l2, i,j, nx,ny,nz, dn;
-int ix1,ix2, iy1,iy2, iz1,iz2, ix,iy,iz;
-PCBrick B;
-Boolean swap;
-
- // choose A2 as the largest atom set convenient for
- // bricking (bricking on larger set is more efficient)
- if (bricking & BRICK_ON_1) {
- A1 = AIndex2;
- A2 = AIndex1;
- l1 = ilen2;
- l2 = ilen1;
- swap = True;
- } else if (bricking & BRICK_ON_2) {
- A1 = AIndex1;
- A2 = AIndex2;
- l1 = ilen1;
- l2 = ilen2;
- swap = False;
- } else if (ilen1<=ilen2) {
- A1 = AIndex1;
- A2 = AIndex2;
- l1 = ilen1;
- l2 = ilen2;
- swap = False;
- } else {
- A1 = AIndex2;
- A2 = AIndex1;
- l1 = ilen2;
- l2 = ilen1;
- swap = True;
- }
-
- contDist2 = contDist*contDist;
-
- if (((bricking & BRICK_READY)==0) || (!Brick))
- MakeBricks ( A2,l2,contDist*1.5 );
-
- ncontacts = 0;
-
- if (!Brick) return;
-
- dn = (int)floor(contDist/brick_size)+1;
-
- if (swap) {
-
- for (i=0;i<l1;i++)
- if (A1[i]) {
- // Find brick location
- GetBrickCoor ( A1[i],nx,ny,nz );
- if (nx>=0) {
- ix1 = IMax ( 0,nx-dn );
- iy1 = IMax ( 0,ny-dn );
- iz1 = IMax ( 0,nz-dn );
- ix2 = IMin ( nbrick_x,nx+dn+1 );
- iy2 = IMin ( nbrick_y,ny+dn+1 );
- iz2 = IMin ( nbrick_z,nz+dn+1 );
- for (ix=ix1;ix<ix2;ix++)
- if (Brick[ix])
- for (iy=iy1;iy<iy2;iy++)
- if (Brick[ix][iy])
- for (iz=iz1;iz<iz2;iz++) {
- B = Brick[ix][iy][iz];
- if (B)
- for (j=0;j<B->nAtoms;j++) {
- dx = A1[i]->x - B->Atom[j]->x;
- dy = A1[i]->y - B->Atom[j]->y;
- dz = A1[i]->z - B->Atom[j]->z;
- d2 = dx*dx + dy*dy + dz*dz;
- if (d2<=contDist2) {
- contact[ncontacts].id1 = B->id[j];
- contact[ncontacts].id2 = i;
- contact[ncontacts].dist = d2;
- ncontacts++;
- }
- }
- }
- }
- }
-
- } else {
-
- for (i=0;i<l1;i++)
- if (A1[i]) {
- // Find brick location
- GetBrickCoor ( A1[i],nx,ny,nz );
- if (nx>=0) {
- ix1 = IMax ( 0,nx-dn );
- iy1 = IMax ( 0,ny-dn );
- iz1 = IMax ( 0,nz-dn );
- ix2 = IMin ( nbrick_x,nx+dn+1 );
- iy2 = IMin ( nbrick_y,ny+dn+1 );
- iz2 = IMin ( nbrick_z,nz+dn+1 );
- for (ix=ix1;ix<ix2;ix++)
- if (Brick[ix])
- for (iy=iy1;iy<iy2;iy++)
- if (Brick[ix][iy])
- for (iz=iz1;iz<iz2;iz++) {
- B = Brick[ix][iy][iz];
- if (B)
- for (j=0;j<B->nAtoms;j++) {
- dx = A1[i]->x - B->Atom[j]->x;
- dy = A1[i]->y - B->Atom[j]->y;
- dz = A1[i]->z - B->Atom[j]->z;
- d2 = dx*dx + dy*dy + dz*dz;
- if (d2<=contDist2) {
- contact[ncontacts].id1 = i;
- contact[ncontacts].id2 = B->id[j];
- contact[ncontacts].dist = d2;
- ncontacts++;
- }
- }
- }
- }
- }
-
- }
-
-}
-
-
-void CMMDBCoorManager::SeekContacts ( PPCAtom AIndex1,
- int ilen1,
- PPCAtom * AIndex2,
- ivector ilen2,
- int nStructures,
- realtype dist1,
- realtype dist2,
- PPCMContact & contact,
- int bricking
- ) {
-// It is Ok to have NULL pointers in AIndex1 and AIndex2
-PCMBrick B;
-PCAtom A;
-realtype d12,d22,d2;
-int dn, i,j,k, nx,ny,nz, ix1,iy1,iz1, ix2,iy2,iz2;
-int ix,iy,iz;
-
- if (dist2<dist1) return;
- if ((!AIndex1) || (!AIndex2)) return;
-
- d12 = dist1*dist1;
- d22 = dist2*dist2;
-
- if (((bricking & BRICK_READY)==0) || (!MBrick))
- MakeMBricks ( AIndex2,ilen2,nStructures,dist2*1.5 );
-
- contact = new PCMContact[ilen1];
-
- dn = mround(dist2/brick_size)+1;
-
- if (MBrick)
- for (i=0;i<ilen1;i++) {
- A = AIndex1[i];
- contact[i] = NULL;
- if (A) {
- if (!A->Ter) {
- contact[i] = new CMContact(nStructures);
- contact[i]->contactID = i;
- // Calculate the brick location
- GetMBrickCoor ( A,nx,ny,nz );
- if (nx>=0) {
- ix1 = IMax ( 0,nx-dn );
- iy1 = IMax ( 0,ny-dn );
- iz1 = IMax ( 0,nz-dn );
- ix2 = IMin ( nmbrick_x,nx+dn+1 );
- iy2 = IMin ( nmbrick_y,ny+dn+1 );
- iz2 = IMin ( nmbrick_z,nz+dn+1 );
- for (ix=ix1;ix<ix2;ix++)
- if (MBrick[ix])
- for (iy=iy1;iy<iy2;iy++)
- if (MBrick[ix][iy])
- for (iz=iz1;iz<iz2;iz++) {
- B = MBrick[ix][iy][iz];
- if (B)
- for (j=0;j<nStructures;j++)
- for (k=0;k<B->nAtoms[j];k++)
- if (B->Atom[j][k]!=A) {
- if (isContact(A,B->Atom[j][k],
- MaxInt4,MinInt4,
- dist2,d12,d22,d2))
- contact[i]->AddContact (
- B->Atom[j][k],j,B->id[j][k] );
- }
- }
- }
- }
- }
- }
- else
- for (i=0;i<ilen1;i++)
- contact[i] = NULL;
-
-}
-
-
-
-DefineClass(CSortContacts);
-
-class CSortContacts : public CQuickSort {
- public :
- CSortContacts() : CQuickSort() {}
- int Compare ( int i, int j );
- void Swap ( int i, int j );
- void Sort ( PSContact contact, int ncontacts, int sortmode );
- protected :
- int mode;
-};
-
-int CSortContacts::Compare ( int i, int j ) {
-Boolean gt,lt;
- switch (mode) {
- default :
- case CNSORT_1INC : gt = (((PSContact)data)[i].id1 >
- ((PSContact)data)[j].id1);
- lt = (((PSContact)data)[i].id1 <
- ((PSContact)data)[j].id1);
- break;
- case CNSORT_1DEC : gt = (((PSContact)data)[j].id1 >
- ((PSContact)data)[i].id1);
- lt = (((PSContact)data)[j].id1 <
- ((PSContact)data)[i].id1);
- break;
- case CNSORT_2INC : gt = (((PSContact)data)[i].id2 >
- ((PSContact)data)[j].id2);
- lt = (((PSContact)data)[i].id2 <
- ((PSContact)data)[j].id2);
- break;
- case CNSORT_2DEC : gt = (((PSContact)data)[j].id2 >
- ((PSContact)data)[i].id2);
- lt = (((PSContact)data)[j].id2 <
- ((PSContact)data)[i].id2);
- break;
- case CNSORT_DINC : gt = (((PSContact)data)[i].dist >
- ((PSContact)data)[j].dist);
- lt = (((PSContact)data)[i].dist <
- ((PSContact)data)[j].dist);
- break;
- case CNSORT_DDEC : gt = (((PSContact)data)[j].dist >
- ((PSContact)data)[i].dist);
- lt = (((PSContact)data)[j].dist <
- ((PSContact)data)[i].dist);
- break;
- }
- if (gt) return 1;
- if (lt) return -1;
- return 0;
-}
-
-void CSortContacts::Swap ( int i, int j ) {
- ((PSContact)data)[i].Swap ( ((PSContact)data)[j] );
-}
-
-
-void CSortContacts::Sort ( PSContact contact, int ncontacts,
- int sortmode ) {
- mode = sortmode;
- if (mode!=CNSORT_OFF)
- CQuickSort::Sort ( &(contact[0]),ncontacts );
-}
-
-
-void SortContacts ( PSContact contact, int ncontacts,
- int sortmode ) {
-CSortContacts SC;
- if (sortmode!=CNSORT_OFF)
- SC.Sort ( contact,ncontacts,sortmode );
-}
-
-
-// ------------------- Stream functions ----------------------
-
-void CMMDBCoorManager::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- CMMDBFile::write ( f );
- f.WriteInt ( &CoorIDCode );
- f.WriteReal ( &brick_size );
- f.WriteReal ( &xbrick_0 );
- f.WriteReal ( &ybrick_0 );
- f.WriteReal ( &zbrick_0 );
- f.WriteInt ( &nbrick_x );
- f.WriteInt ( &nbrick_y );
- f.WriteInt ( &nbrick_z );
-}
-
-void CMMDBCoorManager::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- CMMDBFile::read ( f );
- f.ReadInt ( &CoorIDCode );
- f.ReadReal ( &brick_size );
- f.ReadReal ( &xbrick_0 );
- f.ReadReal ( &ybrick_0 );
- f.ReadReal ( &zbrick_0 );
- f.ReadInt ( &nbrick_x );
- f.ReadInt ( &nbrick_y );
- f.ReadInt ( &nbrick_z );
-}
-
-
-MakeStreamFunctions(CMMDBCoorManager);
-
-
-
-
-// ===================================================================
-
-int SuperposeAtoms ( mat44 & T, PPCAtom A1, int nA, PPCAtom A2,
- ivector C ) {
-realtype xc1,yc1,zc1, xc2,yc2,zc2, det,B;
-rmatrix A,U,V;
-rvector W,RV1;
-vect3 vc1,vc2;
-int i,j,k,i1,i2,nat;
-
-
- // 1. Set unit matrix as "default" return
-
- for (i=0;i<4;i++) {
- for (j=0;j<4;j++)
- T[i][j] = 0.0;
- T[i][i] = 1.0;
- }
-
-
- // 2. Calculate mass centers
-
- xc1 = 0.0;
- yc1 = 0.0;
- zc1 = 0.0;
- xc2 = 0.0;
- yc2 = 0.0;
- zc2 = 0.0;
-
- nat = 0;
- if (C) {
-
- for (i1=0;i1<nA;i1++)
- if (!A1[i1]->Ter) {
- i2 = C[i1];
- if (i2>=0) {
- xc1 += A1[i1]->x;
- yc1 += A1[i1]->y;
- zc1 += A1[i1]->z;
- xc2 += A2[i2]->x;
- yc2 += A2[i2]->y;
- zc2 += A2[i2]->z;
- nat++;
- }
- }
-
- } else {
-
- for (i=0;i<nA;i++)
- if ((!A1[i]->Ter) && (!A2[i]->Ter)) {
- xc1 += A1[i]->x;
- yc1 += A1[i]->y;
- zc1 += A1[i]->z;
- xc2 += A2[i]->x;
- yc2 += A2[i]->y;
- zc2 += A2[i]->z;
- nat++;
- }
-
- }
-
- if (nat>1) {
- xc1 /= nat;
- yc1 /= nat;
- zc1 /= nat;
- xc2 /= nat;
- yc2 /= nat;
- zc2 /= nat;
- } else if (nat>0) {
- T[0][3] = xc2 - xc1;
- T[1][3] = yc2 - yc1;
- T[2][3] = zc2 - zc1;
- return SPOSEAT_Ok;
- } else
- return SPOSEAT_NoAtoms;
-
-
- // 3. Calculate the correlation matrix
-
- GetMatrixMemory ( A,3,3,1,1 );
-
- for (i=1;i<=3;i++)
- for (j=1;j<=3;j++)
- A[i][j] = 0.0;
-
- if (C) {
-
- for (i1=0;i1<nA;i1++)
- if (!A1[i1]->Ter) {
- i2 = C[i1];
- if (i2>=0) {
- vc1[0] = A1[i1]->x - xc1;
- vc1[1] = A1[i1]->y - yc1;
- vc1[2] = A1[i1]->z - zc1;
- vc2[0] = A2[i2]->x - xc2;
- vc2[1] = A2[i2]->y - yc2;
- vc2[2] = A2[i2]->z - zc2;
- for (i=1;i<=3;i++)
- for (j=1;j<=3;j++)
- A[i][j] += vc1[j-1]*vc2[i-1];
- }
- }
-
- } else {
-
- for (k=0;k<nA;k++)
- if ((!A1[k]->Ter) && (!A2[k]->Ter)) {
- vc1[0] = A1[k]->x - xc1;
- vc1[1] = A1[k]->y - yc1;
- vc1[2] = A1[k]->z - zc1;
- vc2[0] = A2[k]->x - xc2;
- vc2[1] = A2[k]->y - yc2;
- vc2[2] = A2[k]->z - zc2;
- for (i=1;i<=3;i++)
- for (j=1;j<=3;j++)
- A[i][j] += vc1[j-1]*vc2[i-1];
- }
-
- }
-
-
- // 4. Calculate transformation matrix (to be applied to A1)
-
- det = A[1][1]*A[2][2]*A[3][3] +
- A[1][2]*A[2][3]*A[3][1] +
- A[2][1]*A[3][2]*A[1][3] -
- A[1][3]*A[2][2]*A[3][1] -
- A[1][1]*A[2][3]*A[3][2] -
- A[3][3]*A[1][2]*A[2][1];
-
- // 4.1 SV-decompose the correlation matrix
-
- GetMatrixMemory ( U ,3,3,1,1 );
- GetMatrixMemory ( V ,3,3,1,1 );
- GetVectorMemory ( W ,3,1 );
- GetVectorMemory ( RV1,3,1 );
-
- SVD ( 3,3,3,A,U,V,W,RV1,True,True,i );
-
- if (i!=0) {
- FreeVectorMemory ( RV1,1 );
- FreeVectorMemory ( W ,1 );
- FreeMatrixMemory ( V ,3,1,1 );
- FreeMatrixMemory ( U ,3,1,1 );
- FreeMatrixMemory ( A ,3,1,1 );
- return SPOSEAT_SVD_Fail;
- }
-
- // 4.2 Check for parasite inversion and fix it if found
-
- if (det<=0.0) {
- k = 0;
- B = MaxReal;
- for (j=1;j<=3;j++)
- if (W[j]<B) {
- B = W[j];
- k = j;
- }
- for (j=1;j<=3;j++)
- V[j][k] = -V[j][k];
- }
-
- // 4.3 Calculate rotational part of T
-
- for (j=1;j<=3;j++)
- for (k=1;k<=3;k++) {
- B = 0.0;
- for (i=1;i<=3;i++)
- B += U[j][i]*V[k][i];
- T[j-1][k-1] = B;
- }
-
-
- // 4.4 Add translational part to T
-
- T[0][3] = xc2 - T[0][0]*xc1 - T[0][1]*yc1 - T[0][2]*zc1;
- T[1][3] = yc2 - T[1][0]*xc1 - T[1][1]*yc1 - T[1][2]*zc1;
- T[2][3] = zc2 - T[2][0]*xc1 - T[2][1]*yc1 - T[2][2]*zc1;
-
-
- // 5. Release memory and quit
-
- FreeVectorMemory ( RV1,1 );
- FreeVectorMemory ( W ,1 );
- FreeMatrixMemory ( V ,3,1,1 );
- FreeMatrixMemory ( U ,3,1,1 );
- FreeMatrixMemory ( A ,3,1,1 );
-
- return SPOSEAT_Ok;
-
-}
-
-realtype getPhi ( PPCAtom A ) {
-//
-// A0 A1 A2 A3
-// o-----o-----o-----o
-// |
-// Phi
-//
-// -Pi <= Phi <= +Pi
-//
-vect3 U,W,V, a,b,c;
-realtype Wmag,S,T;
-
- U[0] = A[0]->x - A[1]->x;
- U[1] = A[0]->y - A[1]->y;
- U[2] = A[0]->z - A[1]->z;
-
- W[0] = A[2]->x - A[1]->x;
- W[1] = A[2]->y - A[1]->y;
- W[2] = A[2]->z - A[1]->z;
-
- V[0] = A[3]->x - A[2]->x;
- V[1] = A[3]->y - A[2]->y;
- V[2] = A[3]->z - A[2]->z;
-
- a[0] = U[1]*W[2] - W[1]*U[2];
- a[1] = U[2]*W[0] - W[2]*U[0];
- a[2] = U[0]*W[1] - W[0]*U[1];
-
- b[0] = V[1]*W[2] - W[1]*V[2];
- b[1] = V[2]*W[0] - W[2]*V[0];
- b[2] = V[0]*W[1] - W[0]*V[1];
-
- c[0] = a[1]*b[2] - b[1]*a[2];
- c[1] = a[2]*b[0] - b[2]*a[0];
- c[2] = a[0]*b[1] - b[0]*a[1];
-
- Wmag = sqrt(W[0]*W[0]+W[1]*W[1]+W[2]*W[2]);
-
- S = c[0]*W[0] + c[1]*W[1] + c[2]*W[2];
- T = a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
- T *= Wmag;
-
- if ((S==0.0) && (T==0.0)) return NO_TORSION;
- else return atan2(S,T);
-
-}
-
-realtype getPsi ( PPCAtom A ) {
-vect3 v1,v2;
-realtype l1,l2;
-
- v1[0] = A[0]->x - A[1]->x;
- v1[1] = A[0]->y - A[1]->y;
- v1[2] = A[0]->z - A[1]->z;
-
- v2[0] = A[2]->x - A[1]->x;
- v2[1] = A[2]->y - A[1]->y;
- v2[2] = A[2]->z - A[1]->z;
-
- l1 = v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2];
- if (l1==0.0) l1 = 1.0;
- l2 = v2[0]*v2[0] + v2[1]*v2[1] + v2[2]*v2[2];
- if (l2==0.0) l2 = 1.0;
-
- return acos((v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])/sqrt(l1*l2));
-
-}
-
diff --git a/mmdb/mmdb_coormngr.h b/mmdb/mmdb_coormngr.h
deleted file mode 100755
index 3d95d35..0000000
--- a/mmdb/mmdb_coormngr.h
+++ /dev/null
@@ -1,951 +0,0 @@
-// $Id: mmdb_coormngr.h,v 1.29 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 08.07.08 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : mmdb_coormngr <interface>
-// ~~~~~~~~~
-// Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CBrick ( space brick )
-// ~~~~~~~~~ CMMDBCoorManager ( MMDB atom coordinate manager )
-//
-// (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-#ifndef __MMDB_CoorMngr__
-#define __MMDB_CoorMngr__
-
-#ifndef __MMDB_File__
-#include "mmdb_file.h"
-#endif
-
-
-
-// =========================== CBrick ==============================
-
-// bricking control
-#define BRICK_ON_1 0x00000001
-#define BRICK_ON_2 0x00000002
-#define BRICK_READY 0x00000004
-
-
-DefineClass(CBrick);
-typedef PPCBrick * PPPCBrick;
-
-class CBrick {
-
- public :
- int nAtoms; // number of atoms hit into brick
- PPCAtom Atom; // pointers to atoms
- ivector id; // atom ids (in present realization, these are
- // indices of atoms from the bricked array)
-
- CBrick ();
- ~CBrick();
-
- void Clear ();
- void AddAtom ( PCAtom A, int atomid );
-
- protected :
- int nAllocAtoms;
- void InitBrick();
-
-};
-
-
-// =========================== CMBrick =============================
-
-// Bricking multiple structures
-
-DefineClass(CMBrick);
-typedef PPCMBrick * PPPCMBrick;
-
-class CMBrick {
-
- public :
- ivector nAtoms; // number of atoms in the brick
- PPCAtom * Atom; // pointers to atoms
- imatrix id; // atom ids (in present realization, these are
- // indices of atoms from the bricked array)
-
- CMBrick ( int nStructures );
- ~CMBrick();
-
- void Clear ();
- void AddAtom ( PCAtom A, int structNo, int atomid );
-
- protected :
- ivector nAllocAtoms;
- int nStruct;
- void InitMBrick ( int nStructures );
-
-};
-
-
-
-// ==================== CGenSym ========================
-
-DefineClass(CGenSym);
-DefineStreamFunctions(CGenSym);
-
-class CGenSym : public CSymOps {
-
- friend class CMMDBCoorManager;
-
- public :
-
- CGenSym ();
- CGenSym ( RPCStream Object );
- ~CGenSym();
-
- void FreeMemory();
-
- int AddSymOp ( cpstr XYZOperation );
- // the number of just added operation may be obtained as
- // Nop = CGenSym::GetNofSymOps()-1 .
-
- int AddRenChain ( int Nop, const ChainID ch1, const ChainID ch2 );
-
- void Copy ( PCSymOps GenSym );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- PChainID * chID1; // pairs of chains to rename from chID1[n][i]
- PChainID * chID2; // to chID2[n][i] for each operation n<Nops
- ivector nChains; // number of chains to rename for each oper-n
-
- void InitGenSym();
-
- private :
- int nOpAlloc; // number of allocated operations
-
-};
-
-
-// ========================= SContact =============================
-
-DefineStructure(SContact);
-
-struct SContact {
- int id1,id2;
- long group;
- realtype dist;
- void Copy ( RSContact c );
- void Swap ( RSContact c );
-};
-
-
-// ======================== CMContact =============================
-
-DefineClass(CMContact);
-
-class CMContact : public CStream {
-
- public :
- int nStruct,contactID;
- ivector nAtoms;
- PPCAtom * Atom;
- imatrix id;
-
- CMContact ( int nStructures );
- ~CMContact();
-
- void AddContact ( PCAtom A, int structNo, int atomid );
-
- protected:
- ivector nAlloc;
-
-};
-
-extern void DeleteMContacts ( PPCMContact & mcontact, int nContacts );
-
-
-// ====================== CMMDBCoorManager =========================
-
-DefineClass(CMMDBCoorManager);
-DefineStreamFunctions(CMMDBCoorManager);
-
-// ---- Atom extraction return codes
-#define CID_Ok 0
-#define CID_NoModel 1
-#define CID_NoChain 2
-#define CID_NoResidue 3
-#define CID_NoAtom 4
-#define CID_WrongPath 5
-
-// ---- generate symmetry mates return codes
-#define GSM_Ok 0
-#define GSM_NoSymOps 1
-#define GSM_NoTransfMatrices 2
-#define GSM_NoCell 3
-
-class CMMDBCoorManager : public CMMDBFile {
-
- public :
-
- int CoorIDCode; // last return from atom extraction procedure
-
- CMMDBCoorManager ();
- CMMDBCoorManager ( RPCStream Object );
- ~CMMDBCoorManager();
-
-
- // ----------------------------------------------------------
-
- int SetDefaultCoorID ( cpstr CID );
-
-
- // ---------------- Bricking ------------------------------
-
- void RemoveBricks ();
- Boolean areBricks () { return (Brick!=NULL); }
- void MakeBricks ( PPCAtom atmvec, int avlen,
- realtype Margin, realtype BrickSize=6.0 );
- void GetBrickDimension (
- int & nxmax, int & nymax, int & nzmax );
- void GetBrickCoor ( PCAtom A, int & nx, int & ny, int & nz );
- void GetBrickCoor ( realtype x, realtype y, realtype z,
- int & nx, int & ny, int & nz );
- PCBrick GetBrick ( int nx, int ny, int nz );
-
- void RemoveMBricks ();
- Boolean areMBricks () { return (MBrick!=NULL); }
- void MakeMBricks ( PPCAtom * atmvec, ivector avlen,
- int nStructures, realtype Margin,
- realtype BrickSize=6.0 );
- void GetMBrickDimension (
- int & nxmax, int & nymax, int & nzmax );
- void GetMBrickCoor ( PCAtom A, int & nx, int & ny, int & nz );
- void GetMBrickCoor ( realtype x, realtype y, realtype z,
- int & nx, int & ny, int & nz );
- PCMBrick GetMBrick ( int nx, int ny, int nz );
-
- // ---------------- Extracting models ---------------------
-
- int GetNumberOfModels () { return nModels; }
- int GetFirstModelNum ();
- PCModel GetFirstDefinedModel();
- PCModel GetModel ( int modelNo ); // 1<=modelNo<=nModels
- PCModel GetModel ( cpstr CID );
- void GetModelTable ( PPCModel & modTable,
- int & NumberOfModels );
-
- // ---------------- Deleting models -----------------------
-
- int DeleteModel ( cpstr CID );
- int DeleteModel ( int modelNo ); // 1<=modelNo<=nOfModels
-
- // ---------------- Adding/Inserting models ---------------
-
- int AddModel ( PCModel model );
- int InsModel ( PCModel model, int modelNo );
- void RotateModels ( int modelNo1, int modelNo2, int rotdir );
- void SwapModels ( int modelNo1, int modelNo2 );
-
- // ---------------- Extracting chains ---------------------
-
- int GetNumberOfChains ( int modelNo );
- int GetNumberOfChains ( cpstr CID );
- PCChain GetChain ( int modelNo, const ChainID chainID );
- PCChain GetChain ( int modelNo, int chainNo );
- PCChain GetChain ( cpstr CID );
- void GetChainTable ( int modelNo, PPCChain & chainTable,
- int & NumberOfChains );
- void GetChainTable ( cpstr CID, PPCChain & chainTable,
- int & NumberOfChains );
-
- // ----------------- Deleting chains ----------------------
-
- int DeleteChain ( int modelNo, const ChainID chID );
- int DeleteChain ( int modelNo, int chainNo );
- int DeleteAllChains ( int modelNo );
- int DeleteAllChains ();
-
- // ------------------ Adding chains -----------------------
-
- int AddChain ( int modelNo, PCChain chain );
-
- // ---------------- Extracting residues -------------------
-
- int GetNumberOfResidues ( int modelNo, const ChainID chainID );
- int GetNumberOfResidues ( int modelNo, int chainNo );
- int GetNumberOfResidues ( cpstr CID );
- PCResidue GetResidue ( int modelNo, const ChainID chainID,
- int seqNo, const InsCode insCode );
- PCResidue GetResidue ( int modelNo, int chainNo,
- int seqNo, const InsCode insCode );
- PCResidue GetResidue ( int modelNo, const ChainID chainID,
- int resNo );
- PCResidue GetResidue ( int modelNo, int chainNo, int resNo );
- PCResidue GetResidue ( cpstr CID );
- int GetResidueNo ( int modelNo, const ChainID chainID,
- int seqNo, const InsCode insCode );
- int GetResidueNo ( int modelNo, int chainNo,
- int seqNo, const InsCode insCode );
- void GetResidueTable ( PPCResidue & resTable,
- int & NumberOfResidues );
- void GetResidueTable ( int modelNo, const ChainID chainID,
- PPCResidue & resTable,
- int & NumberOfResidues );
- void GetResidueTable ( int modelNo, int chainNo,
- PPCResidue & resTable,
- int & NumberOfResidues );
- void GetResidueTable ( cpstr CID, PPCResidue & resTable,
- int & NumberOfResidues );
-
-
- // ----------------- Deleting residues -----------------------
-
- int DeleteResidue ( int modelNo, const ChainID chainID,
- int seqNo, const InsCode insCode );
- int DeleteResidue ( int modelNo, const ChainID chainID,
- int resNo );
- int DeleteResidue ( int modelNo, int chainNo,
- int seqNo, const InsCode insCode );
- int DeleteResidue ( int modelNo, int chainNo, int resNo );
- int DeleteAllResidues ( int modelNo, const ChainID chainID );
- int DeleteAllResidues ( int modelNo, int chainNo );
- int DeleteAllResidues ( int modelNo );
- int DeleteAllResidues ();
- int DeleteSolvent ();
-
- // ------------------- Adding residues -----------------------
-
- int AddResidue ( int modelNo, const ChainID chainID,
- PCResidue res );
- int AddResidue ( int modelNo, int chainNo, PCResidue res );
-
- // -------------------- Extracting atoms ----------------------
-
- int GetNumberOfAtoms () { return nAtoms; }
- int GetNumberOfAtoms ( int modelNo, const ChainID chainID,
- int seqNo, const InsCode insCode );
- int GetNumberOfAtoms ( int modelNo, int chainNo,
- int seqNo, const InsCode insCode );
- int GetNumberOfAtoms ( int modelNo, const ChainID chainID,
- int resNo );
- int GetNumberOfAtoms ( int modelNo, int chainNo, int resNo );
- int GetNumberOfAtoms ( cpstr CID );
-
- PCAtom GetAtom (
- int modelNo, // model serial number 1...
- const ChainID chID, // chain ID
- int seqNo, // residue sequence number
- const InsCode insCode, // residue insertion code
- const AtomName aname, // atom name
- const Element elmnt, // chemical element code or '*'
- const AltLoc aloc // alternate location indicator
- );
-
- PCAtom GetAtom (
- int modelNo, // model serial number 1...
- const ChainID chID, // chain ID
- int seqNo, // residue sequence number
- const InsCode insCode, // residue insertion code
- int atomNo // atom number 0..
- );
-
- PCAtom GetAtom (
- int modelNo, // model serial number 1...
- const ChainID chID, // chain ID
- int resNo, // residue number 0..
- const AtomName aname, // atom name
- const Element elmnt, // chemical element code or '*'
- const AltLoc aloc // alternate location indicator
- );
-
- PCAtom GetAtom (
- int modelNo, // model serial number 1...
- const ChainID chID, // chain ID
- int resNo, // residue number 0..
- int atomNo // atom number 0..
- );
-
- PCAtom GetAtom (
- int modelNo, // model serial number 1...
- int chNo, // chain number 0..
- int seqNo, // residue sequence number
- const InsCode insCode, // residue insertion code
- const AtomName aname, // atom name
- const Element elmnt, // chemical element code or '*'
- const AltLoc aloc // alternate location indicator
- );
-
- PCAtom GetAtom (
- int modelNo, // model serial number 1...
- int chNo, // chain number 0...
- int seqNo, // residue sequence number
- const InsCode insCode, // residue insertion code
- int atomNo // atom number 0...
- );
-
- PCAtom GetAtom (
- int modelNo, // model serial number 1...
- int chNo, // chain number 0...
- int resNo, // residue number 0...
- const AtomName aname, // atom name
- const Element elmnt, // chemical element code or '*'
- const AltLoc aloc // alternate location indicator
- );
-
- PCAtom GetAtom (
- int modelNo, // model serial number 1...
- int chNo, // chain number 0...
- int resNo, // residue number 0...
- int atomNo // atom number 0...
- );
-
-
- // GetAtom(CID) returns atom answering to the following
- // CID pattern:
- // /mdl/chn/seq(res).i/atm[elm]:a
- // where
- // mdl - model number (mandatory); at least model #1 is always
- // present
- // chn - chain identifier ( mandatory)
- // seq - residue sequence number (mandatory)
- // (res) - residue name in round brackets (may be omitted)
- // .i - insert code after a dot; if '.i' or 'i' is missing
- // then residue without an insertion code is looked
- // for
- // atm - atom name (mandatory)
- // [elm] - chemical element code in square brackets; it may
- // be omitted but could be helpful for e.g.
- // distinguishing C_alpha and CA
- // :a - alternate location indicator after colon; if
- // ':a' or 'a' is missing then an atom without
- // alternate location indicator is looked for.
- // All spaces are ignored, all identifiers should be in capital
- // letters (comparisons are case-sensitive).
- PCAtom GetAtom ( cpstr CID );
-
-
- void GetAtomTable ( PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable ( int modelNo, const ChainID chainID,
- int seqNo, const InsCode insCode,
- PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable ( int modelNo, int chainNo,
- int seqNo, const InsCode insCode,
- PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable ( int modelNo, const ChainID chainID, int resNo,
- PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable ( int modelNo, int chainNo, int resNo,
- PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable ( cpstr CID, PPCAtom & atomTable,
- int & NumberOfAtoms );
-
-
- // GetAtomTable1(..) returns atom table without TER atoms and
- // without NULL atom pointers. NumberOfAtoms returns the actual
- // number of atom pointers in atomTable.
- // atomTable is allocated within the function. If it was
- // not set to NULL before calling the function, the function will
- // attempt to deallocate it first.
- // The application is responsible for deleting atomTable,
- // however it must not touch atom pointers, i.e. use simply
- // "delete atomTable;". Never pass atomTable from GetAtomTable(..)
- // into this function, unless you set it to NULL before doing that.
- void GetAtomTable1 ( PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable1 ( int modelNo, const ChainID chainID,
- int seqNo, const InsCode insCode,
- PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable1 ( int modelNo, int chainNo,
- int seqNo, const InsCode insCode,
- PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable1 ( int modelNo, const ChainID chainID, int resNo,
- PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable1 ( int modelNo, int chainNo, int resNo,
- PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable1 ( cpstr CID, PPCAtom & atomTable,
- int & NumberOfAtoms );
-
-
- // -------------------- Deleting atoms -----------------------
-
- int DeleteAtom ( int modelNo,
- const ChainID chID,
- int seqNo,
- const InsCode insCode,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc );
- int DeleteAtom ( int modelNo,
- const ChainID chID,
- int seqNo,
- const InsCode insCode,
- int atomNo );
- int DeleteAtom ( int modelNo,
- const ChainID chID,
- int resNo,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc );
- int DeleteAtom ( int modelNo, const ChainID chID,
- int resNo, int atomNo );
- int DeleteAtom ( int modelNo, int chNo, int seqNo,
- const InsCode insCode,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc );
- int DeleteAtom ( int modelNo, int chNo, int seqNo,
- const InsCode insCode, int atomNo );
- int DeleteAtom ( int modelNo, int chNo, int resNo,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc );
- int DeleteAtom ( int modelNo, int chNo, int resNo, int atomNo );
-
- int DeleteAllAtoms ( int modelNo, const ChainID chID,
- int seqNo, const InsCode insCode );
- int DeleteAllAtoms ( int modelNo, const ChainID chID, int resNo );
- int DeleteAllAtoms ( int modelNo, const ChainID chID );
- int DeleteAllAtoms ( int modelNo, int chNo, int seqNo,
- const InsCode insCode );
- int DeleteAllAtoms ( int modelNo, int chNo, int resNo );
- int DeleteAllAtoms ( int modelNo, int chNo );
- int DeleteAllAtoms ( int modelNo );
- int DeleteAllAtoms ();
-
- // This function leaves only alternative location with maximal
- // occupancy, if those are equal or unspecified, the one with
- // "least" alternative location indicator.
- // The function returns the number of deleted atoms and optimizes
- // the atom index.
- int DeleteAltLocs ();
-
-
- // --------------------- Adding atoms ------------------------
-
- int AddAtom ( int modelNo, const ChainID chID,
- int seqNo, const InsCode insCode, PCAtom atom );
- int AddAtom ( int modelNo, const ChainID chID, int resNo,
- PCAtom atom );
- int AddAtom ( int modelNo, int chNo, int seqNo,
- const InsCode insCode, PCAtom atom );
- int AddAtom ( int modelNo, int chNo, int resNo, PCAtom atom );
-
-
- // -------------------- Transformations -----------------------
-
- int GenerateSymMates ( PCGenSym GenSym=NULL );
- // 1: no Sym operations,
- // 2: no fract/orth matrices
- // 3: no cell parameters
- // 0: Ok
-
- void ApplyTransform ( mat44 & TMatrix ); // simply transforms all
- // coordinates by multiplying
- // with matrix TMatrix
-
- int BringToUnitCell(); // brings all chains into 0th unit cell
-
- // Frac2Orth(..) and Orth2Frac(..) transform between fractional
- // and orthogonal coordinates, if areMatrices() returns True.
- // If the transformation matrices were not set, the functions just
- // copy the coordinates. Returns True if the transformation was
- // done; False return means that transformation matrices were not
- // calculated
- Boolean Frac2Orth (
- realtype xfrac, realtype yfrac, realtype zfrac,
- realtype & xorth, realtype & yorth, realtype & zorth );
- Boolean Orth2Frac (
- realtype xorth, realtype yorth, realtype zorth,
- realtype & xfrac, realtype & yfrac, realtype & zfrac );
-
-
- // Below, F and T are transformation matrices in fractional and
- // orthogonal coordinates, respectively.
- Boolean Frac2Orth ( mat44 & F, mat44 & T );
- Boolean Orth2Frac ( mat44 & T, mat44 & F );
-
- // ==================== Seeking contacts ======================
-
- void SeekContacts (
- PPCAtom AIndex, // index of atoms [0..ilen-1]
- int ilen, // length of index
- int atomNum, // number of 1st contact atom
- // in the index. All other atoms
- // are checked for contact with
- // 1st atom
- realtype dist1, // minimal contact distance
- realtype dist2, // maximal contact distance
- int seqDist, // the sequence distance to neglect.
- // If seqDist==0, all atoms are
- // checked for contact. If
- // seqDist==1, the atoms belonging
- // to the same residue as atom
- // AIndex[atomNum], are neglected.
- // If seqDist>1, all atoms belonging
- // to residues closer than
- // +/-(seqDist-1) around that of
- // atom AIndex[atomNum], are
- // neglected. If chain is broken
- // (has a gap) on section
- // [-(seqDist-1)..seqDist-1], the
- // section of neglection is
- // shortened to that gap.
- RPSContact contact, // indices of contacting atoms
- // [0..ncontacts-1]. contact[i].id1
- // is set to atomNum and
- // contact[i].id2 is set to the
- // index of 2nd contacting atom
- // in vector AIndex
- int & ncontacts, // number of contacts found. If
- // ncontacts>0 on input, it is
- // assumed that new contacts that
- // newly found contacts should be
- // appended to those already
- // existing
- int maxlen=0, // if <=0, then vector contact is
- // allocated dynamically. If
- // contact!=NULL, then it is
- // appended with new contacts.
- // The application is responsible
- // for deallocation of contact
- // after use.
- // If maxlen>0 then vector contact
- // is prohibited of dynamical
- // allocation/deallocation. In this
- // case, not more than maxlen
- // contacts will be returned.
- long group=0 // a contact group ID, which will be
- // simply stored in contact[i].group
- // fields. This ID may be useful
- // if contacts are obtained in
- // multiple calls of the function
- );
-
- void SeekContacts (
- PCAtom A, // 1st atom in contact
- PPCAtom AIndex, // index of atoms [0..ilen-1] to
- // check for contact with 1st atom
- int ilen, // length of index
- realtype dist1, // minimal contact distance
- realtype dist2, // maximal contact distance
- int seqDist, // the sequence distance to neglect.
- // If seqDist==0, all atoms are
- // checked for contact. If
- // seqDist==1, the atoms belonging
- // to the same residue as atom
- // A, are neglected. If seqDist>1,
- // all atoms belonging to residues
- // closer than +/-(seqDist-1) around
- // that of atom A, are neglected. If
- // chain is broken (has a gap) on
- // section
- // [-(seqDist-1)..seqDist-1], the
- // section of neglection is
- // shortened to that gap.
- RPSContact contact, // indices of contacting atoms
- // [0..ncontacts-1]. contact[i].id1
- // is set to -1, and contact[i].id2
- // is set to the index of 2nd
- // contacting atom in vector AIndex
- int & ncontacts, // number of contacts found. If
- // ncontacts>0 on input, it is
- // assumed that new contacts that
- // newly found contacts should be
- // appended those already existing
- int maxlen=0, // if <=0, then vector contact is
- // allocated dynamically. If
- // contact!=NULL, then it is
- // appended with new contacts.
- // The application is responsible
- // for deallocation of contact
- // after use.
- // If maxlen>0 then vector contact
- // is prohibited of dynamical
- // allocation/deallocation. In this
- // case, not more than maxlen
- // contacts will be returned.
- long group=0 // a contact group ID, which will be
- // simply stored in contact[i].group
- // fields. This ID may be useful
- // if contacts are obtained in
- // multiple calls of the function
- );
-
- void SeekContacts (
- PPCAtom AIndex1, // 1st atom index [0..ilen1-1]
- int ilen1, // length of 1st index
- PPCAtom AIndex2, // 2nd atom index [0..ilen2-1] to
- // check for contact with 1st index
- int ilen2, // length of 2nd index
- realtype dist1, // minimal contact distance
- realtype dist2, // maximal contact distance
- int seqDist, // the sequence distance to
- // neglect.
- // If seqDist==0, all atoms are
- // checked for contact.
- // If seqDist==1, the atoms
- // belonging to the same residue
- // are neglected.
- // If seqDist>1, all atoms
- // belonging to residues closer than
- // +/-(seqDist-1) to each other,
- // are neglected. If chain is broken
- // (has a gap) on section
- // [-(seqDist-1)..seqDist-1], the
- // section of neglection is
- // shortened to that gap.
- RPSContact contact, // indices of contacting atoms
- // [0..ncontacts-1]. contact[i].id1
- // contains number of atom from 1st
- // index, and contact[i].id2
- // contains number of atom from 2nd
- // index, contacting with the former
- // one
- int & ncontacts, // number of contacts found. If
- // ncontacts>0 on input, it is
- // assumed that newly found
- // contacts should be appended to
- // those already existing
- int maxlen=0, // if <=0, then vector contact is
- // allocated dynamically. If
- // contact!=NULL, then it is
- // appended with new contacts.
- // The application is responsible
- // for deallocation of contact
- // after use.
- // If maxlen>0 then vector contact
- // is prohibited of dynamical
- // allocation/deallocation. In this
- // case, not more than maxlen
- // contacts will be returned.
- mat44 * TMatrix=NULL, // transformation matrix for 2nd
- // set of atoms (AIndex2)
- long group=0, // a contact group ID, which will
- // be stored in contact[i].group
- // fields. This ID may be useful
- // if contacts are obtained in
- // multiple calls of the function
- int bricking=0, // bricking control; may be a
- // combination of BRICK_ON_1 or
- // BRICK_ON_2 with BRICK_READY
- Boolean doSqrt=True // if False, then SContact contains
- // square distances
- );
-
- // Simplified optimized for speed version:
- // - no NULL pointers and Ters in AIndex1 and AIndex2
- // - no checks for identity atoms in AIndex1 and AIndex2
- // - contact must be pre-allocated with at least ilen1*ilen2
- // elements
- // - contact returns square distances
- // - ncontacts is always reset
- void SeekContacts (
- PPCAtom AIndex1, // 1st atom index [0..ilen1-1]
- int ilen1, // length of 1st index
- PPCAtom AIndex2, // 2nd atom index [0..ilen2-1] to
- // check for contact with 1st index
- int ilen2, // length of 2nd index
- realtype contDist, // maximal contact distance
- PSContact contact, // indices of contacting atoms
- // [0..ncontacts-1]. contact[i].id1
- // contains number of atom from 1st
- // index, and contact[i].id2
- // contains number of atom from 2nd
- // index, contacting with the former
- // one. Must be pre-allocated
- int & ncontacts, // number of contacts found
- int bricking=0 // bricking control; may be a
- // combination of BRICK_ON_1 or
- // BRICK_ON_2 with BRICK_READY
- );
-
- void SeekContacts (
- PPCAtom AIndex1, // 1st atom index [0..ilen1-1]
- int ilen1, // length of 1st index
- PPCAtom * AIndex2, // indexes of atoms to be checked
- // for contact with each atom from
- // Aindex1; dimension
- // [0..nStructures-1][0..ilen2[i]-1]
- ivector ilen2, // lengths of indexes AIndex2
- int nStructures, // number of indexes AIndex2
- realtype dist1, // minimal contact distance
- realtype dist2, // maximal contact distance
- PPCMContact & contact, // resulting contacts, one structure
- // per each position in AIndex1. If
- // AIndex1[i] is NULL, contact[i] is
- // also NULL. "contact" is always
- // allocated, no re-use or
- // re-allocation is attempted.
- int bricking=0 // bricking control; may be
- // BRICK_READY if AIndex2 does not
- // change
- );
-
- protected :
-
- // bricks
- realtype brick_size, xbrick_0,ybrick_0,zbrick_0;
- int nbrick_x,nbrick_y,nbrick_z;
- PPPCBrick * Brick;
-
- realtype mbrick_size, xmbrick_0,ymbrick_0,zmbrick_0;
- int nmbrick_x,nmbrick_y,nmbrick_z;
- PPPCMBrick * MBrick;
-
- // --------------- Stream I/O -----------------------------
- void write ( RCFile f );
- void read ( RCFile f );
-
- void InitMMDBCoorManager();
-
- void ApplySymTransform ( int SymMatrixNo, PCGenSym GenSym=NULL );
-
- void ResetManager ();
-
- void FindSeqSection ( PCAtom atom, int seqDist,
- int & seq1, int & seq2 );
- Boolean isContact ( PCAtom a1, PCAtom a2,
- int seq1, int seq2,
- realtype dd, realtype d12,
- realtype d22, realtype & d2 );
- Boolean isContact ( realtype x, realtype y,
- realtype z, PCAtom a2,
- realtype dd, realtype d12,
- realtype d22, realtype & d2 );
-
-};
-
-
-
-// ===================================================================
-
-
-
-// GetEulerRotMatrix(..) calculates the Euler rotation matrix
-// for rotation:
-// 1) about z-axis by angle alpha
-// 2) about new y-axis by angle beta
-// 3) about new z-axis by angle gamma
-extern void GetEulerRotMatrix ( mat33 & erm, realtype alpha,
- realtype beta, realtype gamma );
-
-// GetEulerTMatrix(..) calculates the Euler rotation-translation
-// matrix for rotation:
-// 1) about z-axis by angle alpha
-// 2) about new y-axis by angle beta
-// 3) about new z-axis by angle gamma
-// Point (x0,y0,z0) is the center of rotation.
-extern void GetEulerTMatrix ( mat44 & erm, realtype alpha,
- realtype beta, realtype gamma,
- realtype x0, realtype y0, realtype z0 );
-
-// Euler rotation: 1) about z-axis by angle alpha
-// 2) about new y-axis by angle beta
-// 3) about new z-axis by angle gamma
-// Point (x0,y0,z0) is the center of rotation.
-extern void EulerRotation ( PPCAtom A, int nA,
- realtype alpha, realtype beta, realtype gamma,
- realtype x0, realtype y0, realtype z0 );
-
-// GetVecRotMatrix(..) calculates the rotation matrix for
-// rotation by angle alpha about arbitrary vector directed
-// as (vx,vy,vz) = (vx2-vx1,vy2-vy1,vz2-vz1).
-extern void GetVecRotMatrix ( mat33 & vrm, realtype alpha,
- realtype vx, realtype vy, realtype vz );
-
-
-// Given the rotation matrix vrm, GetRotParameters(..)
-// returns the rotation angle alpha and the normalized
-// rotation axis vector (vx,vy,vz).
-// The rotation angle and vector are determined up to
-// their sign (however correlated, so that being substituted
-// into GetVecRotMatrix(..) they yield the same rotation
-// matrix).
-// The function does not check for vrm to be a valid
-// rotation matrix.
-extern void GetRotParameters ( mat33 & vrm, realtype & alpha,
- realtype & vx, realtype & vy, realtype & vz );
-
-
-// GetVecTMatrix(..) calculates the rotation-translation matrix
-// for rotation by angle alpha about arbitrary vector directed as
-// (vx,vy,vz) = (vx2-vx1,vy2-vy1,vz2-vz1). Point (x0,y0,z0) is
-// the center of rotation -- actually a point belonging to the
-// rotation axis.
-extern void GetVecTMatrix ( mat44 & vrm, realtype alpha,
- realtype vx, realtype vy, realtype vz,
- realtype x0, realtype y0, realtype z0 );
-
-// Vector rotation is rotation by angle alpha about arbitrary
-// vector directed as (vx,vy,vz) = (vx2-vx1,vy2-vy1,vz2-vz1).
-// Point (x0,y0,z0) is the center of rotation -- actually
-// a point belonging to the rotation axis.
-extern void VectorRotation ( PPCAtom A, int nA, realtype alpha,
- realtype vx, realtype vy, realtype vz,
- realtype x0, realtype y0, realtype z0 );
-
-extern void GetMassCenter ( PPCAtom A, int nA,
- realtype & xmc, realtype & ymc, realtype & zmc );
-
-
-#define SPOSEAT_Ok 0
-#define SPOSEAT_NoAtoms 1
-#define SPOSEAT_SVD_Fail 2
-
-// Given two sets of atoms, A1 and A2, SuperposeAtoms(...) calculates
-// the rotational-translational matrix T such that |T*A1 - A2| is
-// minimal in least-square terms.
-// If vector C is not given (default), all nA atoms of set A1 are
-// considered as corresponding to nA first atoms of set A2,
-// A1[i] <-> A2[i], 0<=i<nA .
-// If vector C is given, then the correspondence of atoms is
-// established as A1[i] <-> A2[C[i]] only for those i that C[i]>=0.
-// The default option (C==NULL) is thus identical to C[i]==i, 0<=i<nA.
-// Upon normal completion, the procedure returns SPOSEAT_Ok.
-
-extern int SuperposeAtoms ( mat44 & T, PPCAtom A1, int nA, PPCAtom A2,
- ivector C=NULL );
-
-
-#define CNSORT_OFF 0
-#define CNSORT_1INC 1
-#define CNSORT_1DEC 2
-#define CNSORT_2INC 3
-#define CNSORT_2DEC 4
-#define CNSORT_DINC 5
-#define CNSORT_DDEC 6
-
-extern void SortContacts ( PSContact contact, int ncontacts,
- int sortmode );
-
-
-#define NO_TORSION (-MaxReal)
-
-extern realtype getPhi ( PPCAtom A ); // A[0] - A[3] used
-extern realtype getPsi ( PPCAtom A ); // A[0] - A[2] used
-
-#endif
-
diff --git a/mmdb/mmdb_cryst.cpp b/mmdb/mmdb_cryst.cpp
deleted file mode 100755
index e205c0b..0000000
--- a/mmdb/mmdb_cryst.cpp
+++ /dev/null
@@ -1,2288 +0,0 @@
-// $Id: mmdb_cryst.cpp,v 1.27 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 05.02.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_Cryst <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CCrystContainer ( container for cryst. data )
-// ~~~~~~~~~ CNCSMatrix ( non-cryst. symm. matrix class )
-// CTVect ( translational vector class )
-// CMMDBCryst ( MMDB cryst. section class )
-//
-// (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifndef __MATH_H
-#include <math.h>
-#endif
-
-#ifndef __MMDB_Cryst__
-#include "mmdb_cryst.h"
-#endif
-
-#ifndef __MMDB_Defs__
-#include "mmdb_defs.h"
-#endif
-
-#ifndef __MMDB_CIFDefs__
-#include "mmdb_cifdefs.h"
-#endif
-
-
-// ============== CCrystContainer ====================
-
-PCContainerClass CCrystContainer::MakeContainerClass ( int ClassID ) {
- switch (ClassID) {
- default :
- case ClassID_Template :
- return CClassContainer::MakeContainerClass(ClassID);
- case ClassID_NCSMatrix : return new CNCSMatrix();
- case ClassID_TVect : return new CTVect ();
- }
-}
-
-int CCrystContainer::AddMTRIXLine ( cpstr S ) {
-int i,RC;
- RC = Error_NCSM_WrongSerial;
- for (i=0;i<length;i++) {
- RC = PCNCSMatrix(Container[i])->ConvertPDBASCII(S);
- if (RC==0) break;
- if (RC!=Error_NCSM_WrongSerial) break;
- }
- return RC;
-}
-
-MakeStreamFunctions(CCrystContainer)
-
-
-// ================ CNCSMatrix ===================
-
-CNCSMatrix::CNCSMatrix() : CContainerClass() {
- Init();
-}
-
-CNCSMatrix::CNCSMatrix ( cpstr S ) : CContainerClass() {
- Init();
- ConvertPDBASCII ( S );
-}
-
-CNCSMatrix::CNCSMatrix ( RPCStream Object )
- : CContainerClass(Object) {
- Init();
-}
-
-CNCSMatrix::~CNCSMatrix() {}
-
-void CNCSMatrix::Init() {
-int i,j;
- serNum = -1;
- iGiven = -1;
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++)
- m[i][j] = 0.0;
- m[i][i] = 1.0;
- v[i] = 0.0;
- }
- WhatIsSet = 0; // nothing is set
-}
-
-Boolean CNCSMatrix::PDBASCIIDump1 ( RCFile f ) {
-// makes the ASCII PDB MATRIXn lines if all
-// of them were set.
-char S[100];
-int i,j;
-
- if ((WhatIsSet & NCSMSET_All)==NCSMSET_All)
- for (i=0;i<3;i++) {
- sprintf ( S,"MTRIX%1i %3i",i+1,serNum );
- PadSpaces ( S,80 );
- for (j=0;j<3;j++)
- PutRealF ( &(S[10+j*10]),m[i][j],10,6 );
- PutRealF ( &(S[45]),v[i],10,5 );
- if (iGiven) S[59] = '1';
- f.WriteLine ( S );
- }
-
- return True; // container should use this virtual
-
-}
-
-int CNCSMatrix::ConvertPDBASCII ( cpstr S ) {
-int sN,iG;
-realtype m0,m1,m2,v0;
-
- if (!(GetInteger(sN,&(S[7]) ,3 ) &&
- GetReal (m0,&(S[10]),10) &&
- GetReal (m1,&(S[20]),10) &&
- GetReal (m2,&(S[30]),10) &&
- GetReal (v0,&(S[45]),10)))
- return Error_NCSM_Unrecognized;
-
- if (S[59]=='1') iG = 1;
- else iG = 0;
-
- if (WhatIsSet & NCSMSET_All) {
- if (sN!=serNum) return Error_NCSM_WrongSerial;
- if (iG!=iGiven) return Error_NCSM_UnmatchIG;
- }
-
- if (!strncmp(S,"MTRIX1",6)) {
-
- if (WhatIsSet & NCSMSET_Matrix1) return Error_NCSM_AlreadySet;
- serNum = sN;
- iGiven = iG;
- m[0][0] = m0;
- m[0][1] = m1;
- m[0][2] = m2;
- v[0] = v0;
- WhatIsSet |= NCSMSET_Matrix1;
-
- } else if (!strncmp(S,"MTRIX2",6)) {
-
- if (WhatIsSet & NCSMSET_Matrix2) return Error_NCSM_AlreadySet;
- serNum = sN;
- iGiven = iG;
- m[1][0] = m0;
- m[1][1] = m1;
- m[1][2] = m2;
- v[1] = v0;
- WhatIsSet |= NCSMSET_Matrix2;
-
- } else if (!strncmp(S,"MTRIX3",6)) {
-
- if (WhatIsSet & NCSMSET_Matrix3) return Error_NCSM_AlreadySet;
- serNum = sN;
- iGiven = iG;
- m[2][0] = m0;
- m[2][1] = m1;
- m[2][2] = m2;
- v[2] = v0;
- WhatIsSet |= NCSMSET_Matrix3;
-
- } else
- return Error_WrongSection;
-
- return 0;
-
-}
-
-void CNCSMatrix::MakeCIF ( PCMMCIFData CIF, int N ) {
-PCMMCIFLoop Loop;
-int RC;
- RC = CIF->AddLoop ( CIFCAT_STRUCT_NCS_OPER,Loop );
- if ((RC!=CIFRC_Ok) || (N==0)) {
- // the category was (re)created, provide tags
- Loop->AddLoopTag ( CIFTAG_ID );
- Loop->AddLoopTag ( CIFTAG_MATRIX11 );
- Loop->AddLoopTag ( CIFTAG_MATRIX12 );
- Loop->AddLoopTag ( CIFTAG_MATRIX13 );
- Loop->AddLoopTag ( CIFTAG_VECTOR1 );
- Loop->AddLoopTag ( CIFTAG_MATRIX21 );
- Loop->AddLoopTag ( CIFTAG_MATRIX22 );
- Loop->AddLoopTag ( CIFTAG_MATRIX23 );
- Loop->AddLoopTag ( CIFTAG_VECTOR2 );
- Loop->AddLoopTag ( CIFTAG_MATRIX31 );
- Loop->AddLoopTag ( CIFTAG_MATRIX32 );
- Loop->AddLoopTag ( CIFTAG_MATRIX33 );
- Loop->AddLoopTag ( CIFTAG_VECTOR3 );
- Loop->AddLoopTag ( CIFTAG_CODE );
- }
- Loop->AddInteger ( serNum );
- if (WhatIsSet & NCSMSET_Matrix1) {
- Loop->AddReal ( m[0][0] );
- Loop->AddReal ( m[0][1] );
- Loop->AddReal ( m[0][2] );
- Loop->AddReal ( v[0] );
- } else {
- Loop->AddString ( NULL );
- Loop->AddString ( NULL );
- Loop->AddString ( NULL );
- Loop->AddString ( NULL );
- }
- if (WhatIsSet & NCSMSET_Matrix2) {
- Loop->AddReal ( m[1][0] );
- Loop->AddReal ( m[1][1] );
- Loop->AddReal ( m[1][2] );
- Loop->AddReal ( v[1] );
- } else {
- Loop->AddString ( NULL );
- Loop->AddString ( NULL );
- Loop->AddString ( NULL );
- Loop->AddString ( NULL );
- }
- if (WhatIsSet & NCSMSET_Matrix3) {
- Loop->AddReal ( m[2][0] );
- Loop->AddReal ( m[2][1] );
- Loop->AddReal ( m[2][2] );
- Loop->AddReal ( v[2] );
- } else {
- Loop->AddString ( NULL );
- Loop->AddString ( NULL );
- Loop->AddString ( NULL );
- Loop->AddString ( NULL );
- }
- if (iGiven==1) Loop->AddString ( pstr("generated") );
- else Loop->AddNoData ( CIF_NODATA_DOT );
-}
-
-void CNCSMatrix::GetCIF ( PCMMCIFData CIF, int & Signal ) {
-PCMMCIFLoop Loop;
-char Code[100];
-
- Loop = CIF->GetLoop ( CIFCAT_STRUCT_NCS_OPER );
- if (!Loop) {
- Signal = -1; // signal to finish processing of this structure
- return;
- }
-
- if (Signal>=Loop->GetLoopLength()) {
- Signal = -1;
- return;
- }
-
- WhatIsSet = 0;
- if (CIFGetInteger(serNum,Loop,CIFTAG_ID,Signal)) return;
- if (CIFGetString(Code,Loop,CIFTAG_CODE,Signal,sizeof(Code),
- pstr("")))
- iGiven = MinInt4;
- else if (!strcasecmp(Code,"generated"))
- iGiven = 1;
- else
- iGiven = MinInt4;
-
-
- if (CIFGetReal(m[0][0],Loop,CIFTAG_MATRIX11,Signal)) return;
- if (CIFGetReal(m[0][1],Loop,CIFTAG_MATRIX12,Signal)) return;
- if (CIFGetReal(m[0][2],Loop,CIFTAG_MATRIX13,Signal)) return;
- if (CIFGetReal(v[0] ,Loop,CIFTAG_VECTOR1 ,Signal)) return;
- WhatIsSet |= NCSMSET_Matrix1;
-
- if (CIFGetReal(m[1][0],Loop,CIFTAG_MATRIX21,Signal)) return;
- if (CIFGetReal(m[1][1],Loop,CIFTAG_MATRIX22,Signal)) return;
- if (CIFGetReal(m[1][2],Loop,CIFTAG_MATRIX23,Signal)) return;
- if (CIFGetReal(v[1] ,Loop,CIFTAG_VECTOR2 ,Signal)) return;
- WhatIsSet |= NCSMSET_Matrix2;
-
- if (CIFGetReal(m[2][0],Loop,CIFTAG_MATRIX31,Signal)) return;
- if (CIFGetReal(m[2][1],Loop,CIFTAG_MATRIX32,Signal)) return;
- if (CIFGetReal(m[2][2],Loop,CIFTAG_MATRIX33,Signal)) return;
- if (CIFGetReal(v[2] ,Loop,CIFTAG_VECTOR3 ,Signal)) return;
- WhatIsSet |= NCSMSET_Matrix3;
-
- Signal++;
-
-}
-
-void CNCSMatrix::SetNCSMatrix ( int serialNum,
- mat33 & ncs_m, vect3 & ncs_v,
- int i_Given ) {
-int i,j;
- serNum = serialNum;
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++)
- m[i][j] = ncs_m[i][j];
- v[i] = ncs_v[i];
- }
- iGiven = i_Given;
- WhatIsSet |= NCSMSET_All;
-}
-
-void CNCSMatrix::Copy ( PCContainerClass NCSMatrix ) {
-int i,j;
-
- serNum = PCNCSMatrix(NCSMatrix)->serNum;
- iGiven = PCNCSMatrix(NCSMatrix)->iGiven;
-
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++)
- m[i][j] = PCNCSMatrix(NCSMatrix)->m[i][j];
- v[i] = PCNCSMatrix(NCSMatrix)->v[i];
- }
-
- WhatIsSet = PCNCSMatrix(NCSMatrix)->WhatIsSet;
-
-}
-
-void CNCSMatrix::write ( RCFile f ) {
-int i,j;
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &serNum );
- f.WriteInt ( &iGiven );
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++)
- f.WriteReal ( &(m[i][j]) );
- f.WriteReal ( &(v[i]) );
- }
- f.WriteWord ( &WhatIsSet );
-}
-
-void CNCSMatrix::read ( RCFile f ) {
-int i,j;
-byte Version;
- f.ReadByte ( &Version );
- f.ReadInt ( &serNum );
- f.ReadInt ( &iGiven );
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++)
- f.ReadReal ( &(m[i][j]) );
- f.ReadReal ( &(v[i]) );
- }
- f.ReadWord ( &WhatIsSet );
-}
-
-MakeStreamFunctions(CNCSMatrix)
-
-
-
-// ================ CTVect ===================
-
-CTVect::CTVect() : CContainerClass() {
- Init();
-}
-
-CTVect::CTVect ( cpstr S ) : CContainerClass() {
- Init();
- ConvertPDBASCII ( S );
-}
-
-CTVect::CTVect ( RPCStream Object ) : CContainerClass(Object) {
- Init();
-}
-
-CTVect::~CTVect() {
- if (comment) delete[] comment;
-}
-
-void CTVect::Init() {
- serNum = -1;
- t[0] = 0.0;
- t[1] = 0.0;
- t[2] = 0.0;
- comment = NULL;
-}
-
-void CTVect::PDBASCIIDump ( pstr S, int N ) {
-UNUSED_ARGUMENT(N);
-// makes the ASCII PDB TVECT line number N
- sprintf ( S,"TVECT %3i",serNum );
- PadSpaces ( S,80 );
- PutRealF ( &(S[10]),t[0],10,5 );
- PutRealF ( &(S[20]),t[1],10,5 );
- PutRealF ( &(S[30]),t[2],10,5 );
- if (comment)
- strncpy ( &(S[40]),comment,IMin(30,strlen(comment)) );
-}
-
-int CTVect::ConvertPDBASCII ( cpstr S ) {
- GetInteger ( serNum ,&(S[7]) ,3 );
- GetReal ( t[0] ,&(S[10]),10 );
- GetReal ( t[1] ,&(S[20]),10 );
- GetReal ( t[2] ,&(S[30]),10 );
- CreateCopy ( comment,&(S[40]) );
- return 0;
-
-}
-
-void CTVect::MakeCIF ( PCMMCIFData CIF, int N ) {
-PCMMCIFLoop Loop;
-int RC;
- RC = CIF->AddLoop ( CIFCAT_DATABASE_PDB_TVECT,Loop );
- if ((RC!=CIFRC_Ok) || (N==0)) {
- // the category was (re)created, provide tags
- Loop->AddLoopTag ( CIFTAG_ID );
- Loop->AddLoopTag ( CIFTAG_VECTOR1 );
- Loop->AddLoopTag ( CIFTAG_VECTOR2 );
- Loop->AddLoopTag ( CIFTAG_VECTOR3 );
- Loop->AddLoopTag ( CIFTAG_DETAILS );
- }
- Loop->AddInteger ( serNum );
- Loop->AddReal ( t[0] );
- Loop->AddReal ( t[1] );
- Loop->AddReal ( t[2] );
- Loop->AddString ( comment );
-}
-
-void CTVect::GetCIF ( PCMMCIFData CIF, int & Signal ) {
-PCMMCIFLoop Loop;
-
- Loop = CIF->GetLoop ( CIFCAT_DATABASE_PDB_TVECT );
- if (!Loop) {
- Signal = -1; // signal to finish processing of this structure
- return;
- }
-
- if (Signal>=Loop->GetLoopLength()) {
- Signal = -1;
- return;
- }
-
- if (CIFGetInteger(serNum,Loop,CIFTAG_ID,Signal)) return;
- if (CIFGetReal(t[0],Loop,CIFTAG_VECTOR1,Signal)) return;
- if (CIFGetReal(t[1],Loop,CIFTAG_VECTOR2,Signal)) return;
- if (CIFGetReal(t[2],Loop,CIFTAG_VECTOR3,Signal)) return;
- Loop->GetString ( comment,CIFTAG_DETAILS,Signal,True );
-
- Signal++;
-
-}
-
-
-void CTVect::Copy ( PCContainerClass TVect ) {
-int i;
- serNum = PCTVect(TVect)->serNum;
- for (i=0;i<3;i++)
- t[i] = PCTVect(TVect)->t[i];
- CreateCopy ( comment,PCTVect(TVect)->comment );
-}
-
-void CTVect::write ( RCFile f ) {
-int i;
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &serNum );
- for (i=0;i<3;i++)
- f.WriteReal ( &(t[i]) );
- f.CreateWrite ( comment );
-}
-
-void CTVect::read ( RCFile f ) {
-int i;
-byte Version;
- f.ReadByte ( &Version );
- f.ReadInt ( &serNum );
- for (i=0;i<3;i++)
- f.ReadReal ( &(t[i]) );
- f.CreateRead ( comment );
-}
-
-MakeStreamFunctions(CTVect)
-
-
-
-// ===================== CMMDBCryst =======================
-
-CMMDBCryst::CMMDBCryst() : CStream() {
- Init ( True );
-}
-
-CMMDBCryst::CMMDBCryst ( RPCStream Object ) : CStream(Object) {
- Init ( True );
-}
-
-void CMMDBCryst::Init ( Boolean fullInit ) {
-int i,j,k;
-
- WhatIsSet = 0; // nothing is set
- a = 1.0;
- b = 1.0;
- c = 1.0;
- alpha = 90.0;
- beta = 90.0;
- gamma = 90.0;
- strcpy ( spaceGroup ,"" );
- strcpy ( spaceGroupFix,"" );
- Z = 1;
- CellCheck = CCHK_NoCell;
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++) {
- o[i][j] = 0.0;
- s[i][j] = 0.0;
- for (k=0;k<6;k++)
- RR[k][i][j] = 0.0;
- }
- o[i][i] = 1.0;
- s[i][i] = 1.0;
- t[i] = 0.0;
- u[i] = 0.0;
- for (k=0;k<6;k++)
- RR[k][i][i] = 1.0;
- }
- for (i=0;i<4;i++) {
- for (j=0;j<4;j++) {
- RO [i][j] = 0.0;
- RF [i][j] = 0.0;
- ROU[i][j] = 0.0;
- RFU[i][j] = 0.0;
- }
- RO [i][i] = 1.0;
- RF [i][i] = 1.0;
- ROU[i][i] = 1.0;
- RFU[i][i] = 1.0;
- }
- Vol = 0.0;
- VolChk = 0.0;
- VolErr = 0.0;
- as = 1.0;
- bs = 1.0;
- cs = 1.0;
- alphas = 90.0;
- betas = 90.0;
- gammas = 90.0;
-
- for (k=0;k<6;k++)
- AC[k] = 0.0;
-
- NCode = 0;
-
- if (fullInit) {
- syminfo_lib = NULL;
- ignoreScalei = False; // flag to ignore SCALEi cards
- processSG = True; // flag to process space group at file read
- fixSpaceGroup = True; // flag to fix space group at file read
- }
-
-}
-
-CMMDBCryst::~CMMDBCryst() {
- FreeMemory();
- if (syminfo_lib) delete[] syminfo_lib;
-}
-
-void CMMDBCryst::FreeMemory() {
- NCSMatrix.FreeContainer();
- TVect .FreeContainer();
- SymOps .FreeMemory ();
-}
-
-void CMMDBCryst::Reset() {
- FreeMemory();
- Init ( False );
-}
-
-cpstr rhombohedral[] = {
- cpstr("R 3" ),
- cpstr("R 3" ),
- cpstr("R 3 2"),
- cpstr("R 3 2")
-};
-
-cpstr short_mono[] = {
- cpstr("P 2" ),
- cpstr("P 21"),
- cpstr("C 2" ),
- cpstr("A 2" ),
- cpstr("B 2" ),
- cpstr("I 2" )
-};
-
-cpstr special[] = {
- cpstr("A1" ),
- cpstr("Hall: P 1 (-x,-1/2*y+1/2*z,1/2*y+1/2*z)" ),
- cpstr("C1211" ),
- cpstr("Hall: C 2y (x+1/4,y+1/4,z)" ),
- cpstr("C21" ),
- cpstr("Hall: C 2y (x+1/4,y+1/4,z)" ),
- cpstr("I1211" ),
- cpstr("Hall: C 2y (x+1/4,y+1/4,-x+z-1/4)" ),
- cpstr("I21" ),
- cpstr("Hall: C 2y (x+1/4,y+1/4,-x+z-1/4)" ),
- cpstr("P21212A"),
- cpstr("Hall: P 2 2ab (x+1/4,y+1/4,z)" ),
- cpstr("F422" ),
- cpstr("Hall: I 4 2 (1/2*x+1/2*y,-1/2*x+1/2*y,z)" ),
- cpstr("C4212" ),
- cpstr("Hall: P 4 2 (1/2*x+1/2*y-1/4,-1/2*x+1/2*y-1/4,z)")
-};
-
-
-
-int CMMDBCryst::FixSpaceGroup() {
-// This function attempts to clean up the Brookhaven mess in space
-// group naming, by checking the space group symbol with cell
-// parameters. Returns:
-//
-// 0 - space group symbol is correct, spaceGroupFix receives
-// a copy of spaceGroup
-// 1 - space group symbol does not agree with cell parameters,
-// and fixed successfully. spaceGroupFix receives
-// the appropriate space group symbol
-// -1 - space group symbol does not agree with cell parameters,
-// however fix is not possible. spaceGroupFix receives
-// a copy of spaceGroup
-// -2 - any checks are not possible because cell parameters
-// are not found, spaceGroupFix receives a copy of
-// spaceGroup
-//
-realtype eps,m1,m2;
-SymGroup s;
-int i,k;
-char c;
-
- strcpy ( spaceGroupFix,spaceGroup );
-
- if ((WhatIsSet & CSET_CellParams)!=CSET_CellParams) return -2;
-
- eps = 0.01;
-
- k = -1;
- for (i=0;(i<4) && (k<0);i++)
- if (!strcmp(spaceGroup,rhombohedral[i])) k = i;
-
- if (k>=0) {
- c = 'N';
- if ((fabs(a-b)<=eps) && (fabs(alpha-90.0)<=eps) &&
- (fabs(beta-90.0)<=eps) && (fabs(gamma-120.0)<=eps))
- c = 'H';
- else {
- m1 = (a+b+c)/3.0;
- m2 = (alpha+beta+gamma)/3.0;
- if ((fabs(a-m1)<=eps) && (fabs(b-m1)<=eps) &&
- (fabs(c-m1)<=eps) &&
- (fabs(alpha-m2)<=eps) && (fabs(beta-m2)<=eps) &&
- (fabs(gamma-m2)<=eps))
- c = 'R';
- }
- if (c!=spaceGroup[0]) {
- if (c!='N') {
- spaceGroupFix[0] = c;
- return 1;
- }
- return -1;
- }
- return 0;
- }
-
- for (i=0;(i<6) && (k<0);i++)
- if (!strcmp(spaceGroup,short_mono[i])) k = i;
-
- if (k>=0) {
- if ((fabs(alpha-90.0)<=eps) && (fabs(gamma-90.0)<=eps)) {
- if (spaceGroup[0]=='B') return -1;
- sprintf ( spaceGroupFix,"%c 1 %s 1",spaceGroup[0],
- &(spaceGroup[2]) );
- return 1;
- }
- if ((fabs(alpha-90.0)<=eps) && (fabs(beta-90.0)<=eps)) {
- if (spaceGroup[0]=='C') return -1;
- sprintf ( spaceGroupFix,"%c 1 1 %s",spaceGroup[0],
- &(spaceGroup[2]) );
- return 1;
- }
- return -1;
- }
-
- i = 0;
- k = 0;
- while (spaceGroup[i]) {
- if (spaceGroup[i]!=' ') s[k++] = spaceGroup[i];
- i++;
- }
- s[k] = char(0);
-
- k = -1;
- for (i=0;(i<16) && (k<0);i+=2)
- if (!strcmp(s,special[i])) k = i;
-
- if (k>=0) {
- strcpy ( spaceGroupFix,special[k+1] );
- return 1;
- }
-
- return 0;
-
-}
-
-int CMMDBCryst::ConvertPDBString ( pstr PDBString ) {
-// Interprets the ASCII PDB line and fills the corresponding fields.
-// Returns zero if the line was converted, otherwise returns a
-// non-negative value of Error_XXXX.
-// PDBString must be not shorter than 81 characters.
-int RC;
-PCNCSMatrix ncsMatrix;
-PCTVect tVect;
-
- // pad input line with spaces, if necessary
- PadSpaces ( PDBString,80 );
-
- if (!strncmp(PDBString,"CRYST",5)) {
- // Here we check for "CRYST" and not for "CRYST1" keyword.
- // As seems, people tend to not differentiating them.
- if (GetReal(a,&(PDBString[6]) ,9) &&
- GetReal(b,&(PDBString[15]),9) &&
- GetReal(c,&(PDBString[24]),9))
- WhatIsSet |= CSET_CellParams1;
-
- if (GetReal(alpha,&(PDBString[33]),7) &&
- GetReal(beta ,&(PDBString[40]),7) &&
- GetReal(gamma,&(PDBString[47]),7))
- WhatIsSet |= CSET_CellParams2;
-
- GetString ( spaceGroup,&(PDBString[55]),11 );
- CutSpaces ( spaceGroup,SCUTKEY_BEGEND );
- if (fixSpaceGroup) FixSpaceGroup();
- else strcpy ( spaceGroupFix,spaceGroup );
- if (spaceGroupFix[0] && processSG) {
- if (SymOps.SetGroup(spaceGroupFix,syminfo_lib)==SYMOP_Ok)
- WhatIsSet |= CSET_SpaceGroup;
- }
-
- if (GetInteger(Z,&(PDBString[66]),4))
- WhatIsSet |= CSET_ZValue;
-
- WhatIsSet &= 0xFBFF;
-
- if ((a*b*c*alpha*beta*gamma==0.0) ||
- ((a==1.0) && (b==1.0) && (c==1.0) &&
- (alpha==90.0) && (beta==90.0) && (gamma==90.0) &&
- (!strcmp(spaceGroup,"P 1")))) {
- WhatIsSet &= ~(CSET_CellParams1 | CSET_CellParams2 |
- CSET_SpaceGroup);
- WhatIsSet |= CSET_DummyCell;
- }
-
- } else if (!strncmp(PDBString,"ORIGX1",6)) {
-
- if (GetReal(o[0][0],&(PDBString[10]),10) &&
- GetReal(o[0][1],&(PDBString[20]),10) &&
- GetReal(o[0][2],&(PDBString[30]),10) &&
- GetReal(t[0] ,&(PDBString[45]),10))
- WhatIsSet |= CSET_OrigMatrix1;
-
- } else if (!strncmp(PDBString,"ORIGX2",6)) {
-
- if (GetReal(o[1][0],&(PDBString[10]),10) &&
- GetReal(o[1][1],&(PDBString[20]),10) &&
- GetReal(o[1][2],&(PDBString[30]),10) &&
- GetReal(t[1] ,&(PDBString[45]),10))
- WhatIsSet |= CSET_OrigMatrix2;
-
- } else if (!strncmp(PDBString,"ORIGX3",6)) {
-
- if (GetReal(o[2][0],&(PDBString[10]),10) &&
- GetReal(o[2][1],&(PDBString[20]),10) &&
- GetReal(o[2][2],&(PDBString[30]),10) &&
- GetReal(t[2] ,&(PDBString[45]),10))
- WhatIsSet |= CSET_OrigMatrix3;
-
- } else if (!strncmp(PDBString,"SCALE1",6)) {
-
- if (GetReal(s[0][0],&(PDBString[10]),10) &&
- GetReal(s[0][1],&(PDBString[20]),10) &&
- GetReal(s[0][2],&(PDBString[30]),10) &&
- GetReal(u[0] ,&(PDBString[45]),10))
- WhatIsSet |= CSET_ScaleMatrix1;
- WhatIsSet &= 0xFBFF;
- CellCheck |= CCHK_Unchecked;
-
- } else if (!strncmp(PDBString,"SCALE2",6)) {
-
- if (GetReal(s[1][0],&(PDBString[10]),10) &&
- GetReal(s[1][1],&(PDBString[20]),10) &&
- GetReal(s[1][2],&(PDBString[30]),10) &&
- GetReal(u[1] ,&(PDBString[45]),10))
- WhatIsSet |= CSET_ScaleMatrix2;
- WhatIsSet &= 0xFBFF;
- CellCheck |= CCHK_Unchecked;
-
- } else if (!strncmp(PDBString,"SCALE3",6)) {
-
- if (GetReal(s[2][0],&(PDBString[10]),10) &&
- GetReal(s[2][1],&(PDBString[20]),10) &&
- GetReal(s[2][2],&(PDBString[30]),10) &&
- GetReal(u[2] ,&(PDBString[45]),10))
- WhatIsSet |= CSET_ScaleMatrix3;
- WhatIsSet &= 0xFBFF;
- CellCheck |= CCHK_Unchecked;
-
- } else if (!strncmp(PDBString,"MTRIX",5)) {
-
- RC = NCSMatrix.AddMTRIXLine ( PDBString );
- if (RC==Error_NCSM_WrongSerial) {
- ncsMatrix = new CNCSMatrix();
- RC = ncsMatrix->ConvertPDBASCII ( PDBString );
- if (RC==0) NCSMatrix.AddData ( ncsMatrix );
- else delete ncsMatrix;
- }
- return RC;
-
- } else if (!strncmp(PDBString,"TVECT ",6)) {
-
- tVect = new CTVect();
- RC = tVect->ConvertPDBASCII(PDBString);
- if (RC==0) TVect.AddData ( tVect );
- else delete tVect;
- return RC;
-
- } else
- return Error_WrongSection;
-
- return 0;
-
-}
-
-void CMMDBCryst::PDBASCIIDump ( RCFile f ) {
-int i,j;
-char S[100];
-
- if (WhatIsSet & (CSET_CrystCard | CSET_DummyCell)) {
- strcpy ( S,"CRYST1" );
- PadSpaces ( S,80 );
- if (WhatIsSet & CSET_CellParams1) {
- PutRealF ( &(S[6 ]),a,9,3 );
- PutRealF ( &(S[15]),b,9,3 );
- PutRealF ( &(S[24]),c,9,3 );
- }
- if (WhatIsSet & CSET_CellParams2) {
- PutRealF ( &(S[33]),alpha,7,2 );
- PutRealF ( &(S[40]),beta ,7,2 );
- PutRealF ( &(S[47]),gamma,7,2 );
- }
- if ((WhatIsSet & CSET_SpaceGroup) || (spaceGroup[0]))
- strncpy ( &(S[55]),spaceGroup,IMin(11,strlen(spaceGroup)) );
- if (WhatIsSet & CSET_ZValue)
- PutInteger ( &(S[66]),Z,4 );
- f.WriteLine ( S );
- }
-
- if ((WhatIsSet & CSET_OrigMatrix)==CSET_OrigMatrix)
- for (i=0;i<3;i++) {
- sprintf ( S,"ORIGX%1i",i+1);
- PadSpaces ( S,80 );
- for (j=0;j<3;j++)
- PutRealF ( &(S[10+j*10]),o[i][j],10,6 );
- PutRealF ( &(S[45]),t[i],10,5 );
- f.WriteLine ( S );
- }
-
- if ((WhatIsSet & CSET_ScaleMatrix)==CSET_ScaleMatrix)
- for (i=0;i<3;i++) {
- sprintf ( S,"SCALE%1i",i+1);
- PadSpaces ( S,80 );
- for (j=0;j<3;j++)
- PutRealF ( &(S[10+j*10]),s[i][j],10,6 );
- PutRealF ( &(S[45]),u[i],10,5 );
- f.WriteLine ( S );
- }
-
- NCSMatrix.PDBASCIIDump ( f );
- TVect .PDBASCIIDump ( f );
-
-}
-
-
-int CMMDBCryst::GetCIF ( PCMMCIFData CIF ) {
-PCMMCIFStruct Struct;
-int RC;
-
- WhatIsSet = 0;
-
- Struct = CIF->GetStructure ( CIFCAT_CELL );
-
- if (Struct) {
-
- RC = CIFGetReal ( a,Struct,CIFTAG_LENGTH_A );
- if (!RC) RC = CIFGetReal ( b,Struct,CIFTAG_LENGTH_B );
- if (!RC) RC = CIFGetReal ( c,Struct,CIFTAG_LENGTH_C );
- if (RC==Error_UnrecognizedReal) return RC;
- if (!RC) WhatIsSet |= CSET_CellParams1;
-
- RC = CIFGetReal ( alpha,Struct,CIFTAG_ANGLE_ALPHA );
- if (!RC) RC = CIFGetReal ( beta,Struct,CIFTAG_ANGLE_BETA );
- if (!RC) RC = CIFGetReal ( gamma,Struct,CIFTAG_ANGLE_GAMMA );
- if (RC==Error_UnrecognizedReal) return RC;
- if (!RC) WhatIsSet |= CSET_CellParams2;
-
- RC = CIFGetInteger ( Z,Struct,CIFTAG_Z_PDB );
- if (RC==Error_UnrecognizedReal) return RC;
- if (!RC) WhatIsSet |= CSET_ZValue;
-
- }
-
- Struct = CIF->GetStructure ( CIFCAT_SYMMETRY );
- if (Struct) {
- CIFGetString ( spaceGroup,Struct,CIFTAG_SPACE_GROUP_NAME_H_M,
- sizeof(spaceGroup),pstr("") );
- CutSpaces ( spaceGroup,SCUTKEY_BEGEND );
- if (fixSpaceGroup) FixSpaceGroup();
- else strcpy ( spaceGroupFix,spaceGroup );
- /*
- if (fixSpaceGroup) {
- if (!strcasecmp(spaceGroup,"P 21"))
- strcpy ( spaceGroup,"P 1 21 1" );
- else if (!strcasecmp(spaceGroup,"C 2"))
- strcpy ( spaceGroup,"C 1 2 1" );
- }
- */
- if (spaceGroupFix[0] && processSG) {
- if (SymOps.SetGroup(spaceGroupFix,syminfo_lib)==SYMOP_Ok)
- WhatIsSet |= CSET_SpaceGroup;
- }
- }
-
- if ((a*b*c*alpha*beta*gamma==0.0) ||
- ((a==1.0) && (b==1.0) && (c==1.0) &&
- (alpha==90.0) && (beta==90.0) && (gamma==90.0) &&
- (!strcmp(spaceGroup,"P 1")))) {
- WhatIsSet &= ~(CSET_CellParams1 | CSET_CellParams2 |
- CSET_SpaceGroup);
- WhatIsSet |= CSET_DummyCell;
- }
-
- Struct = CIF->GetStructure ( CIFCAT_DATABASE_PDB_MATRIX );
- if (Struct) {
- RC = CIFGetReal ( o[0][0],Struct,CIFTAG_ORIGX11 );
- if (!RC) RC = CIFGetReal ( o[0][1],Struct,CIFTAG_ORIGX12 );
- if (!RC) RC = CIFGetReal ( o[0][2],Struct,CIFTAG_ORIGX13 );
- if (!RC) RC = CIFGetReal ( o[1][0],Struct,CIFTAG_ORIGX21 );
- if (!RC) RC = CIFGetReal ( o[1][1],Struct,CIFTAG_ORIGX22 );
- if (!RC) RC = CIFGetReal ( o[1][2],Struct,CIFTAG_ORIGX23 );
- if (!RC) RC = CIFGetReal ( o[2][0],Struct,CIFTAG_ORIGX31 );
- if (!RC) RC = CIFGetReal ( o[2][1],Struct,CIFTAG_ORIGX32 );
- if (!RC) RC = CIFGetReal ( o[2][2],Struct,CIFTAG_ORIGX33 );
- if (!RC) RC = CIFGetReal ( t[0] ,Struct,CIFTAG_ORIGX_VECTOR1 );
- if (!RC) RC = CIFGetReal ( t[1] ,Struct,CIFTAG_ORIGX_VECTOR2 );
- if (!RC) RC = CIFGetReal ( t[2] ,Struct,CIFTAG_ORIGX_VECTOR3 );
- if (RC) return RC;
- WhatIsSet |= CSET_OrigMatrix;
- }
-
- Struct = CIF->GetStructure ( CIFCAT_ATOM_SITES );
- if (Struct) {
- RC = CIFGetReal ( s[0][0],Struct,CIFTAG_FRACT_TRANSF_MATRIX11 );
- if (!RC)
- RC = CIFGetReal(s[0][1],Struct,CIFTAG_FRACT_TRANSF_MATRIX12);
- if (!RC)
- RC = CIFGetReal(s[0][2],Struct,CIFTAG_FRACT_TRANSF_MATRIX13);
- if (!RC)
- RC = CIFGetReal(s[1][0],Struct,CIFTAG_FRACT_TRANSF_MATRIX21);
- if (!RC)
- RC = CIFGetReal(s[1][1],Struct,CIFTAG_FRACT_TRANSF_MATRIX22);
- if (!RC)
- RC = CIFGetReal(s[1][2],Struct,CIFTAG_FRACT_TRANSF_MATRIX23);
- if (!RC)
- RC = CIFGetReal(s[2][0],Struct,CIFTAG_FRACT_TRANSF_MATRIX31);
- if (!RC)
- RC = CIFGetReal(s[2][1],Struct,CIFTAG_FRACT_TRANSF_MATRIX32);
- if (!RC)
- RC = CIFGetReal(s[2][2],Struct,CIFTAG_FRACT_TRANSF_MATRIX33);
- if (!RC)
- RC = CIFGetReal(u[0] ,Struct,CIFTAG_FRACT_TRANSF_VECTOR1 );
- if (!RC)
- RC = CIFGetReal(u[1] ,Struct,CIFTAG_FRACT_TRANSF_VECTOR2 );
- if (!RC)
- RC = CIFGetReal(u[2] ,Struct,CIFTAG_FRACT_TRANSF_VECTOR3 );
- if (RC) return RC;
- WhatIsSet |= CSET_ScaleMatrix;
- }
-
- RC = NCSMatrix.GetCIF(CIF,ClassID_NCSMatrix);
- if (RC) return RC;
-
- RC = TVect.GetCIF(CIF,ClassID_TVect);
- return RC;
-
-}
-
-void CMMDBCryst::MakeCIF ( PCMMCIFData CIF ) {
-PCMMCIFStruct Struct;
-char S[200];
-
- if (WhatIsSet & (CSET_CellParams1 | CSET_DummyCell)) {
- CIF->AddStructure ( CIFCAT_CELL,Struct );
- Struct->PutReal ( a,CIFTAG_LENGTH_A,8 );
- Struct->PutReal ( b,CIFTAG_LENGTH_B,8 );
- Struct->PutReal ( c,CIFTAG_LENGTH_C,8 );
- }
-
- if (WhatIsSet & (CSET_CellParams2 | CSET_DummyCell)) {
- CIF->AddStructure ( CIFCAT_CELL,Struct );
- Struct->PutReal ( alpha,CIFTAG_ANGLE_ALPHA,8 );
- Struct->PutReal ( beta ,CIFTAG_ANGLE_BETA, 8 );
- Struct->PutReal ( gamma,CIFTAG_ANGLE_GAMMA,8 );
- }
-
- if ((WhatIsSet & (CSET_SpaceGroup | CSET_DummyCell)) ||
- (spaceGroup[0]))
- CIF->PutString ( strcpy_cs(S,spaceGroup),CIFCAT_SYMMETRY,
- CIFTAG_SPACE_GROUP_NAME_H_M );
-
- if (WhatIsSet & (CSET_ZValue | CSET_DummyCell))
- CIF->PutInteger ( Z,CIFCAT_CELL,CIFTAG_Z_PDB );
-
-
- if ((WhatIsSet & CSET_OrigMatrix)==CSET_OrigMatrix) {
- CIF->AddStructure ( CIFCAT_DATABASE_PDB_MATRIX,Struct );
- Struct->PutReal ( o[0][0],CIFTAG_ORIGX11 ,8 );
- Struct->PutReal ( o[0][1],CIFTAG_ORIGX12 ,8 );
- Struct->PutReal ( o[0][2],CIFTAG_ORIGX13 ,8 );
- Struct->PutReal ( o[1][0],CIFTAG_ORIGX21 ,8 );
- Struct->PutReal ( o[1][1],CIFTAG_ORIGX22 ,8 );
- Struct->PutReal ( o[1][2],CIFTAG_ORIGX23 ,8 );
- Struct->PutReal ( o[2][0],CIFTAG_ORIGX31 ,8 );
- Struct->PutReal ( o[2][1],CIFTAG_ORIGX32 ,8 );
- Struct->PutReal ( o[2][2],CIFTAG_ORIGX33 ,8 );
- Struct->PutReal ( t[0] ,CIFTAG_ORIGX_VECTOR1,8 );
- Struct->PutReal ( t[1] ,CIFTAG_ORIGX_VECTOR2,8 );
- Struct->PutReal ( t[2] ,CIFTAG_ORIGX_VECTOR3,8 );
- }
-
- if ((WhatIsSet & CSET_ScaleMatrix)==CSET_ScaleMatrix) {
- CIF->AddStructure ( CIFCAT_ATOM_SITES,Struct );
- Struct->PutReal ( s[0][0],CIFTAG_FRACT_TRANSF_MATRIX11,8 );
- Struct->PutReal ( s[0][1],CIFTAG_FRACT_TRANSF_MATRIX12,8 );
- Struct->PutReal ( s[0][2],CIFTAG_FRACT_TRANSF_MATRIX13,8 );
- Struct->PutReal ( s[1][0],CIFTAG_FRACT_TRANSF_MATRIX21,8 );
- Struct->PutReal ( s[1][1],CIFTAG_FRACT_TRANSF_MATRIX22,8 );
- Struct->PutReal ( s[1][2],CIFTAG_FRACT_TRANSF_MATRIX23,8 );
- Struct->PutReal ( s[2][0],CIFTAG_FRACT_TRANSF_MATRIX31,8 );
- Struct->PutReal ( s[2][1],CIFTAG_FRACT_TRANSF_MATRIX32,8 );
- Struct->PutReal ( s[2][2],CIFTAG_FRACT_TRANSF_MATRIX33,8 );
- Struct->PutReal ( u[0] ,CIFTAG_FRACT_TRANSF_VECTOR1 ,8 );
- Struct->PutReal ( u[1] ,CIFTAG_FRACT_TRANSF_VECTOR2 ,8 );
- Struct->PutReal ( u[2] ,CIFTAG_FRACT_TRANSF_VECTOR3 ,8 );
- }
-
- NCSMatrix.MakeCIF ( CIF );
- TVect .MakeCIF ( CIF );
-
-}
-
-
-
-cpstr OrthCode[6] = {
- cpstr("A/X0, C*/Z0"), // (standard brookhaven)
- cpstr("B/X0, A*/Z0"),
- cpstr("C/X0, B*/Z0"),
- cpstr("HEX A+B/X0, C*/Z0"),
- cpstr("A*/X0, C/Z0 (rollett)"),
- cpstr("A/X0, B*/Y0")
-};
-
-cpstr getOrthCodeName ( int NCode ) {
- if ((NCode>0) && (NCode<=6)) return OrthCode[NCode-1];
- return cpstr("CUSTOM");
-}
-
-void CMMDBCryst::CalcCoordTransforms() {
-realtype rChk1,rChk2,Fac;
-int i,j,k;
-
- WhatIsSet &= ~CSET_Transforms; // clear the flag
-
- if ((WhatIsSet & CSET_CellParams)==CSET_CellParams) {
- // The 'cryst1' card was supplied. Calculate
- // standard orthogonalizations.
-
- CalcOrthMatrices();
- if (NCode<0) NCode = 0;
-
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++)
- RO[i][j] = RR[NCode][i][j];
- RO[i][3] = 0.0;
- RO[3][i] = 0.0;
- }
- RO[3][3] = 1.0;
- Mat4Inverse ( RO,RF );
-
- WhatIsSet |= CSET_Transforms;
-
- if (ignoreScalei)
- CellCheck = CCHK_Ok;
- else if ((WhatIsSet & CSET_ScaleMatrix)==CSET_ScaleMatrix) {
- // All 'scalei' cards were supplied. Calculate
- // rotation and translation matrices and check
- // if they are in consistence with the cell.
-
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++)
- RF[i][j] = s[i][j];
- RF[i][3] = u[i];
- RF[3][i] = 0.0;
- }
- RF[3][3] = 1.0;
- Mat4Inverse ( RF,RO );
-
- // Find orthogonalisation type
- VolChk = RO[0][0]*(RO[1][1]*RO[2][2] - RO[1][2]*RO[2][1]) +
- RO[0][1]*(RO[1][2]*RO[2][0] - RO[1][0]*RO[2][2]) +
- RO[0][2]*(RO[1][0]*RO[2][1] - RO[1][1]*RO[2][0]);
-
- CellCheck = CCHK_Ok;
- if (Vol>0.0) {
- VolErr = fabs(VolChk-Vol)/Vol;
- if (VolErr>0.02) CellCheck |= CCHK_Error;
- else if (VolErr>0.1) CellCheck |= CCHK_Disagreement;
- } else
- CellCheck |= CCHK_NoCell;
-
- // try to find NCode
- NCode = -1;
- for (k=0;(k<6) && (NCode<0);k++) {
- NCode = k;
- for (i=0;i<3;i++)
- for (j=0;j<3;j++) {
- rChk1 = RO[i][j] + RR[k][i][j];
- rChk2 = RO[i][j] - RR[k][i][j];
- if (fabs(rChk1)>=0.1) {
- if (fabs(rChk2/rChk1)>0.01)
- NCode = -1;
- }
- }
- }
-
- // Correct inaccuracy of SCALEi input due to FORMAT,
- // replace RF,RO with RR[NCode][][] if possible.
-
- if (NCode>=0) {
- for (i=0;i<3;i++)
- for (j=0;j<3;j++)
- RO[i][j] = RR[NCode][i][j];
- Mat4Inverse ( RO,RF );
- } else
- CellCheck |= CCHK_NoOrthCode;
-
- if ((u[0]!=0.0) || (u[1]!=0.0) || (u[2]!=0.0))
- CellCheck |= CCHK_Translations;
-
- }
-
- // Generate ROU and RFU for AnisoU stuff
- RFU[3][3] = 1.0;
- for (i=0;i<3;i++) {
- Fac = sqrt(RF[i][0]*RF[i][0] + RF[i][1]*RF[i][1] +
- RF[i][2]*RF[i][2]);
- RFU[i][0] = RF[i][0]/Fac;
- RFU[i][1] = RF[i][1]/Fac;
- RFU[i][2] = RF[i][2]/Fac;
- RFU[i][3] = 0.0;
- RFU[3][i] = 0.0;
- }
- RFU[3][3] = 1.0;
- Mat4Inverse ( RFU,ROU );
-
- } else
- CellCheck |= CCHK_NoCell;
-
-}
-
-
-void CMMDBCryst::RWBROOKReadPrintout() {
-int i,j;
-
- if ((WhatIsSet & CSET_CellParams)==CSET_CellParams) {
- printf ( " MATRICES DERIVED FROM CRYST1"
- " CARD IN COORDINATE FILE\n\n\n"
- " RF "
- " RO\n\n" );
- for (i=0;i<4;i++) {
- printf ( " " );
- for (j=0;j<4;j++)
- printf ( "%8.3f",RF[i][j] );
- printf ( " " );
- for (j=0;j<4;j++)
- printf ( "%8.3f",RO[i][j] );
- printf ( "\n" );
- }
- printf ( "\n" );
- } else
- printf ( "\n $WARNING: NO CRYST CARDS READ$\n" );
-
- if ((WhatIsSet & CSET_ScaleMatrix)!=CSET_ScaleMatrix)
- printf ( "\n $WARNING: NO SCALE CARDS READ$\n" );
-
-}
-
-
-void CMMDBCryst::CalcOrthMatrices() {
-// Calculates matrices for standard orthogonalizations
-// and the cell volume.
-// The matrices are stored in array RR
-realtype Conv,Alph,Bet,Gamm,Sum,V;
-realtype sinA,cosA,sinB,cosB,sinG,cosG;
-realtype sinAS,cosAS,sinBS,cosBS,sinGS,cosGS;
-int i,j,k;
-
- if ((WhatIsSet & CSET_CellParams)!=CSET_CellParams) return;
-
- Conv = Pi/180.0;
-
- Alph = alpha*Conv;
- Bet = beta *Conv;
- Gamm = gamma*Conv;
-
- Sum = (Alph+Bet+Gamm)*0.5;
-
- V = sqrt(sin(Sum-Alph)*sin(Sum-Bet)*sin(Sum-Gamm)*sin(Sum));
-
- Vol = 2.0*a*b*c*V;
-
- // Precaution measure for erratic use of the library
- if ((fabs(Alph)<1.0e-6) || (fabs(Bet)<1.0e-6) ||
- (fabs(Gamm)<1.0e-6)) {
- as = 0.0;
- bs = 0.0;
- cs = 0.0;
- alphas = 0.0;
- betas = 0.0;
- gammas = 0.0;
- for (k=0;k<6;k++) {
- AC[k] = 0.0;
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++)
- RR[k][i][j] = 0.0;
- RR[k][i][i] = 1.0;
- }
- }
- return;
- }
-
- sinA = sin(Alph);
- cosA = cos(Alph);
- sinB = sin(Bet);
- cosB = cos(Bet);
- sinG = sin(Gamm);
- cosG = cos(Gamm);
-
- cosAS = (cosG*cosB-cosA) / (sinB*sinG);
- sinAS = sqrt(1.0-cosAS*cosAS);
- cosBS = (cosA*cosG-cosB) / (sinA*sinG);
- sinBS = sqrt(1.0-cosBS*cosBS);
- cosGS = (cosA*cosB-cosG) / (sinA*sinB);
- sinGS = sqrt(1.0-cosGS*cosGS);
-
- as = b*c*sinA/Vol;
- bs = c*a*sinB/Vol;
- cs = a*b*sinG/Vol;
- alphas = atan2(sinAS,cosAS)/Conv;
- betas = atan2(sinBS,cosBS)/Conv;
- gammas = atan2(sinGS,cosGS)/Conv;
-
-// ---- Set useful things for calculating dstar
-
- AC[0] = as*as;
- AC[1] = bs*bs;
- AC[2] = cs*cs;
- AC[3] = 2.0*bs*cs*cosAS;
- AC[4] = 2.0*cs*as*cosBS;
- AC[5] = 2.0*as*bs*cosGS;
-
-// ---- Zero matrices
-
- for (k=0;k<6;k++)
- for (i=0;i<3;i++)
- for (j=0;j<3;j++)
- RR[k][i][j] = 0.0;
-
-// ---- Calculate matrices
-
-// ---- XO along a Zo along c*
-
- RR[0][0][0] = a;
- RR[0][0][1] = b*cosG;
- RR[0][0][2] = c*cosB;
- RR[0][1][1] = b*sinG;
- RR[0][1][2] = -c*sinB*cosAS;
- RR[0][2][2] = c*sinB*sinAS;
-
- // ---- XO along b Zo along a*
-
- RR[1][0][0] = a*cosG;
- RR[1][0][1] = b;
- RR[1][0][2] = c*cosA;
- RR[1][1][0] = -a*sinG*cosBS;
- RR[1][1][2] = c*sinA;
- RR[1][2][0] = a*sinG*sinBS;
-
-// ---- XO along c Zo along b*
-
- RR[2][0][0] = a*cosB;
- RR[2][0][1] = b*cosA;
- RR[2][0][2] = c;
- RR[2][1][0] = a*sinB;
- RR[2][1][1] = -b*sinA*cosGS;
- RR[2][2][1] = b*sinA*sinGS;
-
-// ---- trigonal only - XO along a+b YO alon a-b Zo along c*
-
- RR[3][0][0] = a/2.0;
- RR[3][0][1] = a/2.0;
- RR[3][1][0] = -a*sinG;
- RR[3][1][1] = a*sinG;
- RR[3][2][2] = c;
-
-// ---- XO along a*, ZO along c
-
- RR[4][0][0] = a*sinB*sinGS;
- RR[4][1][0] = -a*sinB*cosGS;
- RR[4][1][1] = b*sinA;
- RR[4][2][0] = a*cosB;
- RR[4][2][1] = b*cosA;
- RR[4][2][2] = c;
-
-// ---- Grr*! to Gerard Bricogne - his setting for P1 in SKEW.
-// XO along a, Y0 along b*
-
- RR[5][0][0] = a;
- RR[5][0][1] = b*cosG;
- RR[5][0][2] = c*cosB;
- RR[5][1][1] = b*sinG*sinAS;
- RR[5][2][1] = -b*sinG*cosAS;
- RR[5][2][2] = c*sinB;
-
-}
-
-
-Boolean CMMDBCryst::areMatrices() {
-// returns True if the orthogonal-to-fractional and
-// fractional-to-orthogonal matrices are defined
- return (WhatIsSet & CSET_Transforms)!=0x0000;
-}
-
-
-Boolean CMMDBCryst::Frac2Orth (
- realtype x, realtype y, realtype z,
- realtype & xx, realtype & yy, realtype & zz ) {
- if (areMatrices()) {
- xx = RO[0][0]*x + RO[0][1]*y + RO[0][2]*z + RO[0][3];
- yy = RO[1][0]*x + RO[1][1]*y + RO[1][2]*z + RO[1][3];
- zz = RO[2][0]*x + RO[2][1]*y + RO[2][2]*z + RO[2][3];
- return True;
- } else {
- xx = x;
- yy = y;
- zz = z;
- return False;
- }
-}
-
-Boolean CMMDBCryst::Orth2Frac (
- realtype x, realtype y, realtype z,
- realtype & xx, realtype & yy, realtype & zz ) {
- if (areMatrices()) {
- xx = RF[0][0]*x + RF[0][1]*y + RF[0][2]*z + RF[0][3];
- yy = RF[1][0]*x + RF[1][1]*y + RF[1][2]*z + RF[1][3];
- zz = RF[2][0]*x + RF[2][1]*y + RF[2][2]*z + RF[2][3];
- return True;
- } else {
- xx = x;
- yy = y;
- zz = z;
- return False;
- }
-}
-
-
-Boolean CMMDBCryst::Frac2Orth ( mat44 & F, mat44 & T ) {
-mat44 A;
- if (areMatrices()) {
- Mat4Mult ( A,F,RF );
- Mat4Mult ( T,RO,A );
- return True;
- } else {
- Mat4Init ( T );
- return False;
- }
-}
-
-
-Boolean CMMDBCryst::Orth2Frac ( mat44 & T, mat44 & F ) {
-mat44 A;
- if (areMatrices()) {
- Mat4Mult ( A,T,RO );
- Mat4Mult ( F,RF,A );
- return True;
- } else {
- Mat4Init ( F );
- return False;
- }
-}
-
-
-int CMMDBCryst::GetNumberOfSymOps() {
- return SymOps.GetNofSymOps();
-}
-
-pstr CMMDBCryst::GetSymOp ( int Nop ) {
- return SymOps.GetSymOp ( Nop );
-}
-
-
-int CMMDBCryst::GetTMatrix ( mat44 & TMatrix, int Nop,
- int cellshift_a, int cellshift_b,
- int cellshift_c, PCSymOps symOpers ) {
-//
-// GetTMatrix(..) calculates and returns the coordinate transformation
-// matrix, which converts orthogonal coordinates according to the
-// symmetry operation Nop and places them into unit cell shifted by
-// cellshift_a a's, cellshift_b b's and cellshift_c c's.
-//
-// Return 0 means everything's fine,
-// 1 there's no symmetry operation Nop defined
-// 2 fractionalizing/orthogonalizing matrices were not
-// calculated
-// 3 cell parameters were not set up.
-//
-mat44 fm;
-int i,j,k;
-
- if (cellshift_a<=-MaxInt4) {
- k = GetFractMatrix ( fm,Nop,0,0,0,symOpers );
- fm[0][3] = frac(fm[0][3]);
- fm[1][3] = frac(fm[1][3]);
- fm[2][3] = frac(fm[2][3]);
- } else
- k = GetFractMatrix ( fm,Nop,cellshift_a,cellshift_b,cellshift_c,
- symOpers );
-
- if (k) {
- Mat4Init ( TMatrix );
- return k;
- }
-
- // transformation back to orthogonal coordinates
- for (i=0;i<3;i++) {
- for (j=0;j<4;j++) {
- TMatrix[i][j] = 0.0;
- for (k=0;k<3;k++)
- TMatrix[i][j] += RO[i][k]*fm[k][j];
- }
- TMatrix[i][3] += RO[i][3];
- }
-
- TMatrix[3][0] = 0.0;
- TMatrix[3][1] = 0.0;
- TMatrix[3][2] = 0.0;
- TMatrix[3][3] = 1.0;
-
- return 0;
-
-}
-
-
-int CMMDBCryst::GetUCTMatrix ( mat44 & TMatrix, int Nop,
- realtype x, realtype y, realtype z,
- int cellshift_a, int cellshift_b,
- int cellshift_c, PCSymOps symOpers ) {
-//
-// GetUCTMatrix(..) calculates and returns the coordinate
-// transformation matrix, which converts orthogonal coordinates
-// according to the symmetry operation Nop. Translation part of
-// the matrix is being chosen such that point (x,y,z) has least
-// distance to the center of primary (333) unit cell, and then
-// it is shifted by cellshift_a a's, cellshift_b b's and
-// cellshift_c c's.
-//
-// Return 0 means everything's fine,
-// 1 there's no symmetry operation Nop defined
-// 2 fractionalizing/orthogonalizing matrices were not
-// calculated
-// 3 cell parameters were not set up.
-//
-mat44 fm,tm;
-vect3 ft;
-realtype x0,y0,z0, dx,dy,dz, d,d0;
-int i,j,k, ic,jc,kc;
-
- k = GetFractMatrix ( fm,Nop,0,0,0,symOpers );
- if (k) {
- Mat4Init ( TMatrix );
- return k;
- }
-
- fm[0][3] = frac(fm[0][3]) + cellshift_a;
- fm[1][3] = frac(fm[1][3]) + cellshift_b;
- fm[2][3] = frac(fm[2][3]) + cellshift_c;
-
- Frac2Orth ( cellshift_a+0.5,cellshift_b+0.5,cellshift_c+0.5,
- x0,y0,z0 );
-
- // transformation back to orthogonal coordinates
-
- for (i=0;i<3;i++)
- for (j=0;j<3;j++) {
- tm[i][j] = 0.0;
- for (k=0;k<3;k++)
- tm[i][j] += RO[i][k]*fm[k][j];
- }
- tm[3][0] = 0.0;
- tm[3][1] = 0.0;
- tm[3][2] = 0.0;
- tm[3][3] = 1.0;
-
- d0 = MaxReal;
- for (ic=-3;ic<3;ic++)
- for (jc=-3;jc<3;jc++)
- for (kc=-3;kc<3;kc++) {
- ft[0] = fm[0][3] + ic;
- ft[1] = fm[1][3] + jc;
- ft[2] = fm[2][3] + kc;
- for (i=0;i<3;i++) {
- tm[i][3] = 0.0;
- for (k=0;k<3;k++)
- tm[i][3] += RO[i][k]*ft[k];
- tm[i][3] += RO[i][3];
- }
- dx = tm[0][0]*x + tm[0][1]*y + tm[0][2]*z + tm[0][3] - x0;
- dy = tm[1][0]*x + tm[1][1]*y + tm[1][2]*z + tm[1][3] - y0;
- dz = tm[2][0]*x + tm[2][1]*y + tm[2][2]*z + tm[2][3] - z0;
- d = dx*dx + dy*dy + dz*dz;
- if (d<d0) {
- d0 = d;
- Mat4Copy ( tm,TMatrix );
- }
- }
-
- return 0;
-
-}
-
-
-int CMMDBCryst::GetFractMatrix ( mat44 & TMatrix, int Nop,
- int cellshift_a, int cellshift_b,
- int cellshift_c,
- PCSymOps symOpers ) {
-//
-// GetFractMatrix(..) calculates and returns the coordinate
-// transformation matrix, which converts fractional coordinates
-// according to the symmetry operation Nop and places them into
-// unit cell shifted by cellshift_a a's, cellshift_b b's and
-// cellshift_c c's.
-//
-// Return 0 means everything's fine,
-// 1 there's no symmetry operation Nop defined
-// 2 fractionalizing/orthogonalizing matrices were not
-// calculated
-// 3 cell parameters were not set up.
-//
-mat44 tm;
-int i,j,k;
-
- k = 0;
- if (symOpers) k = symOpers->GetTMatrix ( tm,Nop );
- else k = SymOps.GetTMatrix ( tm,Nop );
- if (!k) {
- if (!areMatrices()) k = 2;
- if (!isCellParameters()) k = 3;
- } else
- k = 1;
-
- if (k) {
- Mat4Init ( TMatrix );
- return k;
- }
-
- // transformation to fractional coordinates + symmetry operation
- for (i=0;i<3;i++) {
- for (j=0;j<4;j++) {
- TMatrix[i][j] = 0.0;
- for (k=0;k<3;k++)
- TMatrix[i][j] += tm[i][k]*RF[k][j];
- }
- TMatrix[i][3] += tm[i][3]; // symmetry operation shift
- }
-
- // cell shift
- TMatrix[0][3] += cellshift_a;
- TMatrix[1][3] += cellshift_b;
- TMatrix[2][3] += cellshift_c;
-
- TMatrix[3][0] = 0.0;
- TMatrix[3][1] = 0.0;
- TMatrix[3][2] = 0.0;
- TMatrix[3][3] = 1.0;
-
- return 0;
-
-}
-
-int CMMDBCryst::GetSymOpMatrix ( mat44 & TMatrix, int Nop ) {
-//
-// GetSymOpMatrix(..) returns the transformation matrix for
-// Nop-th symmetry operator in the space group
-//
-// Return 0 means everything's fine,
-// 1 there's no symmetry operation Nop defined
-// 2 fractionalizing/orthogonalizing matrices were not
-// calculated
-// 3 cell parameters were not set up.
-//
- return SymOps.GetTMatrix ( TMatrix,Nop );
-}
-
-
-Boolean CMMDBCryst::Cryst2Orth ( rvector U ) {
-mat33 A,AT,Tmp,TmpMat;
-realtype BB;
-int i,j,k;
-
- if (areMatrices()) {
-
- Tmp[0][0] = U[0];
- Tmp[1][1] = U[1];
- Tmp[2][2] = U[2];
- Tmp[0][1] = U[3];
- Tmp[1][0] = U[3];
- Tmp[0][2] = U[4];
- Tmp[2][0] = U[4];
- Tmp[1][2] = U[5];
- Tmp[2][1] = U[5];
-
- for (i=0;i<3;i++)
- for (j=0;j<3;j++) {
- A [j][i] = ROU[j][i];
- AT[i][j] = ROU[j][i];
- }
-
- // TmpMat = Tmp*AT
- for (i=0;i<3;i++)
- for (j=0;j<3;j++) {
- BB = 0.0;
- for (k=0;k<3;k++)
- BB += Tmp[i][k]*AT[k][j];
- TmpMat[i][j] = BB;
- }
-
- // Tmp = A*TmpMat
- for (i=0;i<3;i++)
- for (j=0;j<3;j++) {
- BB = 0.0;
- for (k=0;k<3;k++)
- BB += A[i][k]*TmpMat[k][j];
- Tmp[i][j] = BB;
- }
-
- U[0] = Tmp[0][0];
- U[1] = Tmp[1][1];
- U[2] = Tmp[2][2];
- U[3] = Tmp[0][1];
- U[4] = Tmp[0][2];
- U[5] = Tmp[1][2];
-
- return True;
-
- }
-
- return False;
-
-}
-
-
-Boolean CMMDBCryst::Orth2Cryst ( rvector U ) {
-mat33 A,AT,Tmp,TmpMat;
-realtype BB;
-int i,j,k;
-
- if (areMatrices()) {
-
- Tmp[0][0] = U[0];
- Tmp[1][1] = U[1];
- Tmp[2][2] = U[2];
- Tmp[0][1] = U[3];
- Tmp[1][0] = U[3];
- Tmp[0][2] = U[4];
- Tmp[2][0] = U[4];
- Tmp[1][2] = U[5];
- Tmp[2][1] = U[5];
-
- for (i=0;i<3;i++)
- for (j=0;j<3;j++) {
- A [j][i] = RFU[j][i];
- AT[i][j] = RFU[j][i];
- }
-
- // TmpMat = Tmp*AT
- for (i=0;i<3;i++)
- for (j=0;j<3;j++) {
- BB = 0.0;
- for (k=0;k<3;k++)
- BB += Tmp[i][k]*AT[k][j];
- TmpMat[i][j] = BB;
- }
-
- // Tmp = A*TmpMat
- for (i=0;i<3;i++)
- for (j=0;j<3;j++) {
- BB = 0.0;
- for (k=0;k<3;k++)
- BB += A[i][k]*TmpMat[k][j];
- Tmp[i][j] = BB;
- }
-
- U[0] = Tmp[0][0];
- U[1] = Tmp[1][1];
- U[2] = Tmp[2][2];
- U[3] = Tmp[0][1];
- U[4] = Tmp[0][2];
- U[5] = Tmp[1][2];
-
- return True;
-
- }
-
- return False;
-
-}
-
-
-void CMMDBCryst::SetCell ( realtype cell_a,
- realtype cell_b,
- realtype cell_c,
- realtype cell_alpha,
- realtype cell_beta,
- realtype cell_gamma,
- int OrthCode ) {
-// this function should be used for changing the cell parameters
-int i,j;
-
- if ((cell_a>0.0) && (cell_b>0.0) && (cell_c>0.0) &&
- (cell_alpha!=0.0) && (cell_beta!=0.0) && (cell_gamma!=0.0)) {
-
- if (OrthCode>0) NCode = OrthCode-1;
- else NCode = 0;
-
- a = cell_a;
- b = cell_b;
- c = cell_c;
- alpha = cell_alpha;
- beta = cell_beta;
- gamma = cell_gamma;
-
- WhatIsSet |= CSET_CellParams;
-
- // calculate matrices
-
- for (i=0;i<4;i++) {
- for (j=0;j<4;j++) {
- RO [i][j] = 0.0;
- RF [i][j] = 0.0;
- ROU[i][j] = 0.0;
- RFU[i][j] = 0.0;
- }
- RO [i][i] = 1.0;
- RF [i][i] = 1.0;
- ROU[i][i] = 1.0;
- RFU[i][i] = 1.0;
- }
-
- CalcCoordTransforms();
-
- if (!(CellCheck & CCHK_NoOrthCode)) {
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++)
- RO[i][j] = RR[NCode][i][j];
- RO[i][3] = 0.0;
- RO[3][i] = 0.0;
- }
- RO[3][3] = 1.0;
- Mat4Inverse ( RO,RF );
- }
-
- WhatIsSet |= CSET_Transforms;
-
- } else
-
- WhatIsSet &= ~(CSET_CellParams | CSET_Transforms);
-
-}
-
-void CMMDBCryst::SetSyminfoLib ( cpstr syminfoLib ) {
- CreateCopy ( syminfo_lib,syminfoLib );
-}
-
-pstr CMMDBCryst::GetSyminfoLib() {
- return syminfo_lib;
-}
-
-int CMMDBCryst::SetSpaceGroup ( cpstr spGroup ) {
-// This function does not attempt to fix the space group
-int RC,l;
- RC = SYMOP_UnknownSpaceGroup;
- WhatIsSet &= ~CSET_SpaceGroup;
- if (spGroup) {
- if (spGroup[0]) {
- l = IMin ( strlen(spGroup),sizeof(spaceGroup)-1 );
- strcpy_ncss ( spaceGroup,spGroup,l );
- strcpy ( spaceGroupFix,spaceGroup );
- if (spaceGroup[0]) {
- RC = SymOps.SetGroup ( spaceGroup,syminfo_lib );
- // RC = SymOps.SetGroup ( spGroup,syminfo_lib );
- // strncpy ( spaceGroup,spGroup,l );
- // spaceGroup[l] = char(0);
- if (RC==SYMOP_Ok) WhatIsSet |= CSET_SpaceGroup;
- }
- }
- }
- return RC;
-}
-
-
-void CMMDBCryst::PutCell ( realtype cell_a,
- realtype cell_b,
- realtype cell_c,
- realtype cell_alpha,
- realtype cell_beta,
- realtype cell_gamma,
- int OrthCode ) {
-// this function should be used for setting the cell parameters
-int i,j;
-
- if ((cell_a!=0.0) || (OrthCode>0)) {
- a = cell_a;
- b = cell_b;
- c = cell_c;
- alpha = cell_alpha;
- beta = cell_beta;
- gamma = cell_gamma;
- WhatIsSet |= CSET_CellParams;
- }
-
- if (OrthCode>0) {
-
- // calculate matrices
-
- NCode = OrthCode-1;
- CalcOrthMatrices();
-
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++)
- RO[i][j] = RR[NCode][i][j];
- RO[i][3] = 0.0;
- RO[3][i] = 0.0;
- }
- RO[3][3] = 1.0;
-
- Mat4Inverse ( RO,RF );
-
- WhatIsSet |= CSET_Transforms;
-
- } else
- WhatIsSet &= ~CSET_Transforms;
-
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++)
- s[i][j] = RF[i][j];
- u[i] = RF[i][3];
- }
-
- WhatIsSet |= CSET_ScaleMatrix;
-
-}
-
-
-Boolean CMMDBCryst::isScaleMatrix() {
- return ((WhatIsSet & CSET_ScaleMatrix)==CSET_ScaleMatrix);
-}
-
-Boolean CMMDBCryst::isCellParameters() {
- return ((WhatIsSet & CSET_CellParams)==CSET_CellParams);
-}
-
-Boolean CMMDBCryst::isNCSMatrix() {
- return (NCSMatrix.Length()>0);
-}
-
-int CMMDBCryst::GetNumberOfNCSMatrices() {
- return NCSMatrix.Length();
-}
-
-int CMMDBCryst::GetNumberOfNCSMates() {
-// Returns the number of NCS mates not given in the file (iGiven==0)
-int i,l,iG;
-PCNCSMatrix NCSM;
- iG = 0;
- l = NCSMatrix.Length();
- for (i=0;i<l;i++) {
- NCSM = PCNCSMatrix(NCSMatrix.GetContainerClass(i));
- if (NCSM) {
- if (!NCSM->iGiven) iG++;
- }
- }
- return iG;
-}
-
-Boolean CMMDBCryst::GetNCSMatrix ( int NCSMatrixNo,
- mat33 & ncs_m, vect3 & ncs_v ) {
-int i,j;
-PCNCSMatrix NCSM;
- NCSM = PCNCSMatrix(NCSMatrix.GetContainerClass(NCSMatrixNo));
- if (NCSM) {
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++)
- ncs_m[i][j] = NCSM->m[i][j];
- ncs_v[i] = NCSM->v[i];
- }
- return True;
- }
- return False;
-}
-
-Boolean CMMDBCryst::GetNCSMatrix ( int NCSMatrixNo,
- mat44 & ncs_m, int & iGiven ) {
-int i,j;
-PCNCSMatrix NCSM;
- NCSM = PCNCSMatrix(NCSMatrix.GetContainerClass(NCSMatrixNo));
- if (NCSM) {
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++)
- ncs_m[i][j] = NCSM->m[i][j];
- ncs_m[i][3] = NCSM->v[i];
- }
- ncs_m[3][0] = 0.0;
- ncs_m[3][1] = 0.0;
- ncs_m[3][2] = 0.0;
- ncs_m[3][3] = 1.0;
- iGiven = NCSM->iGiven;
- return True;
- } else {
- for (i=0;i<4;i++) {
- for (j=0;j<4;j++)
- ncs_m[i][j] = 0.0;
- ncs_m[i][i] = 1.0;
- }
- return False;
- }
-}
-
-int CMMDBCryst::AddNCSMatrix ( mat33 & ncs_m, vect3 & ncs_v,
- int iGiven ) {
-PCNCSMatrix ncsMatrix;
- ncsMatrix = new CNCSMatrix();
- ncsMatrix->SetNCSMatrix ( NCSMatrix.Length()+1,ncs_m,ncs_v,
- iGiven );
- NCSMatrix.AddData ( ncsMatrix );
- return ncsMatrix->serNum;
-}
-
-void CMMDBCryst::GetRCell ( realtype & cell_as,
- realtype & cell_bs,
- realtype & cell_cs,
- realtype & cell_alphas,
- realtype & cell_betas,
- realtype & cell_gammas,
- realtype & vols ) {
- cell_as = as;
- cell_bs = bs;
- cell_cs = cs;
- cell_alphas = alphas;
- cell_betas = betas;
- cell_gammas = gammas;
- if (Vol!=0.0) vols = 1.0/Vol;
- else vols = 0.0;
-}
-
-void CMMDBCryst::GetCell ( realtype & cell_a,
- realtype & cell_b,
- realtype & cell_c,
- realtype & cell_alpha,
- realtype & cell_beta,
- realtype & cell_gamma,
- realtype & vol ) {
- if (WhatIsSet & CSET_CellParams) {
- cell_a = a;
- cell_b = b;
- cell_c = c;
- cell_alpha = alpha;
- cell_beta = beta;
- cell_gamma = gamma;
- vol = Vol;
- } else {
- cell_a = 0.0;
- cell_b = 0.0;
- cell_c = 0.0;
- cell_alpha = 0.0;
- cell_beta = 0.0;
- cell_gamma = 0.0;
- vol = 0.0;
- }
-}
-
-pstr CMMDBCryst::GetSpaceGroup() {
- if (WhatIsSet & CSET_SpaceGroup) return spaceGroup;
- else return NULL;
-}
-
-pstr CMMDBCryst::GetSpaceGroupFix() {
- if (WhatIsSet & CSET_SpaceGroup) return spaceGroupFix;
- else return NULL;
-}
-
-
-void CMMDBCryst::Copy ( PCMMDBCryst Cryst ) {
-int i,j,k;
-
- if (Cryst) {
-
- a = Cryst->a;
- b = Cryst->b;
- c = Cryst->c;
- alpha = Cryst->alpha;
- beta = Cryst->beta;
- gamma = Cryst->gamma;
-
- for (i=0;i<4;i++)
- for (j=0;j<4;j++) {
- RO [i][j] = Cryst->RO [i][j];
- RF [i][j] = Cryst->RF [i][j];
- ROU[i][j] = Cryst->ROU[i][j];
- RFU[i][j] = Cryst->RFU[i][j];
- }
-
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++) {
- o[i][j] = Cryst->o[i][j];
- s[i][j] = Cryst->s[i][j];
- for (k=0;k<6;k++)
- RR[k][i][j] = Cryst->RR[k][i][j];
- }
- t[i] = Cryst->t[i];
- u[i] = Cryst->u[i];
- }
-
- Vol = Cryst->Vol;
- NCode = Cryst->NCode;
- Z = Cryst->Z;
- CellCheck = Cryst->CellCheck;
- WhatIsSet = Cryst->WhatIsSet;
- strcpy ( spaceGroup ,Cryst->spaceGroup );
- strcpy ( spaceGroupFix,Cryst->spaceGroupFix );
-
- NCSMatrix.Copy ( &(Cryst->NCSMatrix) );
- TVect .Copy ( &(Cryst->TVect) );
- SymOps .Copy ( &(Cryst->SymOps) );
-
- as = Cryst->as;
- bs = Cryst->bs;
- cs = Cryst->cs;
- alphas = Cryst->alphas;
- betas = Cryst->betas;
- gammas = Cryst->betas;
- VolChk = Cryst->VolChk;
- VolErr = Cryst->VolErr;
-
- for (k=0;k<6;k++)
- AC[k] = Cryst->AC[k];
-
- } else {
-
- NCSMatrix.FreeContainer();
- TVect .FreeContainer();
- WhatIsSet = 0;
-
- }
-
-}
-
-
-void CMMDBCryst::write ( RCFile f ) {
-int i,j,k;
-byte Version=3;
-
- f.WriteByte ( &Version );
- f.WriteWord ( &WhatIsSet );
- f.WriteReal ( &a );
- f.WriteReal ( &b );
- f.WriteReal ( &c );
- f.WriteReal ( &alpha );
- f.WriteReal ( &beta );
- f.WriteReal ( &gamma );
- f.WriteWord ( &CellCheck );
- f.WriteBool ( &ignoreScalei );
- for (i=0;i<4;i++)
- for (j=0;j<4;j++) {
- f.WriteReal ( &(RO [i][j]) );
- f.WriteReal ( &(RF [i][j]) );
- f.WriteReal ( &(ROU[i][j]) );
- f.WriteReal ( &(RFU[i][j]) );
- }
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++) {
- f.WriteReal ( &(o[i][j]) );
- f.WriteReal ( &(s[i][j]) );
- for (k=0;k<6;k++)
- f.WriteReal ( &(RR[k][i][j]) );
- }
- f.WriteReal ( &(t[i]) );
- f.WriteReal ( &(u[i]) );
- }
- f.WriteReal ( &Vol );
- f.WriteReal ( &VolChk );
- f.WriteReal ( &VolErr );
- f.WriteInt ( &NCode );
- f.WriteInt ( &Z );
- f.WriteTerLine ( spaceGroup ,False );
- f.WriteTerLine ( spaceGroupFix,False );
-
- for (i=0;i<6;i++)
- f.WriteReal ( &(AC[6]) );
- f.WriteReal ( &as );
- f.WriteReal ( &bs );
- f.WriteReal ( &cs );
- f.WriteReal ( &alphas );
- f.WriteReal ( &betas );
- f.WriteReal ( &gammas );
-
- NCSMatrix.write ( f );
- TVect .write ( f );
- SymOps .write ( f );
-
-}
-
-void CMMDBCryst::read ( RCFile f ) {
-int i,j,k;
-byte Version;
-
- f.ReadByte ( &Version );
- f.ReadWord ( &WhatIsSet );
- f.ReadReal ( &a );
- f.ReadReal ( &b );
- f.ReadReal ( &c );
- f.ReadReal ( &alpha );
- f.ReadReal ( &beta );
- f.ReadReal ( &gamma );
- f.ReadWord ( &CellCheck );
- if (Version>2)
- f.ReadBool ( &ignoreScalei );
- else ignoreScalei = False;
- for (i=0;i<4;i++)
- for (j=0;j<4;j++) {
- f.ReadReal ( &(RO [i][j]) );
- f.ReadReal ( &(RF [i][j]) );
- f.ReadReal ( &(ROU[i][j]) );
- f.ReadReal ( &(RFU[i][j]) );
- }
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++) {
- f.ReadReal ( &(o[i][j]) );
- f.ReadReal ( &(s[i][j]) );
- for (k=0;k<6;k++)
- f.ReadReal ( &(RR[k][i][j]) );
- }
- f.ReadReal ( &(t[i]) );
- f.ReadReal ( &(u[i]) );
- }
- f.ReadReal ( &Vol );
- f.ReadReal ( &VolChk );
- f.ReadReal ( &VolErr );
- f.ReadInt ( &NCode );
- f.ReadInt ( &Z );
- f.ReadTerLine ( spaceGroup,False );
- if (Version>1)
- f.ReadTerLine ( spaceGroupFix,False );
- else strcpy ( spaceGroupFix,spaceGroup );
-
- for (i=0;i<6;i++)
- f.ReadReal ( &(AC[6]) );
- f.ReadReal ( &as );
- f.ReadReal ( &bs );
- f.ReadReal ( &cs );
- f.ReadReal ( &alphas );
- f.ReadReal ( &betas );
- f.ReadReal ( &gammas );
-
- NCSMatrix.read ( f );
- TVect .read ( f );
- SymOps .read ( f );
-
-}
-
-
-MakeStreamFunctions(CMMDBCryst)
-
-
-// ===================================================================
-
-
-void TestCryst() {
-// reads from 'in.cryst', writes into
-// 'out.cryst' and 'abin.cryst'
-CFile f;
-char S[81];
-PCMMDBCryst Cryst;
-
- Cryst = new CMMDBCryst();
-
- f.assign ( pstr("in.cryst"),True );
- if (f.reset()) {
- while (!f.FileEnd()) {
- f.ReadLine ( S,sizeof(S) );
- Cryst->ConvertPDBString ( S );
- }
- f.shut();
- } else {
- printf ( " Can't open input file 'in.chain' \n" );
- delete Cryst;
- return;
- }
-
- f.assign ( pstr("out.cryst"),True );
- if (f.rewrite()) {
- Cryst->PDBASCIIDump ( f );
- f.shut();
- } else {
- printf ( " Can't open output file 'out.cryst' \n" );
- delete Cryst;
- return;
- }
-
-
- f.assign ( pstr("mmdb.cryst.bin"),False );
- if (f.rewrite()) {
- Cryst->write ( f );
- f.shut();
- } else {
- printf ( " Can't open binary cryst file for writing.\n" );
- delete Cryst;
- return;
- }
-
- delete Cryst;
- printf ( " Cryst deleted.\n" );
-
- Cryst = new CMMDBCryst();
- if (f.reset()) {
- Cryst->read ( f );
- f.shut();
- } else {
- printf ( " Can't open binary cryst file for reading.\n" );
- delete Cryst;
- return;
- }
-
- f.assign ( pstr("abin.cryst"),True );
- if (f.rewrite()) {
- Cryst->PDBASCIIDump ( f );
- f.shut();
- } else
- printf ( " Can't open output file 'abin.cryst' \n" );
-
- delete Cryst;
-
-}
diff --git a/mmdb/mmdb_cryst.h b/mmdb/mmdb_cryst.h
deleted file mode 100755
index f6ddc26..0000000
--- a/mmdb/mmdb_cryst.h
+++ /dev/null
@@ -1,462 +0,0 @@
-// $Id: mmdb_cryst.h,v 1.24 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 06.02.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_Cryst <interface>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CCrystContainer ( container for cryst. data )
-// ~~~~~~~~~ CNCSMatrix ( non-cryst. symm. matrix class )
-// CTVect ( translation vector class )
-// CMMDBCryst ( MMDB cryst. section class )
-//
-// (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-#ifndef __MMDB_Cryst__
-#define __MMDB_Cryst__
-
-
-#ifndef __Stream__
-#include "stream_.h"
-#endif
-
-#ifndef __MMDB_SymOp__
-#include "mmdb_symop.h"
-#endif
-
-#ifndef __MMDB_Defs__
-#include "mmdb_defs.h"
-#endif
-
-#ifndef __MMDB_Utils__
-#include "mmdb_utils.h"
-#endif
-
-
-// ==================== CCrystContainer ======================
-
-DefineClass(CCrystContainer)
-DefineStreamFunctions(CCrystContainer)
-
-class CCrystContainer : public CClassContainer {
-
- public :
-
- CCrystContainer () : CClassContainer() {}
- CCrystContainer ( RPCStream Object )
- : CClassContainer ( Object ) {}
- ~CCrystContainer() {}
-
- PCContainerClass MakeContainerClass ( int ClassID );
-
- int AddMTRIXLine ( cpstr S );
-
-};
-
-
-// ================== CNCSMatrix ========================
-
-#define NCSMSET_Matrix1 0x00000001
-#define NCSMSET_Matrix2 0x00000002
-#define NCSMSET_Matrix3 0x00000004
-#define NCSMSET_All 0x00000007
-
-DefineClass(CNCSMatrix)
-DefineStreamFunctions(CNCSMatrix)
-
-class CNCSMatrix : public CContainerClass {
-
- friend class CMMDBCryst;
-
- public :
-
- int serNum; // serial number
- mat33 m; // non-crystallographic symmetry matrix
- vect3 v; // translational part of ncs matrix
- int iGiven; // iGiven flag (see PDB format)
-
- CNCSMatrix ();
- CNCSMatrix ( cpstr S );
- CNCSMatrix ( RPCStream Object );
- ~CNCSMatrix();
-
- Boolean PDBASCIIDump1 ( RCFile f );
- int ConvertPDBASCII ( cpstr S );
- void MakeCIF ( PCMMCIFData CIF, int N );
- void GetCIF ( PCMMCIFData CIF, int & Signal );
-
- int GetClassID () { return ClassID_NCSMatrix; }
-
- void SetNCSMatrix ( int serialNum,
- mat33 & ncs_m, vect3 & ncs_v,
- int i_Given );
-
- void Copy ( PCContainerClass NCSMatrix );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
- word WhatIsSet; // mask field
- // 0x0001 MTRIX1 was converted
- // 0x0002 MTRIX2 was converted
- // 0x0004 MTRIX3 was converted
-
- void Init();
-
-};
-
-
-// ================== CTVect ========================
-
-DefineClass(CTVect)
-DefineStreamFunctions(CTVect)
-
-class CTVect : public CContainerClass {
-
- public :
-
- int serNum; // serial number
- vect3 t; // translation vector
- pstr comment; // comment
-
- CTVect ();
- CTVect ( cpstr S );
- CTVect ( RPCStream Object );
- ~CTVect();
-
- void PDBASCIIDump ( pstr S, int N );
- int ConvertPDBASCII ( cpstr S );
- void MakeCIF ( PCMMCIFData CIF, int N );
- void GetCIF ( PCMMCIFData CIF, int & Signal );
- int GetClassID () { return ClassID_TVect; }
-
- void Copy ( PCContainerClass TVect );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void Init();
-
-};
-
-
-// ================= CMMDBCryst =======================
-
-DefineClass(CMMDBCryst);
-DefineStreamFunctions(CMMDBCryst);
-
-// constants for the CellCheck field
-#define CCHK_Ok 0x00000000
-#define CCHK_NoCell 0x00000001
-#define CCHK_Error 0x00000002
-#define CCHK_Disagreement 0x00000004
-#define CCHK_NoOrthCode 0x00000008
-#define CCHK_Translations 0x00000010
-#define CCHK_Unchecked 0x00001000
-
-// constants for the WhatIsSet field
-#define CSET_CellParams1 0x00000001
-#define CSET_CellParams2 0x00000002
-#define CSET_CellParams 0x00000003
-#define CSET_SpaceGroup 0x00000004
-#define CSET_ZValue 0x00000008
-#define CSET_CrystCard 0x0000000F
-#define CSET_OrigMatrix1 0x00000010
-#define CSET_OrigMatrix2 0x00000020
-#define CSET_OrigMatrix3 0x00000040
-#define CSET_OrigMatrix 0x00000070
-#define CSET_ScaleMatrix1 0x00000080
-#define CSET_ScaleMatrix2 0x00000100
-#define CSET_ScaleMatrix3 0x00000200
-#define CSET_ScaleMatrix 0x00000380
-#define CSET_Transforms 0x00000400
-#define CSET_DummyCell 0x00001000
-
-extern cpstr OrthCode[6];
-
-class CMMDBCryst : public CStream {
-
- friend class CChannel;
-
- public :
-
- realtype a,b,c; // cell parameters
- realtype alpha,beta,gamma; // cell parameters
- mat44 RO,RF; // orthogonal-fractional recalculation
- // matrices
- mat44 ROU,RFU; // ort-frac recalc matrices for
- // anisotr. t-fac
- mat633 RR; // standard orthogonalizations
- realtype Vol; // cell volume
- int NCode; // code of orthogonalization matrix
- SymGroup spaceGroup; // group of space symmetry as read
- // from file
- SymGroup spaceGroupFix; // actually used space group
- int Z; // Z-value
-
- mat33 o; // orthogonal transformation matrix
- vect3 t; // translation orthogonal vector
- mat33 s; // scale matrix
- vect3 u; // translation part of the scale matrix
-
- word CellCheck; // 0x0000 - Ok
- // 0x0001 - no cell stored
- // 0x0002 - some error in cell volume
- // 0x0004 - disagreement between
- // cell and PDB
- // 0x0008 - no orth code derived
- // 0x0010 - translations also specified
- // 0x1000 - the check was not done
- word WhatIsSet; // indicator of the fields set
- Boolean ignoreScalei; // flag to ignore SCALEi cards
- Boolean processSG; // flag to process space group at file
- // read
- Boolean fixSpaceGroup; // flag to fix space group at file read
-
- CMMDBCryst ();
- CMMDBCryst ( RPCStream Object );
- ~CMMDBCryst();
-
- void FreeMemory();
- void Reset ();
-
- // ConvertPDBString(..) interprets an ASCII PDB line and fills
- // the corresponding data fields. It returns zero if the line was
- // successfully converted, otherwise returns a non-negative value
- // of Error_XXXX.
- // PDBString must be not shorter than 81 characters.
- int ConvertPDBString ( pstr PDBString );
-
- // RWBROOKReadPrintout() may be invoked after reading PDB file
- // for simulating the old RWBROOK messages and warnings
- void RWBROOKReadPrintout();
-
- void SetCell ( realtype cell_a,
- realtype cell_b,
- realtype cell_c,
- realtype cell_alpha,
- realtype cell_beta,
- realtype cell_gamma,
- int OrthCode );
- void PutCell ( realtype cell_a,
- realtype cell_b,
- realtype cell_c,
- realtype cell_alpha,
- realtype cell_beta,
- realtype cell_gamma,
- int OrthCode );
-
- void GetCell ( realtype & cell_a,
- realtype & cell_b,
- realtype & cell_c,
- realtype & cell_alpha,
- realtype & cell_beta,
- realtype & cell_gamma,
- realtype & vol );
-
- void GetRCell ( realtype & cell_as,
- realtype & cell_bs,
- realtype & cell_cs,
- realtype & cell_alphas,
- realtype & cell_betas,
- realtype & cell_gammas,
- realtype & vols );
-
- void SetSyminfoLib ( cpstr syminfoLib );
- pstr GetSyminfoLib ();
-
- int SetSpaceGroup ( cpstr spGroup );
- pstr GetSpaceGroup ();
- pstr GetSpaceGroupFix();
-
- // CalcCoordTransforms() should be called once after all data
- // relevant to the crystallographic information, are read and
- // converted. Field CellCheck will then have bits set if there
- // are errors, e.g. bit CCHK_NoCell means that the coordinate
- // transformations cannot be performed.
- void CalcCoordTransforms();
-
- // A PDB ASCII dump
- void PDBASCIIDump ( RCFile f );
-
- int GetCIF ( PCMMCIFData CIF );
- void MakeCIF ( PCMMCIFData CIF );
-
- Boolean areMatrices(); // returns True if the orthogonal-to-
- // fractional and fractional-to-orthogonal
- // matrices are defined
-
- // Frac2Orth(..) and Orth2Frac(..) transform between fractional
- // and orthogonal coordinates, if areMatrices() returns True.
- // If the transformation matrices were not set, the functions just
- // copy the coordinates. Returns True if the transformation was
- // done; False return means that transformation matrices were not
- // calculated
- Boolean Frac2Orth (
- realtype x, realtype y, realtype z,
- realtype & xx, realtype & yy, realtype & zz );
- Boolean Orth2Frac (
- realtype x, realtype y, realtype z,
- realtype & xx, realtype & yy, realtype & zz );
-
- // Below, F and T are transformation matrices in fractional and
- // orthogonal coordinates, respectively.
- Boolean Frac2Orth ( mat44 & F, mat44 & T );
- Boolean Orth2Frac ( mat44 & T, mat44 & F );
-
-
- // Cryst2Orth(..) and Orth2Cryst(..) transform between fractional
- // and orthogonal anisotropic temperature factors, if areMatrices()
- // returns True. If the transformation matrices were not set, the
- // functions leave the factors unchanged.
- // Vector U is composed as follows:
- // U[0]=u11 U[1]=u22 U[2]=u33
- // U[3]=u12 U[4]=u13 U[5]=u23
- // Returns True if the transformation was done; False retuen
- // means that transformation matrices were not calculated
- Boolean Cryst2Orth ( rvector U );
- Boolean Orth2Cryst ( rvector U );
-
- void CalcOrthMatrices(); // calculates RR, AC, cella's and Vol
-
- Boolean isNCSMatrix ();
- Boolean isScaleMatrix ();
- Boolean isCellParameters();
-
- int GetNumberOfSymOps();
- pstr GetSymOp ( int Nop );
-
- int GetNumberOfNCSMatrices();
- int GetNumberOfNCSMates (); // Returns the number of
- // NCS mates not given in
- // the file (iGiven==0)
-
- Boolean GetNCSMatrix ( int NCSMatrixNo, mat33 & ncs_m,
- vect3 & ncs_v );
- Boolean GetNCSMatrix ( int NCSMatrixNo, mat44 & ncs_m,
- int & iGiven ); // no=0..N-1
- int AddNCSMatrix ( mat33 & ncs_m, vect3 & ncs_v, int iGiven );
-
- // GetTMatrix(..) calculates and returns the coordinate
- // transformation matrix, which converts orthogonal coordinates
- // according to the symmetry operation number Nop and places
- // them into unit cell shifted by cellshift_a a's, cellshift_b
- // b's and cellshift_c c's.
- //
- // Return 0 means everything's fine,
- // 1 there's no symmetry operation Nop defined
- // 2 fractionalizing/orthogonalizing matrices were not
- // calculated
- // 3 cell parameters were not set up.
- int GetTMatrix ( mat44 & TMatrix, int Nop,
- int cellshift_a, int cellshift_b,
- int cellshift_c, PCSymOps symOpers=NULL );
-
- // GetUCTMatrix(..) calculates and returns the coordinate
- // transformation matrix, which converts orthogonal coordinates
- // according to the symmetry operation Nop. Translation part
- // of the matrix is being chosen such that point (x,y,z) has
- // least distance to the center of primary (333) unit cell,
- // and then it is shifted by cellshift_a a's, cellshift_b b's
- // and cellshift_c c's.
- //
- // Return 0 means everything's fine,
- // 1 there's no symmetry operation Nop defined
- // 2 fractionalizing/orthogonalizing matrices were not
- // calculated
- // 3 cell parameters were not set up.
- //
- int GetUCTMatrix ( mat44 & TMatrix, int Nop,
- realtype x, realtype y, realtype z,
- int cellshift_a, int cellshift_b,
- int cellshift_c, PCSymOps symOpers=NULL );
-
- // GetFractMatrix(..) calculates and returns the coordinate
- // transformation matrix, which converts fractional coordinates
- // according to the symmetry operation number Nop and places them
- // into unit cell shifted by cellshift_a a's, cellshift_b b's and
- // cellshift_c c's.
- //
- // Return 0 means everything's fine,
- // 1 there's no symmetry operation Nop defined
- // 2 fractionalizing/orthogonalizing matrices were not
- // calculated
- // 3 cell parameters were not set up.
- int GetFractMatrix ( mat44 & TMatrix, int Nop,
- int cellshift_a, int cellshift_b,
- int cellshift_c, PCSymOps symOpers=NULL );
-
- // GetSymOpMatrix(..) returns the transformation matrix for
- // Nop-th symmetry operator in the space group
- //
- // Return 0 means everything's fine,
- // 1 there's no symmetry operation Nop defined
- // 2 fractionalizing/orthogonalizing matrices were not
- // calculated
- // 3 cell parameters were not set up.
- //
- int GetSymOpMatrix ( mat44 & TMatrix, int Nop );
-
- void Copy ( PCMMDBCryst Cryst );
-
- void write ( RCFile f ); // writes header to PDB binary file
- void read ( RCFile f ); // reads header from PDB binary file
-
- protected :
-
- CCrystContainer NCSMatrix; // non-cryst. symm. matrices
- CCrystContainer TVect; // translation vectors
-
- realtype as,bs,cs; // calculated 'cell parameters'
- realtype alphas,betas,gammas; // calculated 'cell parameters'
- realtype AC[6];
- realtype VolChk,VolErr;
-
- pstr syminfo_lib; // path to syminfo.lib
- CSymOps SymOps; // symmetry operations
-
- void Init ( Boolean fullInit );
- int FixSpaceGroup();
-
-};
-
-extern cpstr getOrthCodeName ( int NCode );
-
-/*
-extern void TestCryst(); // reads from 'in.cryst', writes into
- // 'out.cryst' and 'abin.cryst'
-*/
-
-#endif
-
diff --git a/mmdb/mmdb_defs.h b/mmdb/mmdb_defs.h
deleted file mode 100755
index 1d9908f..0000000
--- a/mmdb/mmdb_defs.h
+++ /dev/null
@@ -1,259 +0,0 @@
-// $Id: mmdb_defs.h,v 1.27 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 23.06.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDBF_Defs <interface>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-//
-// Definition of types, constants and important classes.
-//
-// (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-#ifndef __MMDB_Defs__
-#define __MMDB_Defs__
-
-#ifndef __MatType__
-#include "mattype_.h"
-#endif
-
-#define MMDB_MAJOR_VERSION (1)
-#define MMDB_MINOR_VERSION (25)
-#define MMDB_MICRO_VERSION (5)
-
-
-// ======================= types =================================
-
-typedef char IDCode [16]; // ID code of the entry
-typedef IDCode * PIDCode; // pointer to ID code
-typedef PIDCode & RPIDCode; // ref-ce to pointer to ID code
-typedef char Date [12]; // date DD-MMM-YYYY
-typedef char RecName [7]; // name of PDB record
-
-typedef char ChainID [10]; // chain ID
-typedef ChainID * PChainID; // pointer to chain ID
-typedef char InsCode [10]; // insertion code
-typedef char DBName [10]; // sequence database name
-typedef char DBAcCode[20]; // seq. database accession code
-typedef DBAcCode * PDBAcCode; // pointer to seq. db acc code
-typedef char DBIdCode[20]; // seq. database ident-n code
-typedef DBIdCode * PDBIdCode; // pointer to DBIdCode
-typedef char ResName [20]; // residue name
-typedef ResName * PResName; // pointer to residue name
-typedef PResName * PPResName; // ptr to vector of residue names
-typedef char HelixID [20]; // helix ID
-typedef char StrandID[20]; // strand ID
-typedef char SheetID [20]; // sheet ID
-typedef char TurnID [20]; // turn ID
-typedef char LinkRID [20]; // Refmac link ID
-
-typedef char SymGroup[100]; // group of space symmetry
-typedef realtype vect3 [3]; // vector of 3 real numbers
-typedef vect3 * pvect3;
-typedef pvect3 & rpvect3;
-typedef realtype vect4 [4]; // vector of 4 real numbers
-typedef vect3 mat33 [3]; // matrix 3x3 of real numbers
-
-typedef vect4 mat44 [4]; // matrix 4x4 of real numbers
-typedef mat44 * pmat44;
-typedef mat44 & rmat44;
-typedef pmat44 * ppmat44;
-typedef pmat44 & rpmat44;
-typedef mat33 mat633 [6]; // matrix 6x3x3 of real numbers
-
-typedef char AtomName[20]; // name of the atom
-typedef AtomName * PAtomName; // pointer to atom name
-typedef char AltLoc [20]; // alternate location indicator
-typedef AltLoc * PAltLoc; // pointer to alt loc indicator
-typedef char SegID [20]; // segment identifier
-typedef char Element [10]; // chemical element name
-typedef Element * PElement; // ptr to chemical element name
-typedef char EnergyType[10]; // energy type name
-typedef EnergyType * PEnergyType; // pointer to energy type name
-
-// do not forget update this when change the above typedefs:
-#define MaxMMDBNameLength 40
-typedef char maxMMDBName[MaxMMDBNameLength];
-
-
-// ===================== constants ===============================
-
-// ANY_RES should be used in selection functions for specifying
-// "any residue" to select
-#define ANY_RES MinInt4
-
-// PRNK_XXXXX are the print keys. PRNK_Silent supresses all print
-// inside mmdb_xxxx unless specifically ordered or catastrophic.
-// PRNK_SimRWBROOK instructs mmdb to issue, whenever possible and
-// necessary, printouts and warnings of RWBROOK (fortran) package.
-#define PRNK_Silent 0
-#define PRNK_SimRWBROOK 1
-
-// Error_XXXX may be returned by XX::ConvertPDBString() and GetCIF(..)
-// functions.
-// Error_WrongSection is returned if the string passed into function
-// does not belong to the corresponding PDB section.
-
-#define Error_NoError 0
-#define Error_Ok 0
-#define Error_WrongSection 1
-
-#define Error_WrongChainID 2
-#define Error_WrongEntryID 3
-
-// Error_SEQRES_serNum is returned by CSeqRes::ConvertPDBASCII() if
-// serial numbers of SEQRES records do not increment by 1
-#define Error_SEQRES_serNum 4
-
-// Error_SEQRES_numRes is returned by CSeqRes::ConvertPDBASCII() if
-// SEQRES records show different number of residues
-#define Error_SEQRES_numRes 5
-
-// Error_SEQRES_extraRes is returned by CSeqRes::ConvertPDBASCII() if
-// SEQRES contains more residues than specified
-#define Error_SEQRES_extraRes 6
-
-#define Error_NCSM_Unrecognized 7
-#define Error_NCSM_AlreadySet 8
-#define Error_NCSM_WrongSerial 9
-#define Error_NCSM_UnmatchIG 10
-
-#define Error_ATOM_Unrecognized 11
-#define Error_ATOM_AlreadySet 12
-#define Error_ATOM_NoResidue 13
-#define Error_ATOM_Unmatch 14
-
-#define Error_CantOpenFile 15
-#define Error_UnrecognizedInteger 16
-#define Error_WrongModelNo 17
-#define Error_DuplicatedModel 18
-#define Error_NoModel 19
-#define Error_ForeignFile 20
-#define Error_WrongEdition 21
-
-// CIF specific
-#define Error_NotACIFFile 22
-#define Error_NoData 23
-#define Error_UnrecognCIFItems 24
-#define Error_MissingCIFField 25
-#define Error_EmptyCIFLoop 26
-#define Error_UnexpEndOfCIF 27
-#define Error_MissgCIFLoopField 28
-#define Error_NotACIFStructure 29
-#define Error_NotACIFLoop 30
-#define Error_UnrecognizedReal 31
-
-#define Error_NoSheetID 32
-#define Error_WrongSheetID 33
-#define Error_WrongStrandNo 34
-
-// Error_WrongNumberOfStrands may be issued when reading
-// sheet data from CIF
-#define Error_WrongNumberOfStrands 35
-
-// Error_WrongSheetOrder may be issued when reading
-// sheet data from CIF
-#define Error_WrongSheetOrder 36
-
-// Error_HBondInconsistency may be issued when reading
-// sheet data from CIF
-#define Error_HBondInconsistency 37
-
-// Error_EmptyResidueName is issued when PDB ATOM record
-// does not have a residue name
-#define Error_EmptyResidueName 38
-
-// Error_DuplicateSeqNum is issued when PDB ATOM records
-// show the sequence number and insertion code assigned
-// to more than one residue name
-#define Error_DuplicateSeqNum 39
-
-// Error_NoLogicalName may be returned by file i/o functions
-// if the specified environmental variable for file name
-// is not found.
-#define Error_NoLogicalName 40
-
-// Error_EmptyFile may be returned at reading non-existing
-// coordinate files
-#define Error_EmptyFile 41
-
-
-// Error_CIF_EmptyRow is the event of encountering
-// an empty row in _atom_site loop. It is handled
-// internally and has no effect on API
-#define Error_CIF_EmptyRow 99999
-
-#define Error_GeneralError1 10000
-
-
-// ClassID_XXXX are used by container classes for proper
-// creating containered classes when reading from binary file.
-
-enum ClassID {
- ClassID_Template ,
- ClassID_String ,
- ClassID_ObsLine ,
- ClassID_TitleLine ,
- ClassID_CAVEAT ,
- ClassID_Compound ,
- ClassID_Source ,
- ClassID_ExpData ,
- ClassID_MdlType ,
- ClassID_Author ,
- ClassID_RevData ,
- ClassID_Supersede ,
- ClassID_Journal ,
- ClassID_Remark ,
- ClassID_DBReference,
- ClassID_SeqAdv ,
- ClassID_ModRes ,
- ClassID_Het ,
- ClassID_NCSMatrix ,
- ClassID_TVect ,
- ClassID_Helix ,
- ClassID_Turn ,
- ClassID_Link ,
- ClassID_LinkR ,
- ClassID_CisPep
-};
-
-
-// ===================== classes ===============================
-
-DefineClass(CAtom)
-DefineClass(CResidue)
-DefineClass(CChain)
-DefineClass(CModel)
-DefineClass(CMMDBManager)
-
-
-#endif
-
diff --git a/mmdb/mmdb_file.cpp b/mmdb/mmdb_file.cpp
deleted file mode 100755
index 7eaa664..0000000
--- a/mmdb/mmdb_file.cpp
+++ /dev/null
@@ -1,3060 +0,0 @@
-// $Id: mmdb_file.cpp,v 1.34 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 16.05.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_File <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CMMDBFile ( macromolecular data file class )
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-#ifndef __STRING_H
-#include "string.h"
-#endif
-
-#ifndef __STDLIB_H
-#include "stdlib.h"
-#endif
-
-#ifndef __MMDB_File__
-#include "mmdb_file.h"
-#endif
-
-#ifndef __MMDB_Atom__
-#include "mmdb_atom.h"
-#endif
-
-#ifndef __MMDB_MMCIF__
-#include "mmdb_mmcif.h"
-#endif
-
-#ifndef __MMDB_Defs__
-#include "mmdb_defs.h"
-#endif
-
-#ifndef __MMDB_CIFDefs__
-#include "mmdb_cifdefs.h"
-#endif
-
-#ifndef __MMDB_Tables__
-#include "mmdb_tables.h"
-#endif
-
-
-// ===================== CMMDBFile =======================
-
-CMMDBFile::CMMDBFile() : CUDData() {
- InitMMDBFile();
-}
-
-CMMDBFile::CMMDBFile ( RPCStream Object ) : CUDData(Object) {
- InitMMDBFile();
-}
-
-CMMDBFile::~CMMDBFile() {
- FreeFileMemory();
-}
-
-void CMMDBFile::InitMMDBFile() {
- nModels = 0;
- Model = NULL;
- nAtoms = 0;
- AtmLen = 0;
- Atom = NULL;
- CIF = NULL;
- crModel = NULL;
- crChain = NULL;
- crRes = NULL;
- lcount = 0;
- strcpy ( S,"" );
-// Flags = 0x00000000; // no special effects
- Flags = MMDBF_IgnoreElement; // done at request for default
- FType = MMDB_FILE_Undefined; // undefined file operation
- Exclude = True;
- ignoreRemarks = False; // used temporarily
- allowDuplChID = False; // used temporarily
- enforceUniqueChID = False; // used temporarily
- modelCnt = 0; // used only at reading files
-}
-
-
-void CMMDBFile::FreeCoordMemory() {
- //int i;
-
-/*
- // All atoms are kept in array Atom. Models, chains
- // and residues have only references to Atom and
- // they do not dispose Atoms when disposed themselves.
- // It is important, however, to dispose Atom at
- // still alive residues, because each atom wipes out
- // reference to itself from the corresponding residue
- // before it dies.
- if (Atom) {
- for (i=0;i<AtmLen;i++)
- if (Atom[i]) delete Atom[i];
- delete Atom;
- }
- Atom = NULL;
- AtmLen = 0;
- nAtoms = 0;
-*/
- DeleteAllModels();
- if (Model) delete[] Model;
- Model = NULL;
- nModels = 0;
-
- crModel = NULL;
- crChain = NULL;
- crRes = NULL;
-
- if (Atom) delete[] Atom;
-
- Atom = NULL;
- AtmLen = 0;
- nAtoms = 0;
-
- modelCnt = 0;
-
-}
-
-void CMMDBFile::FreeFileMemory() {
-
- FreeCoordMemory ();
- Title.FreeMemory ( False );
- Cryst.FreeMemory ();
-
- SA .FreeContainer();
- Footnote.FreeContainer();
- SB .FreeContainer();
- SC .FreeContainer();
-
- if (CIF) delete CIF;
- CIF = NULL;
-
- lcount = 0;
- S[0] = char(0);
-
-}
-
-// virtual to be served by MMDB manager classes
-void CMMDBFile::ResetManager() {
- Cryst.Reset();
-}
-
-void CMMDBFile::SetFlag ( word Flag ) {
- Flags |= Flag;
- ignoreSegID = (Flags & MMDBF_IgnoreSegID ) != 0;
- ignoreElement = (Flags & MMDBF_IgnoreElement ) != 0;
- ignoreCharge = (Flags & MMDBF_IgnoreCharge ) != 0;
- ignoreNonCoorPDBErrors = (Flags & MMDBF_IgnoreNonCoorPDBErrors ) != 0;
- ignoreUnmatch = (Flags & MMDBF_IgnoreUnmatch ) != 0;
- allowDuplChID = (Flags & MMDBF_AllowDuplChainID ) != 0;
- enforceUniqueChID = (Flags & MMDBF_EnforceUniqueChainID ) != 0;
- Cryst.processSG = (Flags & MMDBF_DoNotProcessSpaceGroup ) == 0;
- Cryst.fixSpaceGroup = (Flags & MMDBF_FixSpaceGroup ) != 0;
-}
-
-void CMMDBFile::RemoveFlag ( word Flag ) {
- Flags &= ~Flag;
- ignoreSegID = (Flags & MMDBF_IgnoreSegID ) != 0;
- ignoreElement = (Flags & MMDBF_IgnoreElement ) != 0;
- ignoreCharge = (Flags & MMDBF_IgnoreCharge ) != 0;
- ignoreNonCoorPDBErrors = (Flags & MMDBF_IgnoreNonCoorPDBErrors ) != 0;
- ignoreUnmatch = (Flags & MMDBF_IgnoreUnmatch ) != 0;
- allowDuplChID = (Flags & MMDBF_AllowDuplChainID ) != 0;
- enforceUniqueChID = (Flags & MMDBF_EnforceUniqueChainID ) != 0;
- Cryst.processSG = (Flags & MMDBF_DoNotProcessSpaceGroup ) == 0;
- Cryst.fixSpaceGroup = (Flags & MMDBF_FixSpaceGroup ) != 0;
-}
-
-
-int CMMDBFile::ReadPDBASCII1 ( cpstr PDBLFName,
- byte gzipMode ) {
-pstr FName;
- FName = getenv ( PDBLFName );
- if (FName) return ReadPDBASCII ( FName,gzipMode );
- else return Error_NoLogicalName;
-}
-
-void CMMDBFile::ReadPDBLine ( RCFile f, pstr L, int maxlen ) {
-int i;
-Boolean Done;
- do {
- f.ReadLine ( L,maxlen );
- Done = True;
- if (ignoreRemarks) {
- if (!strncasecmp(L,"REMARK",6)) Done = False;
- }
- if (Flags & MMDBF_IgnoreBlankLines) {
- i = 0;
- while (L[i] && (L[i]==' ')) i++;
- if (!L[i]) Done = False;
- }
- if ((Flags & MMDBF_IgnoreHash) && (L[0]=='#'))
- Done = False;
- } while ((!f.FileEnd()) && (!Done));
- PadSpaces ( L,80 );
-}
-
-int CMMDBFile::ReadPDBASCII ( cpstr PDBFileName,
- byte gzipMode ) {
-CFile f;
-int RC;
-
- // open the file as ASCII for reading
- // opening it in pseudo-binary mode helps reading various
- // line terminators for files coming from different platforms
- f.assign ( PDBFileName,False,False,gzipMode );
-
- if (f.reset(True)) {
-
- RC = ReadPDBASCII ( f );
- f.shut();
-
- } else {
-
- RC = Error_CantOpenFile;
- ResetManager ();
- FreeFileMemory();
- FType = MMDB_FILE_PDB;
-
- }
-
- return RC;
-
-}
-
-
-int CMMDBFile::ReadPDBASCII ( RCFile f ) {
-PCContString ContString;
-word cleanKey;
-int RC,modNum;
-Boolean fend;
-
- // remove previous data
- ResetManager ();
- FreeFileMemory();
-
- FType = MMDB_FILE_PDB;
- SetFlag ( 0 );
-
- if (f.FileEnd()) return Error_EmptyFile;
-
- lcount = 1; // line counter
-
- // read title section
- RC = 0;
- ReadPDBLine ( f,S,sizeof(S) );
- if (Flags & MMDBF_EnforceSpaces) EnforceSpaces ( S );
- do {
- if (!strncmp(S,"FTNOTE",6)) {
- ContString = new CContString(S);
- Footnote.AddData ( ContString );
- } else {
- RC = Title.ConvertPDBString(S);
- if ((RC!=Error_WrongSection) && ignoreNonCoorPDBErrors)
- RC = 0;
- if (RC) break;
- }
- fend = f.FileEnd();
- if (!fend) {
- ReadPDBLine ( f,S,sizeof(S) );
- lcount++;
- }
- } while (!fend);
-
- if (RC!=Error_WrongSection) return RC;
-
- ignoreRemarks = (Flags & MMDBF_IgnoreRemarks)!=0;
-
- // read primary structure section
- SwitchModel ( 1 );
- if (!crModel) return Error_GeneralError1;
- do {
- if (!strncmp(S,"FTNOTE",6)) {
- ContString = new CContString(S);
- Footnote.AddData ( ContString );
- } else {
- RC = crModel->ConvertPDBString ( S );
- if ((RC!=Error_WrongSection) && ignoreNonCoorPDBErrors)
- RC = 0;
- if (RC) break;
- }
- fend = f.FileEnd();
- if (!fend) {
- ReadPDBLine ( f,S,sizeof(S) );
- Title.TrimInput ( S );
- lcount++;
- }
- } while (!fend);
-
- if (RC!=Error_WrongSection) return RC;
-
- // temporary solution: the rest of file is stored
- // in the form of strings
- while (!f.FileEnd() &&
- strncmp(S,"CRYST" ,5) &&
- strncmp(S,"ORIGX" ,5) &&
- strncmp(S,"SCALE" ,5) &&
- strncmp(S,"MTRIX" ,5) &&
- strncmp(S,"TVECT" ,5) &&
- strncmp(S,"MODEL ",6) &&
- strncmp(S,"ATOM ",6) &&
- strncmp(S,"SIGATM",6) &&
- strncmp(S,"ANISOU",6) &&
- strncmp(S,"SIGUIJ",6) &&
- strncmp(S,"TER ",6) &&
- strncmp(S,"HETATM",6) &&
- strncmp(S,"ENDMDL",6)) {
- if (!strncmp(S,"LINK ",6))
- crModel->ConvertPDBString ( S );
- else if (!strncmp(S,"LINKR ",6))
- crModel->ConvertPDBString ( S );
- else if (!strncmp(S,"CISPEP",6)) {
- GetInteger ( modNum,&(S[43]),3 );
- if (modNum<=0) modNum = 1;
- if (modNum!=1) SwitchModel ( modNum );
- crModel->ConvertPDBString ( S );
- if (modNum!=1) SwitchModel ( 1 );
- } else {
- ContString = new CContString(S);
- SA.AddData ( ContString );
- }
- ReadPDBLine ( f,S,sizeof(S) );
- Title.TrimInput ( S );
- lcount++;
- }
-
- // read crystallographic information section
- do {
- RC = Cryst.ConvertPDBString ( S );
- if ((RC!=Error_WrongSection) && ignoreNonCoorPDBErrors)
- RC = 0;
- if (RC) break;
- fend = f.FileEnd();
- if (!fend) {
- ReadPDBLine ( f,S,sizeof(S) );
- Title.TrimInput ( S );
- lcount++;
- }
- } while (!fend);
-
- if (!RC) {
- RC = Cryst.ConvertPDBString ( S );
- if ((RC!=Error_WrongSection) && ignoreNonCoorPDBErrors)
- RC = Error_WrongSection;
- }
-
- Cryst.CalcCoordTransforms();
- if (Flags & MMDBF_SimRWBROOK)
- Cryst.RWBROOKReadPrintout();
-
- if (RC!=Error_WrongSection) return RC;
-
- // temporary solution: the rest of file is stored
- // in the form of strings
- while (!f.FileEnd() &&
- strncmp(S,"MODEL ",6) &&
- strncmp(S,"ATOM ",6) &&
- strncmp(S,"SIGATM",6) &&
- strncmp(S,"ANISOU",6) &&
- strncmp(S,"SIGUIJ",6) &&
- strncmp(S,"TER ",6) &&
- strncmp(S,"HETATM",6) &&
- strncmp(S,"ENDMDL",6)) {
- ContString = new CContString(S);
- SB.AddData ( ContString );
- ReadPDBLine ( f,S,sizeof(S) );
- Title.TrimInput ( S );
- lcount++;
- }
-
- if (Flags & MMDBF_NoCoordRead) return 0;
-
- // read coordinate section
- RC = 0;
- do {
- RC = ReadPDBAtom ( S );
- if (RC) break;
- fend = f.FileEnd();
- if (!fend) {
- ReadPDBLine ( f,S,sizeof(S) );
- Title.TrimInput ( S );
- lcount++;
- }
- } while (!fend);
-// if (!RC)
-// RC = ReadPDBAtom(S);
-// commented on 28.05.2004, it appears that "CHAIN_ORDER" should not
-// be enforced here
-// cleanKey = PDBCLEAN_ATNAME | PDBCLEAN_CHAIN_ORDER;
- cleanKey = 0x00000000;
- if (Flags & MMDBF_EnforceAtomNames)
- cleanKey = PDBCLEAN_ATNAME;
- if (Flags & MMDBF_AutoSerials)
- cleanKey |= PDBCLEAN_SERIAL;
-
- if (cleanKey)
- PDBCleanup ( cleanKey );
-
- if ((!f.FileEnd()) && (RC!=Error_WrongSection)) return RC;
-
- // temporary solution: the rest of file is stored
- // in the form of strings
- while (!f.FileEnd()) {
- if (strncmp(S,"END ",6)) { // END is added automatically
- ContString = new CContString(S);
- SC.AddData ( ContString );
- }
- ReadPDBLine ( f,S,sizeof(S) );
- Title.TrimInput ( S );
- lcount++;
- }
- lcount--; // last line was not read
-
- return 0;
-
-}
-
-
-int CMMDBFile::ReadCIFASCII1 ( cpstr CIFLFName, byte gzipMode ) {
-pstr FName;
- FName = getenv ( CIFLFName );
- if (FName) return ReadCIFASCII ( FName,gzipMode );
- else return Error_NoLogicalName;
-}
-
-int CMMDBFile::ReadCIFASCII ( cpstr CIFFileName, byte gzipMode ) {
-CFile f;
-int rc;
-
- // open the file as ASCII for reading
- // opening it in pseudo-binary mode helps reading various
- // line terminators for files coming from different platforms
- f.assign ( CIFFileName,False,False,gzipMode );
-
- if (f.reset(True)) {
- rc = ReadCIFASCII ( f );
- f.shut();
- } else
- rc = Error_CantOpenFile;
-
- return rc;
-
-}
-
-int CMMDBFile::ReadCIFASCII ( RCFile f ) {
-int W;
-
- // remove previous data
- ResetManager ();
- FreeFileMemory();
- FType = MMDB_FILE_CIF;
-
- SetFlag ( 0 );
-
- CIFErrorLocation[0] = char(0); // CIF reading phase
-
- lcount = 0; // line counter
- S[0] = char(0);
-
- if (f.FileEnd())
- return Error_EmptyFile;
-
- if (!CIF) CIF = new CMMCIFData();
- CIF->SetStopOnWarning ( True );
- CIF->SetPrintWarnings ( (Flags & MMDBF_PrintCIFWarnings)!=0 );
- W = CIF->ReadMMCIFData ( f,S,lcount );
-
- if (W) {
- if (W==CIFRC_NoDataLine) return Error_NotACIFFile;
- if (W & CIFW_UnrecognizedItems) return Error_UnrecognCIFItems;
- if (W & CIFW_MissingField) return Error_MissingCIFField;
- if (W & CIFW_EmptyLoop) return Error_EmptyCIFLoop;
- if (W & CIFW_UnexpectedEOF) return Error_UnexpEndOfCIF;
- if (W & CIFW_LoopFieldMissing) return Error_MissgCIFLoopField;
- if (W & CIFW_NotAStructure) return Error_NotACIFStructure;
- if (W & CIFW_NotALoop) return Error_NotACIFLoop;
- return int(W);
- }
-
- W = ReadFromCIF ( CIF );
- if (CIF) {
- delete CIF;
- CIF = NULL;
- }
-
- return W;
-
-}
-
-
-int CMMDBFile::ReadFromCIF ( PCMMCIFData CIFD ) {
-PCMMCIFLoop Loop1,Loop2;
-pstr F,FC;
-word cleanKey;
-int RC,i,l,j,n,retc;
-
- RC = Title.GetCIF ( CIFD );
-
- if (RC) {
- CIFD->Optimize();
- return RC;
- }
-
- SwitchModel ( 1 );
- if (!crModel) return Error_GeneralError1;
- RC = crModel->GetCIF ( CIFD );
- if (RC) {
- CIFD->Optimize();
- return RC;
- }
-
- RC = Cryst.GetCIF ( CIFD );
- if (RC) {
- CIFD->Optimize();
- return RC;
- }
- Cryst.CalcCoordTransforms();
- if (Flags & MMDBF_SimRWBROOK)
- Cryst.RWBROOKReadPrintout();
-
- RC = ReadCIFAtom ( CIFD );
-
- Loop1 = CIFD->GetLoop ( CIFCAT_ENTITY );
- Loop2 = CIFD->GetLoop ( CIFCAT_STRUCT_ASYM );
- if (Loop1 && Loop2) {
- // make 'Het' atoms
- l = Loop1->GetLoopLength();
- n = Loop2->GetLoopLength();
- for (i=0;i<l;i++) {
- F = Loop1->GetString ( CIFTAG_TYPE,i,retc );
- if (F && (!retc)) {
- if (!strcasecmp(F,"non-polymer")) {
- F = Loop1->GetString ( CIFTAG_ID,i,retc );
- if (F && (!retc))
- for (j=0;j<n;j++) {
- FC = Loop2->GetString ( CIFTAG_ENTITY_ID,j,retc );
- if (FC && (!retc)) {
- if (!strcasecmp(FC,F)) {
- FC = Loop2->GetString ( CIFTAG_ID,j,retc );
- if (FC && (!retc))
- MakeHetAtoms ( FC,True );
- }
- }
- }
- }
- }
- }
- }
-
- if (!RC) {
- // deleting these CIF loops here is a temporary solution
- // taken in order to avoid mess at rewriting the CIF file.
- CIFD->DeleteLoop ( CIFCAT_ATOM_SITE );
- CIFD->DeleteLoop ( CIFCAT_ATOM_SITE_ANISOTROP );
- CIFD->Optimize ();
- }
-
- cleanKey = 0x00000000;
- if (Flags & MMDBF_EnforceAtomNames)
- cleanKey = PDBCLEAN_ATNAME;
- if (Flags & MMDBF_AutoSerials)
- cleanKey |= PDBCLEAN_SERIAL;
- if (cleanKey)
- PDBCleanup ( cleanKey );
-
- return RC;
-
-}
-
-int CMMDBFile::ReadCoorFile1 ( cpstr LFName, byte gzipMode ) {
-pstr FName;
- FName = getenv ( LFName );
- if (FName) return ReadCoorFile ( FName,gzipMode );
- else return Error_NoLogicalName;
-}
-
-int CMMDBFile::ReadCoorFile ( cpstr CFName, byte gzipMode ) {
-// auto format recognition
-int kin;
-Boolean IBL;
-
- kin = isMMDBBIN ( CFName,gzipMode );
- if (kin==Error_EmptyFile)
- return Error_EmptyFile;
- if (kin<0) return Error_CantOpenFile;
-
- if (kin==0) return ReadMMDBF ( CFName,gzipMode );
-
- IBL = ((Flags & MMDBF_IgnoreBlankLines)!=0);
- if (isPDB(CFName,gzipMode,IBL)==0)
- return ReadPDBASCII ( CFName,gzipMode );
- if (isCIF(CFName,gzipMode)==0)
- return ReadCIFASCII ( CFName,gzipMode );
-
- return Error_ForeignFile;
-
-}
-
-
-int CMMDBFile::ReadCoorFile ( RCFile f ) {
-// auto format recognition
-int kin;
-Boolean IBL;
-
- kin = isMMDBBIN ( f );
- f.reset ( True );
- if (kin==Error_EmptyFile)
- return Error_EmptyFile;
- if (kin<0) return Error_CantOpenFile;
-
- if (kin==0) return ReadMMDBF ( f );
-
- IBL = ((Flags & MMDBF_IgnoreBlankLines)!=0);
- kin = isPDB ( f,IBL );
- f.reset ( True );
- if (kin==0)
- return ReadPDBASCII ( f );
-
- kin = isCIF ( f );
- f.reset ( True );
- if (kin==0)
- return ReadCIFASCII ( f );
-
- return Error_ForeignFile;
-
-}
-
-
-word CMMDBFile::PDBCleanup ( word CleanKey ) {
-// cleans coordinate part to comply with PDB standards:
-//
-// CleanKey Action
-// PDBCLEAN_ATNAME pads atom names with spaces to form 4-symbol names
-// PDBCLEAN_TER inserts TER cards in the end of each chain
-// PDBCLEAN_CHAIN generates 1-character chain ids instead of
-// those many-character
-// PDBCLEAN_CHAIN_STRONG generates 1-character chain ids starting
-// from 'A' on for all ids, including single-char
-// PDBCLEAN_ALTCODE generates 1-character alternative codes instead
-// of those many-character
-// PDBCLEAN_ALTCODE_STRONG generates 1-character alternative codes
-// from 'A' on for all codes, including
-// single-character ones
-// PDBCLEAN_SERIAL puts serial numbers in due order
-// PDBCLEAN_INDEX reorders the internal index of atoms such that
-// it follows the actual order of atoms in
-// the object hierarchy
-// PDBCLEAN_SEQNUM renumbers all residues so that they go
-// incrementally-by-one without insertion codes
-// PDBCLEAN_CHAIN_ORDER puts chains in order of atom's serial numbers
-// PDBCLEAN_SOLVENT moves solvent chains at the end of each model
-// PDBCLEAN_ELEMENT calculates PDB element names where they are not
-// found in the chemical element table
-// PDBCLEAN_ELEMENT_STRONG calculates all chemical element names
-//
-// Return codes (as bits):
-// 0 Ok
-// PDBCLEAN_CHAIN too many chains for assigning them 1-letter codes
-// PDBCLEAN_ATNAME element names were not available
-// PDBCLEAN_ALTCODE too many alternative codes encountered.
-//
-word RC;
-int i,j,k,nal,nch,nr, nch1,nch2;
-char c;
-AltLoc * altLoc;
-ChainID * chain_ID;
-char aLoc [257];
-char chnID[257];
-int model,modl;
-PPCAtom Atom1;
-PPCChain Chain1,Chain2;
-PCModel crModel0;
-PCChain crChain0;
-PCResidue crRes0;
-PCAtom atom;
-pstr chID;
-ChainID chainID;
-Boolean NewChain,Done,Solvent;
-
- RC = 0;
- if (nAtoms<=0) return RC;
-
- if (CleanKey & PDBCLEAN_ATNAME)
- for (i=0;i<nAtoms;i++)
- if (Atom[i])
- if (!Atom[i]->MakePDBAtomName()) RC |= PDBCLEAN_ATNAME;
-
- k = -1;
-
- if (CleanKey & PDBCLEAN_TER) {
- model = -1;
- crModel0 = crModel;
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- modl = Atom[i]->GetModelNum();
- chID = Atom[i]->GetChainID ();
- if (model<0) {
- model = modl;
- SwitchModel ( model );
- if (chID) strcpy ( chainID,chID );
- else chainID[0] = char(0);
- } else {
- if (model!=modl) NewChain = True;
- else if (chID) NewChain = strcmp(chID,chainID)!=0;
- else NewChain = chainID[0]!=char(0);
- if (NewChain) {
- if (k>=0) {
- if ((!Atom[k]->Ter) && (!Atom[k]->Het)) {
- // insert 'Ter' before atom in position 'i'
- PutAtom ( -(i+1),Atom[k]->serNum+1,pstr("TER"),
- Atom[k]->GetResName(),Atom[k]->GetChainID(),
- Atom[k]->GetSeqNum (),Atom[k]->GetInsCode(),
- pstr(" "),pstr(" "),pstr(" ") );
- Atom[i]->MakeTer();
- }
- }
- model = modl;
- SwitchModel ( model );
- if (chID) strcpy ( chainID,chID );
- else chainID[0] = char(0);
- }
- }
- k = i;
- }
-
- if (k>=0) {
- if ((!Atom[k]->Ter) && (!Atom[k]->Het)) { // add last TER
- i = nAtoms;
- SwitchModel ( Atom[k]->GetModelNum() );
- PutAtom ( 0,nAtoms+1,pstr("TER"),Atom[k]->GetResName(),
- Atom[k]->GetChainID(),Atom[k]->GetSeqNum(),
- Atom[k]->GetInsCode(),pstr(" "),pstr(" "),
- pstr(" ") );
- Atom[i]->MakeTer();
- }
- }
-
- crModel = crModel0;
- }
-
-
- if (CleanKey & (PDBCLEAN_CHAIN | PDBCLEAN_CHAIN_STRONG)) {
- chain_ID = new ChainID[256];
- for (i=0;i<nModels;i++)
- if (Model[i]) {
- for (j=0;j<256;j++) {
- strcpy ( chain_ID[j]," " );
- chnID[j] = char(0);
- }
- chnID[256] = char(0);
- nch = 0;
- for (j=0;j<Model[i]->nChains;j++) {
- crChain0 = Model[i]->Chain[j];
- if (crChain0) {
- if (!crChain0->chainID[0])
- strcpy ( crChain0->chainID," " );
- k = 0;
- while ((k<nch) && (strcmp(chain_ID[k],crChain0->chainID)))
- k++;
- if (k>=nch) {
- if (nch>=255) RC |= PDBCLEAN_CHAIN;
- else {
- strcpy ( chain_ID[nch],crChain0->chainID );
- if (!chain_ID[nch][1])
- chnID[nch] = chain_ID[nch][0];
- nch++;
- }
- }
- }
- }
- c = 'A';
- if (CleanKey & PDBCLEAN_CHAIN_STRONG) {
- // rename all chains through from A to Z
- for (k=0;k<nch;k++) {
- chnID[k] = c;
- c = char(int(c)+1);
- }
- } else {
- // rename only multi-character chain IDs
- for (j=0;(j<nch) && (k<256);j++) {
- k = 0;
- do {
- while ((k<nch) && (chnID[k]!=c)) k++;
- if (k<nch) c = char(int(c)+1);
- } while (k<nch);
- k = 0;
- while ((k<256) && (chnID[k])) k++;
- if (k<256) {
- chnID[k] = c;
- c = char(int(c)+1);
- }
- }
- }
- // assign new chain IDs
- for (j=0;j<Model[i]->nChains;j++) {
- crChain0 = Model[i]->Chain[j];
- if (crChain0) {
- k = 0;
- while ((k<nch) && (strcmp(chain_ID[k],crChain0->chainID)))
- k++;
- strcpy ( crChain0->prevChainID,crChain0->chainID );
- crChain0->chainID[0] = chnID[k];
- crChain0->chainID[1] = char(0);
- }
- }
- }
- delete[] chain_ID;
- }
-
-
- if (CleanKey & (PDBCLEAN_ALTCODE | PDBCLEAN_ALTCODE_STRONG)) {
- altLoc = new AltLoc[256];
- for (i=0;i<256;i++) {
- strcpy ( altLoc[i]," " );
- aLoc[i] = char(0);
- }
- aLoc[0] = ' ';
- aLoc[256] = char(0);
- nal = 1;
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- if (!Atom[i]->altLoc[0]) strcpy ( Atom[i]->altLoc," " );
- else {
- k = 0;
- while ((k<nal) && (strcmp(altLoc[k],Atom[i]->altLoc))) k++;
- if (k>=nal) {
- if (nal>=255) RC |= PDBCLEAN_ALTCODE;
- else {
- strcpy ( altLoc[nal],Atom[i]->altLoc );
- if (!altLoc[nal][1]) aLoc[nal] = altLoc[nal][0];
- nal++;
- }
- }
- }
- }
- c = 'A';
- if (CleanKey & PDBCLEAN_ALTCODE_STRONG)
- for (i=1;i<nal;i++) {
- aLoc[i] = c;
- c = char(int(c)+1);
- }
- else
- for (i=1;(i<nal) && (k<256);i++) {
- k = 0;
- do {
- while ((k<nal) && (aLoc[k]!=c)) k++;
- if (k<nal) c = char(int(c)+1);
- } while (k<nal);
- k = 0;
- while ((k<256) && (aLoc[k])) k++;
- if (k<256) {
- aLoc[k] = c;
- c = char(int(c)+1);
- }
- }
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- k = 0;
- while ((k<nal) && (strcmp(altLoc[k],Atom[i]->altLoc))) k++;
- Atom[i]->altLoc[0] = aLoc[k];
- Atom[i]->altLoc[1] = char(0);
- }
- delete[] altLoc;
- }
-
-
- if (CleanKey & PDBCLEAN_SEQNUM)
- for (i=0;i<nModels;i++) {
- crModel0 = Model[i];
- if (crModel0)
- for (j=0;j<crModel0->nChains;j++) {
- crChain0 = crModel0->Chain[j];
- if (crChain0) {
- nr = 0;
- for (k=0;k<crChain0->nResidues;k++) {
- crRes0 = crChain0->Residue[k];
- if (crRes0) {
- nr++;
- crRes0->seqNum = nr;
- crRes0->insCode[0] = char(0);
- }
- }
- }
- }
- }
-
- if (CleanKey & PDBCLEAN_SOLVENT) {
- Atom1 = new PCAtom[nAtoms];
- k = 1;
- for (i=0;i<nModels;i++)
- if (Model[i]) {
- if (Model[i]->nChains>k) k = Model[i]->nChains;
- }
- Chain1 = new PCChain[k];
- Chain2 = new PCChain[k];
- k = 0;
- for (i=0;i<nModels;i++) {
- crModel0 = Model[i];
- if (crModel0) {
- nch1 = 0;
- nch2 = 0;
- for (nch=0;nch<crModel0->nChains;nch++) {
- crChain0 = crModel0->Chain[nch];
- if (crChain0) {
- Solvent = False;
- for (nr=0;(nr<crChain0->nResidues) && (!Solvent);nr++) {
- crRes0 = crChain0->Residue[nr];
- if (crRes0)
- for (j=0;(j<nSolventNames) && (!Solvent);j++)
- Solvent = !strcmp ( StdSolventName[j],crRes0->name );
- }
- if (Solvent) Chain2[nch2++] = crChain0;
- else Chain1[nch1++] = crChain0;
- }
- }
- for (nch=0;nch<nch1;nch++) {
- crChain0 = Chain1[nch];
- for (nr=0;nr<crChain0->nResidues;nr++) {
- crRes0 = crChain0->Residue[nr];
- if (crRes0)
- for (j=0;j<crRes0->nAtoms;j++)
- if (crRes0->atom[j]) {
- Atom1[k] = crRes0->atom[j];
- Atom1[k]->index = k+1;
- k++;
- }
- }
- crModel0->Chain[nch] = Chain1[nch];
- }
- for (nch=0;nch<nch2;nch++) {
- crChain0 = Chain2[nch];
- for (nr=0;nr<crChain0->nResidues;nr++) {
- crRes0 = crChain0->Residue[nr];
- if (crRes0)
- for (j=0;j<crRes0->nAtoms;j++)
- if (crRes0->atom[j]) {
- Atom1[k] = crRes0->atom[j];
- Atom1[k]->index = k+1;
- k++;
- }
- }
- crModel0->Chain[nch1++] = Chain2[nch];
- }
- crModel0->nChains = nch1;
- }
- }
- delete[] Chain1;
- delete[] Chain2;
- if (Atom) delete[] Atom;
- Atom = Atom1;
- AtmLen = nAtoms;
- nAtoms = k;
- }
-
- if (CleanKey & (PDBCLEAN_CHAIN_ORDER | PDBCLEAN_CHAIN_ORDER_IX)) {
- for (i=0;i<nModels;i++) {
- crModel0 = Model[i];
- if (crModel0) {
- k = 0;
- for (j=0;j<crModel0->nChains;j++) {
- crChain0 = crModel0->Chain[j];
- if (crChain0) {
- crChain0->nWeights = 0;
- crChain0->Weight = 0.0;
- if (k<j) {
- crModel0->Chain[k] = crModel0->Chain[j];
- crModel0->Chain[j] = NULL;
- }
- k++;
- }
- }
- crModel0->nChains = k;
- }
- }
- if (CleanKey & PDBCLEAN_CHAIN_ORDER)
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- crChain0 = Atom[i]->GetChain();
- crChain0->nWeights++;
- crChain0->Weight += Atom[i]->serNum;
- }
- else
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- crChain0 = Atom[i]->GetChain();
- crChain0->nWeights++;
- crChain0->Weight += Atom[i]->GetIndex();
- }
- for (i=0;i<nModels;i++) {
- crModel0 = Model[i];
- if (crModel0) {
- for (j=0;j<crModel0->nChains;j++) {
- crChain0 = crModel0->Chain[j];
- if (crChain0->nWeights)
- crChain0->Weight /= crChain0->nWeights;
- }
- // bubble sorting
- do {
- Done = True;
- for (j=1;j<crModel0->nChains;j++)
- if (crModel0->Chain[j-1]->Weight >
- crModel0->Chain[j]->Weight) {
- crChain0 = crModel0->Chain[j-1];
- crModel0->Chain[j-1] = crModel0->Chain[j];
- crModel0->Chain[j] = crChain0;
- Done = False;
- }
- } while (!Done);
- }
- }
- }
-
- if (CleanKey & PDBCLEAN_INDEX) {
- k = 0;
- for (i=0;i<nModels;i++) {
- crModel0 = Model[i];
- if (crModel0) {
- for (nch=0;nch<crModel0->nChains;nch++) {
- crChain0 = crModel0->Chain[nch];
- if (crChain0) {
- for (nr=0;nr<crChain0->nResidues;nr++) {
- crRes0 = crChain0->Residue[nr];
- if (crRes0) {
- for (j=0;j<crRes0->nAtoms;j++) {
- atom = crRes0->atom[j];
- if (atom) {
- Atom[atom->index-1] = Atom[k];
- if (Atom[k])
- Atom[k]->index = atom->index;
- Atom[k] = atom;
- k++;
- atom->index = k;
- }
- }
- }
- }
- }
- }
- }
- }
- nAtoms = k;
- }
-
- if (CleanKey & PDBCLEAN_SERIAL) {
- k = 0;
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- if (k<i) {
- Atom[k] = Atom[i];
- Atom[i] = NULL;
- }
- Atom[k]->index = k+1;
- Atom[k]->serNum = Atom[k]->index;
- k++;
- }
- nAtoms = k;
- }
-
- if (CleanKey & PDBCLEAN_ELEMENT) {
- for (i=0;i<nAtoms;i++)
- if (Atom[i] && (!Atom[i]->Ter)) {
- if (getElementNo(Atom[i]->element)==ELEMENT_UNKNOWN) {
- strcpy ( Atom[i]->element," " );
- Atom[i]->MakePDBAtomName();
- }
- }
- }
-
- if (CleanKey & PDBCLEAN_ELEMENT_STRONG) {
- for (i=0;i<nAtoms;i++)
- if (Atom[i] && (!Atom[i]->Ter)) {
- strcpy ( Atom[i]->element," " );
- Atom[i]->MakePDBAtomName();
- }
- }
-
- return RC;
-
-}
-
-void CMMDBFile::MakeHetAtoms ( cpstr chainID, Boolean Make ) {
-// Makes all atoms in chain 'chainID', in all models, as 'Het' atoms
-// if Make is set True, and makes them 'ordinary' atoms otherwise.
-// 'Ter' is automatically removed when converting to 'Het' atoms,
-// and is automatically added when converting to 'ordinary' atoms.
-int i,j,k,l,n;
-PCModel crModel0;
-PCChain crChain0;
-PCResidue crRes0;
- crModel0 = crModel;
- for (i=0;i<nModels;i++)
- if (Model[i])
- for (j=0;j<Model[i]->nChains;j++) {
- crChain0 = Model[i]->Chain[j];
- if (crChain0) {
- if (!strcmp(crChain0->chainID,chainID)) {
- n = 0;
- for (k=0;k<crChain0->nResidues;k++) {
- crRes0 = crChain0->Residue[k];
- if (crRes0)
- for (l=0;l<crRes0->nAtoms;l++)
- if (crRes0->atom[l]) {
- crRes0->atom[l]->Het = Make;
- n = crRes0->atom[l]->index;
- }
- }
- if (n>0) {
- n--;
- if (Atom[n]->Het && Atom[n]->Ter) RemoveAtom ( n+1 );
- else if ((!Atom[n]->Het) && (!Atom[n]->Ter)) {
- SwitchModel ( Model[i]->GetSerNum() );
- if (n<nAtoms-1)
- PutAtom ( -(n+2),Atom[n]->serNum+1,pstr("TER"),
- Atom[n]->GetResName(),Atom[n]->GetChainID(),
- Atom[n]->GetSeqNum (),Atom[n]->GetInsCode(),
- pstr(" "),pstr(" "),pstr(" ") );
- else
- PutAtom ( 0,nAtoms+1,pstr("TER"),
- Atom[n]->GetResName(),Atom[n]->GetChainID(),
- Atom[n]->GetSeqNum (),Atom[n]->GetInsCode(),
- pstr(" "),pstr(" "),pstr(" ") );
- Atom[n+1]->MakeTer();
- }
- }
- }
- }
- }
- crModel = crModel0;
-}
-
-
-void CMMDBFile::RemoveAtom ( int index ) {
-// Removes atom at the specified index in the Atom array.
-// This index is always accessible as Atom[index]->index.
-// If this leaves a residue empty, the residue is removed.
-// If this leaves an empty chain, the chain is removed as well;
-// the same happens to the model.
-PCResidue crRes0;
-PCChain crChain0;
-PCModel crModel0;
-int i,j;
-
- if ((index>0) && (index<=nAtoms)) {
- if (Atom[index-1]) {
- crRes0 = Atom[index-1]->residue;
- if (crRes0) {
- if (crRes0->_ExcludeAtom(index)) {
- // the residue appears empty after the exclusion
- if (crRes) {
- if ((crRes->seqNum==crRes0->seqNum) &&
- (!strcmp(crRes->insCode,crRes0->insCode)))
- crRes = NULL;
- }
- crChain0 = crRes0->chain;
- if (crChain0) {
- if (crChain0->_ExcludeResidue(crRes0->name,crRes0->seqNum,
- crRes0->insCode)) {
- // the chain appears empty after the exclusion
- if (crChain) {
- if (!strcmp(crChain->chainID,crChain0->chainID))
- crChain = NULL;
- }
- crModel0 = PCModel(crChain0->model);
- if (crModel0) {
- if (crModel0->_ExcludeChain(crChain0->chainID)) {
- // the model appears ampty after the exclusion
- if (crModel) {
- if (crModel->serNum==crModel0->serNum)
- crModel = NULL;
- }
- i = crModel0->serNum-1;
- delete Model[i];
- Model[i] = NULL;
- }
- }
- delete crChain0; // it is already excluded from the hierarchy!
- }
- }
- delete crRes0; // it is already excluded from the hierarchy!
- }
- }
- delete Atom[index-1]; // it is already excluded from the hierarchy!
- Atom[index-1] = NULL;
- // now rearrange and re-index atoms.
- j = 0;
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- if (j<i) {
- Atom[j] = Atom[i];
- Atom[i] = NULL;
- }
- Atom[j]->index = j+1;
- j++;
- }
- nAtoms = j;
- }
- }
-}
-
-
-int CMMDBFile::_ExcludeModel ( int serNum ) {
-// _ExcludeModel(..) excludes (but does not dispose!) a model
-// from the file. Returns 1 if the file gets empty and 0 otherwise.
-int i,k;
-
- if (!Exclude) return 0;
-
- if ((0<serNum) && (serNum<=nModels))
- Model[serNum-1] = NULL;
-
- k = 0;
- for (i=0;i<nModels;i++)
- if (Model[i]) {
- if (k<i) {
- Model[k] = Model[i];
- Model[i] = NULL;
- }
- Model[k]->serNum = k+1;
- k++;
- }
-
- nModels = k;
-
- if (nModels<=0) return 1;
- else return 0;
-
-}
-
-
-int CMMDBFile::FinishStructEdit() {
-// Makes a new atom index after insertion or deletion of atoms.
-// This function may change atoms' positions in the index and
-// correspondingly the CAtom::index field.
-PCResidue res;
-PCChain chain;
-PCModel model;
-PPCAtom Atom1;
-int i,j,k,l,n,index,nAtoms1;
-
- // calculate new number of atoms
- nAtoms1 = 0;
- for (i=0;i<nModels;i++) {
- model = Model[i];
- if (model) {
- for (j=0;j<model->nChains;j++) {
- chain = model->Chain[j];
- if (chain) {
- for (k=0;k<chain->nResidues;k++) {
- res = chain->Residue[k];
- if (res) {
- res->TrimAtomTable();
- nAtoms1 += res->nAtoms;
- }
- }
- chain->TrimResidueTable();
- }
- }
- model->TrimChainTable();
- }
- }
- TrimModelTable();
-
- // compile a new index and null the old one
-
- if (nAtoms1>0) Atom1 = new PCAtom[nAtoms1];
- else Atom1 = NULL;
-
- n = 0;
- for (i=0;i<nModels;i++) {
- model = Model[i];
- for (j=0;j<model->nChains;j++) {
- chain = model->Chain[j];
- for (k=0;k<chain->nResidues;k++) {
- res = chain->Residue[k];
- for (l=0;l<res->nAtoms;l++) {
- Atom1[n] = res->atom[l];
- index = Atom1[n]->index;
- if ((index>0) && (index<=AtmLen))
- Atom[index-1] = NULL;
- Atom1[n]->index = n+1;
- n++;
- }
- }
- }
- }
-
-// if (n!=nAtoms1) {
-// printf ( " **** PROGRAM ERROR IN CMMDBFile::FinishStructEdit\n" );
-// exit ( 1 );
-// }
-
-
- // check if there are dead atoms in the old index
- for (i=0;i<AtmLen;i++)
- if (Atom[i]) delete Atom[i];
-
- // dispose old index and replace it with the new one
- if (Atom) delete[] Atom;
-
- Atom = Atom1;
- AtmLen = n;
- nAtoms = n;
-
- if (n==nAtoms1) return 0; // Ok
- else return 1; // not Ok; should never happen
-
-}
-
-void CMMDBFile::TrimModelTable() {
-int i,j;
- j = 0;
- for (i=0;i<nModels;i++)
- if (Model[i]) {
- if (j<i) {
- Model[j] = Model[i];
- Model[i] = NULL;
- }
- Model[j]->serNum = j+1;
- j++;
- }
- nModels = j;
-}
-
-
-int CMMDBFile::GenerateNCSMates() {
-//
-// Generates NCS mates according to NCS matrices given
-// in Cryst. This will result in generating many-character
-// chain names, composed as 'x_n' where 'x' is the original
-// name and 'n' is a unique number, which will coincide with
-// the symmetry operation (order) number. Another side
-// effect will be a disorder in atoms' serial numbers.
-// The hierarchy should therefore be cleaned after
-// generating the NCS mates. An appropriate way to do that
-// is to issue the following call:
-//
-// PDBCleanup ( PDBCLEAN_TER | PDBCLEAN_ALTCODE_STRONG |
-// PDBCLEAN_CHAIN_STRONG | PDBCLEAN_SERIAL );
-//
-PPCChain chainTable,chain;
-PCChain chn;
-mat44 ncs_m;
-ChainID chainID;
-int i,j,k,nNCSOps,nChains,iGiven;
-
- nNCSOps = Cryst.GetNumberOfNCSMatrices();
- if (nNCSOps<=0) return 1;
-
- for (i=0;i<nModels;i++)
- if (Model[i]) {
- Model[i]->GetChainTable ( chainTable,nChains );
- if (nChains>0) {
- chain = new PCChain[nChains];
- for (j=0;j<nChains;j++)
- chain[j] = chainTable[j];
- for (j=0;j<nChains;j++)
- if (chain[j]) {
- for (k=0;k<nNCSOps;k++)
- if (Cryst.GetNCSMatrix(k,ncs_m,iGiven)) {
- if (!iGiven) {
- chn = newCChain();
- chn->Copy ( chain[j] );
- sprintf ( chainID,"%s_%i",
- chain[j]->GetChainID(),k+1 );
- chn->SetChainID ( chainID );
- chn->ApplyTransform ( ncs_m );
- Model[i]->AddChain ( chn );
- }
- }
- }
- delete[] chain;
- }
- }
-
- return 0;
-
-}
-
-
-void CMMDBFile::ApplyNCSTransform ( int NCSMatrixNo ) {
-mat33 t;
-vect3 v;
-int i;
- if (!Cryst.GetNCSMatrix(NCSMatrixNo,t,v)) return;
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) Atom[i]->Transform ( t,v );
-}
-
-
-int CMMDBFile::PutPDBString ( cpstr PDBString ) {
-int RC;
-PCContString ContString;
-
- strcpy ( S,PDBString ); // maintain the buffer!
- PadSpaces ( S,80 );
- lcount++;
-
- // belongs to title?
- RC = Title.ConvertPDBString ( S );
- if (RC!=Error_WrongSection) return RC;
-
- // belongs to primary structure section?
- SwitchModel ( 1 );
- RC = crModel->ConvertPDBString ( S );
- if (RC!=Error_WrongSection) return RC;
-
- // belongs to the crystallographic information section?
- RC = Cryst.ConvertPDBString ( S );
- if (RC!=Error_WrongSection) {
-// if (RC==0) Cryst.CalcCoordTransforms();
- return RC;
- }
-
- // belongs to the coordinate section?
- RC = ReadPDBAtom ( S );
- if (RC!=Error_WrongSection) return RC;
-
- // temporary solution: the rest of file is stored
- // in the form of strings
- if ((S[0]) && (S[0]!=' ') && (strncmp(S,"END ",6))) {
- // END is added automatically
- ContString = new CContString(S);
- SC.AddData ( ContString );
- }
-
- return 0;
-
-}
-
-
-int CMMDBFile::AddPDBASCII1 ( cpstr PDBLFName, byte gzipMode ) {
-pstr FName;
- FName = getenv ( PDBLFName );
- if (FName) return AddPDBASCII ( FName,gzipMode );
- else return Error_NoLogicalName;
-}
-
-int CMMDBFile::AddPDBASCII ( cpstr PDBFileName, byte gzipMode ) {
-int RC;
-CFile f;
- // open the file as ASCII for reading
- // opening it in pseudo-binary mode helps reading various
- // line terminators for files coming from different platforms
- f.assign ( PDBFileName,False,False,gzipMode );
- if (f.reset(True)) {
- lcount = 1; // line counter
- RC = 0;
- while ((!f.FileEnd()) && (!RC)) {
- ReadPDBLine ( f,S,sizeof(S) );
- RC = PutPDBString ( S );
- }
- f.shut();
- } else
- RC = Error_CantOpenFile;
- return RC;
-}
-
-
-void CMMDBFile::GetInputBuffer ( pstr Line, int & count ) {
- if (FType==MMDB_FILE_PDB) { // PDB File
- strcpy ( Line,S );
- count = lcount;
- } else if (FType==MMDB_FILE_CIF) {
- if (!CIFErrorLocation[0]) { // CIF reading phase
- strcpy ( Line,S );
- count = lcount;
- } else {
- strcpy ( Line,CIFErrorLocation );
- count = -1; // CIF interpretation phase
- }
- } else {
- Line[0] = char(0);
- count = -2;
- }
-}
-
-
-int CMMDBFile::CrystReady() {
-// Returns flags:
-// CRRDY_Complete if crystallographic information is complete
-// CRRDY_NotPrecise if cryst. inf-n is not precise
-// CRRDY_isTranslation if cryst. inf-n contains translation
-// CRRDY_NoOrthCode no orthogonalization code
-// Fatal:
-// CRRDY_NoTransfMatrices if transform. matrices were not calculated
-// CRRDY_Unchecked if cryst. inf-n was not checked
-// CRRDY_Ambiguous if cryst. inf-n is ambiguous
-// CRRDY_NoCell if cryst. inf-n is unusable
-// CRRDY_NoSpaceGroup if space group is not set
-int k;
-
- if (!(Cryst.WhatIsSet & CSET_Transforms))
- return CRRDY_NoTransfMatrices;
-
- if ((Cryst.WhatIsSet & CSET_CellParams)!=CSET_CellParams)
- return CRRDY_NoCell;
-
- if (!(Cryst.WhatIsSet & CSET_SpaceGroup))
- return CRRDY_NoSpaceGroup;
-
- if (Cryst.CellCheck & CCHK_Unchecked)
- return CRRDY_Unchecked;
-
- if (Cryst.CellCheck & CCHK_Disagreement)
- return CRRDY_Ambiguous;
-
- k = 0x0000;
- if (Cryst.CellCheck & CCHK_Error) k |= CRRDY_NotPrecise;
- if (Cryst.CellCheck & CCHK_Translations) k |= CRRDY_isTranslation;
- if (Cryst.CellCheck & CCHK_NoOrthCode) k |= CRRDY_NoOrthCode;
-
- return k;
-
-}
-
-
-Boolean CMMDBFile::isCrystInfo() {
- return (((Cryst.WhatIsSet & CSET_CellParams)==CSET_CellParams) &&
- (Cryst.WhatIsSet & CSET_SpaceGroup));
-}
-
-Boolean CMMDBFile::isCellInfo() {
- return ((Cryst.WhatIsSet & CSET_CellParams)==CSET_CellParams);
-}
-
-Boolean CMMDBFile::isSpaceGroup() {
- return (Cryst.WhatIsSet & CSET_SpaceGroup);
-}
-
-Boolean CMMDBFile::isTransfMatrix() {
- return Cryst.areMatrices();
-}
-
-Boolean CMMDBFile::isScaleMatrix() {
- return ((Cryst.WhatIsSet & CSET_ScaleMatrix)==CSET_ScaleMatrix);
-}
-
-Boolean CMMDBFile::isNCSMatrix() {
- return Cryst.isNCSMatrix();
-}
-
-int CMMDBFile::AddNCSMatrix ( mat33 & ncs_m, vect3 & ncs_v,
- int iGiven ) {
- return Cryst.AddNCSMatrix ( ncs_m,ncs_v,iGiven );
-}
-
-int CMMDBFile::GetNumberOfNCSMatrices() {
- return Cryst.GetNumberOfNCSMatrices();
-}
-
-int CMMDBFile::GetNumberOfNCSMates() {
-// Returns the number of NCS mates not given in the file (iGiven==0)
- return Cryst.GetNumberOfNCSMates();
-}
-
-Boolean CMMDBFile::GetNCSMatrix ( int NCSMatrixNo, // 0..N-1
- mat44 & ncs_m, int & iGiven ) {
- return Cryst.GetNCSMatrix ( NCSMatrixNo,ncs_m,iGiven );
-}
-
-int CMMDBFile::ReadPDBAtom ( cpstr L ) {
-// If string L belongs to the coordinate section
-// (records ATOM, SIGATM, ANISOU, SIGUIJ, TER, HETATM),
-// the correspondent information is retrieved and
-// stored in the dynamic Atom array. In parallel, the
-// structures of Model/Chain/Residue are generated and
-// referenced to the corresponding Atom.
-// If processing of L was successful, the return is 0,
-// otherwise it returns the corresponding Error_XXX
-// code.
-// If L does not belong to the coordinate section,
-// Error_WrongSection is returned.
-int RC,index,i;
-
- if (!strncmp(L,"ATOM ",6)) {
-
- index = nAtoms+1; // index for the next atom in Atom array
- RC = CheckAtomPlace ( index,L );
- if (!RC) RC = Atom[index-1]->ConvertPDBATOM ( index,L );
-
- } else if (!strncmp(L,"SIGATM",6)) {
-
- index = nAtoms; // keep index!
- RC = CheckAtomPlace ( index,L );
- if (!RC) RC = Atom[index-1]->ConvertPDBSIGATM ( index,L );
-
- } else if (!strncmp(L,"ANISOU",6)) {
-
- index = nAtoms; // keep index
- RC = CheckAtomPlace ( index,L );
- if (!RC) RC = Atom[index-1]->ConvertPDBANISOU ( index,L );
-
- } else if (!strncmp(L,"SIGUIJ",6)) {
-
- index = nAtoms; // keep index
- RC = CheckAtomPlace ( index,L );
- if (!RC) RC = Atom[index-1]->ConvertPDBSIGUIJ ( index,L );
-
- } else if (!strncmp(L,"TER ",6)) {
-
- index = nAtoms+1; // new place in Atom array
- RC = CheckAtomPlace ( index,L );
- if (!RC) RC = Atom[index-1]->ConvertPDBTER ( index,L );
-
- } else if (!strncmp(L,"HETATM",6)) {
-
- index = nAtoms+1; // new place in Atom array
- RC = CheckAtomPlace ( index,L );
- if (!RC) RC = Atom[index-1]->ConvertPDBHETATM ( index,L );
-
- } else if (!strncmp(L,"MODEL ",6)) {
-
- modelCnt++;
- RC = SwitchModel ( L );
- for (i=0;(i<nModels) && (!RC);i++)
- if (Model[i] && (Model[i]!=crModel)) {
- if (crModel->serNum==Model[i]->serNum)
- RC = Error_DuplicatedModel;
- }
-// if (!RC) {
-// if (crModel->serNum!=modelCnt)
-// RC = Error_DuplicatedModel;
-// }
-
- } else if (!strncmp(L,"ENDMDL",6)) {
-
- crModel = NULL;
- crChain = NULL;
- crRes = NULL;
-
- RC = 0;
-
- } else
- return Error_WrongSection;
-
- return RC;
-
-}
-
-
-int CMMDBFile::ReadCIFAtom ( PCMMCIFData CIFD ) {
-PCMMCIFLoop Loop,LoopAnis;
-int RC,i,index,nATS;
-
- Loop = CIFD->GetLoop ( CIFCAT_ATOM_SITE );
- if (!Loop) return 0; // no atom coordinates in the file
-
- LoopAnis = CIFD->GetLoop ( CIFCAT_ATOM_SITE_ANISOTROP );
- nATS = Loop->GetLoopLength();
-
- for (i=1;i<=nATS;i++) {
- // nAtoms and i should always coincide at this point. This piece
- // of code was however left in order to reach identity with
- // ReadPDBAtom(..).
- index = nAtoms+1; // index for the next atom in Atom array
- RC = CheckAtomPlace ( index,Loop );
- if (!RC) RC = Atom[index-1]->GetCIF ( i,Loop,LoopAnis );
- if (RC && (RC!=Error_CIF_EmptyRow)) return RC;
- }
- if (Flags & MMDBF_AutoSerials)
- PDBCleanup ( PDBCLEAN_SERIAL );
-
- return 0;
-
-}
-
-int CMMDBFile::PutAtom ( int index,
- int serNum,
- const AtomName atomName,
- const ResName resName,
- const ChainID chainID,
- int seqNum,
- const InsCode insCode,
- const AltLoc altLoc,
- const SegID segID,
- const Element element ) {
-
-// An atom with the specified properties is put into the
-// structure. The current model is used; if no model is
-// set (crModel==NULL), one is created. Coordinates and
-// other parameters of the atom need to be set separately.
-//
-// If index is positive and there is already an atom at
-// this position in the system, the new atom will REPLACE
-// it. The corresponding residues are automatically
-// updated.
-//
-// If index is null (=0), the new atom will be put on
-// the top of the structure, i.e. it will be put into
-// (index=nAtoms+1)-th position.
-//
-// If index is negative, then the new atom is INSERTED
-// BEFORE the atom in the (-index)th position. For
-// saving the computational efforts, this WILL NOT cause
-// the recalculation of all atoms' serial numbers
-// according to their actual positions. It will be needed
-// however to put the things in order by calling
-// CMMDBFile::OrderAtoms() at a certain point, especially
-// before writing an output ASCII file. NOTE that this
-// ordering is never done automatically.
-//
-// Limitation: if PutAtom implies creating new
-// chains/residues, these are always created on the top
-// of existing chains/residues.
-
-
-int i,kndex,RC;
-
- kndex = index;
-
- if (kndex<0) { // the new atom is to be inserted
-
- kndex = -kndex;
- if (kndex>AtmLen)
- ExpandAtomArray ( kndex+1000-AtmLen );
-
- if (Atom[kndex-1]!=NULL) { // the position is occupied
-
- // expand the array if necessary
- if (nAtoms>=AtmLen)
- ExpandAtomArray ( IMax(kndex,nAtoms)+1000-AtmLen );
-
- // now shift all atoms from (kndex-1)th to the end of array.
- // note that this does not affect residues as they keep only
- // pointers on atoms
- for (i=nAtoms;i>=kndex;i--) {
- Atom[i] = Atom[i-1];
- Atom[i]->index = i+1; // this is Ok because residues keep
- // POINTERS rather than indices!
- }
- Atom[kndex-1] = NULL;
- nAtoms++;
-
- }
-
- }
-
- if (kndex==0) kndex = nAtoms+1;
-
- if (!crModel) SwitchModel ( 1 );
-
-
- RC = AllocateAtom ( kndex,chainID,chainID,resName,resName,
- seqNum,seqNum,1,insCode,True );
- if (!RC)
- Atom[kndex-1]->SetAtomName ( kndex,serNum,atomName,altLoc,
- segID,element );
- return RC;
-
-}
-
-
-int CMMDBFile::PutAtom ( int index, // same meaning as above
- PCAtom A, // pointer to completed atom
- // class
- int serNum // 0 means that the serial
- // number will be set equal
- // to "index". Otherwise,
- // the serial number is set
- // to the specified value
- ) {
-int i,kndex,RC,sn;
-
- if (!A) return -1;
-
- kndex = index;
-
- if (kndex<0) { // the new atom is to be inserted
-
- kndex = -kndex;
-
- if (kndex>AtmLen)
- ExpandAtomArray ( kndex+1000-AtmLen );
-
- if (Atom[kndex-1]!=NULL) { // the position is occupied
-
- // expand the array if necessary
- if (nAtoms>=AtmLen)
- ExpandAtomArray ( IMax(kndex,nAtoms)+1000-AtmLen );
- // now shift all atoms from (kndex-1)th to the end of array.
- // note that this does not affect residues as they keep only
- // pointers on atoms
-
- for (i=nAtoms;i>=kndex;i--) {
- Atom[i] = Atom[i-1];
- Atom[i]->index = i+1; // this is Ok because residues keep
- // POINTERS rather than indices!
- }
-
- Atom[kndex-1] = NULL;
- nAtoms++;
-
- }
-
- }
-
- if (kndex==0) kndex = nAtoms+1;
-
-
- RC = AllocateAtom ( kndex,A->GetChainID(),A->GetLabelAsymID(),
- A->GetResName(),A->GetLabelCompID(),
- A->GetSeqNum (),A->GetLabelSeqID (),
- A->GetLabelEntityID(),A->GetInsCode(),
- True );
-
- if (serNum<=0) sn = kndex;
- else sn = serNum;
- if (!RC) {
- Atom[kndex-1]->Copy ( A );
- Atom[kndex-1]->serNum = sn;
- }
-
- return RC;
-
-}
-
-int CMMDBFile::CheckInAtom ( int index, // same meaning as above
- PCAtom A // pointer to completed
- // atom class
- ) {
-int i,kndex;
-
- if (!A) return -1;
-
- kndex = index;
-
- if (kndex<0) { // the new atom is to be inserted
-
- kndex = -kndex;
-
- if (kndex>AtmLen)
- ExpandAtomArray ( kndex+1000-AtmLen );
-
- if (Atom[kndex-1]!=NULL) { // the position is occupied
-
- // expand the array if necessary
- if (nAtoms>=AtmLen)
- ExpandAtomArray ( IMax(kndex,nAtoms)+1000-AtmLen );
- // now shift all atoms from (kndex-1)th to the end of array.
- // note that this does not affect residues as they keep only
- // pointers on atoms
-
- for (i=nAtoms;i>=kndex;i--) {
- Atom[i] = Atom[i-1];
- if (Atom[i])
- Atom[i]->index = i+1; // this is Ok because residues keep
- // POINTERS rather than indices!
- }
-
- }
-
- nAtoms++;
-
- } else {
- if (kndex==0) kndex = nAtoms + 1; // add atom on the very top
- if (kndex>AtmLen) ExpandAtomArray ( kndex+1000-AtmLen );
- if (kndex>nAtoms) nAtoms = kndex;
- if (Atom[kndex-1]) delete Atom[kndex-1];
- }
-
- Atom[kndex-1] = A;
- A->index = kndex;
-
- return 0;
-
-}
-
-int CMMDBFile::CheckInAtoms ( int index, // same meaning as above
- PPCAtom A, // array of atoms to check in
- int natms // number of atoms to check in
- ) {
-PPCAtom A1;
-int i,j,k,k1,kndex;
-
- if (!A) return -1;
-
- A1 = NULL;
- kndex = index;
-
- if (kndex<0) { // the new atoms are to be inserted
-
- kndex = -kndex;
-
- if (nAtoms+natms>=AtmLen)
- ExpandAtomArray ( IMax(kndex,nAtoms)+1000+natms-AtmLen );
-
- if (kndex<nAtoms)
- A1 = new PCAtom[natms];
- k = kndex-1;
- j = 0;
- for (i=0;i<natms;i++)
- if (A[i]) {
- if (Atom[k]) A1[j++] = Atom[k];
- Atom[k] = A[i];
- Atom[k]->index = k+1;
- k++;
- }
-
- if (j>0) {
- // insert removed atoms into the gap
- nAtoms += j;
- k1 = k+j;
- for (i=nAtoms-1;i>=k1;i--) {
- Atom[i] = Atom[i-j];
- if (Atom[i])
- Atom[i]->index = i+1; // this is Ok because residues keep
- // POINTERS rather than indices!
- }
- for (i=0;i<j;i++) {
- Atom[k] = A1[i];
- Atom[k]->index = k+1;
- k++;
- }
- }
-
- delete[] A1;
-
- } else {
-
- if (kndex==0) kndex = nAtoms + 1; // add atom on the very top
- k = kndex + natms;
- if (k>AtmLen) ExpandAtomArray ( k+1000-AtmLen );
- kndex--;
- for (i=0;i<natms;i++)
- if (A[i]) {
- if (Atom[kndex]) delete Atom[kndex];
- Atom[kndex] = A[i];
- Atom[kndex]->index = kndex+1;
- kndex++;
- }
- nAtoms = IMax(nAtoms,kndex);
-
- }
-
- return 0;
-
-}
-
-
-int CMMDBFile::SwitchModel ( cpstr L ) {
-int nM;
-
- if (!GetInteger(nM,&(L[10]),4))
- return Error_UnrecognizedInteger;
-
- return SwitchModel ( nM );
-
-}
-
-int CMMDBFile::SwitchModel ( int nM ) {
-PPCModel Mdl;
-int i;
-Boolean Transfer;
-
- if (nM<=0)
- return Error_WrongModelNo;
-
- if (nM>nModels) {
- if ((nModels==1) && Model[0]) Transfer = (nAtoms<=0);
- else Transfer = False;
- Mdl = new PCModel[nM];
- for (i=0;i<nModels;i++)
- Mdl[i] = Model[i];
- for (i=nModels;i<nM;i++)
- Mdl[i] = NULL;
- if (Model) delete[] Model;
- Model = Mdl;
- nModels = nM;
- if (Transfer) {
- Model[nM-1] = Model[0];
- Model[0] = NULL;
- }
- }
-
- if (!Model[nM-1])
- Model[nM-1] = newCModel();
- Model[nM-1]->SetMMDBManager ( PCMMDBManager(this),nM );
-
- crModel = Model[nM-1];
- crChain = NULL; // new model - new chain
- crRes = NULL; // new chain - new residue
-
- return 0;
-
-}
-
-int CMMDBFile::CheckAtomPlace ( int index, cpstr L ) {
-// This function gets the residue/chain information stored
-// in PDB string L (the records should start with the
-// keywords ATOM, SIGATM, ANISOU, SIGUIJ, TER, HETATM) and
-// sets the pointers crChain and crRes to the respective.
-// chain and residue. If there is no chain/residue to place
-// the atom in, these will be created.
-// The function prepares place for the atom in the index-th
-// cell of the Atom array, expanding it as necessary. If the
-// corresponding element in the Atom array was not initialized,
-// a CAtom class is created with reference to the current
-// residue.
-// This function DOES NOT check the PDB string L for
-// atom keywords.
-ResName resName;
-int seqNum;
-ChainID chainID;
-InsCode insCode;
-
- // get the residue sequence number/ insert code
- if (!GetIntIns(seqNum,insCode,&(L[22]),4)) {
- if (strncmp(L,"TER ",6))
- return Error_UnrecognizedInteger;
- else { // we allow for empty TER card here
- seqNum = 0;
- insCode[0] = char(1); // unprintable symbol! used as
- // flag that TER card does not
- // have serial number
- insCode[1] = char(0);
- }
- }
-
- // get chain ID
- if (L[20]!=' ') {
- chainID[0] = L[20];
- chainID[1] = L[21];
- chainID[2] = char(0);
- } else if (L[21]!=' ') {
- chainID[0] = L[21];
- chainID[1] = char(0);
- } else
- chainID[0] = char(0);
-
- // get residue name
- strcpy_ncss ( resName,&(L[17]),3 );
- if ((!resName[0]) && (!strncmp(L,"TER ",6))) {
- insCode[0] = char(1);
- insCode[1] = char(0);
- }
-
- return AllocateAtom ( index ,chainID,chainID,resName,resName,
- seqNum,seqNum,1,insCode,False );
-
-}
-
-int CMMDBFile::CheckAtomPlace ( int index, PCMMCIFLoop Loop ) {
-// Version of CheckAtomPlace(..) for reading from CIF file.
-ResName resName,label_comp_id;
-int seqNum ,label_seq_id,label_entity_id,RC,k,nM;
-ChainID chainID,label_asym_id;
-InsCode insCode;
-pstr F;
-
- // Get the residue sequence number/insert code. They are
- // removed from the file after reading.
- k = index-1;
-// if (!CIFGetInteger1(seqNum,Loop,CIFTAG_LABEL_SEQ_ID,k))
- if (!CIFGetInteger1(seqNum,Loop,CIFTAG_AUTH_SEQ_ID,k))
- CIFGetString ( insCode,Loop,CIFTAG_NDB_HELIX_CLASS_PDB,k,
- sizeof(InsCode),pstr("") );
- else {
- F = Loop->GetString ( CIFTAG_GROUP_PDB,k,RC );
- if ((!F) || (RC)) return Error_CIF_EmptyRow;
- if (strcmp(F,"TER")) {
- seqNum = MinInt4; // only at reading CIF we allow this
- CIFGetString ( insCode,Loop,CIFTAG_NDB_HELIX_CLASS_PDB,k,
- sizeof(InsCode),pstr("") );
- } else { // we allow for empty TER card here
- seqNum = 0;
- insCode[0] = char(1); // unprintable symbol! used as
- // flag that TER card does not
- // have serial number
- insCode[1] = char(0);
- }
- }
-
- CIFGetInteger1 ( label_seq_id ,Loop,CIFTAG_LABEL_SEQ_ID ,k );
- CIFGetInteger1 ( label_entity_id,Loop,CIFTAG_LABEL_ENTITY_ID,k );
-
- // get chain/residue ID
- CIFGetString ( chainID,Loop,CIFTAG_AUTH_ASYM_ID,k,
- sizeof(ChainID),pstr("") );
- CIFGetString ( resName,Loop,CIFTAG_AUTH_COMP_ID,k,
- sizeof(ResName),pstr("") );
-
- CIFGetString ( label_asym_id,Loop,CIFTAG_LABEL_ASYM_ID,k,
- sizeof(ChainID),pstr("") );
- CIFGetString ( label_comp_id,Loop,CIFTAG_LABEL_COMP_ID,k,
- sizeof(ResName),pstr("") );
-
- if (!resName[0]) strcpy ( resName,label_comp_id );
-
- if (!CIFGetInteger1(nM,Loop,CIFTAG_PDBX_PDB_MODEL_NUM,k)) {
- if (crModel) {
- if (nM!=crModel->serNum) SwitchModel ( nM );
- } else
- SwitchModel ( nM );
- }
-
- return AllocateAtom ( index ,chainID,label_asym_id,resName,
- label_comp_id,seqNum,label_seq_id,
- label_entity_id,insCode,False );
-
-}
-
-
-int CMMDBFile::AllocateAtom ( int index,
- const ChainID chainID,
- const ChainID label_asym_id,
- const ResName resName,
- const ResName label_comp_id,
- int seqNum,
- int label_seq_id,
- int label_entity_id,
- const InsCode insCode,
- Boolean Replace ) {
-
- if ((!resName[0]) && (insCode[0]!=char(1)))
- return Error_EmptyResidueName;
-
- // check if there is a pointer to model
- if (!crModel) {
- // the model pointer was not set. Check if there are
- // models already defined
- if (!Model)
- SwitchModel ( 1 ); // creates a model
- else return Error_NoModel;
- }
-
- if (crChain && (insCode[0]!=char(1))) {
- // If crChain is not NULL, the model pointer was not
- // changed and we may try to keep using crChain as
- // pointer to the being-read chain. However, we must
- // check that the record still belongs to the same chain.
- // All this does not work if insCode[0] is set to 1
- // which indicates a special case of 'TER' card without
- // parameters.
- if (enforceUniqueChID) {
- // enforcing unique chain IDs should be used only in case
- // of multi-chain complexes where 1-letter chain IDs are
- // not enough to accomodate all chains. Then chains are
- // dynamically renamed like A0,A1,A2,.. etc. Therefore, we
- // check only first symbol here.
- if (chainID[0]!=crChain->chainID[0])
- crChain = NULL; // the chain has to be changed
- } else if (strcmp(chainID,crChain->chainID))
- crChain = NULL; // the chain has to be changed
- }
- if (!crChain) {
- // either the model or chain was changed -- get a new chain
- if (allowDuplChID)
- crChain = crModel->CreateChain ( chainID );
- else crChain = crModel->GetChainCreate ( chainID,
- enforceUniqueChID );
- crRes = NULL; // new chain - new residue
- }
-
- if (crRes && (insCode[0]!=char(1))) {
- // If crRes is not NULL, neither the model nor chain were
- // changed. Check if this record still belongs to the
- // same residue.
- // All this does not work if insCode[0] is set to 1
- // which indicates a special case of 'TER' card without
- // parameters.
- if ((seqNum!=crRes->seqNum) ||
- strcmp(insCode,crRes->insCode) ||
- strcmp(resName,crRes->name))
- crRes = NULL; // the residue has to be changed
- }
- if (!crRes) {
- // either the chain or residue was changed -- get a new residue
- crRes = crChain->GetResidueCreate ( resName,seqNum,insCode,
- Flags & MMDBF_IgnoreDuplSeqNum );
- if (!crRes) return Error_DuplicateSeqNum;
- }
-
- strcpy ( crRes->label_asym_id,label_asym_id );
- strcpy ( crRes->label_comp_id,label_comp_id );
- crRes->label_seq_id = label_seq_id;
- crRes->label_entity_id = label_entity_id;
-
- // now check if there is place in the Atom array
- if (index>AtmLen)
- // there is no place, expand Atom by 1000 atom places at once
- ExpandAtomArray ( index+1000-AtmLen );
- nAtoms = IMax(nAtoms,index);
-
- // delete the to-be-replaced atom if there is any
- if (Replace && Atom[index-1]) {
- delete Atom[index-1];
- Atom[index-1] = NULL;
- }
- if (!Atom[index-1]) {
- Atom[index-1] = newCAtom();
- crRes->_AddAtom ( Atom[index-1] );
- Atom[index-1]->index = index;
- }
-
- return 0;
-
-}
-
-void CMMDBFile::ExpandAtomArray ( int inc ) {
-// Expands the Atom array by adding more inc positions.
-// The length of Atom array is increased unconditionally.
-PPCAtom Atom1;
-int i;
- AtmLen += inc;
- Atom1 = new PCAtom[AtmLen];
- for (i=0;i<nAtoms;i++)
- Atom1[i] = Atom[i];
- for (i=nAtoms;i<AtmLen;i++)
- Atom1[i] = NULL;
- if (Atom) delete[] Atom;
- Atom = Atom1;
-}
-
-void CMMDBFile::AddAtomArray ( int inc ) {
-// Checks if 'inc' atoms may be added into Atom array,
-// and if not, expands the Atom array such that to
-// allocate exactly 'inc' atoms more than is currently
-// contained.
-PPCAtom Atom1;
-int i;
- if (nAtoms+inc>AtmLen) {
- AtmLen = nAtoms+inc;
- Atom1 = new PCAtom[AtmLen];
- for (i=0;i<nAtoms;i++)
- Atom1[i] = Atom[i];
- for (i=nAtoms;i<AtmLen;i++)
- Atom1[i] = NULL;
- if (Atom) delete[] Atom;
- Atom = Atom1;
- }
-}
-
-
-int CMMDBFile::WritePDBASCII1 ( cpstr PDBLFName, byte gzipMode ) {
-pstr FName;
- FName = getenv ( PDBLFName );
- if (FName) return WritePDBASCII ( FName,gzipMode );
- else return Error_NoLogicalName;
-}
-
-int CMMDBFile::WritePDBASCII ( cpstr PDBFileName, byte gzipMode ) {
-CFile f;
-
- // opening it in pseudo-text mode ensures that the line
- // endings will correspond to the system MMDB is running on
- f.assign ( PDBFileName,True,False,gzipMode );
- FType = MMDB_FILE_PDB;
-
- if (f.rewrite()) {
- WritePDBASCII ( f );
- f.shut();
- } else
- return Error_CantOpenFile;
-
- return 0;
-
-}
-
-
-void CMMDBFile::WritePDBASCII ( RCFile f ) {
-int i;
-
- FType = MMDB_FILE_PDB;
-
- Title.PDBASCIIDump ( f );
-
- i = 0;
- while (i<nModels)
- if (Model[i]) break;
- else i++;
- if (i<nModels)
- Model[i]->PDBASCIIDumpPS ( f );
-
- // output cispep records
- for (i=0;i<nModels;i++)
- if (Model[i])
- Model[i]->PDBASCIIDumpCP ( f );
-
- SA .PDBASCIIDump ( f );
- Footnote.PDBASCIIDump ( f );
- Cryst .PDBASCIIDump ( f );
- SB .PDBASCIIDump ( f );
-
- for (i=0;i<nModels;i++)
- if (Model[i])
- Model[i]->PDBASCIIDump ( f );
-
- SC.PDBASCIIDump ( f );
-
- f.WriteLine ( pstr("END") );
-
-}
-
-
-int CMMDBFile::WriteCIFASCII1 ( cpstr CIFLFName, byte gzipMode ) {
-pstr FName;
- FName = getenv ( CIFLFName );
- if (FName) return WriteCIFASCII ( FName,gzipMode );
- else return Error_NoLogicalName;
-}
-
-int CMMDBFile::WriteCIFASCII ( cpstr CIFFileName, byte gzipMode ) {
-int i;
-
- if (!CIF) CIF = new CMMCIFData();
- CIF->SetStopOnWarning ( True );
- CIF->SetPrintWarnings ( (Flags & MMDBF_PrintCIFWarnings)!=0 );
- FType = MMDB_FILE_CIF;
-
- Title.MakeCIF ( CIF );
-
- i = 0;
- while (i<nModels)
- if (Model[i]) break;
- else i++;
- if (i<nModels)
- Model[i]->MakePSCIF ( CIF );
-
- Cryst.MakeCIF ( CIF );
-
- for (i=0;i<nModels;i++)
- if (Model[i])
- Model[i]->MakeAtomCIF ( CIF );
-
- CIF->Optimize();
- CIF->WriteMMCIFData ( CIFFileName,gzipMode );
-
- return 0;
-
-}
-
-
-PCAtom CMMDBFile::GetAtomI ( int index ) {
- if (index>nAtoms) return NULL;
- if (index<1) return NULL;
- if (!Atom) return NULL;
- return Atom[index-1];
-}
-
-
-#define MMDBFLabel "**** This is MMDB binary file ****"
-#define Edition 1
-
-int CMMDBFile::ReadMMDBF1 ( cpstr MMDBLFName, byte gzipMode ) {
-pstr FName;
- FName = getenv ( MMDBLFName );
- if (FName) return ReadCoorFile ( FName,gzipMode );
- else return Error_NoLogicalName;
-}
-
-int CMMDBFile::ReadMMDBF ( cpstr MMDBFileName, byte gzipMode ) {
-CFile f;
-int rc;
-
- f.assign ( MMDBFileName,False,True,gzipMode );
- FType = MMDB_FILE_Binary;
- if (f.reset(True)) {
- rc = ReadMMDBF ( f );
- f.shut();
- } else
- rc = Error_CantOpenFile;
-
- return rc;
-
-}
-
-int CMMDBFile::ReadMMDBF ( RCFile f ) {
-char Label[100];
-byte Version;
-
- FType = MMDB_FILE_Binary;
- f.ReadFile ( Label,sizeof(MMDBFLabel) );
- if (strncmp(Label,MMDBFLabel,sizeof(MMDBFLabel)))
- return Error_ForeignFile;
-
- f.ReadByte ( &Version );
- if (Version>Edition)
- return Error_WrongEdition;
-
- read ( f );
-
- return 0;
-
-}
-
-
-int CMMDBFile::WriteMMDBF1 ( cpstr MMDBLFName, byte gzipMode ) {
-pstr FName;
- FName = getenv ( MMDBLFName );
- if (FName) return WriteMMDBF ( FName,gzipMode );
- else return Error_NoLogicalName;
-}
-
-int CMMDBFile::WriteMMDBF ( cpstr MMDBFileName, byte gzipMode ) {
-char Label[100];
-byte Version=Edition;
-CFile f;
-
- f.assign ( MMDBFileName,False,True,gzipMode );
- FType = MMDB_FILE_Binary;
- if (f.rewrite()) {
- strcpy ( Label,MMDBFLabel );
- f.WriteFile ( Label,sizeof(MMDBFLabel) );
- f.WriteByte ( &Version );
- write ( f );
- f.shut();
- } else
- return Error_CantOpenFile;
-
- return 0;
-
-}
-
-
-pstr CMMDBFile::GetEntryID() {
- return Title.idCode;
-}
-
-void CMMDBFile::SetEntryID ( const IDCode idCode ) {
- strcpy ( Title.idCode,idCode );
-}
-
-void CMMDBFile::SetSyminfoLib ( cpstr syminfo_lib ) {
- Cryst.SetSyminfoLib ( syminfo_lib );
-}
-
-pstr CMMDBFile::GetSyminfoLib() {
- return Cryst.GetSyminfoLib();
-}
-
-int CMMDBFile::SetSpaceGroup ( cpstr spGroup ) {
- return Cryst.SetSpaceGroup ( spGroup );
-}
-
-pstr CMMDBFile::GetSpaceGroup() {
- return Cryst.GetSpaceGroup();
-}
-
-pstr CMMDBFile::GetSpaceGroupFix() {
- return Cryst.GetSpaceGroupFix();
-}
-
-void CMMDBFile::GetAtomStatistics ( RSAtomStat AS ) {
-int i;
- AS.Init();
- for (i=0;i<nModels;i++)
- if (Model[i]) Model[i]->CalcAtomStatistics ( AS );
- AS.Finish();
-}
-
-void CMMDBFile::SetIgnoreSCALEi ( Boolean ignoreScalei ) {
- Cryst.ignoreScalei = ignoreScalei;
-}
-
-void CMMDBFile::SetCell ( realtype cell_a,
- realtype cell_b,
- realtype cell_c,
- realtype cell_alpha,
- realtype cell_beta,
- realtype cell_gamma,
- int OrthCode ) {
- Cryst.SetCell ( cell_a,cell_b,cell_c,cell_alpha,cell_beta,
- cell_gamma,OrthCode );
-}
-
-void CMMDBFile::PutCell ( realtype cell_a,
- realtype cell_b,
- realtype cell_c,
- realtype cell_alpha,
- realtype cell_beta,
- realtype cell_gamma,
- int OrthCode ) {
- Cryst.PutCell ( cell_a,cell_b,cell_c,cell_alpha,cell_beta,
- cell_gamma,OrthCode );
-}
-
-int CMMDBFile::GetCell ( realtype & cell_a,
- realtype & cell_b,
- realtype & cell_c,
- realtype & cell_alpha,
- realtype & cell_beta,
- realtype & cell_gamma,
- realtype & vol,
- int & OrthCode ) {
- if (Cryst.WhatIsSet & CSET_CellParams) {
- Cryst.GetCell ( cell_a,cell_b,cell_c,cell_alpha,cell_beta,
- cell_gamma,vol );
- OrthCode = Cryst.NCode + 1;
- return 1;
- } else {
- cell_a = 0.0; cell_b = 0.0; cell_c = 0.0;
- cell_alpha = 0.0; cell_beta = 0.0; cell_gamma = 0.0;
- vol = 0.0; OrthCode = 0;
- return 0;
- }
-}
-
-int CMMDBFile::GetRCell ( realtype & cell_as,
- realtype & cell_bs,
- realtype & cell_cs,
- realtype & cell_alphas,
- realtype & cell_betas,
- realtype & cell_gammas,
- realtype & vols,
- int & OrthCode ) {
- if (Cryst.WhatIsSet & CSET_CellParams) {
- Cryst.GetRCell ( cell_as,cell_bs,cell_cs,cell_alphas,cell_betas,
- cell_gammas,vols );
- OrthCode = Cryst.NCode + 1;
- return 1;
- } else {
- cell_as = 0.0; cell_bs = 0.0; cell_cs = 0.0;
- cell_alphas = 0.0; cell_betas = 0.0; cell_gammas = 0.0;
- vols = 0.0; OrthCode = 0;
- return 0;
- }
-}
-
-int CMMDBFile::GetNumberOfSymOps() {
- if (Cryst.WhatIsSet & CSET_SpaceGroup)
- return Cryst.GetNumberOfSymOps();
- else return 0;
-}
-
-pstr CMMDBFile::GetSymOp ( int Nop ) {
- return Cryst.GetSymOp ( Nop );
-}
-
-
-void CMMDBFile::GetROMatrix ( mat44 & RO ) {
- Mat4Copy ( Cryst.RO,RO );
-}
-
-int CMMDBFile::GetTMatrix ( mat44 & TMatrix, int Nop,
- int cellshift_a, int cellshift_b,
- int cellshift_c ) {
-// GetTMatrix(..) calculates and returns the coordinate transformation
-// matrix, which converts orthogonal coordinates according to
-// the symmetry operation number Nop and places them into unit cell
-// shifted by cellshift_a a's, cellshift_b b's and cellshift_c c's.
-//
-// Return 0 means everything's fine,
-// 1 there's no symmetry operation Nop defined
-// 2 fractionalizing/orthogonalizing matrices were not
-// calculated
-// 3 cell parameters were not set up.
- return Cryst.GetTMatrix ( TMatrix,Nop,cellshift_a,cellshift_b,
- cellshift_c,NULL );
-}
-
-
-int CMMDBFile::GetUCTMatrix ( mat44 & TMatrix, int Nop,
- realtype x, realtype y, realtype z,
- int cellshift_a, int cellshift_b,
- int cellshift_c ) {
-// GetUCTMatrix(..) calculates and returns the coordinate
-// transformation matrix, which converts orthogonal coordinates
-// according to the symmetry operation number Nop. Translation
-// part of the resulting matrix is being chosen such that point
-// (x,y,z) has least distance to the center of primary (333)
-// unit cell, and then it is shifted by cellshift_a a's,
-// cellshift_b b's and cellshift_c c's.
-//
-// Return 0 means everything's fine,
-// 1 there's no symmetry operation Nop defined
-// 2 fractionalizing/orthogonalizing matrices were not
-// calculated
-// 3 cell parameters were not set up.
- return Cryst.GetUCTMatrix ( TMatrix,Nop,x,y,z,
- cellshift_a,cellshift_b,cellshift_c,
- NULL );
-}
-
-
-int CMMDBFile::GetFractMatrix ( mat44 & TMatrix, int Nop,
- int cellshift_a, int cellshift_b,
- int cellshift_c ) {
-// GetFractMatrix(..) calculates and returns the coordinate
-// transformation matrix, which converts fractional coordinates
-// according to the symmetry operation number Nop and places them
-// into unit cell shifted by cellshift_a a's, cellshift_b b's and
-// cellshift_c c's.
-//
-// Return 0 means everything's fine,
-// 1 there's no symmetry operation Nop defined
-// 2 fractionalizing/orthogonalizing matrices were not
-// calculated
-// 3 cell parameters were not set up.
- return Cryst.GetFractMatrix ( TMatrix,Nop,cellshift_a,cellshift_b,
- cellshift_c,NULL );
-}
-
-int CMMDBFile::GetSymOpMatrix ( mat44 & TMatrix, int Nop ) {
-//
-// GetSymOpMatrix(..) returns the transformation matrix for
-// Nop-th symmetry operator in the space group
-//
-// Return 0 means everything's fine,
-// 1 there's no symmetry operation Nop defined
-// 2 fractionalizing/orthogonalizing matrices were not
-// calculated
-// 3 cell parameters were not set up.
-//
- return Cryst.GetSymOpMatrix ( TMatrix,Nop );
-}
-
-// ------------- User-Defined Data ------------------------
-
-int CMMDBFile::RegisterUDInteger ( int udr_type, cpstr UDDataID ) {
- return UDRegister.RegisterUDInteger ( udr_type,UDDataID );
-}
-
-int CMMDBFile::RegisterUDReal ( int udr_type, cpstr UDDataID ) {
- return UDRegister.RegisterUDReal ( udr_type,UDDataID );
-}
-
-int CMMDBFile::RegisterUDString ( int udr_type, cpstr UDDataID ) {
- return UDRegister.RegisterUDString ( udr_type,UDDataID );
-}
-
-int CMMDBFile::GetUDDHandle ( int udr_type, cpstr UDDataID ) {
- return UDRegister.GetUDDHandle ( udr_type,UDDataID );
-}
-
-
-
-// ----------------------------------------------------------
-
-int CMMDBFile::DeleteAllModels() {
-int i,k;
- Exclude = False;
- k = 0;
- for (i=0;i<nModels;i++) {
- if (Model[i]) {
- delete Model[i];
- Model[i] = NULL;
- k++;
- }
- }
- Exclude = True;
- FinishStructEdit();
- return k;
-}
-
-Boolean CMMDBFile::GetNewChainID ( int modelNo, ChainID chID,
- int length ) {
- if ((modelNo>=1) && (modelNo<=nModels)) {
- if (Model[modelNo-1])
- return Model[modelNo-1]->GetNewChainID ( chID,length );
- }
- return False;
-}
-
-// -------------------------------------------------------------
-
-PCMask CMMDBFile::GetSelMask ( int selHnd ) {
-UNUSED_ARGUMENT(selHnd);
- return NULL;
-}
-
-// -------------------------------------------------------------
-
-int CMMDBFile::GetNofExpDataRecs() {
- return Title.ExpData.Length();
-}
-
-pstr CMMDBFile::GetExpDataRec ( int recNo ) {
-PCExpData expData;
- expData = PCExpData(Title.ExpData.GetContainerClass(recNo));
- if (expData) return expData->Line;
- return NULL;
-}
-
-
-// -------------------------------------------------------------
-
-int CMMDBFile::GetNofMdlTypeRecs() {
- return Title.MdlType.Length();
-}
-
-pstr CMMDBFile::GetMdlTypeRec ( int recNo ) {
-PCMdlType mdlType;
- mdlType = PCMdlType(Title.MdlType.GetContainerClass(recNo));
- if (mdlType) return mdlType->Line;
- return NULL;
-}
-
-
-// ------------------- Stream functions ----------------------
-
-void CMMDBFile::Copy ( PCMMDBFile MMDBFile ) {
-int i;
-
- Title.Copy ( &MMDBFile->Title );
- Cryst.Copy ( &MMDBFile->Cryst );
-
- // It is important to copy atoms _before_ models,
- // residues and chains!
- Flags = MMDBFile->Flags;
- nAtoms = MMDBFile->nAtoms;
- AtmLen = nAtoms;
- if (nAtoms>0) {
- Atom = new PCAtom[AtmLen];
- for (i=0;i<nAtoms;i++)
- if (MMDBFile->Atom[i]) {
- Atom[i] = newCAtom();
- Atom[i]->Copy ( MMDBFile->Atom[i] );
- Atom[i]->index = i+1;
- // the internal atom references are installed
- // by residue classes when they are copied in
- // model->chain below
- } else
- Atom[i] = NULL;
- }
-
- nModels = MMDBFile->nModels;
- if (nModels>0) {
- Model = new PCModel[nModels];
- for (i=0;i<nModels;i++) {
- if (MMDBFile->Model[i]) {
- Model[i] = newCModel();
- Model[i]->SetMMDBManager ( PCMMDBManager(this),i+1 );
- Model[i]->_copy ( MMDBFile->Model[i] );
- } else
- Model[i] = NULL;
- }
- }
-
- SA .Copy ( &MMDBFile->SA );
- Footnote.Copy ( &MMDBFile->Footnote );
- SB .Copy ( &MMDBFile->SB );
- SC .Copy ( &MMDBFile->SC );
-
- if (MMDBFile->CIF) {
- CIF = new CMMCIFData;
- CIF->Copy ( MMDBFile->CIF );
- }
-
-}
-
-
-
-// ------- user-defined data handlers
-
-int CMMDBFile::PutUDData ( int UDDhandle, int iudd ) {
- if (UDDhandle & UDRF_HIERARCHY)
- return CUDData::putUDData ( UDDhandle,iudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CMMDBFile::PutUDData ( int UDDhandle, realtype rudd ) {
- if (UDDhandle & UDRF_HIERARCHY)
- return CUDData::putUDData ( UDDhandle,rudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CMMDBFile::PutUDData ( int UDDhandle, cpstr sudd ) {
- if (UDDhandle & UDRF_HIERARCHY)
- return CUDData::putUDData ( UDDhandle,sudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CMMDBFile::GetUDData ( int UDDhandle, int & iudd ) {
- if (UDDhandle & UDRF_HIERARCHY)
- return CUDData::getUDData ( UDDhandle,iudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CMMDBFile::GetUDData ( int UDDhandle, realtype & rudd ) {
- if (UDDhandle & UDRF_HIERARCHY)
- return CUDData::getUDData ( UDDhandle,rudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CMMDBFile::GetUDData ( int UDDhandle, pstr sudd, int maxLen ) {
- if (UDDhandle & UDRF_HIERARCHY)
- return CUDData::getUDData ( UDDhandle,sudd,maxLen );
- else return UDDATA_WrongUDRType;
-}
-
-int CMMDBFile::GetUDData ( int UDDhandle, pstr & sudd ) {
- if (UDDhandle & UDRF_HIERARCHY)
- return CUDData::getUDData ( UDDhandle,sudd );
- else return UDDATA_WrongUDRType;
-}
-
-
-pstr CMMDBFile::GetStructureTitle ( pstr & L ) {
- return Title.GetStructureTitle ( L );
-}
-
-void CMMDBFile::SetShortBinary() {
-// leaves only coordinates in binary files
-int i;
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) Atom[i]->SetShortBinary();
-}
-
-
-void CMMDBFile::write ( RCFile f ) {
-int i,k;
-byte Version=1;
-
- f.WriteByte ( &Version );
-
- CUDData::write ( f );
-
- Title .write ( f );
- Cryst .write ( f );
- UDRegister.write ( f );
- DefPath .write ( f );
-
- f.WriteWord ( &Flags );
- f.WriteInt ( &nAtoms );
- for (i=0;i<nAtoms;i++) {
- if (Atom[i]) k = 1;
- else k = 0;
- f.WriteInt ( &k );
- if (Atom[i]) Atom[i]->write ( f );
- }
-
- f.WriteInt ( &nModels );
- for (i=0;i<nModels;i++) {
- if (Model[i]) k = 1;
- else k = 0;
- f.WriteInt ( &k );
- if (Model[i]) Model[i]->write ( f );
- }
-
- SA .write ( f );
- Footnote.write ( f );
- SB .write ( f );
- SC .write ( f );
-
- StreamWrite ( f,CIF );
-
-}
-
-void CMMDBFile::read ( RCFile f ) {
-int i,k;
-byte Version;
-
- ResetManager ();
- FreeFileMemory();
-
- f.ReadByte ( &Version );
-
- CUDData::read ( f );
-
- Title .read ( f );
- Cryst .read ( f );
- UDRegister.read ( f );
- DefPath .read ( f );
-
- // It is important to read atoms before models,
- // residues and chains!
- f.ReadWord ( &Flags );
- f.ReadInt ( &nAtoms );
- AtmLen = nAtoms;
- if (nAtoms>0) {
- Atom = new PCAtom[AtmLen];
- for (i=0;i<nAtoms;i++) {
- f.ReadInt ( &k );
- if (k) {
- Atom[i] = newCAtom();
- Atom[i]->read ( f );
- // the internal atom references are installed
- // by residue classes when they are read in
- // model->chain below
- } else
- Atom[i] = NULL;
- }
- }
-
- f.ReadInt ( &nModels );
- if (nModels>0) {
- Model = new PCModel[nModels];
- for (i=0;i<nModels;i++) {
- f.ReadInt ( &k );
- if (k) {
- Model[i] = newCModel();
- Model[i]->SetMMDBManager ( PCMMDBManager(this),0 );
- Model[i]->read ( f );
- } else
- Model[i] = NULL;
- }
- }
-
- SA .read ( f );
- Footnote.read ( f );
- SB .read ( f );
- SC .read ( f );
-
- StreamRead ( f,CIF );
-
-}
-
-
-MakeStreamFunctions(CMMDBFile)
-
-
-int isMMDBBIN ( cpstr FName, byte gzipMode ) {
-CFile f;
-int rc;
-
- f.assign ( FName,False,True,gzipMode );
- if (f.reset(True)) {
- rc = isMMDBBIN ( f );
- f.shut();
- } else
- rc = -1;
-
- return rc;
-
-}
-
-int isMMDBBIN ( RCFile f ) {
-char Label[100];
-byte Version;
-
- if (f.FileEnd())
- return Error_EmptyFile;
-
- f.ReadFile ( Label,sizeof(MMDBFLabel) );
- if (strncmp(Label,MMDBFLabel,sizeof(MMDBFLabel)))
- return 1;
-
- f.ReadByte ( &Version );
-
- if (Version>Edition) return 2;
- else return 0;
-
-}
-
-
-int isPDB ( cpstr FName, byte gzipMode, Boolean IgnoreBlankLines ) {
-CFile f;
-int rc;
-
- f.assign ( FName,False,False,gzipMode );
- if (f.reset(True)) {
- // opening it in pseudo-binary mode helps reading various
- // line terminators for files coming from different platforms
- rc = isPDB ( f,IgnoreBlankLines );
- f.shut();
- } else
- rc = -1;
-
- return rc;
-
-}
-
-int isPDB ( RCFile f, Boolean IgnoreBlankLines ) {
-char S[256];
-int i;
-Boolean Done;
-
- if (f.FileEnd())
- return Error_EmptyFile;
-
- do {
- Done = True;
- f.ReadLine ( S,sizeof(S)-1 );
- if (IgnoreBlankLines) {
- i = 0;
- while (S[i] && (S[i]==' ')) i++;
- if (!S[i]) Done = False;
- }
- } while ((!f.FileEnd()) && (!Done));
-
- PadSpaces ( S,80 );
- if (!strncasecmp(S,"HEADER",6)) return 0;
- if (!strncasecmp(S,"OBSLTE",6)) return 0;
- if (!strncasecmp(S,"TITLE ",6)) return 0;
- if (!strncasecmp(S,"CAVEAT",6)) return 0;
- if (!strncasecmp(S,"COMPND",6)) return 0;
- if (!strncasecmp(S,"SOURCE",6)) return 0;
- if (!strncasecmp(S,"KEYWDS",6)) return 0;
- if (!strncasecmp(S,"EXPDTA",6)) return 0;
- if (!strncasecmp(S,"AUTHOR",6)) return 0;
- if (!strncasecmp(S,"REVDAT",6)) return 0;
- if (!strncasecmp(S,"SPRSDE",6)) return 0;
- if (!strncasecmp(S,"JRNL ",6)) return 0;
- if (!strncasecmp(S,"REMARK",6)) return 0;
- if (!strncasecmp(S,"DBREF ",6)) return 0;
- if (!strncasecmp(S,"SEQADV",6)) return 0;
- if (!strncasecmp(S,"SEQRES",6)) return 0;
- if (!strncasecmp(S,"MODRES",6)) return 0;
- if (!strncasecmp(S,"HET ",6)) return 0;
- if (!strncasecmp(S,"HETNAM",6)) return 0;
- if (!strncasecmp(S,"HETSYN",6)) return 0;
- if (!strncasecmp(S,"FORMUL",6)) return 0;
- if (!strncasecmp(S,"HELIX ",6)) return 0;
- if (!strncasecmp(S,"SHEET ",6)) return 0;
- if (!strncasecmp(S,"TURN ",6)) return 0;
- if (!strncasecmp(S,"SSBOND",6)) return 0;
- if (!strncasecmp(S,"LINK ",6)) return 0;
- if (!strncasecmp(S,"HYDBND",6)) return 0;
- if (!strncasecmp(S,"SLTBRG",6)) return 0;
- if (!strncasecmp(S,"CISPEP",6)) return 0;
- if (!strncasecmp(S,"SITE ",6)) return 0;
- if (!strncasecmp(S,"CRYST1",6)) return 0;
- if (!strncasecmp(S,"CRYST ",6)) return 0;
- if (!strncasecmp(S,"ORIGX1",6)) return 0;
- if (!strncasecmp(S,"ORIGX2",6)) return 0;
- if (!strncasecmp(S,"ORIGX3",6)) return 0;
- if (!strncasecmp(S,"SCALE1",6)) return 0;
- if (!strncasecmp(S,"SCALE2",6)) return 0;
- if (!strncasecmp(S,"SCALE3",6)) return 0;
- if (!strncasecmp(S,"MTRIX1",6)) return 0;
- if (!strncasecmp(S,"MTRIX2",6)) return 0;
- if (!strncasecmp(S,"MTRIX3",6)) return 0;
- if (!strncasecmp(S,"TVECT ",6)) return 0;
- if (!strncasecmp(S,"MODEL ",6)) return 0;
- if (!strncasecmp(S,"ATOM ",6)) return 0;
- if (!strncasecmp(S,"SIGATM",6)) return 0;
- if (!strncasecmp(S,"ANISOU",6)) return 0;
- if (!strncasecmp(S,"SIGUIJ",6)) return 0;
- if (!strncasecmp(S,"TER ",6)) return 0;
- if (!strncasecmp(S,"HETATM",6)) return 0;
- if (!strncasecmp(S,"ENDMDL",6)) return 0;
- if (!strncasecmp(S,"CONECT",6)) return 0;
- if (!strncasecmp(S,"MASTER",6)) return 0;
- if (!strncasecmp(S,"END ",6)) return 0;
- if (!strncasecmp(S,"USER ",6)) return 0;
-
- return 1;
-
-}
diff --git a/mmdb/mmdb_file.h b/mmdb/mmdb_file.h
deleted file mode 100755
index 6489fbd..0000000
--- a/mmdb/mmdb_file.h
+++ /dev/null
@@ -1,650 +0,0 @@
-// $Id: mmdb_file.h,v 1.30 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 16.05.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_File <interface>
-// ~~~~~~~~~
-// Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CMMDBFile
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-#ifndef __MMDB_File__
-#define __MMDB_File__
-
-
-#ifndef __File__
-#include "file_.h"
-#endif
-
-#ifndef __mmdb_uddata__
-#include "mmdb_uddata.h"
-#endif
-
-#ifndef __MMDB_Defs__
-#include "mmdb_defs.h"
-#endif
-
-#ifndef __MMDB_Title__
-#include "mmdb_title.h"
-#endif
-
-#ifndef __MMDB_Cryst__
-#include "mmdb_cryst.h"
-#endif
-
-#ifndef __MMDB_Chain__
-#include "mmdb_chain.h"
-#endif
-
-#ifndef __MMDB_Model__
-#include "mmdb_model.h"
-#endif
-
-
-// ======================= CMMDBFile ===========================
-
-
-// special effect flags
-
-#define MMDBF_AutoSerials 0x00000001
-#define MMDBF_NoCoordRead 0x00000002
-#define MMDBF_SimRWBROOK 0x00000004
-#define MMDBF_PrintCIFWarnings 0x00000008
-#define MMDBF_EnforceSpaces 0x00000010
-#define MMDBF_IgnoreDuplSeqNum 0x00000020
-#define MMDBF_IgnoreSegID 0x00000040
-#define MMDBF_IgnoreElement 0x00000080
-#define MMDBF_IgnoreCharge 0x00000100
-#define MMDBF_IgnoreNonCoorPDBErrors 0x00000200
-#define MMDBF_IgnoreUnmatch 0x00000400
-#define MMDBF_IgnoreBlankLines 0x00000800
-#define MMDBF_IgnoreHash 0x00001000
-#define MMDBF_IgnoreRemarks 0x00002000
-#define MMDBF_AllowDuplChainID 0x00004000
-#define MMDBF_FixSpaceGroup 0x00008000
-#define MMDBF_EnforceAtomNames 0x00010000
-#define MMDBF_EnforceUniqueChainID 0x00020000
-#define MMDBF_DoNotProcessSpaceGroup 0x00040000
-
-// MMDBF_EnforceUniqueChainID will make MMDB to rename chains on
-// reading a file such as to maintain chains uniquesness. This
-// is supposed to work only with 1-letter chain IDs and only
-// if chain names are interchanged in the file. For example,
-// if file contains a sequence of chains named
-//
-// A,B, A,B, A,B, A,B, A,B
-//
-// and this flag is set on, the resulting chain names in
-// MMDB will be:
-//
-// A,B, A0,B0, A1,B1, A2,B2, A3,B3
-//
-
-// file types:
-#define MMDB_FILE_Undefined -1
-#define MMDB_FILE_PDB 0
-#define MMDB_FILE_CIF 1
-#define MMDB_FILE_Binary 2
-
-// cleanup flags:
-#define PDBCLEAN_ATNAME 0x00000001
-#define PDBCLEAN_TER 0x00000002
-#define PDBCLEAN_CHAIN 0x00000004
-#define PDBCLEAN_CHAIN_STRONG 0x00000008
-#define PDBCLEAN_ALTCODE 0x00000010
-#define PDBCLEAN_ALTCODE_STRONG 0x00000020
-#define PDBCLEAN_SERIAL 0x00000040
-#define PDBCLEAN_SEQNUM 0x00000080
-#define PDBCLEAN_CHAIN_ORDER 0x00000100
-#define PDBCLEAN_CHAIN_ORDER_IX 0x00000200
-#define PDBCLEAN_SOLVENT 0x00000400
-#define PDBCLEAN_INDEX 0x00000800
-#define PDBCLEAN_ELEMENT 0x00001000
-#define PDBCLEAN_ELEMENT_STRONG 0x00002000
-
-
-// crystallographic info inquery
-#define CRRDY_NotPrecise 0x00000001
-#define CRRDY_isTranslation 0x00000002
-#define CRRDY_NoOrthCode 0x00000004
-
-#define CRRDY_Complete 0
-#define CRRDY_NoTransfMatrices -1
-#define CRRDY_Unchecked -2
-#define CRRDY_Ambiguous -3
-#define CRRDY_NoCell -4
-#define CRRDY_NoSpaceGroup -5
-
-
-DefineClass(CMMDBFile)
-DefineStreamFunctions(CMMDBFile)
-
-class CMMDBFile : public CUDData {
-
- friend class CModel;
- friend class CChain;
- friend class CResidue;
- friend class CAtom;
- friend class CChannel;
-
- public :
-
- CMMDBFile ();
- CMMDBFile ( RPCStream Object );
- ~CMMDBFile();
-
- void FreeFileMemory();
-
-
- // --------------- Reading/Writing external files ---------
-
- void SetFlag ( word Flag );
- void RemoveFlag ( word Flag );
-
- int ReadPDBASCII ( cpstr PDBFileName,
- byte gzipMode=GZM_CHECK );
- int ReadPDBASCII1 ( cpstr PDBLFName,
- byte gzipMode=GZM_CHECK );
- int ReadPDBASCII ( RCFile f );
-
- int ReadCIFASCII ( cpstr CIFFileName,
- byte gzipMode=GZM_CHECK );
- int ReadCIFASCII1 ( cpstr CIFLFName,
- byte gzipMode=GZM_CHECK );
- int ReadCIFASCII ( RCFile f );
- int ReadFromCIF ( PCMMCIFData CIFD );
-
- // adds info from PDB file
- int AddPDBASCII1 ( cpstr PDBLFName,
- byte gzipMode=GZM_CHECK );
- int AddPDBASCII ( cpstr PDBFileName,
- byte gzipMode=GZM_CHECK );
-
- // auto format recognition
- int ReadCoorFile ( cpstr LFName,
- byte gzipMode=GZM_CHECK );
- int ReadCoorFile1 ( cpstr CFName,
- byte gzipMode=GZM_CHECK );
- int ReadCoorFile ( RCFile f );
-
- int WritePDBASCII ( cpstr PDBFileName,
- byte gzipMode=GZM_CHECK );
- int WritePDBASCII1 ( cpstr PDBLFName,
- byte gzipMode=GZM_CHECK );
- void WritePDBASCII ( RCFile f );
-
- int WriteCIFASCII ( cpstr CIFFileName,
- byte gzipMode=GZM_CHECK );
- int WriteCIFASCII1 ( cpstr CIFLFName,
- byte gzipMode=GZM_CHECK );
-
- int ReadMMDBF ( cpstr MMDBFileName,
- byte gzipMode=GZM_CHECK );
- int ReadMMDBF1 ( cpstr MMDBLFName,
- byte gzipMode=GZM_CHECK );
- int ReadMMDBF ( RCFile f );
- int WriteMMDBF ( cpstr MMDBFileName,
- byte gzipMode=GZM_CHECK );
- int WriteMMDBF1 ( cpstr MMDBLFName,
- byte gzipMode=GZM_CHECK );
-
- void GetInputBuffer ( pstr Line, int & count );
-
- // PutPDBString adds a PDB-keyworded string
- // to the existing structure. Note that the string
- // is namely added meaning that it will be the
- // last REMARK, last JRNL, last ATOM etc. string
- // -- always the last one in its group.
- int PutPDBString ( cpstr PDBString );
-
-
-
- // PDBCleanup(..) cleans coordinate part to comply with PDB
- // standards and MMDB "expectations":
- //
- // PDBCLEAN_ATNAME pads atom names with spaces to form
- // 4-symbol names
- // PDBCLEAN_TER inserts TER cards in the end of each chain
- // PDBCLEAN_CHAIN generates 1-character chain ids instead of
- // those many-character
- // PDBCLEAN_CHAIN_STRONG generates 1-character chain ids starting
- // from 'A' on for all ids, including the
- // single-character ones
- // PDBCLEAN_ALTCODE generates 1-character alternative codes
- // instead of many-character ones
- // PDBCLEAN_ALTCODE_STRONG generates 1-character alternative codes
- // from 'A' on for all codes, including the
- // single-character ones
- // PDBCLEAN_SERIAL puts serial numbers in due order
- // PDBCLEAN_SEQNUM renumbers all residues so that they go
- // incrementally-by-one without insertion codes
- // PDBCLEAN_CHAIN_ORDER puts chains in order of atom's serial
- // numbers
- // PDBCLEAN_CHAIN_ORDER_IX puts chains in order of atom's
- // indices internal to MMDB
- // PDBCLEAN_SOLVENT moves solvent chains at the end of each model
- //
- // Return codes (as bits):
- // 0 Ok
- // PDBCLEAN_CHAIN too many chains for assigning them
- // 1-letter codes
- // PDBCLEAN_ATNAME element names were not available
- // PDBCLEAN_ALTCODE too many alternative codes encountered.
- //
- word PDBCleanup ( word CleanKey );
-
- // Makes all atoms in chain 'chainID', in all models, as
- // 'Het' atoms if Make is set True, and makes them 'ordinary'
- // atoms otherwise. 'Ter' is automatically removed when
- // converting to 'Het' atoms, and is automatically added
- // when converting to 'ordinary' atoms. This may cause
- // disorder in serial numbers -- just call
- // PDBClean(PDBCLEAN_SERIAL) when necessary to fix this.
- void MakeHetAtoms ( cpstr chainID, Boolean Make );
-
- // --------------- Working with atoms by serial numbers ---
-
- PPCAtom GetAtomArray () { return Atom; }
- int GetAtomArrayLength() { return AtmLen; } // strictly not for
- // use in applications!!
- PCAtom GetAtomI ( int index ); // returns Atom[index-1]
-
- // PutAtom(..) puts atom with the specified properties
- // into the structure. The current model is used; if no model
- // is set (crModel==NULL), one is created. Coordinates and
- // other parameters of the atom need to be set separately.
- // The place, at which the atom is put, is determined by
- // index. If index is positive, then it points onto (index-1)th
- // element of the Atom array (the index counts 1,2,... and
- // generally coincides with the atom's serial number). If
- // there is already an atom at this position in the system,
- // the new atom will REPLACE it. The corresponding residues
- // are automatically updated.
- // If index is null (=0), the new atom will be put on
- // the top of the structure, i.e. it will be put into
- // (index=nAtoms+1)-th position.
- // If index is negative, then the new atom is INSERTED
- // BEFORE the atom in the (-index)th position. For saving
- // the computational efforts, this WILL NOT cause the
- // recalculation of all atoms' serial numbers according
- // to their actual positions. It will be needed, however,
- // for putting the things in order at a certain point,
- // especially before writing an output ASCII file. NOTE
- // that this ordering is never done automatically.
- // In a correct PDB file the serial number (serNum) is always
- // equal to its position (index). However here we allow them
- // to be different for easing the management of relations,
- // particularly the connectivity.
- //
- // Limitation: if PutAtom implies creating new
- // chains/residues, these are always created on the top
- // of existing chains/residues.
- int PutAtom ( int index,
- int serNum,
- const AtomName atomName,
- const ResName resName,
- const ChainID chainID,
- int seqNum,
- const InsCode insCode,
- const AltLoc altLoc,
- const SegID segID,
- const Element element );
-
- int PutAtom (
- int index, // same meaning as above
- PCAtom A, // pointer to completed atom class
- int serNum=0 // 0 means that the serial number
- // will be set equal to index.
- // Otherwise the serial number
- // is set to the specified
- // value
- );
-
-
- // RemoveAtom(..) removes atom at the specified index
- // in the Atom array. This index is always accessible
- // as Atom[index]->index. If this leaves a residue empty,
- // the residue is removed. If this leaves an empty chain,
- // the chain is removed as well; the same happens to the
- // model.
- void RemoveAtom ( int index );
-
- int FinishStructEdit();
-
- void TrimModelTable();
-
- // ---------------- Deleting models -----------------------
-
- int DeleteAllModels ();
- Boolean GetNewChainID ( int modelNo, ChainID chID, int length=1 );
-
- // --------------- Enquiring -------------------------------
-
- int CrystReady();
- // Returns flags:
- // CRRDY_Complete if crystallographic information is complete
- // CRRDY_NotPrecise if cryst. inf-n is not precise
- // CRRDY_isTranslation if cryst. inf-n contains translation
- // CRRDY_NoOrthCode no orthogonalization code
- // Fatal:
- // CRRDY_NoTransfMatrices if transform. matrices were not
- // calculated
- // CRRDY_Unchecked if cryst. inf-n was not checked
- // CRRDY_Ambiguous if cryst. inf-n is ambiguous
- // CRRDY_NoCell if cryst. inf-n is unusable
- // CRRDY_NoSpaceGroup if space group is not set
-
-
- Boolean isCrystInfo (); // cell parameters and space group
- Boolean isCellInfo (); // cell param-s a,b,c, alpha,beta,gamma
- Boolean isSpaceGroup (); // space group on CRYST1 card
- Boolean isTransfMatrix(); // orthogonalizing/fractionalizing
- // matrices
- Boolean isScaleMatrix (); // SCALEx PDB records
- Boolean isNCSMatrix (); // MTRIXx PDB records
- int GetNumberOfNCSMatrices();
- int GetNumberOfNCSMates (); // Returns the number of
- // NCS mates not given in
- // the file (iGiven==0)
- Boolean GetNCSMatrix ( int NCSMatrixNo, // 0..N-1
- mat44 & ncs_m, int & iGiven );
-
- int GetNumberOfSymOps (); // number of symmetry operations
- pstr GetSymOp ( int Nop ); // XYZ symmetry operation name
-
-
- // ------------- User-Defined Data ------------------------
-
- int RegisterUDInteger ( int udr_type, cpstr UDDataID );
- int RegisterUDReal ( int udr_type, cpstr UDDataID );
- int RegisterUDString ( int udr_type, cpstr UDDataID );
- int GetUDDHandle ( int udr_type, cpstr UDDataID );
-
- // ----------------------------------------------------------
-
- void SetSyminfoLib ( cpstr syminfo_lib );
- pstr GetSyminfoLib ();
- int SetSpaceGroup ( cpstr spGroup );
- pstr GetSpaceGroup ();
- pstr GetSpaceGroupFix();
-
- void GetAtomStatistics ( RSAtomStat AS );
-
- void SetIgnoreSCALEi ( Boolean ignoreScalei );
-
- // SetCell(..) is for changing cell parameters
- void SetCell ( realtype cell_a,
- realtype cell_b,
- realtype cell_c,
- realtype cell_alpha,
- realtype cell_beta,
- realtype cell_gamma,
- int OrthCode=0 );
-
- // PutCell(..) is for setting cell parameters
- void PutCell ( realtype cell_a,
- realtype cell_b,
- realtype cell_c,
- realtype cell_alpha,
- realtype cell_beta,
- realtype cell_gamma,
- int OrthCode=0 );
-
- int GetCell ( realtype & cell_a,
- realtype & cell_b,
- realtype & cell_c,
- realtype & cell_alpha,
- realtype & cell_beta,
- realtype & cell_gamma,
- realtype & vol,
- int & OrthCode );
-
- int GetRCell ( realtype & cell_as,
- realtype & cell_bs,
- realtype & cell_cs,
- realtype & cell_alphas,
- realtype & cell_betas,
- realtype & cell_gammas,
- realtype & vols,
- int & OrthCode );
-
- void GetROMatrix ( mat44 & RO );
-
- // GetTMatrix(..) calculates and returns the coordinate
- // transformation matrix, which converts orthogonal coordinates
- // according to the symmetry operation number Nop and places
- // them into unit cell shifted by cellshift_a a's, cellshift_b
- // b's and cellshift_c c's.
- //
- // Return 0 means everything's fine,
- // 1 there's no symmetry operation Nop defined
- // 2 fractionalizing/orthogonalizing matrices were not
- // calculated
- // 3 cell parameters were not set up.
- int GetTMatrix ( mat44 & TMatrix, int Nop,
- int cellshift_a, int cellshift_b,
- int cellshift_c );
-
- // GetUCTMatrix(..) calculates and returns the coordinate
- // transformation matrix, which converts orthogonal coordinates
- // according to the symmetry operation number Nop. Translation
- // part of the matrix is being chosen such that point (x,y,z)
- // has least distance to the center of primary (333) unit cell,
- // and then it is shifted by cellshift_a a's, cellshift_b b's and
- // cellshift_c c's.
- //
- // Return 0 means everything's fine,
- // 1 there's no symmetry operation Nop defined
- // 2 fractionalizing/orthogonalizing matrices were not
- // calculated
- // 3 cell parameters were not set up.
- int GetUCTMatrix ( mat44 & TMatrix, int Nop,
- realtype x, realtype y, realtype z,
- int cellshift_a, int cellshift_b,
- int cellshift_c );
-
- // GetFractMatrix(..) calculates and returns the coordinate
- // transformation matrix, which converts fractional coordinates
- // according to the symmetry operation number Nop and places them
- // into unit cell shifted by cellshift_a a's, cellshift_b b's
- // and cellshift_c c's.
- //
- // Return 0 means everything's fine,
- // 1 there's no symmetry operation Nop defined
- // 2 fractionalizing/orthogonalizing matrices were not
- // calculated
- // 3 cell parameters were not set up.
- int GetFractMatrix ( mat44 & TMatrix, int Nop,
- int cellshift_a, int cellshift_b,
- int cellshift_c );
-
-
- // GetSymOpMatrix(..) returns the transformation matrix for
- // Nop-th symmetry operator in the space group
- //
- // Return 0 means everything's fine,
- // 1 there's no symmetry operation Nop defined
- // 2 fractionalizing/orthogonalizing matrices were not
- // calculated
- // 3 cell parameters were not set up.
- //
- int GetSymOpMatrix ( mat44 & TMatrix, int Nop );
-
-
- int AddNCSMatrix ( mat33 & ncs_m, vect3 & ncs_v, int iGiven );
- int GenerateNCSMates(); // 1: no NCS matrices, 0: Ok
-
- pstr GetEntryID ();
- void SetEntryID ( const IDCode idCode );
-
- int GetNofExpDataRecs();
- pstr GetExpDataRec ( int recNo ); // 0.. on
-
- int GetNofMdlTypeRecs();
- pstr GetMdlTypeRec ( int recNo ); // 0.. on
-
- int GetFileType() { return FType; }
-
- void Copy ( PCMMDBFile MMDBFile );
-
- void SetShortBinary(); // leaves only coordinates in binary files
-
- // ------- user-defined data handlers
- int PutUDData ( int UDDhandle, int iudd );
- int PutUDData ( int UDDhandle, realtype rudd );
- int PutUDData ( int UDDhandle, cpstr sudd );
-
- int GetUDData ( int UDDhandle, int & iudd );
- int GetUDData ( int UDDhandle, realtype & rudd );
- int GetUDData ( int UDDhandle, pstr sudd, int maxLen );
- int GetUDData ( int UDDhandle, pstr & sudd );
-
- // GetStructureTitle() returns the contents of TITLE record
- // unfolded into single line. If Title is missing, returns
- // contents of COMPND(:MOLECULE). If COMPND is missing, returns
- // HEADER. If Header is missing, returns PDB code. If no PDB
- // code is there, returns "Not available".
- pstr GetStructureTitle ( pstr & L );
-
- protected :
-
- word Flags; // special effect flags
- int FType; // type of last file operation:
- // -1 : none
- // 0 : PDB
- // 1 : CIF
- // 2 : BIN
- // encoded as MMDB_FILE_XXXXX above
-
- CMMDBTitle Title; // title section
- CMMDBCryst Cryst; // crystallographic information section
- CUDRegister UDRegister; // register of user-defined data
-
- int nModels; // number of models
- PPCModel Model; // array of models [0..nModels-1]
-
- int nAtoms; // number of atoms
- int AtmLen; // length of Atom array
- PPCAtom Atom; // array of atoms ordered by serial numbers
-
- CAtomPath DefPath; // default coordinate path
-
- CClassContainer SA; // string container for unrecognized strings
- // which are between the title and the
- // crystallographic sections
- CClassContainer Footnote; // string container for footnotes
- CClassContainer SB; // string container for unrecognized strings
- // which are between the crystallographic and
- // the coordinate sections
- CClassContainer SC; // string container for unrecognized strings
- // following the coordinate section
-
- // input buffer
- int lcount; // input line counter
- char S[500]; // read buffer
- PCMMCIFData CIF; // CIF file manager
-
- PCModel crModel; // current model, used at reading a PDB file
- PCChain crChain; // current chain, used at reading a PDB file
- PCResidue crRes; // current residue, used at reading a PDB file
-
- Boolean Exclude; // used internally
- Boolean ignoreRemarks; // used temporarily
- Boolean allowDuplChID; // used temporarily
- Boolean enforceUniqueChID; // used temporarily
-
- void InitMMDBFile ();
- void FreeCoordMemory ();
- void ReadPDBLine ( RCFile f, pstr L, int maxlen );
- int ReadPDBAtom ( cpstr L );
- int ReadCIFAtom ( PCMMCIFData CIFD );
- int CheckAtomPlace ( int index, cpstr L );
- int CheckAtomPlace ( int index, PCMMCIFLoop Loop );
- int SwitchModel ( cpstr L );
- int SwitchModel ( int nM );
- int AllocateAtom ( int index,
- const ChainID chainID,
- const ChainID label_asym_id,
- const ResName resName,
- const ResName label_comp_id,
- int seqNum,
- int label_seq_id,
- int label_entity_id,
- const InsCode insCode,
- Boolean Replace );
- void ExpandAtomArray ( int inc );
- void AddAtomArray ( int inc );
-
- void ApplyNCSTransform ( int NCSMatrixNo );
-
- virtual void ResetManager();
-
- // --------------- Stream I/O -----------------------------
- void write ( RCFile f );
- void read ( RCFile f );
-
- // don't use _ExcludeModel in your applications!
- int _ExcludeModel ( int serNum );
-
- int CheckInAtom ( int index, PCAtom A );
- int CheckInAtoms ( int index, PPCAtom A, int natms );
-
- virtual PCMask GetSelMask ( int selHnd );
-
- private :
- int modelCnt; // used only at reading files
-
-};
-
-
-
-// isMMDBBIN will return
-// -1 if file FName does not exist
-// 0 if file FName is likely a MMDB BIN (binary) file
-// 1 if file FName is not a MMDB BIN (binary) file
-// 2 if file FName is likely a MMDB BIN (binary) file,
-// but of a wrong edition (i.e. produced by a lower
-// version of MMDB).
-extern int isMMDBBIN ( cpstr FName, byte gzipMode=GZM_CHECK );
-extern int isMMDBBIN ( RCFile f );
-
-// isPDB will return
-// -1 if file FName does not exist
-// 0 if file FName is likely a PDB file
-// 1 if file FName is not a PDB file
-extern int isPDB ( cpstr FName, byte gzipMode=GZM_CHECK,
- Boolean IgnoreBlankLines=False );
-extern int isPDB ( RCFile f, Boolean IgnoreBlankLines=False );
-
-#endif
-
diff --git a/mmdb/mmdb_graph.cpp b/mmdb/mmdb_graph.cpp
deleted file mode 100755
index d598dbf..0000000
--- a/mmdb/mmdb_graph.cpp
+++ /dev/null
@@ -1,2460 +0,0 @@
-// $Id: mmdb_graph.cpp,v 1.25 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 22.05.12 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : mmdb_graph <implementation>
-// ~~~~~~~~~
-// **** Classes : CVertex ( graph vertex )
-// ~~~~~~~~~ CEdge ( graph edge )
-// CGraph ( structural graph )
-// CMatch ( match of structural graphs )
-// CGraphMatch ( CSIA algorithms for graph matching )
-//
-// (C) E. Krissinel 2000-2012
-//
-// When used, please cite:
-//
-// Krissinel, E. and Henrick, K. (2004)
-// Common subgraph isomorphism detection by backtracking search.
-// Software - Practice and Experience, 34, 591-607.
-//
-// =================================================================
-//
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __MMDB_Graph__
-#include "mmdb_graph.h"
-#endif
-
-#ifndef __MMDB_Tables__
-#include "mmdb_tables.h"
-#endif
-
-
-// ========================== CVertex ============================
-
-CVertex::CVertex() : CStream() {
- InitVertex();
-}
-
-CVertex::CVertex ( RPCStream Object ) : CStream(Object) {
- InitVertex();
-}
-
-CVertex::CVertex ( cpstr chem_elem )
- : CStream() {
- InitVertex();
- SetVertex ( chem_elem );
-}
-
-CVertex::CVertex ( int vtype )
- : CStream() {
- InitVertex();
- SetVertex ( vtype );
-}
-
-CVertex::CVertex ( int vtype, cpstr vname )
- : CStream() {
- InitVertex();
- SetVertex ( vtype,vname );
-}
-
-CVertex::CVertex ( cpstr chem_elem, cpstr vname )
- : CStream() {
- InitVertex ();
- SetVertex ( chem_elem );
- CreateCopy ( name,vname );
-}
-
-CVertex::~CVertex() {
- if (name) delete[] name;
-}
-
-void CVertex::InitVertex() {
- name = NULL;
- type = 0;
- type_ext = 0;
- property = 0;
- id = 0;
- user_id = 0;
-}
-
-
-void CVertex::SetVertex ( cpstr chem_elem ) {
-// This function generates vertex type according to a chemical
-// element name passed in chem_elem.
-//
-// The element type has the following meaning:
-//
-// 0xCHSSTTTT
-//
-// where
-// T - resreved for elemenmt type
-// S - resreved for symmetry relief
-// H - reserved for hydrogen bonds
-// C - resreved for chirality flags
-//
-// Note that when more than 2 symbols are used for chemical element
-// name (custom use), fields S may be reallocated for element type
-// and then symmetry relief becomes impossible.
-//
- CreateCopy ( name,chem_elem );
- type = getElementNo ( chem_elem );
- if (type==ELEMENT_UNKNOWN) {
- type = 0;
- if (name[0]) {
- type = (int)name[0];
- if (name[1]) {
- type = type*256+(int)name[1];
- if (name[2]) type = type*256+(int)name[2];
- }
- }
- type += nElementNames;
- }
-}
-
-void CVertex::SetVertex ( int vtype ) {
-// This function sets vertex type. See comments above for
-// the general rule for vertex types implied by this code.
-char N[50];
-int type0;
- type = vtype;
- type0 = vtype & TYPE_MASK;
- if ((type0>=1) && (type0<=nElementNames))
- CreateCopy ( name,ElementName[type0-1] );
- else {
- sprintf ( N,"%i",type );
- CreateCopy ( name,N );
- }
-}
-
-void CVertex::SetType ( int vtype ) {
- type = vtype;
-}
-
-void CVertex::SetTypeExt ( int typeExt ) {
- type_ext = typeExt;
-}
-
-void CVertex::SetVertex ( int vtype, cpstr vname ) {
- type = vtype;
- CreateCopy ( name,vname );
-}
-
-void CVertex::SetName ( cpstr vname ) {
- CreateCopy ( name,vname );
-}
-
-void CVertex::SetID ( int vid ) {
- id = vid;
-}
-
-void CVertex::SetProperty ( int vprop ) {
- property = vprop;
-}
-
-int CVertex::GetNBonds() {
- return ((type & HYDROGEN_BOND) >> 24);
-}
-
-void CVertex::AddBond() {
-int nb = GetNBonds()+1;
- type &= ~HYDROGEN_BOND;
- type |= nb << 24;
-}
-
-void CVertex::CopyNBonds ( PCVertex V ) {
-int nb = V->GetNBonds();
- type &= ~HYDROGEN_BOND;
- type |= nb << 24;
-}
-
-void CVertex::RemoveChirality() {
- type &= CHIRAL_MASK;
-}
-
-void CVertex::LeaveChirality ( int eltype ) {
-// leaves chirality only on specified elements
-int vtype;
- vtype = type & CHIRAL_MASK;
- if (vtype!=eltype) type = vtype;
-}
-
-void CVertex::SaveType() {
- user_id = type;
-}
-
-void CVertex::RestoreType() {
- type = user_id;
-}
-
-void CVertex::CopyType ( PCVertex V ) {
- type = V->type;
-}
-
-
-void CVertex::Print ( int PKey ) {
- if (PKey!=0)
- printf ( " name type" );
- else printf ( " %10s %5i",name,type );
-}
-
-void CVertex::Copy ( PCVertex V ) {
- CreateCopy ( name,V->name );
- type = V->type;
- type_ext = V->type_ext;
- property = V->property;
- id = V->id;
- user_id = V->user_id;
-}
-
-void CVertex::write ( RCFile f ) {
-int Version=2;
- f.WriteInt ( &Version );
- f.CreateWrite ( name );
- f.WriteInt ( &type );
- f.WriteInt ( &property );
- f.WriteInt ( &id );
- f.WriteInt ( &user_id );
- f.WriteInt ( &type_ext );
-}
-
-void CVertex::read ( RCFile f ) {
-int Version;
- f.ReadInt ( &Version );
- f.CreateRead ( name );
- f.ReadInt ( &type );
- f.ReadInt ( &property );
- f.ReadInt ( &id );
- f.ReadInt ( &user_id );
- if (Version>1) f.ReadInt ( &type_ext );
- else type_ext = 0;
-}
-
-void CVertex::mem_write ( pstr S, int & l ) {
-byte Version=2;
- ::mem_write_byte ( Version,S,l );
- ::mem_write ( name ,S,l );
- ::mem_write ( type ,S,l );
- ::mem_write ( property,S,l );
- ::mem_write ( id ,S,l );
- ::mem_write ( user_id ,S,l );
- ::mem_write ( type_ext,S,l );
-}
-
-void CVertex::mem_read ( cpstr S, int & l ) {
-byte Version;
- ::mem_read_byte ( Version,S,l );
- ::mem_read ( name ,S,l );
- ::mem_read ( type ,S,l );
- ::mem_read ( property,S,l );
- ::mem_read ( id ,S,l );
- ::mem_read ( user_id ,S,l );
- ::mem_read ( type_ext,S,l );
-}
-
-MakeStreamFunctions(CVertex);
-
-
-
-// =========================== CEdge =============================
-
-CEdge::CEdge() : CStream() {
- InitEdge();
-}
-
-CEdge::CEdge ( RPCStream Object ) : CStream(Object) {
- InitEdge();
-}
-
-CEdge::CEdge ( int vx1, int vx2, int btype ) {
- InitEdge();
- SetEdge ( vx1,vx2,btype );
-}
-
-CEdge::~CEdge() {}
-
-void CEdge::InitEdge() {
- v1 = 0;
- v2 = 0;
- type = 0;
- property = 0;
-}
-
-
-#define NofBondTypes 4
-
-static pstr BondType[NofBondTypes+1] = {
- pstr("SING"), pstr("DOUB"), pstr("AROM"), pstr("TRIP"),
- pstr("") // should be here for safety
-};
-
-
-void CEdge::SetEdge ( int vx1, int vx2, cpstr btype ) {
- v1 = vx1;
- v2 = vx2;
- type = 0;
- while (type<NofBondTypes)
- if (!strncasecmp(btype,BondType[type],4)) break;
- else type++;
- if (type>=NofBondTypes) {
- type = 0;
- if (btype[0]) type = (int)btype[0];
- if (btype[1]) type = type*16+(int)btype[1];
- if (btype[2]) type = type*16+(int)btype[2];
- type += NofBondTypes;
- }
- type++;
-}
-
-void CEdge::SetEdge ( int vx1, int vx2, int btype ) {
- v1 = vx1;
- v2 = vx2;
- type = btype;
-}
-
-void CEdge::SetType ( int btype ) {
- type = btype;
-}
-
-void CEdge::SetProperty ( int eprop ) {
- property = eprop;
-}
-
-void CEdge::SaveType() {
- property = type;
-}
-
-void CEdge::RestoreType() {
- type = property;
-}
-
-void CEdge::Print ( int PKey ) {
- if (PKey!=0)
- printf ( " v1 v2 type" );
- else printf ( " %5i %5i %5i",v1,v2,type );
-}
-
-void CEdge::Copy ( PCEdge G ) {
- v1 = G->v1;
- v2 = G->v2;
- type = G->type;
- property = G->property;
-}
-
-void CEdge::write ( RCFile f ) {
-int Version=1;
- f.WriteInt ( &Version );
- f.WriteInt ( &v1 );
- f.WriteInt ( &v2 );
- f.WriteInt ( &type );
- f.WriteInt ( &property );
-}
-
-void CEdge::read ( RCFile f ) {
-int Version;
- f.ReadInt ( &Version );
- f.ReadInt ( &v1 );
- f.ReadInt ( &v2 );
- f.ReadInt ( &type );
- f.ReadInt ( &property );
-}
-
-void CEdge::mem_write ( pstr S, int & l ) {
-byte Version=1;
- ::mem_write_byte ( Version,S,l );
- ::mem_write ( v1 ,S,l );
- ::mem_write ( v2 ,S,l );
- ::mem_write ( type ,S,l );
- ::mem_write ( property,S,l );
-}
-
-void CEdge::mem_read ( cpstr S, int & l ) {
-byte Version;
- ::mem_read_byte ( Version,S,l );
- ::mem_read ( v1 ,S,l );
- ::mem_read ( v2 ,S,l );
- ::mem_read ( type ,S,l );
- ::mem_read ( property,S,l );
-}
-
-
-MakeStreamFunctions(CEdge);
-
-
-
-// ========================== CGraph ============================
-
-CGraph::CGraph() : CStream() {
- InitGraph();
-}
-
-CGraph::CGraph ( PCResidue R, cpstr altLoc ) : CStream() {
- InitGraph();
- MakeGraph ( R,altLoc );
-}
-
-CGraph::CGraph ( RPCStream Object ) : CStream(Object) {
- InitGraph();
-}
-
-CGraph::~CGraph() {
- FreeMemory();
-}
-
-void CGraph::InitGraph() {
- nVAlloc = 0;
- nEAlloc = 0;
- nGAlloc = 0;
- nVertices = 0;
- nEdges = 0;
- nAllVertices = 0;
- nAllEdges = 0;
- Vertex = NULL;
- Edge = NULL;
- graph = NULL;
- name = NULL;
- CreateCopy ( name,pstr("UNNAMED") );
-}
-
-void CGraph::FreeMemory() {
-int i;
-
- if (Vertex) {
- for (i=0;i<nVAlloc;i++)
- if (Vertex[i])
- delete Vertex[i];
- delete[] Vertex;
- }
- nVAlloc = 0;
- nVertices = 0;
- nAllVertices = 0;
- Vertex = NULL;
-
- if (Edge) {
- for (i=0;i<nEAlloc;i++)
- if (Edge[i])
- delete Edge[i];
- delete[] Edge;
- }
- nEAlloc = 0;
- nEdges = 0;
- nAllEdges = 0;
- Edge = NULL;
-
- FreeMatrixMemory ( graph,nGAlloc,1,1 );
- nGAlloc = 0;
-
- if (name) delete[] name;
- name = NULL;
-
-}
-
-void CGraph::Reset() {
- FreeMemory();
- CreateCopy ( name,pstr("UNNAMED") );
-}
-
-void CGraph::SetName ( cpstr gname ) {
- CreateCopy ( name,gname );
-}
-
-
-static int AllocPortion = 100;
-
-void SetGraphAllocPortion ( int alloc_portion ) {
- AllocPortion = alloc_portion;
-}
-
-void CGraph::AddVertex ( PCVertex V ) {
-int i;
-PCVertex * V1;
-
- if (nAllVertices>=nVAlloc) {
- nVAlloc += AllocPortion;
- V1 = new PCVertex[nVAlloc];
- for (i=0;i<nAllVertices;i++)
- V1[i] = Vertex[i];
- for (i=nAllVertices;i<nVAlloc;i++)
- V1[i] = NULL;
- if (Vertex) delete[] Vertex;
- Vertex = V1;
- }
- if (Vertex[nAllVertices])
- delete Vertex[nAllVertices];
- Vertex[nAllVertices] = V;
- nAllVertices++;
- nVertices = nAllVertices;
-
-}
-
-void CGraph::SetVertices ( PPCVertex V, int vlen ) {
- if (nVAlloc>0) FreeMemory();
- Vertex = V;
- nVertices = vlen;
- nAllVertices = vlen;
- nVAlloc = vlen;
-}
-
-int CGraph::GetVertexID ( int vertexNo ) {
- if ((vertexNo>0) && (vertexNo<=nAllVertices))
- return Vertex[vertexNo-1]->GetID();
- else return MinInt4;
-}
-
-int CGraph::GetNBondedVertices ( int vertexNo ) {
- if ((vertexNo>0) && (vertexNo<=nAllVertices)) {
- if (Vertex[vertexNo-1])
- return Vertex[vertexNo-1]->GetNBonds();
- }
- return 0;
-}
-
-int CGraph::GetBondedVertexID ( int vertexNo, int bond_vx_type,
- int bondNo ) {
-int i,k, v1,v2;
- if ((vertexNo>0) && (vertexNo<=nAllVertices)) {
- if (Vertex[vertexNo-1]) {
- if (Vertex[vertexNo-1]->GetNBonds()>=bondNo) {
- k = 0;
- for (i=0;(i<nAllEdges) && (!k);i++)
- if (Edge[i]) {
- v1 = Edge[i]->v1;
- v2 = Edge[i]->v2;
- if ((v1==vertexNo) &&
- ((Vertex[v2-1]->type & TYPE_MASK)==bond_vx_type) &&
- (Vertex[v2-1]->GetNBonds()==bondNo))
- k = v2;
- if ((v2==vertexNo) &&
- ((Vertex[v1-1]->type & TYPE_MASK)==bond_vx_type) &&
- (Vertex[v2-1]->GetNBonds()==bondNo))
- k = v1;
- }
- if (k) return Vertex[k-1]->GetID();
- }
- }
- }
- return MinInt4;
-}
-
-PCVertex CGraph::GetVertex ( int vertexNo ) {
- if ((vertexNo>0) && (vertexNo<=nAllVertices))
- return Vertex[vertexNo-1];
- else return NULL;
-}
-
-int CGraph::GetVertexNo ( cpstr vname ) {
-int i,k;
- k = 0;
- if (vname)
- for (i=0;(i<nAllVertices) && (!k);i++)
- if (!strcmp(vname,Vertex[i]->name))
- k = i+1;
- return k;
-}
-
-PCEdge CGraph::GetEdge ( int edgeNo ) {
- if ((edgeNo>0) && (edgeNo<=nAllEdges))
- return Edge[edgeNo-1];
- else return NULL;
-}
-
-void CGraph::AddEdge ( PCEdge G ) {
-int i;
-PPCEdge G1;
-
- if (nAllEdges>=nEAlloc) {
- nEAlloc += AllocPortion;
- G1 = new PCEdge[nEAlloc];
- for (i=0;i<nAllEdges;i++)
- G1[i] = Edge[i];
- for (i=nAllEdges;i<nEAlloc;i++)
- G1[i] = NULL;
- if (Edge) delete[] Edge;
- Edge = G1;
- }
- if (Edge[nAllEdges])
- delete Edge[nAllEdges];
- Edge[nAllEdges] = G;
- nAllEdges++;
- nEdges = nAllEdges;
-
-}
-
-void CGraph::SetEdges ( PPCEdge G, int glen ) {
- if (nEAlloc>0) FreeMemory();
- Edge = G;
- nEdges = glen;
- nAllEdges = glen;
- nEAlloc = glen;
-}
-
-void CGraph::GetVertices ( PPCVertex & V, int & nV ) {
- V = Vertex;
- nV = nVertices;
-}
-
-void CGraph::GetEdges ( PPCEdge & E, int & nE ) {
- E = Edge;
- nE = nEdges;
-}
-
-
-int CGraph::MakeGraph ( PCResidue R, cpstr altLoc ) {
-int i,j, a1,a2,e1,e2, nAltLocs,alflag, rc;
-Boolean B;
-rvector occupancy;
-AltLoc aLoc;
-PAltLoc aL;
-realtype dx,dy,dz, sr;
-PCEdge G;
-
- rc = MKGRAPH_Ok;
- // reset graph
- FreeMemory();
-
- occupancy = NULL;
- aL = NULL;
- R->GetAltLocations ( nAltLocs,aL,occupancy,alflag );
- if (nAltLocs<=0) return MKGRAPH_NoAtoms;
-
- if (altLoc) strcpy ( aLoc,altLoc );
- else aLoc[0] = char(0);
- if (nAltLocs<=1) {
- // Only one alt code is there, check if it is what was ordered
- if (strcmp(aLoc,aL[0])) {
- rc = MKGRAPH_ChangedAltLoc;
- strcpy ( aLoc,aL[0] );
- }
- } else if ((alflag & ALF_Mess) ||
- ((alflag & ALF_NoEmptyAltLoc) && (!aLoc[0]))) {
- // There is a mess in the residue alt codes, or empty alt code
- // does not designate a conformation but ordered. In this
- // situation build graph for maximal-occupancy conformation
- // and store its altLoc in aLoc.
- rc = MKGRAPH_MaxOccupancy;
- dx = -2.0;
- for (i=0;i<nAltLocs;i++)
- if ((aL[i][0]) && (occupancy[i]>dx)) {
- dx = occupancy[i];
- strcpy ( aLoc,aL[i] );
- }
- }
-
- SetName ( R->name );
-
- nVAlloc = R->nAtoms; // upper estimate for vertices to allocate
- if (nVAlloc<=0) {
- if (aL) delete[] aL;
- FreeVectorMemory ( occupancy,0 );
- return MKGRAPH_NoAtoms;
- }
-
- // allocate vertex array
- Vertex = new PCVertex[nVAlloc];
- for (i=0;i<nVAlloc;i++)
- Vertex[i] = NULL;
-
- // make vertices
- for (i=0;i<R->nAtoms;i++)
- if (R->atom[i]) {
- if (!R->atom[i]->Ter) {
- if (nAltLocs>1) {
- // This is a many-altcode residue. aLoc contains the altcode
- // that has to be included. Check on it:
- B = !strcmp(aLoc,R->atom[i]->altLoc);
- if ((!B) && (!R->atom[i]->altLoc[0])) {
- // We got a non-aLoc code that is an "empty-altcode".
- // Check if this atom has the altcode that we need.
- for (j=i+1;(j<R->nAtoms) && (!B);j++)
- if (R->atom[j]) {
- if ((!R->atom[j]->Ter) &&
- (!strcmp(R->atom[j]->name,R->atom[i]->name)))
- B = !strcmp(aLoc,R->atom[j]->altLoc);
- }
- // if altcode=aLoc is not there for the atom (B is set
- // False) then we take its "empty-code" location
- B = !B;
- }
- } else
- B = True;
- if (B) {
- Vertex[nVertices] = new CVertex ( R->atom[i]->element,
- R->atom[i]->name );
- Vertex[nVertices]->id = nVertices;
- Vertex[nVertices]->user_id = i;
- nVertices++;
- }
- }
- }
-
- if (nVertices<=0) {
- if (aL) delete[] aL;
- FreeVectorMemory ( occupancy,0 );
- return MKGRAPH_NoAtoms;
- }
-
- // make edges
- nEAlloc = 3*nVertices;
- Edge = new PCEdge[nEAlloc];
- for (i=0;i<nEAlloc;i++)
- Edge[i] = NULL;
-
- for (i=0;i<nVertices;i++) {
- a1 = Vertex[i]->user_id;
- e1 = Vertex[i]->type;
- if (e1>nElementNames) e1 = 6;
- e1--;
- for (j=i+1;j<nVertices;j++) {
- a2 = Vertex[j]->user_id;
- e2 = Vertex[j]->type;
- if (e2>nElementNames) e2 = 6;
- e2--;
- dx = R->atom[a2]->x - R->atom[a1]->x;
- dy = R->atom[a2]->y - R->atom[a1]->y;
- dz = R->atom[a2]->z - R->atom[a1]->z;
-// sr = CovalentRadius[e1] + CovalentRadius[e2] + 0.15;
- sr = CovalentRadius[e1] + CovalentRadius[e2] + 0.25;
- if (dx*dx+dy*dy+dz*dz<sr*sr) { // it's a bond
- G = new CEdge(i+1,j+1,1);
- AddEdge ( G );
- }
- }
- Vertex[i]->id = i+1;
- }
-
- if (aL) delete[] aL;
- FreeVectorMemory ( occupancy,0 );
-
- nAllVertices = nVertices;
- nAllEdges = nEdges;
-
- return rc;
-
-}
-
-int CGraph::MakeGraph ( PPCAtom atom, int nAtoms ) {
-PCEdge G;
-char atomID[100];
-realtype dx,dy,dz, sr;
-int i,j, a1,a2,e1,e2, rc;
-
- rc = MKGRAPH_Ok;
- // reset graph
- FreeMemory();
-
- nVAlloc = nAtoms; // upper estimate for vertices to allocate
- if (nVAlloc<=0) return MKGRAPH_NoAtoms;
-
- // allocate vertex array
- Vertex = new PCVertex[nVAlloc];
- for (i=0;i<nVAlloc;i++)
- Vertex[i] = NULL;
-
- // make vertices
- for (i=0;i<nAtoms;i++)
- if (atom[i]) {
- if (!atom[i]->Ter) {
- Vertex[nVertices] = new CVertex ( atom[i]->element,
- atom[i]->GetAtomIDfmt(atomID) );
- Vertex[nVertices]->user_id = i;
- nVertices++;
- }
- }
-
- if (nVertices<=0) {
- FreeMemory();
- return MKGRAPH_NoAtoms;
- }
-
- // make edges
- nEAlloc = 3*nVertices; // just an inital guess
- Edge = new PCEdge[nEAlloc];
- for (i=0;i<nEAlloc;i++)
- Edge[i] = NULL;
-
- for (i=0;i<nVertices;i++) {
- a1 = Vertex[i]->user_id;
- e1 = Vertex[i]->type;
- if (e1>nElementNames) e1 = 6;
- e1--;
- for (j=i+1;j<nVertices;j++) {
- a2 = Vertex[j]->user_id;
- e2 = Vertex[j]->type;
- if (e2>nElementNames) e2 = 6;
- e2--;
- dx = atom[a2]->x - atom[a1]->x;
- dy = atom[a2]->y - atom[a1]->y;
- dz = atom[a2]->z - atom[a1]->z;
- sr = CovalentRadius[e1] + CovalentRadius[e2] + 0.25;
- if (dx*dx+dy*dy+dz*dz<sr*sr) { // it's a bond
- G = new CEdge(i+1,j+1,1); // don't guess on bond order here
- AddEdge ( G );
- }
- }
- Vertex[i]->id = i+1;
- }
-
- nAllVertices = nVertices;
- nAllEdges = nEdges;
-
- return rc;
-
-}
-
-
-void CGraph::MakeVertexIDs() {
-int i;
- for (i=0;i<nAllVertices;i++)
- Vertex[i]->id = i+1;
-}
-
-void CGraph::HideType ( int bond_vx_type ) {
-// 1. Moves vertices bond_vx_type to the end of vertex array
-// 2. Moves edges to bond_vx_type vertices to the end of edge array
-// 3. Saves lengths of full vertex and edge arrays, and redefines
-// lengths to initial parts of the arrays not containing
-// bond_vx_type vertices.
-PPCEdge Edge1;
-PPCVertex Vertex1;
-int i,k,v1,v2, nEdges1,nVertices1;
-ivector iv;
-
- Edge1 = new PCEdge[nEdges];
- Vertex1 = new PCVertex[nVertices];
- GetVectorMemory ( iv,nVertices,1 );
-
- for (i=0;i<nEdges;i++)
- if (Edge[i]) {
- v1 = Edge[i]->v1-1;
- v2 = Edge[i]->v2-1;
- if (Vertex[v1] && Vertex[v2]) {
- if ((Vertex[v1]->type & TYPE_MASK)==bond_vx_type) {
- Vertex[v2]->AddBond();
- Vertex[v1]->CopyNBonds ( Vertex[v2] );
- }
- if ((Vertex[v2]->type & TYPE_MASK)==bond_vx_type) {
- Vertex[v1]->AddBond();
- Vertex[v2]->CopyNBonds ( Vertex[v1] );
- }
- }
- }
-
- nVertices1 = 0;
- for (i=0;i<nVertices;i++)
- if (Vertex[i]) {
- if ((Vertex[i]->type & TYPE_MASK)!=bond_vx_type) {
- Vertex1[nVertices1++] = Vertex[i];
- iv[i+1] = nVertices1;
- }
- }
- k = nVertices1;
- for (i=0;i<nVertices;i++)
- if (Vertex[i]) {
- if ((Vertex[i]->type & TYPE_MASK)==bond_vx_type) {
- Vertex1[k++] = Vertex[i];
- iv[i+1] = k;
- }
- }
-
- nEdges1 = 0;
- for (i=0;i<nEdges;i++)
- if (Edge[i]) {
- Edge[i]->v1 = iv[Edge[i]->v1];
- Edge[i]->v2 = iv[Edge[i]->v2];
- if (((Vertex1[Edge[i]->v1-1]->type & TYPE_MASK)!=bond_vx_type) &&
- ((Vertex1[Edge[i]->v2-1]->type & TYPE_MASK)!=bond_vx_type))
- Edge1[nEdges1++] = Edge[i];
- }
- k = nEdges1;
- for (i=0;i<nEdges;i++)
- if (Edge[i]) {
- if (((Vertex1[Edge[i]->v1-1]->type & TYPE_MASK)==bond_vx_type) ||
- ((Vertex1[Edge[i]->v2-1]->type & TYPE_MASK)==bond_vx_type))
- Edge1[k++] = Edge[i];
- }
-
- nAllVertices = nVertices;
- nAllEdges = nEdges;
- nVAlloc = nVertices;
- nEAlloc = nEdges;
- nVertices = nVertices1;
- nEdges = nEdges1;
-
- if (Vertex) delete[] Vertex;
- if (Edge) delete[] Edge;
- FreeVectorMemory ( iv,1 );
-
- Vertex = Vertex1;
- Edge = Edge1;
-
-}
-
-void CGraph::ExcludeType ( int type ) {
-int i,k;
-ivector iv;
- GetVectorMemory ( iv,nAllVertices,1 );
- k = 0;
- for (i=0;i<nAllVertices;i++)
- if ((Vertex[i]->type & TYPE_MASK)!=type) {
- if (k<i) {
- Vertex[k] = Vertex[i];
- Vertex[i] = NULL;
- }
- k++;
- iv[i+1] = k;
- } else {
- delete Vertex[i];
- Vertex[i] = NULL;
- iv[i+1] = 0;
- }
- nAllVertices = k;
- nVertices = nAllVertices;
- k = 0;
- for (i=0;i<nAllEdges;i++)
- if ((iv[Edge[i]->v1]!=0) && (iv[Edge[i]->v2]!=0)) {
- if (k<i) {
- Edge[k] = Edge[i];
- Edge[i] = NULL;
- }
- Edge[k]->v1 = iv[Edge[k]->v1];
- Edge[k]->v2 = iv[Edge[k]->v2];
- k++;
- } else {
- delete Edge[i];
- Edge[i] = NULL;
- }
- nAllEdges = k;
- nEdges = nAllEdges;
- FreeVectorMemory ( iv,1 );
-}
-
-void CGraph::RemoveChirality() {
-int i;
- for (i=0;i<nAllVertices;i++)
- if (Vertex[i]) Vertex[i]->RemoveChirality();
-}
-
-void CGraph::LeaveChirality ( int eltype ) {
-// leaves chirality for specified atom types
-int i;
- for (i=0;i<nAllVertices;i++)
- if (Vertex[i]) Vertex[i]->LeaveChirality ( eltype );
-}
-
-void CGraph::MakeSymmetryRelief ( Boolean noCO2 ) {
-// This function looks for groups of equivalent vertices
-// attached to a single vertice (e.g. chemical SO3 or
-// PO3 groups), and re-lables them by adding a unique
-// symmetry-relief number. This eliminates equivalent
-// matches (3! for each SO3/PO3 group), and increases
-// vertex diversity, which considerably speeds up matching.
-// The function is cheap and harmless even if such groups
-// of vertices are not found.
-// If noCO2 is True then CO2 symmetry is not releaved.
-ivector v,vc;
-int i,j,k,n,m,almask,vjtype, ctype,otype;
-Boolean noOxygens;
-
- otype = 0;
- ctype = 0;
-
- GetVectorMemory ( v ,nVertices,0 );
- GetVectorMemory ( vc,nVertices,1 );
-
- for (i=1;i<=nVertices;i++)
- vc[i] = 0;
-
- for (j=0;j<nEdges;j++) {
- if ((Edge[j]->v1>0) && (Edge[j]->v1<=nVertices))
- vc[Edge[j]->v1]++;
- if ((Edge[j]->v2>0) && (Edge[j]->v2<=nVertices))
- vc[Edge[j]->v2]++;
- }
-
- almask = ~ATOM_LEAVING;
-
- if (noCO2) {
- ctype = getElementNo ( "C" );
- otype = getElementNo ( "O" );
- }
-
- noOxygens = False;
-
- for (i=1;i<=nVertices;i++)
- if (vc[i]>1) { // vertex at more than 1 edge
- // v[] will list connected vertices, k will be their number
- k = 0;
- for (j=0;j<nEdges;j++) {
- if ((Edge[j]->v1==i) && (vc[Edge[j]->v2]==1) && (k<nVertices))
- v[k++] = Edge[j]->v2-1;
- if ((Edge[j]->v2==i) && (vc[Edge[j]->v1]==1) && (k<nVertices))
- v[k++] = Edge[j]->v1-1;
- }
- if (k>1) {
- if (noCO2) noOxygens = ((Vertex[i-1]->type & almask)==ctype);
- // A group of vertices with single connection is
- // identified. Assign symmetry relief modifiers
- // to *equivalent* vertices in the group
- for (j=0;j<k;j++)
- if ((v[j]>=0) && (v[j]<nVertices)) {
- vjtype = Vertex[v[j]]->type & almask;
- if ((!noOxygens) || (vjtype!=otype)) {
- n = 1; // symmetry relief modifier
- for (m=j+1;m<k;m++)
- if ((v[m]>=0) && (v[m]<nVertices)) {
- if (Vertex[v[j]]->type==
- (Vertex[v[m]]->type & almask)) {
- Vertex[v[m]]->type |= (n << 16);
- n++;
- v[m] = -1;
- }
- }
- }
- }
- }
- }
-
- FreeVectorMemory ( v ,0 );
- FreeVectorMemory ( vc,1 );
-
-}
-
-int CGraph::Build ( Boolean bondOrder ) {
-int i,j, rc;
-
- if (nVertices<=0) return 2;
-
- if (nGAlloc<nVertices) {
- FreeMatrixMemory ( graph,nGAlloc,1,1 );
- nGAlloc = nVertices;
- GetMatrixMemory ( graph,nGAlloc,nGAlloc,1,1 );
- }
-
- for (i=1;i<=nVertices;i++)
- for (j=1;j<=nVertices;j++)
- graph[i][j] = 0;
-
- rc = 0;
- if (bondOrder) {
-
- for (i=0;(i<nEdges) && (!rc);i++)
- if ((Edge[i]->v1>=1) && (Edge[i]->v1<=nVertices) &&
- (Edge[i]->v2>=1) && (Edge[i]->v2<=nVertices)) {
- graph[Edge[i]->v1][Edge[i]->v2] = Edge[i]->type;
- graph[Edge[i]->v2][Edge[i]->v1] = Edge[i]->type;
- } else
- rc = 1;
-
- } else {
-
- for (i=0;i<nEdges;i++)
- if ((Edge[i]->v1>=1) && (Edge[i]->v1<=nVertices) &&
- (Edge[i]->v2>=1) && (Edge[i]->v2<=nVertices)) {
- graph[Edge[i]->v1][Edge[i]->v2] = 1;
- graph[Edge[i]->v2][Edge[i]->v1] = 1;
- } else
- rc = 1;
-
- }
-
- return rc;
-
-}
-
-
-const int ring_mask[] = {
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000001,
- 0x00000002,
- 0x00000004,
- 0x00000008,
- 0x00000010,
- 0x00000020,
- 0x00000040,
- 0x00000080
-};
-
-void CGraph::IdentifyRings() {
-CGraphMatch GM;
-CGraph ring;
-ivector F1,F2;
-AtomName aname;
-realtype p1,p2;
-int i,j,n,nrings,nv;
-
- Build ( False );
-
- for (i=0;i<nVertices;i++)
- Vertex[i]->type_ext = 0;
-
- GM.SetFlag ( GMF_UniqueMatch );
-
- for (n=3;n<=10;n++) {
-
- ring.Reset();
-
- for (i=1;i<=n;i++) {
- sprintf ( aname,"C%i",i );
- ring.AddVertex ( new CVertex("C",aname) );
- }
-
- ring.MakeVertexIDs();
-
- for (i=1;i<=n;i++) {
- j = i+1;
- if (j>n) j = 1;
- ring.AddEdge ( new CEdge(i,j,1) );
- }
-
- ring.Build ( False );
-
- GM.MatchGraphs ( this,&ring,n,False,EXTTYPE_Ignore );
-
- nrings = GM.GetNofMatches();
- for (i=0;i<nrings;i++) {
- GM.GetMatch ( i,F1,F2,nv,p1,p2 );
- for (j=1;j<nv;j++)
- Vertex[F1[j]-1]->type_ext |= ring_mask[n];
- }
-
- }
-
-}
-
-void CGraph::markConnected ( int vno, int cno ) {
-int i;
-
- Vertex[vno]->type_ext = cno;
- for (i=0;i<nVertices;i++)
- if (graph[vno+1][i+1] && (!Vertex[i]->type_ext))
- markConnected ( i,cno );
-
-}
-
-
-int CGraph::IdentifyConnectedComponents() {
-// Returns the number of connected components and sets
-// Vertex[]->type_ext equal to component number >=1.
-int nComponents,i;
-
- nComponents = 0;
-
- Build ( False );
-
- for (i=0;i<nVertices;i++)
- Vertex[i]->type_ext = 0;
-
- i = 0;
- while (i<nVertices) {
- while (i<nVertices)
- if (Vertex[i]->type_ext) i++;
- else break;
- if (i<nVertices) {
- nComponents++;
- markConnected ( i,nComponents );
- }
- }
-
- return nComponents;
-
-}
-
-
-
-void CGraph::Print() {
-int i;
-
- printf ( " ===== Graph %s \n\n",name );
-
- if (nVertices>0) {
- printf ( " Vertices:\n"" ## " );
- Vertex[0]->Print(1);
- printf ( "\n" );
- for (i=0;i<nVertices;i++) {
- printf ( " %4i ",i+1 );
- Vertex[i]->Print(0);
- printf ( "\n" );
- }
- }
-
- if (nEdges>0) {
- printf ( " Edges:\n"" ## " );
- Edge[0]->Print(1);
- printf ( "\n" );
- for (i=0;i<nEdges;i++) {
- printf ( " %4i ",i+1 );
- Edge[i]->Print(0);
- printf ( "\n" );
- }
- }
-
-
-}
-
-void CGraph::Print1() {
-int i,j;
- for (i=0;i<nVertices;i++) {
- printf ( " %4i %5i %3i %7s ",
- i+1,Vertex[i]->id,Vertex[i]->type,Vertex[i]->name );
- for (j=0;j<nEdges;j++)
- if (Edge[j]->v1==i+1)
- printf ( " %4i(%i)",Edge[j]->v2,Edge[j]->type );
- else if (Edge[j]->v2==i+1)
- printf ( " %4i(%i)",Edge[j]->v1,Edge[j]->type );
- printf ( "\n" );
- }
-}
-
-
-void CGraph::Copy ( PCGraph G ) {
-int i;
-
- FreeMemory();
-
- CreateCopy ( name,G->name );
- nVertices = G->nVertices;
- nEdges = G->nEdges;
- nAllVertices = G->nAllVertices;
- nAllEdges = G->nAllEdges;
- if (nAllVertices>0) {
- nVAlloc = nAllVertices;
- Vertex = new PCVertex[nVAlloc];
- for (i=0;i<nAllVertices;i++) {
- Vertex[i] = new CVertex();
- Vertex[i]->Copy ( G->Vertex[i] );
- }
- }
- if (nAllEdges>0) {
- nEAlloc = nAllEdges;
- Edge = new PCEdge[nEAlloc];
- for (i=0;i<nAllEdges;i++) {
- Edge[i] = new CEdge();
- Edge[i]->Copy ( G->Edge[i] );
- }
- }
-
-}
-
-void CGraph::write ( RCFile f ) {
-int i;
-int Version=2;
-Boolean bondOrder=False;
- f.WriteInt ( &Version );
- f.WriteBool ( &bondOrder );
- f.CreateWrite ( name );
- f.WriteInt ( &nVertices );
- f.WriteInt ( &nEdges );
- f.WriteInt ( &nAllVertices );
- f.WriteInt ( &nAllEdges );
- for (i=0;i<nAllVertices;i++)
- StreamWrite ( f,Vertex[i] );
- for (i=0;i<nAllEdges;i++)
- StreamWrite ( f,Edge[i] );
-}
-
-void CGraph::read ( RCFile f ) {
-int i,Version;
-Boolean bondOrder;
-
- FreeMemory();
-
- f.ReadInt ( &Version );
- f.ReadBool ( &bondOrder );
- f.CreateRead ( name );
- f.ReadInt ( &nVertices );
- f.ReadInt ( &nEdges );
- if (Version>1) {
- f.ReadInt ( &nAllVertices );
- f.ReadInt ( &nAllEdges );
- } else {
- nAllVertices = nVertices;
- nAllEdges = nEdges;
- }
- if (nAllVertices>0) {
- nVAlloc = nAllVertices;
- Vertex = new PCVertex[nVAlloc];
- for (i=0;i<nAllVertices;i++) {
- Vertex[i] = NULL;
- StreamRead ( f,Vertex[i] );
- }
- }
- if (nAllEdges>0) {
- nEAlloc = nAllEdges;
- Edge = new PCEdge[nEAlloc];
- for (i=0;i<nAllEdges;i++) {
- Edge[i] = NULL;
- StreamRead ( f,Edge[i] );
- }
- }
-
-// Build ( bondOrder );
-
-}
-
-void CGraph::mem_write ( pstr S, int & l ) {
-int i,k;
-byte Version=2;
-Boolean bondOrder=False;
-
- ::mem_write_byte ( Version,S,l );
- ::mem_write ( bondOrder ,S,l );
- ::mem_write ( name ,S,l );
- ::mem_write ( nVertices ,S,l );
- ::mem_write ( nEdges ,S,l );
- ::mem_write ( nAllVertices,S,l );
- ::mem_write ( nAllEdges ,S,l );
- for (i=0;i<nAllVertices;i++)
- if (Vertex[i]) {
- k = 1;
- ::mem_write ( k,S,l );
- Vertex[i]->mem_write ( S,l );
- } else {
- k = 0;
- ::mem_write ( k,S,l );
- }
- for (i=0;i<nAllEdges;i++)
- if (Edge[i]) {
- k = 1;
- ::mem_write ( k,S,l );
- Edge[i]->mem_write ( S,l );
- } else {
- k = 0;
- ::mem_write ( k,S,l );
- }
-
-}
-
-void CGraph::mem_read ( cpstr S, int & l ) {
-int i,k;
-byte Version;
-Boolean bondOrder;
-
- FreeMemory();
-
- ::mem_read_byte ( Version,S,l );
- ::mem_read ( bondOrder ,S,l );
- ::mem_read ( name ,S,l );
- ::mem_read ( nVertices ,S,l );
- ::mem_read ( nEdges ,S,l );
- ::mem_read ( nAllVertices,S,l );
- ::mem_read ( nAllEdges ,S,l );
- if (nAllVertices>0) {
- nVAlloc = nAllVertices;
- Vertex = new PCVertex[nVAlloc];
- for (i=0;i<nAllVertices;i++) {
- ::mem_read ( k,S,l );
- if (k) {
- Vertex[i] = new CVertex();
- Vertex[i]->mem_read ( S,l );
- } else
- Vertex[i] = NULL;
- }
- }
- if (nAllEdges>0) {
- nEAlloc = nAllEdges;
- Edge = new PCEdge[nEAlloc];
- for (i=0;i<nAllEdges;i++) {
- ::mem_read ( k,S,l );
- if (k) {
- Edge[i] = new CEdge();
- Edge[i]->mem_read ( S,l );
- } else {
- Edge[i] = NULL;
- }
- }
- }
-
-// Build ( bondOrder );
-
-}
-
-MakeStreamFunctions(CGraph);
-
-
-// ========================== CMatch ============================
-
-CMatch::CMatch() : CStream() {
- InitMatch();
-}
-
-CMatch::CMatch ( RPCStream Object ) : CStream ( Object ) {
- InitMatch();
-}
-
-CMatch::CMatch ( ivector FV1, ivector FV2, int nv, int n, int m ) {
-int i;
- if (FV1 && FV2) {
- n1 = n;
- n2 = m;
- nAlloc = n;
- GetVectorMemory ( F1,nAlloc,1 );
- GetVectorMemory ( F2,nAlloc,1 );
- mlength = nv;
- for (i=1;i<=mlength;i++) {
- F1[i] = FV1[i];
- F2[i] = FV2[i];
- }
- } else
- InitMatch();
-}
-
-void CMatch::InitMatch() {
- mlength = 0;
- n1 = 0;
- n2 = 0;
- nAlloc = 0;
- F1 = NULL;
- F2 = NULL;
-}
-
-CMatch::~CMatch() {
- FreeVectorMemory ( F1,1 );
- FreeVectorMemory ( F2,1 );
-}
-
-void CMatch::SetMatch ( ivector FV1, ivector FV2, int nv, int n, int m ) {
-int i;
- if (FV1 && FV2) {
- if (nv>nAlloc) {
- FreeVectorMemory ( F1,1 );
- FreeVectorMemory ( F2,1 );
- nAlloc = n;
- GetVectorMemory ( F1,nAlloc,1 );
- GetVectorMemory ( F2,nAlloc,1 );
- }
- n1 = n;
- n2 = m;
- mlength = nv;
- for (i=1;i<=mlength;i++) {
- F1[i] = FV1[i];
- F2[i] = FV2[i];
- }
- } else {
- FreeVectorMemory ( F1,1 );
- FreeVectorMemory ( F2,1 );
- mlength = 0;
- n1 = 0;
- n2 = 0;
- }
-}
-
-
-Boolean CMatch::isMatch ( ivector FV1, ivector FV2, int nv ) {
-int i,j;
-Boolean B;
- if (FV1 && FV2 && (nv<=mlength)) {
- B = True;
- for (i=1;(i<=nv) && B;i++) {
- B = False;
- for (j=1;(j<=mlength) && (!B);j++)
- B = (FV1[i]==F1[j]) && (FV2[i]==F2[j]);
- }
- return B;
- }
- return False;
-}
-
-Boolean CMatch::isCombination ( ivector FV1, ivector FV2, int nv ) {
-int i,j;
-Boolean B;
- if (FV1 && FV2 && (nv==mlength)) {
- B = True;
- for (i=1;(i<=nv) && B;i++) {
- B = False;
- for (j=1;(j<=mlength) && (!B);j++)
- B = (FV1[i]==F1[j]);
- if (B) {
- B = False;
- for (j=1;(j<=mlength) && (!B);j++)
- B = (FV2[i]==F2[j]);
- }
- }
- return B;
- }
- return False;
-}
-
-
-void CMatch::GetMatch ( ivector & FV1, ivector & FV2, int & nv,
- realtype & p1, realtype & p2 ) {
- FV1 = F1;
- FV2 = F2;
- nv = mlength;
- p1 = mlength;
- if (p1>0.0) p1 /= n1;
- p2 = mlength;
- if (p2>0.0) p2 /= n2;
-}
-
-void CMatch::write ( RCFile f ) {
-int i;
-int Version=1;
- f.WriteInt ( &Version );
- f.WriteInt ( &mlength );
- f.WriteInt ( &n1 );
- f.WriteInt ( &n2 );
- for (i=1;i<=mlength;i++) {
- f.WriteInt ( &(F1[i]) );
- f.WriteInt ( &(F2[i]) );
- }
-}
-
-void CMatch::read ( RCFile f ) {
-int i,Version;
- FreeVectorMemory ( F1,1 );
- FreeVectorMemory ( F2,1 );
- f.ReadInt ( &Version );
- f.ReadInt ( &mlength );
- f.ReadInt ( &n1 );
- f.ReadInt ( &n2 );
- if (mlength>0) {
- nAlloc = n1;
- GetVectorMemory ( F1,nAlloc,1 );
- GetVectorMemory ( F2,nAlloc,1 );
- for (i=1;i<=mlength;i++) {
- f.ReadInt ( &(F1[i]) );
- f.ReadInt ( &(F2[i]) );
- }
- }
-}
-
-void CMatch::mem_write ( pstr S, int & l ) {
-int i;
- ::mem_write ( mlength,S,l );
- ::mem_write ( n1 ,S,l );
- ::mem_write ( n2 ,S,l );
- for (i=1;i<=mlength;i++) {
- ::mem_write ( F1[i],S,l );
- ::mem_write ( F2[i],S,l );
- }
-}
-
-void CMatch::mem_read ( cpstr S, int & l ) {
-int i;
- FreeVectorMemory ( F1,1 );
- FreeVectorMemory ( F2,1 );
- ::mem_read ( mlength,S,l );
- ::mem_read ( n1 ,S,l );
- ::mem_read ( n2 ,S,l );
- if (mlength>0) {
- nAlloc = n1;
- GetVectorMemory ( F1,nAlloc,1 );
- GetVectorMemory ( F2,nAlloc,1 );
- for (i=1;i<=mlength;i++) {
- ::mem_read ( F1[i],S,l );
- ::mem_read ( F2[i],S,l );
- }
- }
-}
-
-
-MakeStreamFunctions(CMatch);
-
-
-
-// ======================== CGraphMatch ==========================
-
-CGraphMatch::CGraphMatch()
- : CStream() {
- InitGraphMatch();
-}
-
-CGraphMatch::CGraphMatch ( RPCStream Object )
- : CStream ( Object ) {
- InitGraphMatch();
-}
-
-CGraphMatch::~CGraphMatch() {
- FreeMemory();
-}
-
-void CGraphMatch::InitGraphMatch() {
- G1 = NULL;
- G2 = NULL;
- n = 0;
- m = 0;
- P = NULL;
- nAlloc = 0;
- mAlloc = 0;
- nMatches = 0;
- maxNMatches = -1; // unlimited
- Match = NULL;
- nMAlloc = 0;
- flags = 0;
- swap = False;
- wasFullMatch = False;
- maxMatch = 0;
- timeLimit = 0; // no time limit
- Stop = False;
- stopOnMaxNMathches = False;
- F1 = NULL;
- F2 = NULL;
- iF1 = NULL;
- ix = NULL;
-#ifndef _UseRecursion
- jj = NULL;
-#endif
-}
-
-
-void CGraphMatch::SetFlag ( word flag ) {
- flags |= flag;
-}
-
-void CGraphMatch::RemoveFlag ( word flag ) {
- flags &= ~flag;
-}
-
-void CGraphMatch::SetMaxNofMatches ( int maxNofMatches,
- Boolean stopOnMaxN ) {
- maxNMatches = maxNofMatches;
- stopOnMaxNMathches = stopOnMaxN;
-}
-
-void CGraphMatch::SetTimeLimit ( int maxTimeToRun ) {
- timeLimit = maxTimeToRun;
-}
-
-void CGraphMatch::Reset() {
- FreeMemory();
-}
-
-void CGraphMatch::FreeMemory() {
-int i;
-
- if (P) {
- FreeMatrixMemory ( P[1],nAlloc,1,0 );
- FreeRecHeap ();
- P = P + 1;
- delete[] P;
- P = NULL;
- }
-
- FreeMatrixMemory ( iF1,nAlloc,1,1 );
-
- FreeVectorMemory ( F1 ,1 );
- FreeVectorMemory ( F2 ,1 );
- FreeVectorMemory ( ix ,1 );
- nAlloc = 0;
- mAlloc = 0;
-
- if (Match) {
- for (i=0;i<nMAlloc;i++)
- if (Match[i]) delete Match[i];
- delete[] Match;
- }
- Match = NULL;
- nMatches = 0;
- nMAlloc = 0;
-
-#ifndef _UseRecursion
- FreeVectorMemory ( jj,1 );
-#endif
-
-}
-
-void CGraphMatch::FreeRecHeap() {
-int i;
- if (P)
- for (i=2;i<=nAlloc;i++)
- FreeMatrixMemory ( P[i],nAlloc,1,0 );
-}
-
-
-void CGraphMatch::GetMemory() {
-int i;
-
- FreeMemory();
-
- P = new imatrix[n];
- P = P-1;
- GetMatrixMemory ( P[1],n,m+1,1,0 );
- for (i=2;i<=n;i++)
- P[i] = NULL;
-
- GetMatrixMemory ( iF1,n,n,1,1 );
-
- GetVectorMemory ( F1,n,1 );
- GetVectorMemory ( F2,n,1 );
- GetVectorMemory ( ix,n,1 );
-
-#ifndef _UseRecursion
- GetVectorMemory ( jj,n,1 );
-#endif
-
- nAlloc = n;
- mAlloc = m;
-
-}
-
-void CGraphMatch::GetRecHeap() {
-int i,j;
- for (i=2;i<=n;i++) {
- P[i] = new ivector[nAlloc];
- P[i] = P[i]-1;
- for (j=1;j<=n;j++)
- GetVectorMemory ( P[i][j],P[1][j][0]+1,0 );
- for (j=n+1;j<=nAlloc;j++)
- P[i][j] = NULL;
- }
-}
-
-
-void CGraphMatch::MatchGraphs ( PCGraph Gh1, PCGraph Gh2,
- int minMatch,
- Boolean vertexType,
- int vertexExt ) {
-// MatchGraphs looks for maximal common subgraphs of size
-// not less than minMatch. The number of found subgraphs
-// is returned by GetNofMatches(), the subgraph vertices
-// are returned by GetMatch(..). Control parameters:
-// vertexType True if vertex type should be taken
-// into account and False otherwise
-// vertexExt key to use extended vertex types (defined
-// as type_ext in CVertex).
-int n1;
-
- if (Gh1->nVertices<=Gh2->nVertices) {
- G1 = Gh1;
- G2 = Gh2;
- swap = False;
- } else {
- G1 = Gh2;
- G2 = Gh1;
- swap = True;
- }
- n = G1->nVertices;
- m = G2->nVertices;
- V1 = G1->Vertex;
- V2 = G2->Vertex;
- c1 = G1->graph;
- c2 = G2->graph;
-
- nMatches = 0;
-
- if (n<=0) return;
-
- if ((n>nAlloc) || (m>mAlloc)) GetMemory();
- else FreeRecHeap();
-
- n1 = Initialize ( vertexType,vertexExt );
- if (n1<=0) return;
-
- GetRecHeap();
-
- maxMatch = IMax(1,IMin(n,minMatch));
- Stop = False;
- startTime = time(NULL);
-
- // Use of Backtrack(..) and Ullman() is completely
- // equivalent. One of them should be commented.
-
- if (minMatch<n) {
-
- if (n1>=minMatch) Backtrack1 ( 1,n1 );
-
- } else if (n1>=n) {
-
- #ifdef _UseRecursion
- Backtrack ( 1 );
- #else
- Ullman();
- #endif
-
- }
-
-}
-
-
-int CGraphMatch::Initialize ( Boolean vertexType, int vertexExt ) {
-ivector jF1;
-int i,j,v1type,v1type_ext,v2type_ext,almask,iW,pl;
-
- wasFullMatch = False;
-
- jF1 = iF1[1];
- for (i=1;i<=n;i++)
- jF1[i] = i;
-
- almask = ~ATOM_LEAVING;
-
-/* -- experiment for symmetry reliefs
-int v2type,v1type_sr,srmask;
- srmask = ~SYMREL_MASK;
-
- for (i=1;i<=n;i++) {
- if (vertexType) {
- ix[i] = 0;
- v1type = V1[i-1]->type & almask;
- v1type_sr = v1type & srmask;
- pl = 0;
- for (j=1;j<=m;j++) {
- v2type = V2[j-1]->type & almask;
- if ((v1type==v2type) ||
- (v1type_sr==v2type) ||
- (v1type==(v2type & srmask)))
- P[1][i][++pl] = j;
- }
- P[1][i][0] = pl;
- if (pl) ix[i] = i;
- } else {
- ix[i] = i;
- for (j=1;j<=m;j++)
- P[1][i][j] = j;
- P[1][i][0] = m;
- }
- F1[i] = 0;
- F2[i] = 0;
- }
- */
-
- for (i=1;i<=n;i++) {
- ix[i] = 0;
- v1type = V1[i-1]->type & almask;
- v1type_ext = V1[i-1]->type_ext;
- pl = 0;
- for (j=1;j<=m;j++)
- if ((v1type==(V2[j-1]->type & almask)) || (!vertexType)) {
- if (vertexExt==EXTTYPE_Ignore)
- P[1][i][++pl] = j;
- else {
- v2type_ext = V2[j-1]->type_ext;
- if ((!v1type_ext) && (!v2type_ext))
- P[1][i][++pl] = j;
- else
- switch (vertexExt) {
- default :
- case EXTTYPE_Ignore : P[1][i][++pl] = j;
- break;
- case EXTTYPE_Equal : if (v1type_ext==v2type_ext)
- P[1][i][++pl] = j;
- break;
- case EXTTYPE_AND : if (v1type_ext & v2type_ext)
- P[1][i][++pl] = j;
- break;
- case EXTTYPE_OR : if (v1type_ext | v2type_ext)
- P[1][i][++pl] = j;
- break;
- case EXTTYPE_XOR : if (v1type_ext ^ v2type_ext)
- P[1][i][++pl] = j;
- break;
- case EXTTYPE_NotEqual : if (v1type_ext!=v2type_ext)
- P[1][i][++pl] = j;
- break;
- case EXTTYPE_NotAND : if ((v1type_ext & v2type_ext)
- ==0)
- P[1][i][++pl] = j;
- break;
- case EXTTYPE_NotOR : if ((v1type_ext | v2type_ext)
- ==0)
- P[1][i][++pl] = j;
- }
- }
- }
- P[1][i][0] = pl;
- if (pl) ix[i] = i;
- F1[i] = 0;
- F2[i] = 0;
- }
- /*
- } else {
- for (i=1;i<=n;i++) {
- ix[i] = i;
- for (j=1;j<=m;j++)
- P[1][i][j] = j;
- P[1][i][0] = m;
- F1[i] = 0;
- F2[i] = 0;
- }
- }
- */
-
- i = 1;
- j = n;
- while (i<j)
- if (ix[j]==0) // make sure that j points on a true-containing
- j--; // row of P[1]
- else {
- if (ix[i]==0) { // swap lower empty row of P[1]
- iW = ix[i]; // with the lth one, which
- ix[i] = ix[j]; // is surely not empty
- ix[j] = iW;
- iW = jF1[i];
- jF1[i] = jF1[j];
- jF1[j] = iW;
- }
- i++;
- }
-
- if (ix[i]==0) return i-1;
- else return i;
-
-}
-
-
-#ifdef _UseRecursion
-
-void CGraphMatch::Backtrack ( int i ) {
-// Recursive version of Ullman's algorithm for exact
-// (structure-to-structure or substructure-to-structure)
-// matching
-int i1,pli,cntj,j,k,pl1,pl2,cntl,l,c1ik;
-ivector c1i,c2j;
-ivector p1,p2;
-
- if (Stop) return;
- if (timeLimit>0)
- Stop = (difftime(time(NULL),startTime)>timeLimit);
-
- F1[i] = i;
- pli = P[i][i][0];
-
- if (i>=n) {
-
- for (cntj=1;(cntj<=pli) && (!Stop);cntj++) {
- F2[n] = P[n][n][cntj];
- CollectMatch ( n );
- }
-
- } else {
-
- i1 = i+1;
- c1i = c1[i];
-
- for (cntj=1;(cntj<=pli) && (!Stop);cntj++) {
- j = P[i][i][cntj];
- F2[i] = j; // mapped F1[i]:F2[i], i.e. i:j
- // Forward checking
- c2j = c2[j];
- pl2 = 1;
- for (k=i1;(k<=n) && (pl2>0);k++) {
- p1 = P[i][k];
- p2 = P[i1][k];
- c1ik = c1i[k];
- pl1 = p1[0];
- pl2 = 0;
- for (cntl=1;cntl<=pl1;cntl++) {
- l = p1[cntl];
- if ((c1ik==c2j[l]) && // check that bonds are compatible
- (l!=j)) // and make sure jth vertex is excluded
- p2[++pl2] = l;
- }
- p2[0] = pl2; // new length of P-row
- }
- if (pl2>0) Backtrack ( i1 );
- }
-
- }
-
-}
-
-#else
-
-void CGraphMatch::Ullman() {
-// A non-recursive translation of Ullman's Backtrack.
-// It might give some gain in performance, although tests
-// on SGI machine show that the gain is negligible, (if
-// there is any at all) if compiler's optimization is
-// switched on.
-int i,pl,i1,pli,cntj,j,pl1,pl2,k,cntl,l,l1,cik;
-ivector ci,cj;
-ivector p1,p2;
-
- if (Stop) return;
- if (timeLimit>0)
- Stop = (difftime(time(NULL),startTime)>timeLimit);
-
- i = 1;
- jj[1] = 1;
- pl = P[1][1][0];
-
- do {
-
- F1[i] = i;
- pli = P[i][i][0];
-
- if (i>=n) {
-
- for (cntj=jj[n];(cntj<=pli) && (!Stop);cntj++) {
- jj[n]++;
- F2[n] = P[n][n][cntj];
- CollectMatch ( n );
- }
-
- } else {
-
- i1 = i+1;
- ci = c1[i];
- for (cntj=jj[i];(cntj<=pli) && (!Stop);cntj++) {
- jj[i]++;
- j = P[i][i][cntj];
- F2[i] = j;
- // Forward checking
- cj = c2[j];
- pl2 = 1;
- for (k=i1;(k<=n) && (pl2>0);k++) {
- p1 = P[i][k];
- p2 = P[i1][k];
- cik = ci[k];
- pl1 = p1[0];
- pl2 = 0;
- for (cntl=1;cntl<=pl1;cntl++) {
- l = p1[cntl];
- if ((cik==cj[l]) && // check that bonds are compatible
- (l!=j)) // and make sure jth vertex is excluded
- p2[++pl2] = l;
- }
- p2[0] = pl2; // new length of P-row
- }
- if (pl2>0) {
- i++;
- jj[i] = 1;
- i++; // in order to compensate the following decrement
- break;
- }
- }
-
- }
- i--;
-
- } while ((!Stop) && ((jj[1]<=pl) || (i>1)));
-
-}
-
-#endif
-
-void CGraphMatch::Backtrack1 ( int i, int k0 ) {
-// Recursive version of CSIA algorithm for partial
-// (substructure-to-substructure) matching
-int i1,pl0,cntj,j,k,pl1,pl2,cntl,l,c1ik,ii,iW,k1;
-ivector jF1,c1i,c2j;
-ivector p0,p1,p2;
-
- if (Stop) return;
- if (timeLimit>0)
- Stop = (difftime(time(NULL),startTime)>timeLimit);
-
- jF1 = iF1[i];
-
- if (i>=k0) {
-
- F1[i] = jF1[i];
- p0 = P[i][jF1[i]];
- pl0 = p0[0];
-
- // collect matches of k0-th (the upmost) level
- if (pl0>0) {
- maxMatch = k0;
- for (cntj=1;cntj<=pl0;cntj++) {
- F2[k0] = p0[cntj];
- CollectMatch ( k0 );
- }
- }
-
- } else {
-
- i1 = i+1;
-
- pl0 = P[i][jF1[i]][0];
- j = i;
- for (k=i1;k<=k0;k++)
- if (P[i][jF1[k]][0]<pl0) {
- pl0 = P[i][jF1[k]][0];
- j = k;
- }
- if (j>i) {
- iW = jF1[i];
- jF1[i] = jF1[j];
- jF1[j] = iW;
- }
-
- F1[i] = jF1[i];
- p0 = P[i][jF1[i]];
- pl0 = p0[0];
-
- c1i = c1[jF1[i]];
-
- // 1. Find all matches that include jF1[i]th vertex of graph G1
-
- for (cntj=1;(cntj<=pl0) && (!Stop);cntj++) {
- j = p0[cntj];
- F2[i] = j; // mapped F1[i]:F2[i], i.e. iF1[i][i]:j
- // Forward checking
- c2j = c2[j];
- k1 = k0; // k1 is the limit for match size
- for (k=i1;(k<=k0) && (k1>=maxMatch);k++) {
- ix[k] = 0;
- p1 = P[i] [jF1[k]];
- p2 = P[i1][jF1[k]];
- c1ik = c1i [jF1[k]];
- pl1 = p1[0];
- pl2 = 0;
- for (cntl=1;cntl<=pl1;cntl++) {
- l = p1[cntl];
- if ((c1ik==c2j[l]) && // check that bonds are compatible
- (l!=j)) // and make sure jth vertex is excluded
- p2[++pl2] = l;
- }
- p2[0] = pl2; // new length of P-row
- if (pl2>0) {
- ix[k] = k;
- } else if (wasFullMatch) {
- k1 = maxMatch-1; // we are not interested in partial
- } else { // match anymore
- k1--;
- }
- }
- if (k1>=maxMatch) {
- // shift unmatching vertices to the end
- for (ii=1;ii<=n;ii++)
- iF1[i1][ii] = jF1[ii];
- k = i1;
- l = k0;
- while (k<l)
- if (ix[l]==0) // make sure that l points on a true-containing
- l--; // row of P[i1]
- else {
- if (ix[k]==0) { // swap lower empty row of P[i1]
- iW = ix[k]; // with the lth one, which
- ix[k] = ix[l]; // is surely not empty
- ix[l] = iW;
- iW = iF1[i1][k];
- iF1[i1][k] = iF1[i1][l];
- iF1[i1][l] = iW;
- }
- k++;
- }
- if (ix[i1]) Backtrack1 ( i1,k1 );
- else if (i>=maxMatch) {
- CollectMatch ( i ); // collect match of ith level
- maxMatch = i;
- }
- }
- }
-
- // 2. Find all matches that do not include jF1[i]th vertex
- // of graph G1
-
- if (k0>maxMatch) {
- // Shift jF1[i]th vertex to the end
- iW = jF1[i];
- jF1[i] = jF1[k0];
- jF1[k0] = iW;
- Backtrack1 ( i,k0-1 );
- }
-
- }
-
-}
-
-
-void CGraphMatch::CollectMatch ( int nm ) {
-int i;
-Boolean B;
-PPCMatch M1;
-
- if (maxNMatches==0) return;
-
- // find out if this should be a new match
- if (nMatches>0) {
- // a match is already found; check with it
- if (nm<Match[0]->mlength) return;
- if (nm>Match[0]->mlength) {
- nMatches = 0;
- } else if (flags & GMF_UniqueMatch) {
- // check if such a match was already found
- B = False;
- for (i=0;(i<nMatches) && (!B);i++)
- B = Match[i]->isMatch(F1,F2,nm);
- if (B) return; // repeating match -- just quit.
- } else if (flags & GMF_NoCombinations) {
- // check if such a match was already found
- B = False;
- for (i=0;(i<nMatches) && (!B);i++)
- B = Match[i]->isCombination(F1,F2,nm);
- if (B) return; // repeating match -- just quit.
- }
- }
-
- if (nMatches>=nMAlloc) {
- if ((nMAlloc<maxNMatches) || (maxNMatches<=0)) {
- if (maxNMatches>0) nMAlloc = IMin(maxNMatches,nMAlloc+100);
- else nMAlloc += 100;
- M1 = new PCMatch[nMAlloc];
- for (i=0;i<nMatches;i++)
- M1[i] = Match[i];
- for (i=nMatches;i<nMAlloc;i++)
- M1[i] = NULL;
- if (Match) delete[] Match;
- Match = M1;
- } else
- nMatches--;
- }
-
- if (!Match[nMatches])
- Match[nMatches] = new CMatch ( F1,F2,nm,n,m );
- else Match[nMatches]->SetMatch ( F1,F2,nm,n,m );
-
- if (nm==n) wasFullMatch = True;
-
- if (nm>maxMatch) maxMatch = nm;
-
- nMatches++;
-
- if (stopOnMaxNMathches && (maxNMatches>0) &&
- (nMatches>=maxNMatches))
- Stop = True;
-
-}
-
-void CGraphMatch::PrintMatches() {
-int i,j,k;
- if (nMatches<=0)
- printf ( "\n\n *** NO MATCHES FOUND\n\n" );
- else {
- if (flags & GMF_UniqueMatch)
- printf ( "\n\n *** FOUND Unique Matches\n\n" );
- else printf ( "\n\n *** FOUND Matches\n\n" );
- printf ( " ## Vertices\n" );
- for (i=0;i<nMatches;i++) {
- printf ( " %5i ",i+1 );
- k = 8;
- for (j=1;j<=Match[i]->mlength;j++) {
- if (swap)
- printf ( " (%i,%i)",Match[i]->F2[j],Match[i]->F1[j] );
- else printf ( " (%i,%i)",Match[i]->F1[j],Match[i]->F2[j] );
- k += 8;
- if (k>70) {
- printf ( "\n" );
- k = 8;
- }
- }
- printf ( "\n" );
- }
- }
- printf ( "\n **************************\n" );
-}
-
-void CGraphMatch::GetMatch ( int MatchNo, ivector & FV1,
- ivector & FV2, int & nv,
- realtype & p1, realtype & p2 ) {
-// do not allocate or dispose FV1 and FV2 in application!
-// FV1/p1 will always correspond to Gh1, and FV2/p2 -
-// to Gh2 as specified in MatchGraphs(..)
- if ((MatchNo<0) || (MatchNo>=nMatches)) {
- FV1 = NULL;
- FV2 = NULL;
- nv = 0;
- p1 = 0.0;
- p2 = 0.0;
- } else if (swap)
- Match[MatchNo]->GetMatch ( FV2,FV1,nv,p2,p1 );
- else Match[MatchNo]->GetMatch ( FV1,FV2,nv,p1,p2 );
-
-}
-
-
-void CGraphMatch::write ( RCFile f ) {
-int i;
-int Version=1;
- f.WriteInt ( &Version );
- f.WriteInt ( &nMatches );
- f.WriteWord ( &flags );
- f.WriteBool ( &swap );
- for (i=0;i<nMatches;i++)
- Match[i]->write ( f );
-}
-
-void CGraphMatch::read ( RCFile f ) {
-int i,Version;
- FreeMemory ();
- f.ReadInt ( &Version );
- f.ReadInt ( &nMatches );
- f.ReadWord ( &flags );
- f.ReadBool ( &swap );
- if (nMatches>0) {
- nMAlloc = nMatches;
- Match = new PCMatch[nMatches];
- for (i=0;i<nMatches;i++) {
- Match[i] = new CMatch();
- Match[i]->read ( f );
- }
- }
-}
-
-
-void CGraphMatch::mem_write ( pstr S, int & l ) {
-int i;
- ::mem_write ( nMatches,S,l );
- ::mem_write ( flags ,S,l );
- ::mem_write ( swap ,S,l );
- for (i=0;i<nMatches;i++)
- Match[i]->mem_write ( S,l );
-}
-
-void CGraphMatch::mem_read ( cpstr S, int & l ) {
-int i;
- FreeMemory ();
- ::mem_read ( nMatches,S,l );
- ::mem_read ( flags ,S,l );
- ::mem_read ( swap ,S,l );
- if (nMatches>0) {
- nMAlloc = nMatches;
- Match = new PCMatch[nMatches];
- for (i=0;i<nMatches;i++) {
- Match[i] = new CMatch();
- Match[i]->mem_read ( S,l );
- }
- }
-}
-
-MakeStreamFunctions(CGraphMatch);
-
-
-
-// =============================================================
-
-/*
-static char Mol1[][3] = {
- "C", "C", "C", "C", "C", "C" };
-
-static int Bond1[] = {
- 1, 2,
- 1, 6,
- 2, 3,
- 3, 4,
- 4, 5,
- 5, 6
-};
-
-static char Mol2[][3] = {
- "C", "C", "C", "C", "C", "C",
- "C", "C", "C", "C", "C", "C" };
-
-static int Bond2[] = {
- 1, 2,
- 1, 6,
- 2, 3,
- 3, 4,
- 4, 5,
- 5, 6,
- 1, 7,
- 2, 8,
- 3, 9,
- 4, 10,
- 5, 11,
- 6, 12
-};
-
-
-static char Mol1[][3] = {
- "C", "C", "N", "C" };
-
-static int Bond1[] = {
- 1, 2,
- 2, 3,
- 3, 4
-};
-
-static char Mol2[][3] = {
- "C", "C", "N", "C" };
-
-static int Bond2[] = {
- 1, 2,
- 2, 3,
- 2, 4,
- 3, 4
-};
-
-void TestGraphMatch() {
-int i,k1,k2, nv1,nb1, nv2,nb2;
-PCVertex V;
-PCEdge G;
-CGraph G1,G2;
-CGraphMatch U;
-
- G1.Reset ();
- G1.SetName ( "#1" );
-
- nv1 = sizeof(Mol1)/3;
- for (i=0;i<nv1;i++) {
- V = new CVertex();
- V->SetVertex ( Mol1[i] );
- G1.AddVertex ( V );
- }
- nb1 = sizeof(Bond1)/(2*sizeof(int));
- k1 = 0;
- k2 = 1;
- for (i=0;i<nb1;i++) {
- G = new CEdge();
- G->SetEdge ( Bond1[k1],Bond1[k2],1 );
- G1.AddEdge ( G );
- k1 += 2;
- k2 += 2;
- }
-
- G2.Reset ();
- G2.SetName ( "#2" );
-
- nv2 = sizeof(Mol2)/3;
- for (i=0;i<nv2;i++) {
- V = new CVertex();
- V->SetVertex ( Mol2[i] );
- G2.AddVertex ( V );
- }
- nb2 = sizeof(Bond2)/(2*sizeof(int));
- k1 = 0;
- k2 = 1;
- for (i=0;i<nb2;i++) {
- G = new CEdge();
- G->SetEdge ( Bond2[k1],Bond2[k2],1 );
- G2.AddEdge ( G );
- k1 += 2;
- k2 += 2;
- }
-
- G1.Build();
- G2.Build();
-
- U.MatchGraphs ( &G1,&G2,nv1 );
-
- U.PrintMatches();
-
-
-}
-*/
-
diff --git a/mmdb/mmdb_graph.h b/mmdb/mmdb_graph.h
deleted file mode 100755
index 70aa523..0000000
--- a/mmdb/mmdb_graph.h
+++ /dev/null
@@ -1,484 +0,0 @@
-// $Id: mmdb_graph.h,v 1.23 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 08.07.08 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : mmdb_graph <interface>
-// ~~~~~~~~~
-// **** Classes : CVertex ( graph vertex )
-// ~~~~~~~~~ CEdge ( graph edge )
-// CGraph ( structural graph )
-// CMatch ( match of structural graphs )
-// CGraphMatch ( CSIA algorithms for graphs matching )
-//
-// (C) E. Krissinel 2000-2008
-//
-// When used, please cite:
-//
-// Krissinel, E. and Henrick, K. (2004)
-// Common subgraph isomorphism detection by backtracking search.
-// Software - Practice and Experience, 34, 591-607.
-//
-// =================================================================
-//
-
-#ifndef __MMDB_Graph__
-#define __MMDB_Graph__
-
-
-#ifndef __TIME_H
-#include <time.h>
-#endif
-
-#ifndef __MMDB_Atom__
-#include "mmdb_atom.h"
-#endif
-
-// ========================== CVertex ============================
-
-DefineClass(CVertex);
-
-#define CHIRAL_RIGHT 0x10000000
-#define CHIRAL_LEFT 0x20000000
-#define ATOM_LEAVING 0x40000000
-#define HYDROGEN_BOND 0x0F000000
-#define SYMREL_MASK 0x00FF0000
-#define CHIRAL_MASK 0xCFFFFFFF
-#define TYPE_MASK 0x00FFFFFF
-
-class CVertex : public CStream {
-
- friend class CGraph;
- friend class CGraphMatch;
- friend class CSBase0;
-
- public:
-
- CVertex ();
- CVertex ( RPCStream Object );
- CVertex ( int vtype, cpstr vname );
- CVertex ( int vtype );
- CVertex ( cpstr chem_elem );
- CVertex ( cpstr chem_elem, cpstr name );
- ~CVertex();
-
- void SetVertex ( cpstr chem_elem );
- void SetVertex ( int vtype, cpstr vname );
- void SetVertex ( int vtype );
- void SetType ( int vtype );
- void SetTypeExt ( int typeExt );
-
- void RemoveChirality();
- void LeaveChirality ( int eltype );
-
- void SetName ( cpstr vname );
- void SetProperty ( int vprop );
- void SetID ( int vid );
- void SetUserID ( int vid ) { user_id = vid; }
- void AddBond ();
- void CopyNBonds ( PCVertex V );
- int GetProperty () { return property; }
- int GetID () { return id; }
- int GetUserID () { return user_id; }
- cpstr GetName () { return name; }
- int GetType () { return type; }
- int GetTypeExt () { return type_ext; }
- int GetNBonds ();
-
- void SaveType (); // in userid
- void RestoreType (); // from userid
- void CopyType ( PCVertex V );
-
- virtual void Print ( int PKey );
-
- virtual void Copy ( PCVertex V );
-
- void read ( RCFile f );
- void write ( RCFile f );
-
- void mem_read ( cpstr S, int & l );
- void mem_write ( pstr S, int & l );
-
- protected:
- pstr name; // name may be general, "C", "Hg", "Cl" etc.
- int type; // type of vertex, see comments in mmdb_graph.cpp
- int type_ext; // vertex type extention
- int property; // flagwise properties -- user-defined
- int id; // a graph-defined vertex id
- int user_id; // a user-defined vertex id
-
- void InitVertex();
-
-};
-
-DefineStreamFunctions(CVertex);
-
-
-
-// =========================== CEdge =============================
-
-#define BOND_SINGLE 1
-#define BOND_DOUBLE 2
-#define BOND_AROMATIC 3
-#define BOND_TRIPLE 4
-
-DefineClass(CEdge);
-
-class CEdge : public CStream {
-
- friend class CGraph;
- friend class CGMatch;
- friend class CSBase0;
-
- public:
-
- CEdge ();
- CEdge ( RPCStream Object );
- CEdge ( int vx1, int vx2, int btype ); // vx1,vx2 are numbered
- // as 1,2,3 on and refer
- // to vertices in the order
- // as they were added to
- // the graph; btype>0
- ~CEdge();
-
- void SetEdge ( int vx1, int vx2, cpstr btype );
- void SetEdge ( int vx1, int vx2, int btype ); // btype>0
-
- void SetType ( int btype );
- void SetProperty ( int eprop );
- void SaveType (); // in property
- void RestoreType (); // from property
-
- inline int GetVertex1 () { return v1; }
- inline int GetVertex2 () { return v2; }
- inline int GetType () { return type; }
- inline int GetProperty () { return property; }
-
- virtual void Print ( int PKey );
-
- virtual void Copy ( PCEdge G );
-
- void read ( RCFile f );
- void write ( RCFile f );
-
- void mem_read ( cpstr S, int & l );
- void mem_write ( pstr S, int & l );
-
- protected:
- int v1,v2; // >=1
- int type;
- int property;
-
- void InitEdge();
-
-};
-
-DefineStreamFunctions(CEdge);
-
-
-
-// ========================== CGraph ============================
-
-#define MKGRAPH_Ok 0
-#define MKGRAPH_NoAtoms -1
-#define MKGRAPH_ChangedAltLoc 1
-#define MKGRAPH_MaxOccupancy 2
-
-DefineClass(CGraph);
-
-class CGraph : public CStream {
-
- friend class CGraphMatch;
- friend class CSBase0;
-
- public :
-
- CGraph ();
- CGraph ( PCResidue R, cpstr altLoc=NULL );
- CGraph ( RPCStream Object );
- ~CGraph();
-
- void Reset ();
- void SetName ( cpstr gname );
- pstr GetName () { return name; }
-
- // AddVertex(..) and AddEdge(..) do not copy the objects, but
- // take them over. This means that application should forget
- // about pointers to V and G once they were given to CGraph.
- // Vertices and edges must be allocated newly prior each call
- // to AddVertex(..) and AddEdge(..).
- void AddVertex ( PCVertex V );
- void AddEdge ( PCEdge G );
- void SetVertices ( PPCVertex V, int vlen );
- void SetEdges ( PPCEdge G, int glen );
-
- void RemoveChirality();
- void LeaveChirality ( int eltype );
-
- // MakeGraph(..) makes a graph corresponding to residue R.
- // The graphs vertices then correspond to the residue's atoms
- // (CVertex::userid points to atom R->atom[CVertex::userid]),
- // edges are calculated as chemical bonds between atoms basing
- // on the table of cut-off distances.
- // altCode specifies a particular conformation that should be
- // used for making the graph. If it is set to "" or NULL ("empty"
- // altcode) but the residue does not have conformation which
- // contains *only* ""-altcode atoms, a conformation corresponding
- // to maximal occupancy will be used. The same will happen if
- // altcode information in residue is not correct, whatever altCode
- // is specified.
- // After making the graph, Build(..) should be called as usual
- // before graph matching.
- // Non-negative return means that graph has been made.
- // MakeGraph(..) may return:
- // MKGRAPH_Ok everything is Ok
- // MKGRAPH_NoAtoms residue does not have atoms, graph
- // is not made
- // MKGRAPH_ChangedAltLoc a different altcode was used because
- // the residue has only one altcode and
- // that is different of
- // MKGRAPH_MaxOccupancy a maximal-occupancy conformation has
- // been chosen because of default
- // ""-altcode supplied or incorrect
- // altcode information in the residue
- int MakeGraph ( PCResidue R, cpstr altLoc=NULL );
-
- int MakeGraph ( PPCAtom atom, int nAtoms );
-
- void HideType ( int bond_vx_type );
- void ExcludeType ( int type );
-
- void MakeSymmetryRelief ( Boolean noCO2 );
- void IdentifyRings ();
- int IdentifyConnectedComponents(); // returns their number >= 1
-
- int Build ( Boolean bondOrder ); // returns 0 if Ok
-
- void MakeVertexIDs (); // simply numbers vertices as 1.. on
- int GetVertexID ( int vertexNo );
- int GetVertexNo ( cpstr vname );
- // GetBondedVertexID(..) works after MoveType(..)
- int GetNBondedVertices ( int vertexNo );
- int GetBondedVertexID ( int vertexNo, int bond_vx_type,
- int bondNo );
-
- PCVertex GetVertex ( int vertexNo ); // 1<=vertexNo<=nVertices
- inline int GetNofVertices() { return nVertices; }
-
- PCEdge GetEdge ( int edgeNo ); // 1<=edgeNo<=nEdges
- inline int GetNofEdges() { return nEdges; }
-
- void GetVertices ( PPCVertex & V, int & nV );
- void GetEdges ( PPCEdge & E, int & nE );
-
- virtual void Print();
- void Print1();
-
- virtual void Copy ( PCGraph G );
-
- void read ( RCFile f );
- void write ( RCFile f );
-
- void mem_read ( cpstr S, int & l );
- void mem_write ( pstr S, int & l );
-
- protected :
- pstr name;
- int nVertices,nEdges, nAllVertices,nAllEdges;
- PPCVertex Vertex;
- PPCEdge Edge;
- imatrix graph;
-
- void InitGraph ();
- void FreeMemory();
-
- void markConnected ( int vno, int cno );
-
- private :
- int nVAlloc,nEAlloc,nGAlloc;
-
-};
-
-DefineStreamFunctions(CGraph);
-
-
-// ========================== CMatch ============================
-
-DefineClass(CMatch);
-DefineStreamFunctions(CMatch);
-
-class CMatch : public CStream {
-
- friend class CGraphMatch;
-
- public :
-
- CMatch ();
- CMatch ( RPCStream Object );
- CMatch ( ivector FV1, ivector FV2, int nv, int n, int m );
- ~CMatch();
-
- // FV1[] and FV2[] are copied into internal buffers
- void SetMatch ( ivector FV1, ivector FV2, int nv, int n, int m );
-
- Boolean isMatch ( ivector FV1, ivector FV2, int nv );
- Boolean isCombination ( ivector FV1, ivector FV2, int nv );
-
- // do not allocate or dispose FV1 and FV2 in application!
- void GetMatch ( ivector & FV1, ivector & FV2, int & nv,
- realtype & p1, realtype & p2 );
-
- void read ( RCFile f );
- void write ( RCFile f );
-
- void mem_read ( cpstr S, int & l );
- void mem_write ( pstr S, int & l );
-
- protected :
- int n1,n2,mlength;
- ivector F1,F2;
-
- void InitMatch();
-
- private :
- int nAlloc;
-
-};
-
-
-// ======================= CGraphMatch =========================
-
-#define _UseRecursion
-
-#define GMF_UniqueMatch 0x00000001
-#define GMF_NoCombinations 0x00000002
-
-#define EXTTYPE_Ignore 0
-#define EXTTYPE_Equal 1
-#define EXTTYPE_AND 2
-#define EXTTYPE_OR 3
-#define EXTTYPE_XOR 4
-#define EXTTYPE_NotEqual 5
-#define EXTTYPE_NotAND 6
-#define EXTTYPE_NotOR 7
-
-
-DefineClass(CGraphMatch);
-
-class CGraphMatch : public CStream {
-
- public :
-
- CGraphMatch ();
- CGraphMatch ( RPCStream Object );
- ~CGraphMatch();
-
- void SetFlag ( word flag );
- void RemoveFlag ( word flag );
- void SetMaxNofMatches ( int maxNofMatches, Boolean stopOnMaxN );
- void SetTimeLimit ( int maxTimeToRun=0 );
- Boolean GetStopSignal () { return Stop; }
-
- void Reset();
-
- // MatchGraphs looks for maximal common subgraphs of size
- // not less than minMatch. The number of found subgraphs
- // is returned by GetNofMatches(), the subgraph vertices
- // are returned by GetMatch(..). Control parameters:
- // vertexType True if vertex type should be taken
- // into account and False otherwise
- // vertexExt key to use extended vertex types (defined
- // as type_ext in CVertex).
- void MatchGraphs ( PCGraph Gh1, PCGraph Gh2, int minMatch,
- Boolean vertexType=True,
- int vertexExt=EXTTYPE_Ignore );
- void PrintMatches ();
- int GetNofMatches () { return nMatches; }
- int GetMaxMatchSize() { return maxMatch; }
-
- // do not allocate or dispose FV1 and FV2 in application!
- // FV1/p1 will always correspond to Gh1, and FV2/p2 -
- // to Gh2 as specified in MatchGraphs(..)
- void GetMatch ( int MatchNo, ivector & FV1, ivector & FV2,
- int & nv, realtype & p1, realtype & p2 );
-
- void read ( RCFile f );
- void write ( RCFile f );
-
- void mem_read ( cpstr S, int & l );
- void mem_write ( pstr S, int & l );
-
- protected :
- PCGraph G1,G2;
- PPCVertex V1;
- PPCVertex V2;
- imatrix c1,c2;
- Boolean swap;
-#ifndef _UseRecursion
- ivector jj;
-#endif
- int n,m;
-
- imatrix3 P;
- imatrix iF1;
- ivector F1,F2,ix;
-
- int nMatches,maxNMatches;
- PPCMatch Match;
- Boolean wasFullMatch,Stop,stopOnMaxNMathches;
- word flags;
- int maxMatch,timeLimit;
-
- void InitGraphMatch();
- void FreeMemory ();
- void FreeRecHeap ();
- void GetMemory ();
- void GetRecHeap ();
- int Initialize ( Boolean vertexType, int vertexExt );
-#ifdef _UseRecursion
- void Backtrack ( int i ); // exact matching
-#else
- void Ullman ();
-#endif
- void Backtrack1 ( int i, int k0 ); // exact/partial matching
- void CollectMatch ( int nm );
-
- private :
- int nAlloc,mAlloc,nMAlloc;
- time_t startTime;
-
-};
-
-DefineStreamFunctions(CGraphMatch);
-
-extern void SetGraphAllocPortion ( int alloc_portion );
-
-/*
-extern void TestGraphMatch();
-*/
-
-
-#endif
diff --git a/mmdb/mmdb_manager.cpp b/mmdb/mmdb_manager.cpp
deleted file mode 100755
index 77e46f1..0000000
--- a/mmdb/mmdb_manager.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-// $Id: mmdb_manager.cpp,v 1.25 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 23.06.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : mmdb_manager <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CMMDBManager ( MMDB file manager class )
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __MMDB_Manager__
-#include "mmdb_manager.h"
-#endif
-
-
-// ===================== CMMDBManager =======================
-
-CMMDBManager::CMMDBManager() : CMMDBBondManager() {
-}
-
-CMMDBManager::CMMDBManager ( RPCStream Object )
- : CMMDBBondManager(Object) {
-}
-
-CMMDBManager::~CMMDBManager() {}
-
-void CMMDBManager::Copy ( PCMMDBManager MMDB, word CopyMask ) {
-PCModel model;
-PPCChain chain;
-PCChain ch;
-ChainID chID;
-int i,j, nchains;
-
- if (CopyMask & MMDBFCM_Flags) Flags = MMDB->Flags;
-
- if (CopyMask & MMDBFCM_Title) Title.Copy ( &(MMDB->Title) );
- if (CopyMask & MMDBFCM_Cryst) Cryst.Copy ( &(MMDB->Cryst) );
-
- if (CopyMask & MMDBFCM_Coord) {
-
- FreeCoordMemory ();
- DeleteAllSelections();
-
- nAtoms = MMDB->nAtoms;
- AtmLen = nAtoms;
- if (nAtoms>0) {
- Atom = new PCAtom[AtmLen];
- for (i=0;i<nAtoms;i++) {
- if (MMDB->Atom[i]) {
- Atom[i] = newCAtom();
- Atom[i]->Copy ( MMDB->Atom[i] );
- // the internal atom references are installed
- // by residue classes when they are read in
- // model->chain below
- Atom[i]->SetAtomIndex ( i+1 );
- } else
- Atom[i] = NULL;
- }
- }
-
- nModels = MMDB->nModels;
- if (nModels>0) {
- Model = new PCModel[nModels];
- for (i=0;i<nModels;i++) {
- if (MMDB->Model[i]) {
- Model[i] = newCModel();
- Model[i]->SetMMDBManager ( this,0 );
- Model[i]->_copy ( MMDB->Model[i] );
- } else
- Model[i] = NULL;
- }
- }
-
- crModel = NULL;
- crChain = NULL;
- crRes = NULL;
-
- if (MMDB->crModel) {
-
- for (i=0;i<nModels;i++)
- if (Model[i]) {
- if (Model[i]->serNum==MMDB->crModel->serNum) {
- crModel = Model[i];
- break;
- }
- }
-
- if (crModel && crModel->Chain && MMDB->crChain)
- for (i=0;i<crModel->nChains;i++)
- if (crModel->Chain[i]) {
- if (!strcmp(crModel->Chain[i]->chainID,
- MMDB->crModel->Chain[i]->chainID)) {
- crChain = crModel->Chain[i];
- break;
- }
- }
-
- if (crChain && crChain->Residue && MMDB->crRes)
- for (i=0;i<crChain->nResidues;i++)
- if (crChain->Residue[i]) {
- if ((!strcmp(crChain->Residue[i]->name,
- MMDB->crRes->name)) &&
- (crChain->Residue[i]->seqNum==MMDB->crRes->seqNum) &&
- (!strcmp(crChain->Residue[i]->insCode,
- MMDB->crRes->insCode))) {
- crRes = crChain->Residue[i];
- break;
- }
- }
- }
-
- /*
- if ((MMDB->nSelections>0) && MMDB->Mask) {
- nSelections = MMDB->nSelections;
- if (nSelections>0) {
- Mask = new PCMask [nSelections];
- SelAtom = new PPCAtom[nSelections];
- nSelAtoms = new int [nSelections];
- for (i=0;i<nSelections;i++) {
- Mask[i] = new CMask();
- Mask[i]->CopyMask ( MMDB->Mask[i] );
- nSelAtoms[i] = MMDB->nSelAtoms[i];
- if (nSelAtoms[i]>0) {
- SelAtom[i] = new PCAtom[nSelAtoms[i]];
- for (j=0;j<nSelAtoms[i];j++)
- SelAtom[i][j] = Atom[MMDB->SelAtom[i][j]->index];
- } else
- SelAtom[i] = NULL;
- }
- }
- }
- */
-
- } else if (CopyMask & (MMDBFCM_HetInfo | MMDBFCM_SecStruct |
- MMDBFCM_Links | MMDBFCM_CisPeps |
- MMDBFCM_ChainAnnot)) {
-
- for (i=0;i<MMDB->nModels;i++)
- if (MMDB->Model[i]) {
-
- model = GetModel ( i+1 );
- if (!model) {
- model = new CModel( NULL,i+1 );
- AddModel ( model );
- }
-
- if (CopyMask & MMDBFCM_HetInfo)
- model->CopyHets ( MMDB->Model[i] );
- if (CopyMask & MMDBFCM_SecStruct)
- model->CopySecStructure ( MMDB->Model[i] );
- if (CopyMask & MMDBFCM_Links) {
- model->CopyLinks ( MMDB->Model[i] );
- model->CopyLinkRs ( MMDB->Model[i] );
- }
- if (CopyMask & MMDBFCM_CisPeps)
- model->CopyCisPeps ( MMDB->Model[i] );
- if (CopyMask & MMDBFCM_ChainAnnot) {
- MMDB->GetChainTable ( i+1,chain,nchains );
- for (j=0;j<nchains;j++)
- if (chain[j]) {
- chain[j]->GetChainID ( chID );
- ch = model->GetChain ( chID );
- if (!ch) {
- ch = new CChain();
- ch->SetChainID ( chID );
- model->AddChain ( ch );
- }
- ch->CopyAnnotations ( chain[j] );
- }
-
- }
-
- }
-
- }
-
- if (CopyMask & MMDBFCM_SA) SA.Copy ( &(MMDB->SA) );
- if (CopyMask & MMDBFCM_SB) SB.Copy ( &(MMDB->SB) );
- if (CopyMask & MMDBFCM_SC) SC.Copy ( &(MMDB->SC) );
- if (CopyMask & MMDBFCM_Footnotes)
- Footnote.Copy ( &(MMDB->Footnote) );
-
- if (CopyMask & MMDBFCM_Buffer) {
- lcount = MMDB->lcount;
- strncpy ( S,MMDB->S,sizeof(S) );
- }
-
-}
-
-void CMMDBManager::Delete ( word DelMask ) {
-PPCModel model;
-PPCChain chain;
-int i,j,nm, nchains;
-
- if (DelMask & MMDBFCM_Flags) Flags = 0;
-
- if (DelMask & MMDBFCM_Title) Title.Copy ( NULL );
- if (DelMask & MMDBFCM_TitleKeepBM) Title.FreeMemory ( True );
- if (DelMask & MMDBFCM_Cryst) Cryst.Copy ( NULL );
-
- if (DelMask & MMDBFCM_Coord) {
- FreeCoordMemory ();
- DeleteAllSelections();
- }
-
- if (DelMask & MMDBFCM_SecStruct) {
- GetModelTable ( model,nm );
- if (model)
- for (i=0;i<nm;i++)
- if (model[i])
- model[i]->RemoveSecStructure();
- }
-
- if (DelMask & MMDBFCM_HetInfo) {
- GetModelTable ( model,nm );
- if (model)
- for (i=0;i<nm;i++)
- if (model[i])
- model[i]->RemoveHetInfo();
- }
-
- if (DelMask & MMDBFCM_Links) {
- GetModelTable ( model,nm );
- if (model)
- for (i=0;i<nm;i++)
- if (model[i]) {
- model[i]->RemoveLinks ();
- model[i]->RemoveLinkRs();
- }
- }
-
- if (DelMask & MMDBFCM_CisPeps) {
- GetModelTable ( model,nm );
- if (model)
- for (i=0;i<nm;i++)
- if (model[i])
- model[i]->RemoveCisPeps();
- }
-
- if (DelMask & MMDBFCM_ChainAnnot) {
- nm = GetNumberOfModels();
- for (i=1;i<=nm;i++) {
- GetChainTable ( i,chain,nchains );
- if (chain)
- for (j=0;j<nchains;j++)
- if (chain[j])
- chain[j]->FreeAnnotations();
- }
- }
-
- if (DelMask & MMDBFCM_SA) SA.FreeContainer();
- if (DelMask & MMDBFCM_SB) SB.FreeContainer();
- if (DelMask & MMDBFCM_SC) SC.FreeContainer();
- if (DelMask & MMDBFCM_Footnotes) Footnote.FreeContainer();
-
- if (DelMask & MMDBFCM_Buffer) {
- lcount = 0;
- S[0] = char(0);
- }
-
-}
-
-PCTitleContainer CMMDBManager::GetRemarks() {
- return Title.GetRemarks();
-}
-
-
-PCTitleContainer CMMDBManager::GetJournal() {
- return Title.GetJournal();
-}
-
-realtype CMMDBManager::GetResolution() {
- return Title.GetResolution();
-}
-
-int CMMDBManager::ParseBiomolecules() {
- return Title.ParseBiomolecules();
-}
-
-int CMMDBManager::GetNofBiomolecules() {
- return Title.GetNofBiomolecules();
-}
-
-void CMMDBManager::GetBiomolecules ( PPCBiomolecule & BM,
- int & nBMs ) {
- Title.GetBiomolecules ( BM,nBMs );
-}
-
-PCBiomolecule CMMDBManager::GetBiomolecule ( int bmNo ) {
- return Title.GetBiomolecule ( bmNo );
-}
-
-PCMMDBManager CMMDBManager::MakeBiomolecule ( int bmNo, int modelNo ) {
-PCMMDBManager M;
-PPCChain ch;
-PCChain chain;
-PCModel model;
-PCBiomolecule BM;
-int i,j,k,n,n0,nChains;
-
- BM = Title.GetBiomolecule ( bmNo );
- if (!BM) return NULL;
-
- GetChainTable ( modelNo,ch,nChains );
- if ((!ch) || (nChains<=0)) return NULL;
-
- n0 = 0;
- model = new CModel();
-
- for (i=0;(i<BM->nBMAs) && (n0>=0);i++)
- if (BM->BMApply[i]) {
- for (j=0;(j<BM->BMApply[i]->nMatrices) && (n0>=0);j++)
- for (k=0;(k<BM->BMApply[i]->nChains) && (n0>=0);k++) {
- n0 = -1;
- for (n=0;(n<nChains) && (n0<0);n++)
- if (!strcmp(ch[n]->GetChainID(),BM->BMApply[i]->chain[k]))
- n0 = n;
- if (n0>=0) {
- chain = new CChain();
- chain->Copy ( ch[n0] );
- chain->ApplyTransform ( BM->BMApply[i]->tm[j] );
- model->AddChain ( chain );
- }
- }
- }
-
- if (n0>=0) {
- M = new CMMDBManager();
- M->AddModel ( model );
- M->PDBCleanup ( PDBCLEAN_SERIAL | PDBCLEAN_INDEX );
- } else {
- delete model;
- M = NULL;
- }
-
- return M;
-
-}
-
-
-// ------------------- Stream functions ----------------------
-
-
-void CMMDBManager::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- CMMDBBondManager::write ( f );
-}
-
-void CMMDBManager::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- CMMDBBondManager::read ( f );
-}
-
-
-MakeStreamFunctions(CMMDBManager)
diff --git a/mmdb/mmdb_manager.h b/mmdb/mmdb_manager.h
deleted file mode 100755
index fd04b58..0000000
--- a/mmdb/mmdb_manager.h
+++ /dev/null
@@ -1,122 +0,0 @@
-// $Id: mmdb_manager.h,v 1.23 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 23.06.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : mmdb_manager <interface>
-// ~~~~~~~~~
-// Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CMMDBManager ( MMDB file manager )
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-#ifndef __MMDB_Manager__
-#define __MMDB_Manager__
-
-#ifndef __MMDB_BondMngr__
-#include "mmdb_bondmngr.h"
-#endif
-
-
-// ======================= CMMDBManager ===========================
-
-
-// copy masks
-#define MMDBFCM_All 0xFFFFFFFF
-#define MMDBFCM_Title 0x00000001
-#define MMDBFCM_TitleKeepBM 0x00000002
-#define MMDBFCM_Cryst 0x00000004
-#define MMDBFCM_Coord 0x00000008
-#define MMDBFCM_SecStruct 0x00000010
-#define MMDBFCM_HetInfo 0x00000020
-#define MMDBFCM_Links 0x00000040
-#define MMDBFCM_CisPeps 0x00000080
-#define MMDBFCM_SA 0x00000100
-#define MMDBFCM_SB 0x00000200
-#define MMDBFCM_SC 0x00000400
-#define MMDBFCM_Footnotes 0x00000800
-#define MMDBFCM_ChainAnnot 0x00001000
-#define MMDBFCM_Flags 0x00002000
-#define MMDBFCM_Buffer 0x80000000
-#define MMDBFCM_Top 0xFFFFFFF7
-
-DefineStreamFunctions(CMMDBManager)
-
-class CMMDBManager : public CMMDBBondManager {
-
- public :
-
- CMMDBManager ();
- CMMDBManager ( RPCStream Object );
- ~CMMDBManager();
-
-
- // --------------- Copying/Deleting -----------------------
-
- // Copy(..) will transfer different sort of information
- // between two MMDB's according to the copy mask given
- // (cf. MMDBFCM_XXXXX values). Note that the copying content
- // replaces the corresponding information (e.g. copying
- // coordinates will replace existing coordinates rather than
- // add to them).
- void Copy ( PCMMDBManager MMDB, word CopyMask );
-
- // Delete(..) deletes different sort of information from
- // the MMDB according to the delete mask given.
- void Delete ( word DelMask ); // DelMask is the same as CopyMask
-
- PCTitleContainer GetRemarks();
- PCTitleContainer GetJournal();
-
- realtype GetResolution(); // -1.0 means no resolution record in file
-
- int ParseBiomolecules(); // returns the number of biomolecules,
- // -2 for general format error
- // -3 for errors in BIOMT records
- int GetNofBiomolecules();
- void GetBiomolecules ( PPCBiomolecule & BM, int & nBMs );
-
- PCBiomolecule GetBiomolecule ( int bmNo ); // bmno=0,1,..
- // returns NULL if bmNo is incorrect
- PCMMDBManager MakeBiomolecule ( int bmNo, int modelNo=1 );
-
-
-
- protected :
-
- // --------------- Stream I/O -----------------------------
- void write ( RCFile f );
- void read ( RCFile f );
-
-};
-
-#endif
-
diff --git a/mmdb/mmdb_mask.cpp b/mmdb/mmdb_mask.cpp
deleted file mode 100755
index 9f50748..0000000
--- a/mmdb/mmdb_mask.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-// $Id: mmdb_mask.cpp,v 1.20 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 29.01.10 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_Mask <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-//
-// **** Classes : CMask ( atom selection mask )
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2010
-//
-// =================================================================
-//
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifndef __MMDB_Mask__
-#include "mmdb_mask.h"
-#endif
-
-
-// ==================== CMask ========================
-
-CMask::CMask() : CStream() {
- InitMask();
-}
-
-CMask::CMask ( RPCStream Object ) : CStream(Object) {
- InitMask();
-}
-
-CMask::~CMask() {
- ClearMask();
-}
-
-void CMask::InitMask() {
- mlen = 0;
- m = NULL;
-}
-
-void CMask::SetMaskBit ( int BitNo ) {
-int n,i;
- n = BitNo/(8*sizeof(word));
- Expand ( n+1 );
- i = BitNo - n*(8*sizeof(word));
- m[n] |= ((word)1 << i);
-}
-
-void CMask::Expand ( int n ) {
-wvector m1;
-int i;
- if (mlen<n) {
- m1 = new word[n];
- for (i=0;i<mlen;i++)
- m1[i] = m[i];
- for (i=mlen;i<n;i++)
- m1[i] = 0;
- if (m) delete[] m;
- m = m1;
- mlen = n;
- }
-}
-
-void CMask::NewMask ( PPCMask Mask, int nMasks ) {
-int i,nlen;
-word w;
- ClearMask();
- if (Mask && (nMasks>0)) {
- nlen = 0;
- w = 0;
- while (w==0) {
- for (i=0;i<nMasks;i++)
- if (Mask[i]) {
- if (nlen<Mask[i]->mlen)
- w |= Mask[i]->m[nlen];
- }
- nlen++;
- w = ~w;
- }
- Expand ( nlen );
- i = nlen-1;
- m[i] = 1;
- while (!(m[i] & w))
- m[i] <<= 1;
- } else {
- Expand ( 1 );
- m[0] = 1;
- }
-}
-
-void CMask::CopyMask ( PCMask Mask ) {
-int i;
- if (mlen!=Mask->mlen) ClearMask();
- if (Mask) {
- mlen = Mask->mlen;
- if (mlen>0) {
- m = new word[mlen];
- for (i=0;i<mlen;i++)
- m[i] = Mask->m[i];
- }
- }
-}
-
-void CMask::SetMask ( PCMask Mask ) {
-int i;
- if (Mask) {
- Expand ( Mask->mlen );
- for (i=0;i<Mask->mlen;i++)
- m[i] |= Mask->m[i];
- }
-}
-
-void CMask::RemoveMask ( PCMask Mask ) {
-int i,l;
- if (Mask) {
- l = IMin(mlen,Mask->mlen);
- for (i=0;i<l;i++)
- m[i] &= ~Mask->m[i];
- }
-}
-
-void CMask::SelMask ( PCMask Mask ) {
-int i,l;
- if (Mask) {
- l = IMin(mlen,Mask->mlen);
- for (i=0;i<l;i++)
- m[i] &= Mask->m[i];
- for (i=l;i<mlen;i++)
- m[i] = 0;
- } else
- ClearMask();
-}
-
-void CMask::XadMask ( PCMask Mask ) {
-int i;
- if (Mask) {
- Expand ( Mask->mlen );
- for (i=0;i<Mask->mlen;i++)
- m[i] ^= Mask->m[i];
- }
-}
-
-void CMask::ClearMask() {
- if (m) delete[] m;
- m = NULL;
- mlen = 0;
-}
-
-void CMask::NegMask() {
-int i;
- for (i=0;i<mlen;i++)
- m[i] = ~m[i];
-}
-
-Boolean CMask::CheckMask ( PCMask Mask ) {
-int i,l;
- if (Mask) {
- i = 0;
- l = IMin(mlen,Mask->mlen);
- while ((i<l) && (!(m[i] & Mask->m[i]))) i++;
- return (i<l);
- } else
- return False;
-}
-
-Boolean CMask::isMask() {
-int i=0;
- while ((i<mlen) && (!m[i])) i++;
- return (i<mlen);
-}
-
-pstr CMask::Print ( pstr S ) {
-int i,j,k;
-word w;
- j = 0;
- for (i=0;i<mlen;i++) {
- w = 1;
- for (k=0;k<8*(int)sizeof(word);k++) {
- if (w & m[i]) S[j] = '1';
- else S[j] = '0';
- w <<= 1;
- j++;
- }
- }
- S[j] = char(0);
- return S;
-}
-
-void CMask::write ( RCFile f ) {
-int i;
- f.WriteInt ( &mlen );
- for (i=0;i<mlen;i++)
- f.WriteWord ( &(m[i]) );
-}
-
-void CMask::read ( RCFile f ) {
-int i;
- if (m) {
- delete[] m;
- m = NULL;
- }
- f.ReadInt ( &mlen );
- if (mlen>0) {
- m = new word[mlen];
- for (i=0;i<mlen;i++)
- f.ReadWord ( &(m[i]) );
- }
-}
-
-
-MakeStreamFunctions(CMask)
-
-
diff --git a/mmdb/mmdb_mmcif.cpp b/mmdb/mmdb_mmcif.cpp
deleted file mode 100755
index 65b2823..0000000
--- a/mmdb/mmdb_mmcif.cpp
+++ /dev/null
@@ -1,3671 +0,0 @@
-// $Id: mmdb_mmcif.cpp,v 1.24 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2013.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 07.02.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_MMCIF <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CMMCIFCategory ( mmCIF category )
-// ~~~~~~~~~ CMMCIFStruct ( mmCIF structure )
-// CMMCIFLoop ( mmCIF loop )
-// CMMCIFData ( mmCIF data block )
-// CMMCIFFile ( mmCIF file )
-//
-// (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifndef __TIME_H
-#include <time.h>
-#endif
-
-#ifndef __MMDB_MMCIF__
-#include "mmdb_mmcif.h"
-#endif
-
-
-
-// ====================== SortTags ===============================
-
-void SortTags ( psvector tag, int len, ivector index ) {
-int i,k,l,l1,l2;
- if (len==1) {
- index[0] = 0;
- return;
- }
- if (strcasecmp(tag[0],tag[1])<0) {
- index[0] = 0;
- index[1] = 1;
- } else {
- index[0] = 1;
- index[1] = 0;
- }
- for (k=2;k<len;k++) {
- l2 = k-1;
- if (strcasecmp(tag[k],tag[index[0]])<0) l2 = 0;
- else if (strcasecmp(tag[k],tag[index[l2]])>0) l2 = k;
- else {
- l1 = 0;
- while (l1<l2-1) {
- l = (l1+l2)/2;
- if (strcasecmp(tag[k],tag[index[l]])<0) l2 = l;
- else l1 = l;
- }
- }
- for (i=k;i>l2;i--)
- index[i] = index[i-1];
- index[l2] = k;
- }
-}
-
-
-
-// ====================== CMMCIFCategory ==========================
-
-
-CMMCIFCategory::CMMCIFCategory() : CStream() {
- InitMMCIFCategory();
-}
-
-CMMCIFCategory::CMMCIFCategory ( cpstr N ) : CStream() {
- InitMMCIFCategory();
- SetCategoryName ( N );
-}
-
-CMMCIFCategory::CMMCIFCategory ( RPCStream Object )
- : CStream(Object) {
- InitMMCIFCategory();
-}
-
-CMMCIFCategory::~CMMCIFCategory() {
- FreeMemory();
-}
-
-void CMMCIFCategory::InitMMCIFCategory() {
- name = NULL;
- nTags = 0;
- tag = NULL;
- index = NULL;
- nAllocTags = 0;
-}
-
-void CMMCIFCategory::FreeMemory() {
-int i;
- if (name) delete[] name;
- name = NULL;
- for (i=0;i<nAllocTags;i++)
- if (tag[i]) delete[] tag[i];
- FreeVectorMemory ( tag ,0 );
- FreeVectorMemory ( index,0 );
- nTags = 0;
- nAllocTags = 0;
-}
-
-void CMMCIFCategory::SetCategoryName ( cpstr N ) {
- if (N[0]) CreateCopy ( name,N );
- else {
- CreateCopy ( name,pstr(" ") );
- name[0] = char(1); // no category name
- }
-}
-
-void CMMCIFCategory::ExpandTags ( int nTagsNew ) {
-int i,nAT;
-psvector tag1;
-ivector index1;
- if (nTagsNew>nAllocTags) {
- nAT = nTagsNew + IMin(nAllocTags/2+1,20);
- GetVectorMemory ( tag1 ,nAT,0 );
- GetVectorMemory ( index1,nAT,0 );
- for (i=0;i<nAllocTags;i++) {
- tag1 [i] = tag [i];
- index1[i] = index[i];
- }
- for (i=nAllocTags;i<nAT;i++) {
- tag1 [i] = NULL;
- index1[i] = i;
- }
- FreeVectorMemory ( tag ,0 );
- FreeVectorMemory ( index,0 );
- tag = tag1;
- index = index1;
- nAllocTags = nAT;
- }
-}
-
-pstr CMMCIFCategory::GetTag ( int tagNo ) {
- if ((tagNo>=0) && (tagNo<nTags)) return tag[tagNo];
- return NULL;
-}
-
-void CMMCIFCategory::Sort() {
-// Sorts tags for easing the search
-int i,k;
- if (nAllocTags>0) {
- k = 0;
- if (!index)
- GetVectorMemory ( index,nAllocTags,0 );
- for (i=0;i<nTags;i++)
- if (tag[i]) {
- if (k<i) {
- tag[k] = tag[i];
- tag[i] = NULL;
- }
- k++;
- }
- nTags = k;
- SortTags ( tag,nTags,index );
- }
-}
-
-void CMMCIFCategory::Optimize() {
-int i,k;
-psvector tag1;
- k = 0;
- for (i=0;i<nTags;i++)
- if (tag[i]) k++;
- if (k<=0) FreeMemory();
- else if (k!=nAllocTags) {
- GetVectorMemory ( tag1,k,0 );
- FreeVectorMemory ( index,0 );
- k = 0;
- for (i=0;i<nTags;i++)
- if (tag[i])
- tag1[k++] = tag[i];
- FreeVectorMemory ( tag,0 );
- tag = tag1;
- nTags = k;
- nAllocTags = nTags;
- Sort();
- }
-}
-
-int CMMCIFCategory::GetTagNo ( cpstr ttag ) {
-// Binary search for index of tag ttag in tag[].
-// Return:
-// >=0 : position of the tag found
-// <0 : the tag was not found, it could be inserted before
-// (-RC-1)th element, where RC is the return value
-int l1,l2,l,k;
-
- if (!tag) return -1;
-
- if (!index) Sort();
-
- l = 0;
- l1 = 0;
- l2 = nTags-1;
- k = 1;
- while (l1<l2-1) {
- l = (l1+l2)/2;
- k = strcasecmp ( ttag,tag[index[l]] );
- if (k<0) l2 = l;
- else if (k>0) l1 = l;
- else {
- l1 = l;
- break;
- }
- }
-
- if (k==0) return index[l]; // is at RCth position
- k = strcasecmp ( ttag,tag[index[l1]] );
- if (k==0) return index[l1]; // is at RCth position
- if (k<0) return -1; // would be at (-RC-1)th position
- if (l2!=l1) {
- k = strcasecmp ( ttag,tag[index[l2]] );
- if (k==0) return index[l2]; // is at RCth position
- if (k>0) return -2-l2; // would be at l2+1=(-RC-1)th position
- }
-
- return -2-l1; // would be at l1+1=(-RC-1)th position
-
-}
-
-int CMMCIFCategory::AddTag ( cpstr ttag ) {
-// return -1: the tag has been added on the top of array;
-// index is added and sorted automatically
-// >=0: the tag is already in the array -- its position
-// is returned
-int i1,i;
- if (!tag) {
- ExpandTags ( 3 ); // get space for first 3 tags
- CreateCopy ( tag[0],ttag );
- nTags = 1;
- return -nTags; // the tag has been added on the top of array
- }
- i1 = GetTagNo ( ttag );
- if (i1>=0) return i1; // non-negative returns mean that
- // the tag is already in the array
- i1 = -i1-1; // otherwise the tag has to be added and indexed at here
- // put new tag on the top of array and update index
- ExpandTags ( nTags+1 );
- CreateCopy ( tag[nTags],ttag );
- for (i=nTags;i>i1;i--)
- index[i] = index[i-1];
- index[i1] = nTags;
- nTags++;
- return -nTags; // the tag has been added on the top of array
-}
-
-void CMMCIFCategory::PrintTags() {
-int i;
- Sort();
- printf ( " Unsorted tags:\n" );
- for (i=0;i<nTags;i++)
- if (tag[i])
- printf ( " %s.%s\n",name,tag[i] );
- if (index) {
- printf ( " Sorted tags:\n" );
- for (i=0;i<nTags;i++)
- if (tag[index[i]])
- printf ( " %s.%s\n",name,tag[index[i]] );
- }
-}
-
-Boolean CMMCIFCategory::CheckTags ( cpstr * tagList ) {
-int i;
- i = 0;
- while (tagList[i][0]) {
- if (GetTagNo(tagList[i])<0) return False;
- i++;
- }
- return True;
-}
-
-void CMMCIFCategory::PutCategoryName ( cpstr newName ) {
- CreateCopy ( name,newName );
-}
-
-void CMMCIFCategory::Copy ( PCMMCIFCategory Category ) {
-int i;
- FreeMemory();
- if (Category) {
- CreateCopy ( name,Category->name );
- nTags = Category->nTags;
- nAllocTags = nTags;
- if (nTags>0) {
- GetVectorMemory ( tag ,nAllocTags,0 );
- GetVectorMemory ( index,nAllocTags,0 );
- for (i=0;i<nTags;i++) {
- tag[i] = NULL;
- CreateCopy ( tag[i],Category->tag[i] );
- index[i] = Category->index[i];
- }
- }
- }
-}
-
-
-void CMMCIFCategory::write ( RCFile f ) {
-int i;
- if (!index) Sort();
- f.CreateWrite ( name );
- f.WriteInt ( &nTags );
- for (i=0;i<nTags;i++)
- f.CreateWrite ( tag[i] );
- f.WriteVector ( index,nTags,0 );
-}
-
-void CMMCIFCategory::read ( RCFile f ) {
-int i;
- FreeMemory ();
- f.CreateRead ( name );
- f.ReadInt ( &nTags );
- nAllocTags = nTags;
- if (nTags>0) {
- GetVectorMemory ( tag,nTags,0 );
- for (i=0;i<nTags;i++) {
- tag[i] = NULL;
- f.CreateRead ( tag[i] );
- }
- }
- f.CreateReadVector ( index,0 );
-}
-
-MakeStreamFunctions(CMMCIFCategory);
-
-
-
-// ====================== CMMCIFStruct ===========================
-
-
-CMMCIFStruct::CMMCIFStruct() : CMMCIFCategory() {
- InitMMCIFStruct();
-}
-
-CMMCIFStruct::CMMCIFStruct ( cpstr N ) : CMMCIFCategory(N) {
- InitMMCIFStruct();
-}
-
-CMMCIFStruct::CMMCIFStruct ( RPCStream Object ) : CMMCIFCategory(Object) {
- InitMMCIFStruct();
-}
-
-CMMCIFStruct::~CMMCIFStruct() {
- FreeMemory();
-}
-
-void CMMCIFStruct::FreeMemory() {
-int i;
- for (i=0;i<nAllocTags;i++)
- if (field[i]) delete[] field[i];
- FreeVectorMemory ( field,0 );
- CMMCIFCategory::FreeMemory();
-}
-
-void CMMCIFStruct::InitMMCIFStruct() {
- field = NULL;
-}
-
-void CMMCIFStruct::Optimize() {
-int i,k;
-psvector f1;
- k = 0;
- for (i=0;i<nTags;i++)
- if (!tag[i]) {
- if (field[i]) delete[] field[i];
- field[i] = NULL;
- } else if (!field[i]) {
- delete[] tag[i];
- tag[i] = NULL;
- } else
- k++;
- if (k<=0) FreeMemory();
- else if (k!=nAllocTags) {
- f1 = new pstr[k];
- k = 0;
- for (i=0;i<nTags;i++)
- if (tag[i])
- f1[k++] = field[i];
- FreeVectorMemory ( field,0 );
- field = f1;
- CMMCIFCategory::Optimize();
- }
-}
-
-void CMMCIFStruct::AddField ( cpstr F, cpstr T, Boolean Concatenate ) {
-psvector field1;
-int i,nAT;
-pstr nf;
-
- nAT = nAllocTags;
- i = AddTag ( T );
-
- if (i<0) {
- // The tag was not in the list, but has been added on the top
- // of list. Now expand the field list and put new field on
- // the top of it.
- if (nAllocTags>nAT) {
- GetVectorMemory ( field1,nAllocTags,0 );
- for (i=0;i<nTags-1;i++)
- field1[i] = field[i];
- for (i=nTags-1;i<nAllocTags;i++)
- field1[i] = NULL;
- FreeVectorMemory ( field,0 );
- field = field1;
- }
- i = nTags-1;
- field[i] = NULL;
- }
-
- if (!F) {
- if ((!Concatenate) || (!field[i])) {
- CreateCopy ( field[i],pstr(" ?") );
- field[i][0] = char(2);
- }
- } else if ((!Concatenate) || (!field[i]))
- CreateCopy ( field[i],F );
- else {
- nf = new char[strlen(field[i])+strlen(F)+1];
- strcpy ( nf,field[i] );
- strcat ( nf,F );
- delete[] field[i];
- field[i] = nf;
- }
-
-}
-
-pstr CMMCIFStruct::GetField ( int tagNo ) {
- if ((tagNo>=0) && (tagNo<nTags)) return field[tagNo];
- return NULL;
-}
-
-int CMMCIFStruct::GetString ( pstr & S, cpstr TName,
- Boolean Remove ) {
-int k = GetTagNo ( TName );
- if (S) delete[] S;
- S = NULL;
- if (!field) return CIFRC_NoField;
- if (k<0) return CIFRC_NoTag;
- if (!field[k]) return CIFRC_NoField;
- if (field[k][0]==char(2)) {
- if (Remove) {
- delete[] field[k];
- field[k] = NULL;
- }
- } else if (Remove) {
- S = field[k];
- field[k] = NULL;
- } else
- CreateCopy ( S,field[k] );
- return 0;
-}
-
-pstr CMMCIFStruct::GetString ( cpstr TName, int & RC ) {
-int k = GetTagNo ( TName );
- if (k<0) {
- RC = CIFRC_NoTag;
- return NULL;
- }
- if (!field) {
- RC = CIFRC_NoField;
- return NULL;
- }
- if (!field[k]) {
- RC = CIFRC_NoField;
- return NULL;
- }
- RC = 0;
- if (field[k][0]==char(2)) return NULL;
- return field[k];
-}
-
-int CMMCIFStruct::DeleteField ( cpstr TName ) {
-int k = GetTagNo ( TName );
- if ((k>=0) && (field)) {
- if (field[k]) delete[] field[k];
- field[k] = NULL;
- }
- return k;
-}
-
-int CMMCIFStruct::GetReal ( realtype & R, cpstr TName,
- Boolean Remove ) {
-pstr endptr;
-int RC;
-int k = GetTagNo ( TName );
- R = 0.0;
- if (!field) return CIFRC_NoField;
- if (k<0) return CIFRC_NoTag;
- if (!field[k]) return CIFRC_NoField;
- if (field[k][0]==char(2)) return CIFRC_NoData;
- R = strtod ( field[k],&endptr );
- if (endptr==field[k]) RC = CIFRC_WrongFormat;
- else {
- RC = 0;
- if (Remove) {
- delete[] field[k];
- field[k] = NULL;
- }
- }
- return RC;
-}
-
-int CMMCIFStruct::GetInteger ( int & I, cpstr TName,
- Boolean Remove ) {
-pstr endptr;
-int RC;
-int k = GetTagNo ( TName );
- I = 0;
- if (!field) return CIFRC_NoField;
- if (k<0) return CIFRC_NoTag;
- if (!field[k]) return CIFRC_NoField;
- if (field[k][0]==char(2)) {
- if (field[k][1]=='.') I = MinInt4;
- return CIFRC_NoData;
- }
- I = mround ( strtod(field[k],&endptr) );
- if (endptr==field[k]) RC = CIFRC_WrongFormat;
- else {
- RC = 0;
- if (Remove) {
- delete[] field[k];
- field[k] = NULL;
- }
- }
- return RC;
-}
-
-
-void CMMCIFStruct::PutString ( cpstr S, cpstr T,
- Boolean NonBlankOnly ) {
-pstr p;
- if (!S) PutNoData ( CIF_NODATA_QUESTION,T );
- else {
- p = pstr(S);
- if (NonBlankOnly)
- while (*p==' ') p++;
- if (!(*p)) PutNoData ( CIF_NODATA_DOT,T );
- else AddField ( S,T,False );
- }
-}
-
-void CMMCIFStruct::PutDate ( cpstr T ) {
-time_t t;
-tm * tstruct;
- char S[100];
- t = time ( NULL );
- tstruct = localtime(&t);
- if (tstruct)
- sprintf ( S,"%4i-%02i-%02i",
- tstruct->tm_year+1900,tstruct->tm_mon+1,tstruct->tm_mday );
- else strcpy ( S,"YYYY-MM-DD" );
- AddField ( S,T,False );
-}
-
-
-void CMMCIFStruct::PutNoData ( int NoDataType, cpstr T ) {
-char S[10];
- S[0] = char(2);
- if (NoDataType==CIF_NODATA_DOT) S[1] = '.';
- else S[1] = '?';
- S[2] = char(0);
- AddField ( S,T,False );
-}
-
-
-void CMMCIFStruct::PutReal ( realtype R, cpstr T, int prec ) {
-char rS[100];
- sprintf ( rS,"%.*g",prec,R );
- AddField ( rS,T,False );
-}
-
-void CMMCIFStruct::PutReal ( realtype R, cpstr T, cpstr format ) {
-char rS[100];
- sprintf ( rS,format,R );
- AddField ( DelSpaces(rS,' '),T,False );
-}
-
-void CMMCIFStruct::PutInteger ( int I, cpstr T ) {
-char iS[100];
- if (I>MinInt4) {
- sprintf ( iS,"%i",I );
- AddField ( iS,T,False );
- } else
- PutNoData ( CIF_NODATA_DOT,T );
-}
-
-
-
-#define NODATA_Q pstr("?")
-#define NODATA_P pstr(".")
-
-Boolean CMMCIFStruct::WriteMMCIFStruct ( cpstr FName,
- byte gzipMode ) {
-CFile f;
- f.assign ( FName,True,False,gzipMode );
- if (f.rewrite()) {
- WriteMMCIF ( f );
- f.shut();
- return True;
- } else
- return False;
-}
-
-#define _max_output_line_width 256
-
-void CMMCIFStruct::WriteMMCIF ( RCFile f ) {
-int i,j,k,l,m,n;
-pstr F;
-
- // calculate maximal length of tags
- l = 0;
- for (i=0;i<nTags;i++)
- l = IMax(l,strlen(tag[i]));
- l += 1; // add one space separator
-
- // calculate maximal space left for data
- m = _max_output_line_width - l;
- // subtract category name width
- if (name[0]!=char(1)) m -= strlen(name);
-
- // start outout
- f.LF();
- for (i=0;i<nTags;i++) { // for each tag
-
- // print category name, if not hidden, and dot
- if (name[0]!=char(1)) {
- f.Write ( name );
- f.Write ( pstr(".") );
- }
-
- // print tag, checking for duplicate tag flag
- F = strchr ( tag[i],'\1' );
- if (F) {
- *F = char(0);
- f.Write ( tag[i] );
- *F = '\1';
- } else
- f.Write ( tag[i] );
-
- // print field
- if (field[i]) { // field is defined
- F = field[i];
- if (strchr(F,'\n') || strstr(F,"\" ")) {
- f.Write ( pstr("\n;") );
- f.Write ( F );
- f.Write ( pstr("\n;\n") );
- } else {
- n = strlen(F);
- if (n>m) // wrap around if field is too long
- f.Write ( pstr("\n ") );
- else {
- k = l-strlen(tag[i]);
- for (j=0;j<k;j++)
- f.Write ( pstr(" ") );
- }
- if ((((F[0]=='.') || (F[0]=='?')) && (!F[1])) ||
- strchr(F,' ')) {
- f.Write ( pstr("\"") );
- f.Write ( field[i] );
- f.Write ( pstr("\"\n") );
- } else if (field[i][0]==char(2)) {
- f.WriteLine ( &(field[i][1]) );
- } else if (!field[i][0]) {
- f.WriteLine ( NODATA_P );
- } else
- f.WriteLine ( field[i] );
- }
-
- } else { // field if not defined, put question mark
-
- k = l-strlen(tag[i]);
- for (j=0;j<k;j++)
- f.Write ( pstr(" ") );
- f.WriteLine ( NODATA_Q );
-
- }
-
- }
-
-}
-
-void CMMCIFStruct::Copy ( PCMMCIFCategory Struct ) {
-int i;
- CMMCIFCategory::Copy ( Struct );
- if (nTags>0) {
- GetVectorMemory ( field,nTags,0 );
- for (i=0;i<nTags;i++) {
- field[i] = NULL;
- CreateCopy ( field[i],PCMMCIFStruct(Struct)->field[i] );
- }
- }
-}
-
-void CMMCIFStruct::write ( RCFile f ) {
-int i;
- CMMCIFCategory::write ( f );
- for (i=0;i<nTags;i++)
- f.CreateWrite ( field[i] );
-}
-
-void CMMCIFStruct::read ( RCFile f ) {
-int i;
- CMMCIFCategory::read ( f );
- if (nTags>0) {
- GetVectorMemory ( field,nTags,0 );
- for (i=0;i<nTags;i++) {
- field[i] = NULL;
- f.CreateRead ( field[i] );
- }
- }
-}
-
-
-MakeStreamFunctions(CMMCIFStruct);
-
-
-
-// ====================== CMMCIFLoop ==============================
-
-
-CMMCIFLoop::CMMCIFLoop() : CMMCIFCategory() {
- InitMMCIFLoop();
-}
-
-CMMCIFLoop::CMMCIFLoop ( cpstr N ) : CMMCIFCategory(N) {
- InitMMCIFLoop();
-}
-
-CMMCIFLoop::CMMCIFLoop ( RPCStream Object ) : CMMCIFCategory(Object) {
- InitMMCIFLoop();
-}
-
-CMMCIFLoop::~CMMCIFLoop() {
- FreeMemory();
-}
-
-void CMMCIFLoop::InitMMCIFLoop() {
- nRows = 0;
- field = NULL;
- iColumn = 0;
- nAllocRows = 0;
-}
-
-void CMMCIFLoop::FreeMemory() {
- DeleteFields();
- CMMCIFCategory::FreeMemory();
-}
-
-void CMMCIFLoop::Optimize() {
-int i,j,nT,nR,k,m;
-Boolean empty;
-psmatrix f1;
-
- if (!field) {
- CMMCIFCategory::Optimize(); // optimize tags
- return;
- }
-
- // first check for empty columns
- nT = 0;
- for (i=0;i<nTags;i++)
- if (!tag[i]) {
- for (j=0;j<nRows;j++) // delete ith column of field
- if (field[j]) {
- if (field[j][i])
- delete[] field[j][i];
- field[j][i] = NULL;
- }
- } else {
- empty = True;
- j = 0;
- while ((j<nRows) && empty) { // check if ith column is empty
- if (field[j])
- empty = !field[j][i];
- j++;
- }
- if (empty) { // if ith column is empty, delete its tag
- delete[] tag[i];
- tag[i] = NULL;
- } else // otherwise count ith tag
- nT++;
- }
-
- // now check for empty rows
- nR = 0;
- for (j=0;j<nRows;j++)
- if (field[j]) {
- i = 0;
- while ((i<nTags) && (!field[j][i])) i++;
- if (i>=nTags) {
- delete[] field[j]; // delete empty row
- field[j] = NULL;
- } else
- nR++; // count non-empty row
- }
- if ((nT<=0) || (nR<=0))
- FreeMemory(); // the loop is completely empty
- else if ((nT!=nTags) || (nR!=nAllocRows)) {
- f1 = new psvector[nR];
- m = 0;
- for (j=0;j<nRows;j++)
- if (field[j]) {
- f1[m] = new pstr[nT];
- k = 0;
- for (i=0;i<nTags;i++)
- if (tag[i])
- f1[m][k++] = field[j][i];
- m++;
- delete[] field[j];
- }
- if (field) delete[] field;
- field = f1;
- nRows = nR;
- nAllocRows = nRows;
- CMMCIFCategory::Optimize(); // optimize tags
- }
-
-}
-
-void CMMCIFLoop::DeleteFields() {
-int i,j;
- if (field) {
- for (i=0;i<nAllocRows;i++)
- if (field[i]) {
- for (j=0;j<nTags;j++)
- if (field[i][j]) delete[] field[i][j];
- delete[] field[i];
- }
- delete[] field;
- field = NULL;
- nRows = 0;
- nAllocRows = 0;
- }
-}
-
-void CMMCIFLoop::AddLoopTag ( cpstr T, Boolean Remove ) {
-psmatrix f1;
-int i,j,nT1;
- if (Remove) {
- DeleteFields();
- AddTag ( T );
- } else {
- f1 = field;
- field = NULL;
- i = AddTag ( T );
- if ((f1) && (i<0)) {
- // The tag was added on the top of tag array. Create
- // and fill new fields.
- field = new psvector[nAllocRows];
- nT1 = nTags-1;
- for (i=0;i<nAllocRows;i++)
- if (f1[i]) {
- field[i] = new pstr[nTags];
- for (j=0;j<nT1;j++)
- field[i][j] = f1[i][j];
- field[i][nT1] = NULL;
- f1[i] = NULL;
- } else
- field[i] = NULL;
- delete[] f1;
- } else
- // The tag was already in the category. Just restore fields.
- field = f1;
- }
-}
-
-
-void CMMCIFLoop::ExpandRows ( int nRowsNew ) {
-int nAR,i;
-psmatrix field1;
- if (nRowsNew>nAllocRows) {
- nAR = nRowsNew + IMin(nAllocRows/2+10,2000);
- field1 = new psvector[nAR];
- for (i=0;i<nAllocRows;i++)
- field1[i] = field[i];
- for (i=nAllocRows;i<nAR;i++)
- field1[i] = NULL;
- if (field) delete[] field;
- field = field1;
- nAllocRows = nAR;
- }
-}
-
-void CMMCIFLoop::AddString ( cpstr S, Boolean NonBlankOnly ) {
-int i;
-pstr p;
- if (!S) AddNoData ( CIF_NODATA_QUESTION );
- else {
- p = pstr(S);
- if (NonBlankOnly)
- while (*p==' ') p++;
- if (!(*p)) AddNoData ( CIF_NODATA_DOT );
- else {
- if (iColumn==0) { // start a new row
- ExpandRows ( nRows+1 );
- field[nRows] = new pstr[nTags];
- for (i=0;i<nTags;i++)
- field[nRows][i] = NULL;
- nRows++;
- }
- CreateCopy ( field[nRows-1][iColumn],S );
- iColumn++;
- if (iColumn>=nTags) iColumn = 0;
- }
- }
-}
-
-void CMMCIFLoop::AddNoData ( int NoDataType ) {
-char S[10];
- S[0] = char(2);
- if (NoDataType==CIF_NODATA_DOT) S[1] = '.';
- else S[1] = '?';
- S[2] = char(0);
- AddString ( S );
-}
-
-void CMMCIFLoop::AddReal ( realtype R, int prec ) {
-char rS[100];
- sprintf ( rS,"%.*g",prec,R );
- AddString ( rS );
-}
-
-void CMMCIFLoop::AddReal ( realtype R, cpstr format ) {
-char rS[100];
- sprintf ( rS,format,R );
- AddString ( DelSpaces(rS,' ') );
-}
-
-void CMMCIFLoop::AddInteger ( int I ) {
-char iS[100];
- if (I>MinInt4) {
- sprintf ( iS,"%i",I );
- AddString ( iS );
- } else
- AddNoData ( CIF_NODATA_DOT );
-}
-
-
-pstr CMMCIFLoop::GetField ( int rowNo, int tagNo ) {
- if ((tagNo>=0) && (tagNo<nTags) &&
- (rowNo>=0) && (rowNo<nRows)) {
- if (field[rowNo]) return field[rowNo][tagNo];
- }
- return NULL;
-}
-
-int CMMCIFLoop::GetString ( pstr & S, cpstr TName, int nrow,
- Boolean Remove) {
-int k = GetTagNo ( TName );
- if (S) delete[] S;
- S = NULL;
- if (k<0) return CIFRC_NoTag;
- if ((nrow<0) || (nrow>=nRows)) return CIFRC_WrongIndex;
- if (!field[nrow]) return CIFRC_NoField;
- if (!field[nrow][k]) return CIFRC_NoField;
- if (field[nrow][k][0]==char(2)) {
- if (Remove) {
- delete[] field[nrow][k];
- field[nrow][k] = NULL;
- }
- } else if (Remove) {
- S = field[nrow][k];
- field[nrow][k] = NULL;
- } else
- CreateCopy ( S,field[nrow][k] );
- return 0;
-}
-
-pstr CMMCIFLoop::GetString ( cpstr TName, int nrow, int & RC ) {
-int k = GetTagNo ( TName );
- if (k<0) {
- RC = CIFRC_NoTag;
- return NULL;
- }
- if ((nrow<0) || (nrow>=nRows)) {
- RC = CIFRC_WrongIndex;
- return NULL;
- }
- if (!field[nrow]) {
- RC = CIFRC_NoField;
- return NULL;
- }
- if (!field[nrow][k]) {
- RC = CIFRC_NoField;
- return NULL;
- }
- RC = 0;
- // char(2) means the field was either '.' or '?'
- if (field[nrow][k][0]==char(2)) return NULL;
- return field[nrow][k];
-}
-
-// CopyString() does nothing if RC is not 0
-void CMMCIFLoop::CopyString ( pstr buf, int maxlength,
- cpstr TName, int nrow, int & RC ) {
-pstr p;
-int k;
-
- if (RC) return;
-
- k = GetTagNo ( TName );
- if (k<0) {
- RC = CIFRC_NoTag;
- buf[0] = char(0);
- return;
- }
- if ((nrow<0) || (nrow>=nRows)) {
- RC = CIFRC_WrongIndex;
- buf[0] = char(0);
- return;
- }
- if (!field[nrow]) {
- RC = CIFRC_NoField;
- buf[0] = char(0);
- return;
- }
- p = field[nrow][k];
- if (!p) {
- RC = CIFRC_NoField;
- buf[0] = char(0);
- return;
- }
-
- // char(2) means the field was either '.' or '?'
- if (p[0]==char(2)) {
- buf[0] = p[0];
- buf[1] = char(0);
- } else
- strncpy ( buf,p,IMin(maxlength,strlen(p)+1) );
-
-}
-
-
-
-int CMMCIFLoop::DeleteField ( cpstr TName, int nrow ) {
-int k = GetTagNo ( TName );
- if (k<0) return CIFRC_NoTag;
- if ((nrow<0) || (nrow>=nRows))
- return CIFRC_WrongIndex;
- if (field[nrow]) {
- if (field[nrow][k]) delete[] field[nrow][k];
- field[nrow][k] = NULL;
- }
- return k;
-}
-
-int CMMCIFLoop::DeleteRow ( int nrow ) {
-int i;
- if ((nrow<0) || (nrow>=nRows))
- return CIFRC_WrongIndex;
- if (field[nrow]) {
- for (i=0;i<nTags;i++)
- if (field[nrow][i]) {
- delete[] field[nrow][i];
- field[nrow][i] = NULL;
- }
- delete[] field[nrow];
- field[nrow] = NULL;
- }
- return 0;
-}
-
-int CMMCIFLoop::GetReal ( realtype & R, cpstr TName, int nrow,
- Boolean Remove ) {
-pstr endptr;
-int k = GetTagNo ( TName );
- if (k<0) return CIFRC_NoTag;
- if ((nrow<0) || (nrow>=nRows))
- return CIFRC_WrongIndex;
- R = 0.0;
- if (!field[nrow]) return CIFRC_NoField;
- if (!field[nrow][k]) return CIFRC_NoField;
- if (field[nrow][k][0]==char(2)) return CIFRC_NoField;
- R = strtod ( field[nrow][k],&endptr );
- if (endptr==field[nrow][k]) return CIFRC_WrongFormat;
- if (Remove) {
- delete[] field[nrow][k];
- field[nrow][k] = NULL;
- }
- return 0;
-}
-
-void CMMCIFLoop::CopyReal ( realtype & R, cpstr TName, int nrow,
- int & RC ) {
-pstr endptr;
-int k;
-
- if (RC) return;
-
-// R = 0.0;
- k = GetTagNo ( TName );
-
- if (k<0) RC = CIFRC_NoTag;
- else if ((nrow<0) || (nrow>=nRows)) RC = CIFRC_WrongIndex;
- else if (!field[nrow]) RC = CIFRC_NoField;
- else if (!field[nrow][k]) RC = CIFRC_NoField;
- else if (field[nrow][k][0]==char(2)) RC = CIFRC_NoField;
- else {
- R = strtod ( field[nrow][k],&endptr );
- if (endptr==field[nrow][k]) RC = CIFRC_WrongFormat;
- }
-
-}
-
-void CMMCIFLoop::CopyInteger ( int & I, cpstr TName, int nrow,
- int & RC ) {
-pstr endptr;
-int k;
-
- if (RC) return;
-
- I = 0;
- k = GetTagNo ( TName );
-
- if (k<0) RC = CIFRC_NoTag;
- else if ((nrow<0) || (nrow>=nRows)) RC = CIFRC_WrongIndex;
- else if (!field[nrow]) RC = CIFRC_NoField;
- else if (!field[nrow][k]) RC = CIFRC_NoField;
- else if (field[nrow][k][0]==char(2)) RC = CIFRC_NoField;
- else {
- I = mround ( strtod ( field[nrow][k],&endptr ) );
- if (endptr==field[nrow][k]) RC = CIFRC_WrongFormat;
- }
-
-}
-
-int CMMCIFLoop::GetInteger ( int & I, cpstr TName, int nrow,
- Boolean Remove ) {
-pstr endptr;
-int k = GetTagNo ( TName );
- if (k<0) return CIFRC_NoTag;
- if ((nrow<0) || (nrow>=nRows))
- return CIFRC_WrongIndex;
- I = 0;
- if (!field[nrow]) return CIFRC_NoField;
- if (!field[nrow][k]) return CIFRC_NoField;
- if (field[nrow][k][0]==char(2)) {
- if (field[nrow][k][1]=='.') I = MinInt4;
- return CIFRC_NoField;
- }
- I = mround ( strtod(field[nrow][k],&endptr) );
- if (endptr==field[nrow][k]) return CIFRC_WrongFormat;
- if (Remove) {
- delete[] field[nrow][k];
- field[nrow][k] = NULL;
- }
- return 0;
-}
-
-
-int CMMCIFLoop::GetSVector ( psvector & S, cpstr TName,
- int i1, int i2, Boolean Remove ) {
-int j,k,r1,r2;
- r1 = IMin(i1,i2);
- r2 = IMin(IMax(i1,i2),nRows-1);
- if ((r1<0) || (r1>=nRows) || (r2<0)) return CIFRC_WrongIndex;
- k = GetTagNo ( TName );
- if (k<0) return CIFRC_NoTag;
- if (!S)
- GetVectorMemory ( S,r2-r1+1,r1 );
- if (Remove) {
- for (j=r1;j<=r2;j++)
- if (field[j]) {
- S[j] = field[j][k];
- field[j][k] = NULL;
- if (S[j]) {
- if (S[j][0]==char(2)) {
- delete[] S[j];
- S[j] = NULL;
- }
- }
- } else
- S[j] = NULL;
- } else {
- for (j=r1;j<=r2;j++) {
- S[j] = NULL;
- if (field[j]) {
- if (field[j][k]) {
- if (field[j][k][0]!=char(2))
- CreateCopy ( S[j],field[j][k] );
- }
- }
- }
- }
- return 0;
-}
-
-int CMMCIFLoop::GetRVector ( rvector & R, cpstr TName,
- int i1, int i2, Boolean Remove ) {
-int j,k,r1,r2,RC;
-pstr endptr;
- r1 = IMin(i1,i2);
- r2 = IMin(IMax(i1,i2),nRows-1);
- if ((r1<0) || (r1>=nRows) || (r2<0)) return CIFRC_WrongIndex;
- k = GetTagNo ( TName );
- if (k<0) return CIFRC_NoTag;
- if (!R)
- GetVectorMemory ( R,r2-r1+1,r1 );
- RC = 0;
- for (j=r1;j<=r2;j++) {
- R[j] = 0.0;
- if (field[j]) {
- if (field[j][k]) {
- R[j] = strtod ( field[j][k],&endptr );
- if (endptr==field[j][k]) RC = CIFRC_WrongFormat;
- if (Remove) {
- delete[] field[j][k];
- field[j][k] = NULL;
- }
- }
- }
- }
- return RC;
-}
-
-int CMMCIFLoop::GetIVector ( ivector & I, cpstr TName,
- int i1, int i2, Boolean Remove ) {
-int j,k,r1,r2,RC;
-pstr endptr;
- r1 = IMin(i1,i2);
- r2 = IMin(IMax(i1,i2),nRows-1);
- if ((r1<0) || (r1>=nRows) || (r2<0)) return CIFRC_WrongIndex;
- k = GetTagNo ( TName );
- if (k<0) return CIFRC_NoTag;
- if (!I)
- GetVectorMemory ( I,r2-r1+1,r1 );
- RC = 0;
- for (j=r1;j<=r2;j++) {
- I[j] = 0;
- if (field[j]) {
- if (field[j][k]) {
- I[j] = mround ( strtod(field[j][k],&endptr) );
- if (endptr==field[j][k]) RC = CIFRC_WrongFormat;
- if (Remove) {
- delete[] field[j][k];
- field[j][k] = NULL;
- }
- }
- }
- }
- return RC;
-}
-
-
-void CMMCIFLoop::PutString ( cpstr S, cpstr T, int nrow ) {
-psmatrix field1;
-int nT,nR,iT,i,j;
- nT = nTags;
- nR = nRows;
- iT = AddTag ( T );
- if (iT<0) iT = nTags-1;
- if (nTags>nT) {
- // a new tag has been added; all field must be reallocated.
- nRows = IMax(nR,nrow+1); // nrow is indexed like 0,1,...
- nAllocRows = IMax(nR,nrow+IMin(nR/2+1,2000));
- field1 = new psvector[nAllocRows];
- for (i=0;i<nR;i++)
- if (field[i]) {
- field1[i] = new pstr[nTags];
- for (j=0;j<nT;j++)
- field1[i][j] = field[i][j];
- for (j=nT;j<nTags;j++)
- field1[i][j] = NULL;
- delete[] field[i];
- } else
- field1[i] = NULL;
- for (i=nR;i<nRows;i++)
- field1[i] = NULL;
- if (field) delete[] field;
- field = field1;
- } else if (nrow>=nR) {
- // only new rows are to be added
- ExpandRows ( nrow+1 );
- nRows++;
- }
- if (!field[nrow]) {
- field[nrow] = new pstr[nTags];
- for (j=0;j<nTags;j++)
- field[nrow][j] = NULL;
- }
- CreateCopy ( field[nrow][iT],S );
- iColumn = iT+1;
- if (iColumn>=nTags) iColumn = 0;
-}
-
-
-void CMMCIFLoop::PutNoData ( int NoDataType, cpstr T, int nrow ) {
-char S[10];
- S[0] = char(2);
- if (NoDataType==CIF_NODATA_DOT) S[1] = '.';
- else S[1] = '?';
- S[2] = char(0);
- PutString ( S,T,nrow );
-}
-
-
-void CMMCIFLoop::PutReal ( realtype R, cpstr T, int nrow, int prec ) {
-char rS[100];
- sprintf ( rS,"%.*g",prec,R );
- PutString ( rS,T,nrow );
-}
-
-void CMMCIFLoop::PutReal ( realtype R, cpstr T, int nrow,
- cpstr format ) {
-char rS[100];
- sprintf ( rS,format,R );
- PutString ( DelSpaces(rS,' '),T,nrow );
-}
-
-void CMMCIFLoop::PutInteger ( int I, cpstr T, int nrow ) {
-char iS[100];
- if (I>MinInt4) {
- sprintf ( iS,"%i",I );
- PutString ( iS,T,nrow );
- } else
- PutNoData ( CIF_NODATA_DOT,T,nrow );
-}
-
-void CMMCIFLoop::PutSVector ( psvector S, cpstr T, int i1, int i2 ) {
-int i,j,k;
- PutString ( S[i2],T,i2 );
- if (iColumn==0) k = nTags-1;
- else k = iColumn-1;
- for (i=i2-1;i>=i1;i--) {
- if (!field[i]) {
- field[i] = new pstr[nTags];
- for (j=0;j<nTags;j++)
- field[i][j] = NULL;
- }
- CreateCopy ( field[i][k],S[i] );
- }
-}
-
-void CMMCIFLoop::PutRVector ( rvector R, cpstr T,
- int i1, int i2, int prec ) {
-int i,j,k;
-char rS[100];
- PutReal ( R[i2],T,i2,prec );
- if (iColumn==0) k = nTags-1;
- else k = iColumn-1;
- for (i=i2-1;i>=i1;i--) {
- if (!field[i]) {
- field[i] = new pstr[nTags];
- for (j=0;j<nTags;j++)
- field[i][j] = NULL;
- }
- sprintf ( rS,"%.*g",prec,R[i] );
- CreateCopy ( field[i][k],rS );
- }
-}
-
-void CMMCIFLoop::PutIVector ( ivector I, cpstr T,
- int i1, int i2 ) {
-int l,j,k;
-char iS[100];
- PutInteger ( I[i2],T,i2 );
- if (iColumn==0) k = nTags-1;
- else k = iColumn-1;
- for (l=i2-1;l>=i1;l--) {
- if (!field[l]) {
- field[l] = new pstr[nTags];
- for (j=0;j<nTags;j++)
- field[l][j] = NULL;
- }
- sprintf ( iS,"%i",I[l] );
- CreateCopy ( field[l][k],iS );
- }
-}
-
-Boolean CMMCIFLoop::WriteMMCIFLoop ( cpstr FName,
- byte gzipMode ) {
-CFile f;
- f.assign ( FName,True,False,gzipMode );
- if (f.rewrite()) {
- WriteMMCIF ( f );
- f.shut();
- return True;
- } else
- return False;
-}
-
-void CMMCIFLoop::WriteMMCIF ( RCFile f ) {
-int i,j,k,m,n;
-ivector l;
-pstr F;
-
- // write loop keyword
- f.Write ( pstr("\nloop_\n") );
-
- GetVectorMemory ( l,nTags,0 );
- k = 0;
- for (i=0;i<nTags;i++) {
- if (name[0]!=char(1)) {
- f.Write ( name );
- f.Write ( pstr(".") );
- }
- F = strchr ( tag[i],'\1' );
- if (F) {
- *F = char(0);
- f.WriteLine ( tag[i] );
- *F = '\1';
- } else
- f.WriteLine ( tag[i] );
- l[i] = 0;
- for (j=0;j<nRows;j++)
- if (field[j]) {
- if (field[j][i]) {
- F = field[j][i];
- if (strchr(F,'\n') || strstr(F,"\" "))
- l[i] = 10001;
- else if (F[0]==char(2)) l[i] = IMax(l[i],1);
- else if (((F[0]=='.') || (F[0]=='?')) &&
- (!F[1])) l[i] = IMax(l[i],3);
- else {
- if (strchr(F,' ')) m = 2;
- else m = 0;
- l[i] = IMax(l[i],strlen(F)+m);
- }
- }
- }
- l[i] = IMax(l[i],1);
- k += l[i]+1;
- if (k>_max_output_line_width) {
- l[i] = -l[i];
- k = 0;
- }
- }
- for (i=0;i<nRows;i++) {
- m = 0; // counts symbols in the string
- k = 0; // rest of left-aligned fields to fill with spaces
- for (j=0;j<nTags;j++) {
- n = k;
- k = l[j]; // length of the field
- if (k<0) k = -k;
- m += k+1;
- if (m>_max_output_line_width) {
- f.LF();
- m = k+1;
- } else
- while (n>0) {
- f.Write ( pstr(" ") );
- n--;
- }
- if (field[i]) {
- if (field[i][j]) {
- F = field[i][j];
- if (k>10000) {
- if (F[0]==char(2)) {
- f.Write ( pstr(" ") );
- f.WriteLine ( &(F[1]) );
- } else if (!F[0]) {
- f.Write ( pstr(" ") );
- f.WriteLine ( NODATA_P );
- } else {
- f.Write ( pstr(";") );
- f.WriteLine ( F );
- f.WriteLine ( pstr(";") );
- }
- m = 0;
- k = 0;
- } else if ((((F[0]=='.') || (F[0]=='?')) && (!F[1])) ||
- strchr(F,' ')) {
- f.Write ( pstr(" \"") );
- f.Write ( F );
- f.Write ( pstr("\"") );
- k -= strlen(F)+2;
- } else if (F[0]==char(2)) {
- f.Write ( pstr(" ") );
- f.Write ( &(F[1]) );
- k--;
- } else if (!F[0]) {
- f.Write ( pstr(" ") );
- f.Write ( NODATA_P );
- k--;
- } else {
- f.Write ( pstr(" ") );
- f.Write ( F );
- k -= strlen(F);
- }
- } else {
- f.Write ( pstr(" ") );
- f.Write ( NODATA_Q );
- k--;
- }
- } else {
- f.Write ( pstr(" ") );
- f.Write ( NODATA_Q );
- k--;
- }
- }
- if (m) f.LF();
- }
-
-}
-
-
-void CMMCIFLoop::Copy ( PCMMCIFCategory Loop ) {
-int i,j;
- CMMCIFCategory::Copy ( Loop );
- nRows = PCMMCIFLoop(Loop)->nRows;
- nAllocRows = nRows;
- if ((nTags>0) && (nRows>0)) {
- field = new psvector[nRows];
- for (i=0;i<nRows;i++) {
- if (PCMMCIFLoop(Loop)->field[i]) {
- field[i] = new pstr[nTags];
- for (j=0;j<nTags;j++) {
- field[i][j] = NULL;
- CreateCopy ( field[i][j],PCMMCIFLoop(Loop)->field[i][j] );
- }
- } else
- field[i] = NULL;
- }
- }
- iColumn = PCMMCIFLoop(Loop)->iColumn;
-}
-
-
-void CMMCIFLoop::write ( RCFile f ) {
-int i,j;
- CMMCIFCategory::write ( f );
- f.WriteInt ( &nRows );
- if ((nTags>0) && (nRows>0))
- for (i=0;i<nRows;i++)
- if (field[i]) {
- j = 1;
- f.WriteInt ( &j );
- for (j=0;j<nTags;j++)
- f.CreateWrite ( field[i][j] );
- } else {
- j = 0;
- f.WriteInt ( &j );
- }
- f.WriteInt ( &iColumn );
-}
-
-void CMMCIFLoop::read ( RCFile f ) {
-int i,j;
- CMMCIFCategory::read ( f );
- f.ReadInt ( &nRows );
- nAllocRows = nRows;
- if ((nTags>0) && (nRows>0)) {
- field = new psvector[nRows];
- for (i=0;i<nRows;i++) {
- f.ReadInt ( &j );
- if (j) {
- field[i] = new pstr[nTags];
- for (j=0;j<nTags;j++) {
- field[i][j] = NULL;
- f.CreateRead ( field[i][j] );
- }
- } else
- field[i] = NULL;
- }
- }
- f.ReadInt ( &iColumn );
-}
-
-
-MakeStreamFunctions(CMMCIFLoop)
-
-
-
-// ====================== CMMCIFData =============================
-
-
-CMMCIFData::CMMCIFData() : CStream() {
- InitMMCIFData();
-}
-
-CMMCIFData::CMMCIFData ( cpstr N ) : CStream() {
- InitMMCIFData();
- CreateCopy ( name,N );
-}
-
-CMMCIFData::CMMCIFData ( RPCStream Object ) : CStream(Object) {
- InitMMCIFData();
-}
-
-CMMCIFData::~CMMCIFData() {
- FreeMemory(0);
-}
-
-void CMMCIFData::InitMMCIFData() {
- name = NULL;
- nCategories = 0;
- Category = NULL;
- index = NULL;
- flags = 0;
- Warning = 0;
- loopNo = 0;
- tagNo = 0;
- WrongCat = NULL;
- WrongTag = NULL;
- nWrongFields = 0;
-}
-
-void CMMCIFData::FreeMemory ( int key ) {
-int i;
- if (name) delete[] name;
- name = NULL;
- if (Category) {
- for (i=0;i<nCategories;i++)
- if (Category[i]) delete Category[i];
- delete[] Category;
- Category = NULL;
- }
- nCategories = 0;
- FreeVectorMemory ( index,0 );
- if (key==0) FreeWrongFields();
-}
-
-void CMMCIFData::FreeWrongFields() {
-int i;
- if (WrongCat) {
- for (i=0;i<nWrongFields;i++)
- if (WrongCat[i]) delete[] WrongCat[i];
- delete[] WrongCat;
- }
- if (WrongTag) {
- for (i=0;i<nWrongFields;i++)
- if (WrongTag[i]) delete[] WrongTag[i];
- delete[] WrongTag;
- }
- WrongCat = NULL;
- WrongTag = NULL;
- nWrongFields = 0;
-}
-
-
-void CMMCIFData::SetPrintWarnings ( Boolean SPW ) {
- if (SPW) SetFlag ( CIFFL_PrintWarnings );
- else RemoveFlag ( CIFFL_PrintWarnings );
-}
-
-void CMMCIFData::SetStopOnWarning ( Boolean SOW ) {
- if (SOW) SetFlag ( CIFFL_StopOnWarnings );
- else RemoveFlag ( CIFFL_StopOnWarnings );
-}
-
-void CMMCIFData::SetFlag ( int F ) {
- flags |= F;
-}
-
-void CMMCIFData::RemoveFlag ( int F ) {
- flags &= ~F;
-}
-
-void CMMCIFData::SetWrongFields ( cpstr *cats, cpstr *tags ) {
-int i,lc,lt;
- FreeWrongFields();
- if ((!cats) || (!tags)) return;
- lc = 0;
- while (cats[lc]) lc++;
- lt = 0;
- while (tags[lt]) lt++;
- nWrongFields = IMax(lc,lt);
- if (nWrongFields>0) {
- WrongCat = new pstr[nWrongFields];
- WrongTag = new pstr[nWrongFields];
- for (i=0;i<nWrongFields;i++) {
- WrongCat[i] = NULL;
- WrongTag[i] = NULL;
- if (cats[i]) {
- if (cats[i][0]) CreateCopy ( WrongCat[i],cats[i] );
- }
- if (!WrongCat[i]) {
- CreateCopy ( WrongCat[i],pstr(" ") );
- WrongCat[i][0] = char(1);
- }
- if (tags[i]) CreateCopy ( WrongTag[i],tags[i] );
- else CreateCopy ( WrongTag[i],pstr("") );
- }
- }
-}
-
-Boolean CMMCIFData::CheckWrongField ( cpstr C, cpstr T ) {
-int i;
- for (i=0;i<nWrongFields;i++)
- if ((!strcasecmp(C,WrongCat[i])) &&
- (!strcasecmp(T,WrongTag[i]))) return True;
- return False;
-}
-
-#define _max_buf_len 500
-
-static char _err_string[_max_buf_len+1];
-static int _err_line;
-
-
-int CMMCIFData::ReadMMCIFData ( cpstr FName, byte gzipMode ) {
-CFile f;
-char S[_max_buf_len+1];
-int RC,lcount;
- f.assign ( FName,True,False,gzipMode );
- if (f.reset(True)) {
- S[0] = char(0);
- lcount = 0;
- RC = ReadMMCIFData ( f,S,lcount );
- f.shut();
- return RC;
- } else {
- _err_string[0] = char(0);
- _err_line = 0;
- Warning = CIFRC_CantOpenFile;
- return CIFRC_CantOpenFile;
- }
-}
-
-
-// --------------- General I/O functions
-
-int CMMCIFData::ReadMMCIFData ( RCFile f, pstr S, int & lcount ) {
-pstr p;
-int i,llen;
-pstr L;
-
- FreeMemory(1);
- Warning = 0;
- loopNo = 0;
- tagNo = 0;
-
- // 1. Look for 'data_' tag
- do {
- p = &(S[0]);
- while ((*p==' ') || (*p==char(9))) p++;
- if (strncmp(p,"data_",5)) {
- f.ReadLine ( S,_max_buf_len );
- lcount++;
- p = NULL;
- }
- } while ((!p) && (!f.FileEnd()));
-
- if (!p) {
- strcpy ( _err_string,S );
- _err_line = lcount;
- if (flags & CIFFL_PrintWarnings)
- printf ( "\n **** mmCIF READ ERROR "
- "<<line %i: no 'data_XXXX' tag found>>\n",lcount );
- return CIFRC_NoDataLine;
- }
-
- llen = _max_buf_len;
- L = new char[llen];
- i = 0;
- p += 5;
- while ((*p) && (*p!=' ') && (*p!=char(9))) {
- L[i++] = *p;
- p++;
- }
- L[i] = char(0);
- CreateCopy ( name,L );
-
-
- // 2. Loop over tags until next 'data_' or end of file
-
- while (p) {
-
- // skip spaces
- while ((*p==' ') || (*p==char(9))) p++;
-
- if ((*p) && (*p!='#')) { // this is not a comment, continue
- if (*p=='_')
- GetDataItem ( f,S,L,p,lcount,llen );
- else if (!strncmp(p,"loop_",5))
- GetLoop ( f,S,L,p,lcount,llen );
- else if (!strncmp(p,"data_",5)) {
- p = NULL;
- break;
- } else {
- // if got to here, the file is corrupted
- strcpy ( _err_string,S );
- _err_line = lcount;
- Warning |= CIFW_UnrecognizedItems;
- if (flags & CIFFL_PrintWarnings)
- printf ( "\n **** mmCIF READ WARNING "
- "<<line %i: unrecognized string>>\n%s\n",
- lcount,S );
- while ((*p) && (*p!=' ') && (*p!=char(9)))
- if (*p=='#') *p = char(0);
- else p++;
- }
- } else
- *p = char(0);
-
- if (Warning && (flags & CIFFL_StopOnWarnings)) {
- if (L) delete[] L;
- return Warning;
- }
-
- if (!(*p)) {
- if (!f.FileEnd()) {
- f.ReadLine ( S,_max_buf_len );
- lcount++;
- p = &(S[0]);
- } else
- p = NULL;
- }
-
- }
-
- if (L) delete[] L;
-
- Optimize(); // get rid of over-allocated fields.
-
- return Warning;
-
-}
-
-
-void CMMCIFData::GetDataItem ( RCFile f, pstr S, pstr & L,
- pstr & p, int & lcount, int & llen ) {
-PCMMCIFStruct Struct;
-char T[100];
-int RC,i;
-
- i = 0;
- while ((*p) && (*p!=' ') && (*p!=char(9)) && (*p!='.')) {
- if (i<(int)sizeof(T)-1) T[i++] = *p;
- p++;
- }
- T[i] = char(0);
-
- if (*p!='.') { // category name missing
- strcpy ( L,T ); // item name
- T[0] = char(1); // special
- T[1] = char(0); // category name
- }
-
- // look for category
- i = AddCategory ( T );
- if (i<0) {
- // negative value means that the category was not in the list,
- // but a place for it has been provided and index updated
- Struct = new CMMCIFStruct ( T );
- Category[nCategories-1] = Struct;
- } else {
- Struct = PCMMCIFStruct(Category[i]);
- if (Struct->GetCategoryID()!=MMCIF_Struct) {
- strcpy ( _err_string,S );
- _err_line = lcount;
- Warning |= CIFW_NotAStructure;
- if (flags & CIFFL_PrintWarnings)
- printf ( "\n **** mmCIF READ WARNING "
- "<<line %i: %s was a loop -- replaced>>\n%s\n",
- lcount,T,S );
- delete Category[i];
- Struct = new CMMCIFStruct ( T );
- Category[i] = Struct;
- }
- }
-
- if (*p=='.') { // get item name
- i = 0;
- p++; // skip period
- while ((*p) && (*p!=' ') && (*p!=char(9))) {
- T[i++] = *p;
- p++;
- }
- T[i] = char(0);
- } else
- strcpy ( T,L );
-
- if (nWrongFields>0) {
- if (CheckWrongField(Struct->name,T)) {
- GetField ( f,S,L,p,lcount,llen );
- Struct->DeleteField ( T );
- return;
- }
- }
-
- RC = GetField ( f,S,L,p,lcount,llen );
-
- if (RC) {
- strcpy ( _err_string,S );
- _err_line = lcount;
- Warning |= CIFW_MissingField;
- if (flags & CIFFL_PrintWarnings)
- printf ( "\n **** mmCIF READ WARNING "
- "<<line %i: expected data field missing>>\n%s\n",
- lcount,S );
- }
-
- while ((*p==' ') || (*p==char(9))) p++;
- if (*p=='#') *p = char(0);
-
- i = Struct->GetTagNo ( T );
- if (i>=0) {
- if (flags & CIFFL_SuggestTags) {
- tagNo++;
- ParamStr ( T,pstr("\1"),tagNo );
- } else {
- strcpy ( _err_string,S );
- _err_line = lcount;
- Warning |= CIFW_DuplicateTag;
- if (flags & CIFFL_PrintWarnings)
- printf ( "\n **** mmCIF READ WARNING "
- "<<line %i: duplicated tag>>\n%s\n",lcount,S );
- }
- }
- Struct->AddField ( L,T );
-
-}
-
-void CMMCIFData::GetLoop ( RCFile f, pstr S, pstr & L,
- pstr & p, int & lcount, int & llen ) {
-PCMMCIFLoop Loop;
-pstr p1;
-char T[100];
-Boolean Repeat,WrongField;
-int RC,i,nC;
-
- RC = 0;
-
- p += 5; // skip 'loop_' tag
-
- loopNo++;
- Loop = NULL;
- nC = -1; // undefined category number
- do {
-
- while ((*p==' ') || (*p==char(9))) p++;
- p1 = p;
-
- if (*p=='_') {
-
- // get category name
- i = 0;
- while ((*p) && (*p!=' ') && (*p!=char(9)) && (*p!='.')) {
- if (i<(int)sizeof(T)-1) T[i++] = *p;
- p++;
- }
- T[i] = char(0);
-
- if (*p!='.') { // category name missing
- strcpy ( L,T ); // item name
- if (flags & CIFFL_SuggestCategories)
- sprintf ( T,"X%i",loopNo );
- else strcpy ( T,"X" );
- T[0] = char(1); // special category name
- }
-
- if (Loop) {
- if (strcmp(Loop->GetCategoryName(),T)) {
- // loop ended, empty
- p = p1; // play back to last category
- Loop = NULL;
- }
- } else {
- // look for category
- i = AddCategory ( T );
- if ((i!=nC) && (nC>=0)) { // empty loop; most probably
- // a corrupted file
- p = p1; // play back to last category
- strcpy ( _err_string,S );
- _err_line = lcount;
- Warning |= CIFW_EmptyLoop;
- if (flags & CIFFL_PrintWarnings)
- printf ( "\n **** mmCIF READ WARNING "
- "<<line %i: empty loop>>\n%s\n",lcount,S );
- // AddCategory(..) has added a NULL-Category on the top of
- // category list; remove it now
- DeleteCategory ( nCategories-1 );
- Loop = NULL;
-// return;
- }
- if (i<0) {
- // negative value means that the category was not in the list,
- // but a place for it has been provided and index updated
- Loop = new CMMCIFLoop ( T );
- Category[nCategories-1] = Loop;
- nC = nCategories-1;
- }
- }
-/*
- else if (Loop) {
- if (!strcmp(Loop->GetCategoryName(),
- Category[i]->GetCategoryName())) {
- if (Loop->GetCategoryID()!=MMCIF_Loop) {
- Warning |= CIFW_NotALoop;
- if (flags & CIFFL_PrintWarnings)
- printf ( "\n **** mmCIF READ WARNING "
- "<<line %i: %s was a structure --"
- " replaced>>\n%s\n",lcount,T,S );
- delete Category[i];
- Loop = new CMMCIFLoop ( T );
- Category[i] = Loop;
- }
- } else
- Loop = NULL;
- }
-*/
- if (Loop) {
-
- if (*p=='.') { // get item name
- i = 0;
- p++; // skip period
- while ((*p) && (*p!=' ') && (*p!=char(9))) {
- T[i++] = *p;
- p++;
- }
- T[i] = char(0);
- } else
- strcpy ( T,L );
-
- if (nWrongFields>0)
- WrongField = CheckWrongField ( Loop->name,T );
- else WrongField = False;
-
- if (!WrongField) {
- if (Loop->AddTag(T)>=0) {
- if (flags & CIFFL_SuggestTags) {
- tagNo++;
- ParamStr ( T,pstr("\1"),tagNo );
- Loop->AddTag(T);
- } else {
- strcpy ( _err_string,S );
- _err_line = lcount;
- Warning |= CIFW_DuplicateTag;
- if (flags & CIFFL_PrintWarnings)
- printf ( "\n **** mmCIF READ WARNING "
- "<<line %i: duplicate tag>>\n%s\n",lcount,S );
- }
- }
- }
- Repeat = True;
-
- } else {
-
- p = p1;
- Repeat = False;
-
- }
-
- } else if (!(*p) || (*p=='#')) {
- Repeat = !f.FileEnd();
- if (Repeat) {
- f.ReadLine ( S,_max_buf_len );
- lcount++;
- p = &(S[0]);
- } else {
- strcpy ( _err_string,S );
- _err_line = lcount;
- Warning |= CIFW_UnexpectedEOF;
- if (flags & CIFFL_PrintWarnings)
- printf ( "\n **** mmCIF READ WARNING "
- "<<line %i: unexpected end of file>>\n%s\n",
- lcount,S );
- }
- } else
- Repeat = False;
-
- } while (Repeat);
-
- if (Loop) {
- do {
- while ((*p==' ') || (*p==char(9))) p++;
- if (!(*p) || (*p=='#')) {
- Repeat = !f.FileEnd();
- if (Repeat) {
- f.ReadLine ( S,_max_buf_len );
- lcount++;
- p = &(S[0]);
- }
- } else if (*p=='_') Repeat = False;
- else if (!strncmp(p,"loop_",5)) Repeat = False;
- else if (!strncmp(p,"data_",5)) Repeat = False;
- else if (!strncmp(p,"stop_",5)) {
- p += 5;
- Repeat = False;
- } else {
- RC = GetField ( f,S,L,p,lcount,llen );
- if (!RC) {
- Loop->AddString ( L );
- Repeat = True;
- } else
- Repeat = False;
- }
- } while (Repeat);
- if ((Loop->iColumn!=0) || (RC)) {
- strcpy ( _err_string,S );
- _err_line = lcount;
- Warning |= CIFW_LoopFieldMissing;
- if (flags & CIFFL_PrintWarnings)
- printf ( "\n **** mmCIF READ WARNING "
- "<<line %i: expected loop field missing>>\n%s\n",
- lcount,S );
- }
- }
-
-}
-
-int CMMCIFData::GetField ( RCFile f, pstr S, pstr & L,
- pstr & p, int & lcount, int & llen ) {
-Boolean Repeat;
-pstr L1;
-int i,flen;
-char c;
-
- flen = 0;
- L[flen] = char(0);
-
- do {
-
- // skip all spaces before the field
- while ((*p==' ') || (*p==char(9))) p++;
-
- if ((*p=='#') || (!(*p))) {
- // comment or end of line met; the field should be
- // found on the next line
- Repeat = !f.FileEnd();
- if (Repeat) {
- // take the next line
- f.ReadLine ( S,_max_buf_len );
- lcount++;
- p = &(S[0]);
- Repeat = (*p!=';');
- } else {
- // end of file and the field is not taken
- L[0] = char(0);
- return 1;
- }
- } else
- // first symbol of a field is found
- Repeat = False;
-
- } while (Repeat);
-
-
- if (*p==';') { // this is a multiline field
- p++;
- strcpy ( L,p ); // take first line of the field
- flen = strlen(L);
- while (!f.FileEnd()) {
- f.ReadLine ( S,_max_buf_len );
- lcount++;
- p = &(S[0]);
- if (*p==';') { // multiline field terminated
- p++;
- while ((*p==' ') || (*p==char(9))) p++;
- return 0;
- } else { // multiline field continues -- take next line
- flen += strlen(S)+2;
- if (flen>=llen) {
- llen = flen + IMin(2000,llen);
- L1 = new char[llen];
- strcpy ( L1,L );
- delete[] L;
- L = L1;
- }
- strcat ( L,"\n" );
- strcat ( L,S );
- }
- }
-
- // end of file -- take the last line of the multiline field
- p = &(S[strlen(S)]);
-
- } else {
-
- i = 0;
- if (*p!='_') {
- if ((*p=='\'') || (*p=='"')) {
- c = *p;
- // field in quotation marks
- do {
- p++;
- // stop taking characters either on end of line
- // or the quotation mark
- while ((*p) && (*p!=c)) {
- L[i++] = *p;
- p++;
- }
- while (*p==c) {
- // it was a quotation mark -- check that it is followed
- // by end of line or space
- p++;
- if ((*p) && (*p!=' ') && (*p!=char(9))) {
- // the quotation mark is not a field terminator and
- // belongs to the field.
- L[i++] = c; // take the quotation mark
- if (*p!=c) // take the non-space character
- L[i++] = *p; // but check for field terminator
- }
- }
- // terminate the loop only on space or end of line
- } while ((*p) && (*p!=' ') && (*p!=char(9)));
- if (*p) p++;
- L[i] = char(0);
- } else {
- // a simplest field without spaces
- while ((*p) && (*p!=' ') && (*p!=char(9))) {
- L[i++] = *p;
- p++;
- }
- L[i] = char(0);
- if (((L[0]=='.') || (L[0]=='?')) && (!L[1])) {
- // "no data" tokens
- L[1] = L[0];
- L[0] = char(2);
- L[2] = char(0);
- }
- }
- }
-
- }
-
- return 0;
-
-}
-
-void CMMCIFData::Sort() {
-int i,k;
-psvector cnames;
-
- k = 0;
- for (i=0;i<nCategories;i++)
- if (Category[i]) {
- if (k<i) Category[k] = Category[i];
- k++;
- }
- for (i=k;i<nCategories;i++)
- Category[i] = NULL;
- nCategories = k;
-
- FreeVectorMemory ( index ,0 );
- GetVectorMemory ( cnames,nCategories,0 );
- GetVectorMemory ( index ,nCategories,0 );
-
- for (i=0;i<nCategories;i++) {
- Category[i]->Sort();
- cnames[i] = NULL;
- CreateCopy ( cnames[i],Category[i]->name );
- }
-
- SortTags ( cnames,nCategories,index );
-
- for (i=0;i<nCategories;i++)
- if (cnames[i]) delete[] cnames[i];
-
- if (cnames) delete[] cnames;
-
-}
-
-int CMMCIFData::GetCategoryNo ( cpstr cname ) {
-// Binary search for index of category cname in Category[].
-// Return:
-// >=0 : position of the category found
-// <0 : the category was not found, it could be inserted before
-// (-RC-1)th element, where RC is the return value
-int l1,l2,l,k;
-
- if (!Category) return -1;
-
- if (!index) Sort();
-
- if (cname[0]) {
- l = 0;
- l1 = 0;
- l2 = nCategories-1;
- k = 1;
- while (l1<l2-1) {
- l = (l1+l2)/2;
- k = strcasecmp ( cname,Category[index[l]]->name );
- if (k<0) l2 = l;
- else if (k>0) l1 = l;
- else {
- l1 = l;
- break;
- }
- }
- if (k==0) return index[l]; // is at RCth position
- k = strcasecmp(cname,Category[index[l1]]->name);
- if (k==0) return index[l1]; // is at RCth position
- if (k<0) return -1; // would be at (-RC-1)th position
- if (l2!=l1) {
- k = strcasecmp(cname,Category[index[l2]]->name);
- if (k==0) return index[l2]; // is at RCth position
- if (k>0) return -2-l2; // would be at l2+1=(-RC-1)th position
- }
- return -2-l1; // would be at l1+1=(-RC-1)th position
- } else
- // 'root' category should be always on top
- if (Category[index[0]]->name[0]==char(1)) return index[0];
-
- return -1;
-
-}
-
-int CMMCIFData::AddCategory ( cpstr cname ) {
-// return -1: a place for category has been added on the top of array;
-// index is added and sorted automatically
-// >=0: the category is already in the array -- its position
-// is returned
-int l1,l;
-PPCMMCIFCategory Category1;
-ivector index1;
-
-
- if (!Category) {
- Category = new PCMMCIFCategory[1];
- Category[0] = NULL;
- GetVectorMemory ( index,1,0 );
- index[0] = 0;
- nCategories = 1;
- return -nCategories; // the category has been added on the top of array
- }
- l1 = GetCategoryNo ( cname );
- if (l1>=0) return l1; // non-negative returns mean that
- // the category is already in the array
- l1 = -l1-1; // otherwise the category has to be added and indexed at here
- // put new NULL-category on the top of array and update the index
- Category1 = new PCMMCIFCategory[nCategories+1];
- GetVectorMemory ( index1,nCategories+1,0 );
- for (l=0;l<nCategories;l++)
- Category1[l] = Category[l];
- Category1[nCategories] = NULL;
- for (l=0;l<l1;l++)
- index1[l] = index[l];
- index1[l1] = nCategories;
- for (l=l1+1;l<=nCategories;l++)
- index1[l] = index[l-1];
- delete[] Category;
- FreeVectorMemory ( index,0 );
- Category = Category1;
- index = index1;
- nCategories++;
- return -nCategories; // the category has been added on
- // the top of array
-}
-
-Boolean CMMCIFData::WriteMMCIFData ( cpstr FName, byte gzipMode ) {
-CFile f;
- f.assign ( FName,True,False,gzipMode );
- if (f.rewrite()) {
- WriteMMCIF ( f );
- f.shut();
- return True;
- } else
- return False;
-}
-
-void CMMCIFData::WriteMMCIF ( RCFile f ) {
-int i;
-
- if (name) {
- f.Write ( pstr("\ndata_") );
- f.WriteLine ( name );
- } else
- f.WriteLine ( pstr("\ndata_") );
-
- for (i=0;i<nCategories;i++)
- if (Category[i])
- Category[i]->WriteMMCIF ( f );
-
-}
-
-
-// --------------- Retrieving data
-
-int CMMCIFData::DeleteCategory ( cpstr CName ) {
-int k;
- k = GetCategoryNo ( CName );
- if (k<0) return CIFRC_NoCategory;
- return DeleteCategory ( k );
-}
-
-int CMMCIFData::DeleteCategory ( int CatNo ) {
-int i;
- if (Category[CatNo]) delete Category[CatNo];
- for (i=CatNo+1;i<nCategories;i++)
- Category[i-1] = Category[i];
- i = 0;
- while ((i<nCategories) && (index[i]!=CatNo)) {
- if (index[i]>CatNo) index[i]--;
- i++;
- }
- i++;
- while (i<nCategories) {
- if (index[i]>CatNo) index[i]--;
- index[i-1] = index[i];
- i++;
- }
- nCategories--;
- index [nCategories] = 0;
- Category[nCategories] = NULL;
- return 0;
-}
-
-int CMMCIFData::DeleteStructure ( cpstr CName ) {
-int k;
- k = GetCategoryNo ( CName );
- if (k<0) return CIFRC_NoCategory;
- if (Category[k]->GetCategoryID()==MMCIF_Struct)
- return DeleteCategory ( k );
- else return CIFRC_NotAStructure;
-}
-
-int CMMCIFData::DeleteLoop ( cpstr CName ) {
-int k;
- k = GetCategoryNo ( CName );
- if (k<0) return CIFRC_NoCategory;
- if (Category[k]->GetCategoryID()==MMCIF_Loop)
- return DeleteCategory ( k );
- else return CIFRC_NotALoop;
-}
-
-PCMMCIFCategory CMMCIFData::GetCategory ( int categoryNo ) {
- if ((categoryNo>=0) && (categoryNo<nCategories))
- return Category[categoryNo];
- return NULL;
-}
-
-PCMMCIFStruct CMMCIFData::GetStructure ( cpstr CName ) {
-int i;
- i = GetCategoryNo ( CName );
- if (i<0) return NULL;
- if (Category[i]->GetCategoryID()==MMCIF_Struct)
- return PCMMCIFStruct(Category[i]);
- else return NULL;
-}
-
-PCMMCIFLoop CMMCIFData::GetLoop ( cpstr CName ) {
-int i;
- i = GetCategoryNo ( CName );
- if (i<0) return NULL;
- if (Category[i]->GetCategoryID()==MMCIF_Loop)
- return PCMMCIFLoop(Category[i]);
- else return NULL;
-}
-
-PCMMCIFLoop CMMCIFData::FindLoop ( cpstr * tagList ) {
-int i;
- for (i=0;i<nCategories;i++)
- if (Category[i]) {
- if (Category[i]->GetCategoryID()==MMCIF_Loop) {
- if (Category[i]->CheckTags(tagList))
- return PCMMCIFLoop(Category[i]);
- }
- }
- return NULL;
-}
-
-void CMMCIFData::GetDataName ( pstr & dname, Boolean Remove ) {
- if (Remove) {
- if (dname) delete[] dname;
- dname = name;
- name = NULL;
- } else
- CreateCopy ( dname,name );
-}
-
-int CMMCIFData::CheckData ( cpstr CName, cpstr TName ) {
-// CheckData(..) returns positive value if the field is in the
-// file:
-// CIFRC_Structure category CName is a structure
-// CIFRC_Loop category CName is a loop
-// Negative returns mean:
-// CIFRC_StructureNoTag category CName is present,
-// it is a structure, but it does not
-// have tag TName
-// CIFRC_LoopNoTag category CName is present,
-// it is a loop, but it does not have
-// tag TName
-// CIFRC_NoCategory category CName is not present.
-// If TName is set to NULL then only the CName is checked and
-// possible returns are CIFRC_Structure, CIFRC_Loop and
-// CIFRC_NoCategory.
-int i,k;
- i = GetCategoryNo ( CName );
- if (i<0) return CIFRC_NoCategory;
- if (Category[i]->GetCategoryID()==MMCIF_Struct)
- k = CIFRC_Structure;
- else k = CIFRC_Loop;
- if (TName) {
- if (Category[i]->GetTagNo(TName)<0) {
- if (k==CIFRC_Structure)
- k = CIFRC_StructureNoTag;
- else k = CIFRC_LoopNoTag;
- }
- }
- return k;
-}
-
-void CMMCIFData::Optimize() {
-int i,k;
-PPCMMCIFCategory C1;
- k = 0;
- for (i=0;i<nCategories;i++)
- if (Category[i]) {
- Category[i]->Optimize();
- if (Category[i]->nTags<=0) {
- delete Category[i];
- Category[i] = NULL;
- } else
- k++;
- }
- if (k>0) {
- if (k!=nCategories) {
- C1 = new PCMMCIFCategory[k];
- k = 0;
- for (i=0;i<nCategories;i++)
- if (Category[i])
- C1[k++] = Category[i];
- if (Category) delete[] Category;
- Category = C1;
- nCategories = k;
- FreeVectorMemory ( index,0 );
- Sort();
- }
- } else {
- if (Category) delete[] Category;
- Category = NULL;
- nCategories = 0;
- }
-}
-
-int CMMCIFData::GetString ( pstr & Dest, cpstr CName,
- cpstr TName, Boolean Remove ) {
-// GetString(..), GetReal(..) and GetInteger(..) return 0 if the
-// requested field was found and successfully converted. Negative
-// returns mean:
-// CIFRC_WrongFormat the field was found but failed to convert
-// due to improper numeric format
-// CIFRC_NoTag category CName was found, but it does not
-// have tag TName
-// CIFRC_NoCategory category CName was not found
-// CIFRC_NotAStructure category CName was found, but it is a loop
-// rather than a structure.
-// GetString(..) will try to dispose Dest unless it is assugned
-// NULL value before the call. The string will be then dynamically
-// allocated and copied.
-int i = GetCategoryNo ( CName );
- if (i<0) return CIFRC_NoCategory;
- if (Category[i]->GetCategoryID()!=MMCIF_Struct)
- return CIFRC_NotAStructure;
- return PCMMCIFStruct(Category[i])->GetString ( Dest,TName,Remove );
-}
-
-pstr CMMCIFData::GetString ( cpstr CName, cpstr TName, int & RC ) {
-int i = GetCategoryNo ( CName );
- if (i<0) {
- RC = CIFRC_NoCategory;
- return NULL;
- }
- if (Category[i]->GetCategoryID()!=MMCIF_Struct) {
- RC = CIFRC_NotAStructure;
- return NULL;
- }
- return PCMMCIFStruct(Category[i])->GetString ( TName,RC );
-}
-
-int CMMCIFData::DeleteField ( cpstr CName, cpstr TName ) {
-int i = GetCategoryNo ( CName );
- if (i<0) return CIFRC_NoCategory;
- if (Category[i]->GetCategoryID()!=MMCIF_Struct)
- return CIFRC_NotAStructure;
- return PCMMCIFStruct(Category[i])->DeleteField ( TName );
-}
-
-int CMMCIFData::GetReal ( realtype & R, cpstr CName,
- cpstr TName, Boolean Remove ) {
-int i = GetCategoryNo ( CName );
- if (i<0) return CIFRC_NoCategory;
- if (Category[i]->GetCategoryID()!=MMCIF_Struct)
- return CIFRC_NotAStructure;
- return PCMMCIFStruct(Category[i])->GetReal ( R,TName,Remove );
-}
-
-int CMMCIFData::GetInteger ( int & I, cpstr CName,
- cpstr TName, Boolean Remove ) {
-int j = GetCategoryNo ( CName );
- if (j<0) return CIFRC_NoCategory;
- if (Category[j]->GetCategoryID()!=MMCIF_Struct)
- return CIFRC_NotAStructure;
- return PCMMCIFStruct(Category[j])->GetInteger ( I,TName,Remove );
-}
-
-int CMMCIFData::GetLoopLength ( cpstr CName ) {
-// GetLoopLength(..) returns CIFRC_NotALoop if the category CName
-// is not a loop, CIFRC_NoCategory if the category CName is not
-// found. Non-negative returns give the length of the loop (may be
-// 0 if the loop is empty).
-int i;
- i = GetCategoryNo ( CName );
- if (i<0) return CIFRC_NoCategory;
- if (Category[i]->GetCategoryID()!=MMCIF_Loop)
- return CIFRC_NotALoop;
- return PCMMCIFLoop(Category[i])->nRows;
-}
-
-int CMMCIFData::GetLoopString ( pstr & Dest, cpstr CName,
- cpstr TName, int nrow,
- Boolean Remove ) {
-// GetLoopString(..), GetLoopReal(..) and GetLoopInteger(..) act
-// like GetString(..), GetReal(..) and GetInteger(..) above for
-// nrow-th element of the 'loop_' (indexed like 0..N-1 where N
-// is obtained through GetLoopLength(..)). They will return
-// CIFRC_WrongIndex if nrow is out of range.
-int i = GetCategoryNo ( CName );
- if (i<0) return CIFRC_NoCategory;
- if (Category[i]->GetCategoryID()!=MMCIF_Loop)
- return CIFRC_NotALoop;
- return PCMMCIFLoop(Category[i])->GetString ( Dest,TName,nrow,Remove );
-}
-
-pstr CMMCIFData::GetLoopString ( cpstr CName, cpstr TName,
- int nrow, int & RC ) {
-int i = GetCategoryNo ( CName );
- if (i<0) {
- RC = CIFRC_NoCategory;
- return NULL;
- }
- if (Category[i]->GetCategoryID()!=MMCIF_Loop) {
- RC = CIFRC_NotALoop;
- return NULL;
- }
- return PCMMCIFLoop(Category[i])->GetString ( TName,nrow,RC );
-}
-
-int CMMCIFData::DeleteLoopField ( cpstr CName, cpstr TName,
- int nrow ) {
-int i = GetCategoryNo ( CName );
- if (i<0) return CIFRC_NoCategory;
- if (Category[i]->GetCategoryID()!=MMCIF_Loop)
- return CIFRC_NotALoop;
- return PCMMCIFLoop(Category[i])->DeleteField ( TName,nrow );
-}
-
-int CMMCIFData::GetLoopReal ( realtype & R, cpstr CName,
- cpstr TName, int nrow,
- Boolean Remove ) {
-int i = GetCategoryNo ( CName );
- if (i<0) return CIFRC_NoCategory;
- if (Category[i]->GetCategoryID()!=MMCIF_Loop)
- return CIFRC_NotALoop;
- return PCMMCIFLoop(Category[i])->GetReal ( R,TName,nrow,Remove );
-}
-
-int CMMCIFData::GetLoopInteger ( int & I, cpstr CName,
- cpstr TName, int nrow,
- Boolean Remove ) {
-int j = GetCategoryNo ( CName );
- if (j<0) return CIFRC_NoCategory;
- if (Category[j]->GetCategoryID()!=MMCIF_Loop)
- return CIFRC_NotALoop;
- return PCMMCIFLoop(Category[j])->GetInteger ( I,TName,nrow,Remove );
-}
-
-
-int CMMCIFData::GetLoopSVector ( psvector & S, cpstr CName,
- cpstr TName, int i1, int i2,
- Boolean Remove ) {
-// GetLoopSVector(..), GetLoopRVector(..) and GetLoopIVector(..)
-// read CIF 'loop_' data into allocated vectors of strings, reals and
-// integers, correspondingly. The vectors may be deallocated prior
-// to call and assigned NULL, in which case they will be allocated
-// with offsets of i1, which is also the lower index of the 'loop_'
-// data transferred into it. The upper vector index is given by i2 or
-// by the loop's length whichever is less. If vectors are not assigned
-// NULL prior the call, it is assumed that they are properly (i1-offset,
-// i2-i1+1 length) allocated.
-// The return codes are same as those of GetLoopString(..),
-// GetLoopReal(..) and GetLoopInteger(..).
-int i;
- i = GetCategoryNo ( CName );
- if (i<0) return CIFRC_NoCategory;
- if (Category[i]->GetCategoryID()!=MMCIF_Loop)
- return CIFRC_NotALoop;
- return PCMMCIFLoop(Category[i])->GetSVector ( S,TName,i1,i2,Remove );
-}
-
-int CMMCIFData::GetLoopRVector ( rvector & R, cpstr CName,
- cpstr TName, int i1, int i2,
- Boolean Remove ) {
-int i;
- i = GetCategoryNo ( CName );
- if (i<0) return CIFRC_NoCategory;
- if (Category[i]->GetCategoryID()!=MMCIF_Loop)
- return CIFRC_NotALoop;
- return PCMMCIFLoop(Category[i])->GetRVector ( R,TName,i1,i2,Remove );
-}
-
-int CMMCIFData::GetLoopIVector ( ivector & I, cpstr CName,
- cpstr TName, int i1, int i2,
- Boolean Remove ) {
-int j;
- j = GetCategoryNo ( CName );
- if (j<0) return CIFRC_NoCategory;
- if (Category[j]->GetCategoryID()!=MMCIF_Loop)
- return CIFRC_NotALoop;
- return PCMMCIFLoop(Category[j])->GetIVector ( I,TName,i1,i2,Remove );
-}
-
-
-// --------------- Storing data
-
-void CMMCIFData::PutDataName ( cpstr dname ) {
-// stores name for 'data_' record
- CreateCopy ( name,dname );
-}
-
-int CMMCIFData::PutNoData ( int NoDataType, cpstr CName,
- cpstr TName ) {
-PCMMCIFStruct Struct;
-int i,RC;
-
- RC = CIFRC_Ok;
-
- // look for category
- i = AddCategory ( CName );
- if (i<0) {
- // negative value means that the category was not in the list,
- // but a place for it has been provided and index updated
- Struct = new CMMCIFStruct ( CName );
- Category[nCategories-1] = Struct;
- } else {
- Struct = PCMMCIFStruct(Category[i]);
- if (Struct->GetCategoryID()!=MMCIF_Struct) {
- RC = CIFRC_NotAStructure;
- delete Category[i];
- Struct = new CMMCIFStruct ( CName );
- Category[i] = Struct;
- }
- }
-
- Struct->PutNoData ( NoDataType,TName );
-
- return RC;
-
-}
-
-int CMMCIFData::PutString ( cpstr S, cpstr CName,
- cpstr TName, Boolean Concatenate ) {
-// PutString(..), PutReal(..) and PutInteger(..) will put the
-// values given into the specified category (CName) under the
-// specified tag (TName). The category, tag and field are created
-// automatically; the field will be replaced silently if identical
-// CName.TName is specified in two calls. Calls of these functions
-// may follow in random order; however CIF file will have all tags
-// grouped by categories and catgories will follow in the order
-// of first appearance in PutString(..), PutReal(..) or
-// PutInteger(..).
-// Return code - one of CIFRC_Ok or CIFRC_NotAStruct
-PCMMCIFStruct Struct;
-int i,RC;
-
- RC = CIFRC_Ok;
-
- // look for category
- i = AddCategory ( CName );
- if (i<0) {
- // negative value means that the category was not in the list,
- // but a place for it has been provided and index updated
- Struct = new CMMCIFStruct ( CName );
- Category[nCategories-1] = Struct;
- } else {
- Struct = PCMMCIFStruct(Category[i]);
- if (Struct->GetCategoryID()!=MMCIF_Struct) {
- RC = CIFRC_NotAStructure;
- delete Category[i];
- Struct = new CMMCIFStruct ( CName );
- Category[i] = Struct;
- }
- }
-
- Struct->AddField ( S,TName,Concatenate );
-
- return RC;
-
-}
-
-int CMMCIFData::PutDate ( cpstr CName, cpstr TName ) {
-PCMMCIFStruct Struct;
-int i,RC;
-
- RC = CIFRC_Ok;
-
- // look for category
- i = AddCategory ( CName );
- if (i<0) {
- // negative value means that the category was not in the list,
- // but a place for it has been provided and index updated
- Struct = new CMMCIFStruct ( CName );
- Category[nCategories-1] = Struct;
- } else {
- Struct = PCMMCIFStruct(Category[i]);
- if (Struct->GetCategoryID()!=MMCIF_Struct) {
- RC = CIFRC_NotAStructure;
- delete Category[i];
- Struct = new CMMCIFStruct ( CName );
- Category[i] = Struct;
- }
- }
-
- Struct->PutDate ( TName );
-
- return RC;
-
-}
-
-int CMMCIFData::PutReal ( realtype R, cpstr CName,
- cpstr TName, int prec ) {
-char rS[100];
- sprintf ( rS,"%.*g",prec,R );
- return PutString ( rS,CName,TName,False );
-}
-
-int CMMCIFData::PutInteger ( int I, cpstr CName,
- cpstr TName ) {
-char iS[100];
- if (I>MinInt4) sprintf ( iS,"%i",I );
- else {
- iS[0] = char(2);
- iS[1] = '.';
- iS[2] = char(0);
- }
- return PutString ( iS,CName,TName,False );
-}
-
-
-int CMMCIFData::AddLoop ( cpstr CName, PCMMCIFLoop & Loop ) {
-int i,RC;
-
- RC = CIFRC_Ok;
-
- // look for category
- i = AddCategory ( CName );
- if (i<0) {
- // negative value means that the category was not in the list,
- // but a place for it has been provided and index updated
- Loop = new CMMCIFLoop ( CName );
- Category[nCategories-1] = Loop;
- RC = CIFRC_Created;
- } else {
- Loop = PCMMCIFLoop(Category[i]);
- if (Loop->GetCategoryID()!=MMCIF_Loop) {
- RC = CIFRC_NotALoop;
- delete Category[i];
- Loop = new CMMCIFLoop ( CName );
- Category[i] = Loop;
- }
- }
-
- return RC;
-
-}
-
-int CMMCIFData::AddStructure ( cpstr CName,
- PCMMCIFStruct & Struct ) {
-int i,RC;
-
- RC = CIFRC_Ok;
-
- // look for category
- i = AddCategory ( CName );
- if (i<0) {
- // negative value means that the category was not in the list,
- // but a place for it has been provided and index updated
- Struct = new CMMCIFStruct ( CName );
- Category[nCategories-1] = Struct;
- RC = CIFRC_Created;
- } else {
- Struct = PCMMCIFStruct(Category[i]);
- if (Struct->GetCategoryID()!=MMCIF_Struct) {
- RC = CIFRC_NotAStructure;
- delete Category[i];
- Struct = new CMMCIFStruct ( CName );
- Category[i] = Struct;
- }
- }
-
- return RC;
-
-}
-
-
-int CMMCIFData::PutLoopNoData ( int NoDataType, cpstr CName,
- cpstr TName, int nrow ) {
-PCMMCIFLoop Loop;
-int i,RC;
-
- RC = CIFRC_Ok;
-
- // look for category
- i = AddCategory ( CName );
- if (i<0) {
- // negative value means that the category was not in the list,
- // but a place for it has been provided and index updated
- Loop = new CMMCIFLoop ( CName );
- Category[nCategories-1] = Loop;
- } else {
- Loop = PCMMCIFLoop(Category[i]);
- if (Loop->GetCategoryID()!=MMCIF_Loop) {
- RC = CIFRC_NotALoop;
- delete Category[i];
- Loop = new CMMCIFLoop ( CName );
- Category[i] = Loop;
- }
- }
-
- Loop->PutNoData ( NoDataType,TName,nrow );
-
- return RC;
-
-}
-
-
-int CMMCIFData::PutLoopString ( cpstr S, cpstr CName,
- cpstr TName, int nrow ) {
-// PutLoopString(..), PutLoopReal(..) and PutLoopInteger(..) act
-// like PutString(..), PutReal(..) and PutInteger(..) above for
-// nrow-th element of the 'loop_' CName (indexed begining from 0).
-// In consequitive calls, given values of nrow does not have to be
-// ordered; the most efficient way is to start with HIGHEST value
-// for nrow in the loop and move down to 0. The least efficient way
-// is to start with nrow=0 and move up.
-PCMMCIFLoop Loop;
-int i,RC;
-
- RC = CIFRC_Ok;
-
- // look for category
- i = AddCategory ( CName );
- if (i<0) {
- // negative value means that the category was not in the list,
- // but a place for it has been provided and index updated
- Loop = new CMMCIFLoop ( CName );
- Category[nCategories-1] = Loop;
- } else {
- Loop = PCMMCIFLoop(Category[i]);
- if (Loop->GetCategoryID()!=MMCIF_Loop) {
- RC = CIFRC_NotALoop;
- delete Category[i];
- Loop = new CMMCIFLoop ( CName );
- Category[i] = Loop;
- }
- }
-
- Loop->PutString ( S,TName,nrow );
-
- return RC;
-
-}
-
-int CMMCIFData::PutLoopReal ( realtype R, cpstr CName,
- cpstr TName, int nrow, int prec ) {
-char rS[100];
- sprintf ( rS,"%.*g",prec,R );
- return PutLoopString ( rS,CName,TName,nrow );
-}
-
-int CMMCIFData::PutLoopInteger ( int I, cpstr CName,
- cpstr TName, int nrow ) {
-char iS[100];
- sprintf ( iS,"%i",I );
- return PutLoopString ( iS,CName,TName,nrow );
-}
-
-
-int CMMCIFData::PutLoopSVector ( psvector S, cpstr CName,
- cpstr TName, int i1, int i2 ) {
-// PutLoopSVector(..), PutLoopRVector(..) and PutLoopIVector(..)
-// put vectors of values into specified loop fields. Parameters i1
-// and i2 give the range of indices of values which are to be
-// transfered. To transfer an entire vector allocated as [0..N-1]
-// i1 shoudl be set to 0 and i2 - to N-1. Note that the loop is
-// always indexed as starting form 0 on, therefore negative i1 and
-// i2 are not allowed, and specifying i1>0 will leave first i1
-// elements of the CIF loop for the corresponding tag undefined
-// (will be output like '?').
-PCMMCIFLoop Loop;
-int i,RC;
-
- RC = CIFRC_Ok;
-
- // look for category
- i = AddCategory ( CName );
- if (i<0) {
- // negative value means that the category was not in the list,
- // but a place for it has been provided and index updated
- Loop = new CMMCIFLoop ( CName );
- Category[nCategories-1] = Loop;
- } else {
- Loop = PCMMCIFLoop(Category[i]);
- if (Loop->GetCategoryID()!=MMCIF_Loop) {
- RC = CIFRC_NotALoop;
- delete Category[i];
- Loop = new CMMCIFLoop ( CName );
- Category[i] = Loop;
- }
- }
-
- Loop->PutSVector ( S,TName,i1,i2 );
-
- return RC;
-
-}
-
-int CMMCIFData::PutLoopRVector ( rvector R, cpstr CName,
- cpstr TName,
- int i1, int i2, int prec ) {
-PCMMCIFLoop Loop;
-int i,RC;
-
- RC = CIFRC_Ok;
-
- // look for category
- i = AddCategory ( CName );
- if (i<0) {
- // negative value means that the category was not in the list,
- // but a place for it has been provided and index updated
- Loop = new CMMCIFLoop ( CName );
- Category[nCategories-1] = Loop;
- } else {
- Loop = PCMMCIFLoop(Category[i]);
- if (Loop->GetCategoryID()!=MMCIF_Loop) {
- RC = CIFRC_NotALoop;
- delete Category[i];
- Loop = new CMMCIFLoop ( CName );
- Category[i] = Loop;
- }
- }
-
- Loop->PutRVector ( R,TName,i1,i2,prec );
-
- return RC;
-
-}
-
-int CMMCIFData::PutLoopIVector ( ivector I, cpstr CName,
- cpstr TName,
- int i1, int i2 ) {
-PCMMCIFLoop Loop;
-int j,RC;
-
- RC = CIFRC_Ok;
-
- // look for category
- j = AddCategory ( CName );
- if (j<0) {
- // negative value means that the category was not in the list,
- // but a place for it has been provided and index updated
- Loop = new CMMCIFLoop ( CName );
- Category[nCategories-1] = Loop;
- } else {
- Loop = PCMMCIFLoop(Category[j]);
- if (Loop->GetCategoryID()!=MMCIF_Loop) {
- RC = CIFRC_NotALoop;
- delete Category[j];
- Loop = new CMMCIFLoop ( CName );
- Category[j] = Loop;
- }
- }
-
- Loop->PutIVector ( I,TName,i1,i2 );
-
- return RC;
-
-}
-
-
-int CMMCIFData::RenameCategory ( cpstr CName,
- cpstr newCName ) {
-int i,RC;
- i = GetCategoryNo ( CName );
- if (i>=0) {
- Category[i]->PutCategoryName ( newCName );
- Sort();
- RC = CIFRC_Ok;
- } else
- RC = CIFRC_NoCategory;
- return RC;
-}
-
-
-void CMMCIFData::Copy ( PCMMCIFData Data ) {
-int i;
- FreeMemory(0);
- CreateCopy ( name,Data->name );
- nCategories = Data->nCategories;
- if (nCategories>0) {
- Category = new PCMMCIFCategory[nCategories];
- GetVectorMemory ( index,nCategories,0 );
- for (i=0;i<nCategories;i++) {
- if (Data->Category[i]) {
- if (Data->Category[i]->GetCategoryID()==MMCIF_Struct)
- Category[i] = new CMMCIFStruct();
- else Category[i] = new CMMCIFLoop();
- Category[i]->Copy ( Data->Category[i] );
- } else
- Category[i] = NULL;
- index[i] = Data->index[i];
- }
- }
- flags = Data->flags;
- Warning = Data->Warning;
-}
-
-
-int CMMCIFData::CopyCategory ( PCMMCIFData Data, cpstr CName,
- cpstr newCName ) {
-PCMMCIFCategory Cat;
-int i,di,dc,RC;
-
- di = Data->GetCategoryNo ( CName );
-
- if (di>=0) {
-
- RC = CIFRC_Ok;
- dc = Data->Category[di]->GetCategoryID();
-
- // look for category
- i = AddCategory ( CName );
- if (i<0) {
- // negative value means that the category was not in the list,
- // but a place for it has been provided and index updated
- if (dc==MMCIF_Loop) Cat = new CMMCIFLoop ( CName );
- else Cat = new CMMCIFStruct ( CName );
- Category[nCategories-1] = Cat;
- } else {
- Cat = Category[i];
- if (Cat->GetCategoryID()!=dc) {
- RC = CIFRC_NotAStructure;
- delete Category[i];
- if (dc==MMCIF_Loop) Cat = new CMMCIFLoop ( CName );
- else Cat = new CMMCIFStruct ( CName );
- Category[i] = Cat;
- }
- }
-
- Cat->Copy ( Data->Category[di] );
- if (newCName) {
- Cat->PutCategoryName ( newCName );
- Sort();
- }
-
- } else
- RC = CIFRC_NoCategory;
-
- return RC;
-
-}
-
-void CMMCIFData::PrintCategories() {
-// for debuging only
-int i;
- printf ( " Total %i categories:\n",nCategories );
- for (i=0;i<nCategories;i++)
- if (Category[i]) {
- printf ( " %5i. ",i+1 );
- if (Category[i]->GetCategoryID()==MMCIF_Loop)
- printf ( "Loop %s\n",Category[i]->name );
- else printf ( "Structure %s\n",Category[i]->name );
- }
-}
-
-
-void CMMCIFData::write ( RCFile f ) {
-int i,k;
- if (!index) Sort();
- f.CreateWrite ( name );
- f.WriteInt ( &nCategories );
- for (i=0;i<nCategories;i++) {
- if (Category[i]) {
- k = Category[i]->GetCategoryID();
- f.WriteInt ( &k );
- Category[i]->write ( f );
- } else {
- k = -1;
- f.WriteInt ( &k );
- }
- f.WriteInt ( &(index[i]) );
- }
- f.WriteInt ( &flags );
- f.WriteInt ( &Warning );
-}
-
-
-void CMMCIFData::read ( RCFile f ) {
-int i,k;
- FreeMemory(0);
- f.CreateRead ( name );
- f.ReadInt ( &nCategories );
- if (nCategories>0) {
- Category = new PCMMCIFCategory[nCategories];
- GetVectorMemory ( index,nCategories,0 );
- for (i=0;i<nCategories;i++) {
- f.ReadInt ( &k );
- if (k>=0) {
- if (k==MMCIF_Struct) Category[i] = new CMMCIFStruct();
- else Category[i] = new CMMCIFLoop();
- Category[i]->read ( f );
- } else
- Category[i] = NULL;
- f.ReadInt ( &(index[i]) );
- }
- }
- f.ReadInt ( &flags );
- f.ReadInt ( &Warning );
-}
-
-
-MakeStreamFunctions(CMMCIFData)
-
-
-
-// ====================== CMMCIFFile =============================
-
-
-CMMCIFFile::CMMCIFFile() : CStream() {
- InitMMCIFFile();
-}
-
-CMMCIFFile::CMMCIFFile ( cpstr FName, byte gzipMode ) : CStream() {
- InitMMCIFFile ();
- ReadMMCIFFile ( FName,gzipMode );
-}
-
-CMMCIFFile::CMMCIFFile ( RPCStream Object ) : CStream(Object) {
- InitMMCIFFile();
-}
-
-CMMCIFFile::~CMMCIFFile() {
- FreeMemory();
-}
-
-void CMMCIFFile::InitMMCIFFile() {
- nData = 0;
- nAllocData = 0;
- data = NULL;
- index = NULL;
- PrintWarnings = False;
- StopOnWarning = False;
-}
-
-void CMMCIFFile::FreeMemory() {
-int i;
- for (i=0;i<nData;i++)
- if (data[i]) delete data[i];
- if (data) delete[] data;
- data = NULL;
- FreeVectorMemory ( index,0 );
- nData = 0;
- nAllocData = 0;
-}
-
-
-pstr GetMMCIFInputBuffer ( int & LineNo ) {
- LineNo = _err_line;
- _err_string[sizeof(_err_string)-1] = char(0);
- return _err_string;
-}
-
-int CMMCIFFile::ReadMMCIFFile ( cpstr FName, byte gzipMode ) {
-CFile f;
-PCMMCIFData CIF;
-char S[500];
-int RC,lcount;
-
- FreeMemory();
-
- CIF = NULL;
- f.assign ( FName,True,False,gzipMode );
- if (f.reset(True)) {
- S[0] = char(0);
- lcount = 0;
- RC = 0;
- while ((!RC) && (!f.FileEnd())) {
- if (!CIF) CIF = new CMMCIFData();
- CIF->SetPrintWarnings ( PrintWarnings );
- CIF->SetStopOnWarning ( StopOnWarning );
- RC = CIF->ReadMMCIFData ( f,S,lcount );
- if (!RC) {
- ExpandData ( nData+1 );
- data[nData] = CIF;
- nData++;
- CIF = NULL;
- }
- }
- if (CIF) delete CIF;
- f.shut();
- if (RC==CIFRC_NoDataLine) {
- if (nData>0) RC = 0;
- }
- Sort();
- return RC;
- } else
- return CIFRC_CantOpenFile;
-
-}
-
-int CMMCIFFile::WriteMMCIFFile ( cpstr FName, byte gzipMode ) {
-CFile f;
- f.assign ( FName,True,False,gzipMode );
- if (f.rewrite()) {
- WriteMMCIF ( f );
- f.shut();
- return 0;
- } else
- return CIFRC_CantOpenFile;
-}
-
-void CMMCIFFile::WriteMMCIF ( RCFile f ) {
-int i;
- for (i=0;i<nData;i++)
- if (data[i])
- data[i]->WriteMMCIF ( f );
-}
-
-
-void CMMCIFFile::Sort() {
-psvector tag;
-int i;
- if (nData>0) {
- FreeVectorMemory ( index,0 );
- GetVectorMemory ( index,nData,0 );
- GetVectorMemory ( tag ,nData,0 );
- for (i=0;i<nData;i++) {
- tag[i] = NULL;
- CreateCopy ( tag[i],data[i]->name );
- }
- SortTags ( tag,nData,index );
- for (i=0;i<nData;i++)
- if (tag[i]) {
- delete[] tag[i];
- tag[i] = NULL;
- }
- FreeVectorMemory ( tag,0 );
- }
-}
-
-int CMMCIFFile::GetCIFDataNo ( cpstr DName ) {
-// Binary search for index of DName ttag in data[].
-// Return:
-// >=0 : position of the DName found
-// <0 : the DName was not found, it could be inserted before
-// (-RC-1)th element, where RC is the return value
-int l1,l2,l,k;
-
- if (!data) return -1;
- if (!index) Sort();
-
- l = 0;
- l1 = 0;
- l2 = nData-1;
- k = 1;
- while (l1<l2-1) {
- l = (l1+l2)/2;
- k = strcasecmp ( DName,data[index[l]]->name );
- if (k<0) l2 = l;
- else if (k>0) l1 = l;
- else {
- l1 = l;
- break;
- }
- }
-
- if (k==0) return index[l]; // is at RCth position
- k = strcasecmp ( DName,data[index[l1]]->name );
- if (k==0) return index[l1]; // is at RCth position
- if (k<0) return -1; // would be at (-RC-1)th position
- if (l2!=l1) {
- k = strcasecmp ( DName,data[index[l2]]->name );
- if (k==0) return index[l2]; // is at RCth position
- if (k>0) return -2-l2; // would be at l2+1=(-RC-1)th position
- }
-
- return -2-l1; // would be at l1+1=(-RC-1)th position
-
-}
-
-PCMMCIFData CMMCIFFile::GetCIFData ( int dataNo ) {
- if ((dataNo>=0) && (dataNo<nData)) return data[dataNo];
- else return NULL;
-}
-
-PCMMCIFData CMMCIFFile::GetCIFData ( cpstr DName ) {
-int l;
- l = GetCIFDataNo ( DName );
- if (l>=0) return data[l];
- else return NULL;
-}
-
-void CMMCIFFile::ExpandData ( int nDataNew ) {
-int i,nAD;
-PPCMMCIFData data1;
-ivector index1;
- if (nDataNew>nAllocData) {
- nAD = nDataNew + IMin(nAllocData/2+1,100);
- data1 = new PCMMCIFData[nAD];
- GetVectorMemory ( index1,nAD,0 );
- for (i=0;i<nAllocData;i++) {
- data1 [i] = data [i];
- index1[i] = index[i];
- }
- for (i=nAllocData;i<nAD;i++) {
- data1 [i] = NULL;
- index1[i] = i;
- }
- if (data) delete[] data;
- FreeVectorMemory ( index,0 );
- data = data1;
- index = index1;
- nAllocData = nAD;
- }
-}
-
-int CMMCIFFile::AddMMCIFData ( cpstr DName ) {
-// return -1: the CIF data structure has been added on the
-// top of data array; the index is added and sorted
-// automatically
-// >=0: the CIF data structure is already in the array
-// -- its position is returned
-int i1,i;
- if (!data) {
- ExpandData ( 3 ); // get space for first 3 CIF data structures
- data[0] = new CMMCIFData ( DName );
- nData = 1;
- return -nData; // the CIF data structure has been added
- // "on the top" of array
- }
- i1 = GetCIFDataNo ( DName );
- if (i1>=0) return i1; // non-negative returns mean that the CIF
- // data structure is already in the array
- i1 = -i1-1; // otherwise the data has to be added and indexed at here
- // put new CIF data structure on the top of array and update index
- ExpandData ( nData+1 );
- data[nData] = new CMMCIFData ( DName );
- for (i=nData;i>i1;i--)
- index[i] = index[i-1];
- index[i1] = nData;
- nData++;
- return -nData; // the tag has been added on the top of array
-}
-
-
-int CMMCIFFile::DeleteMMCIFData ( cpstr DName ) {
-int dataNo = GetCIFDataNo ( DName );
-
- if (dataNo>=0) return DeleteMMCIFData ( dataNo );
- return dataNo;
-
-}
-
-int CMMCIFFile::DeleteMMCIFData ( int dataNo ) {
-int i;
-
- if ((0<=dataNo) && (dataNo<nData)) {
-
- if (data[dataNo]) delete data[dataNo];
- for (i=dataNo+1;i<nData;i++)
- data[i-1] = data[i];
- nData--;
-
- Sort();
-
- return 0;
-
- }
-
- return -nData;
-
-}
-
-void CMMCIFFile::Copy ( PCMMCIFFile File ) {
-int i;
- FreeMemory();
- nData = File->nData;
- nAllocData = nData;
- if (nData>0) {
- data = new PCMMCIFData[nData];
- for (i=0;i<nData;i++) {
- if (File->data[i]) {
- data[i] = new CMMCIFData();
- data[i]->Copy ( File->data[i] );
- } else
- data[i] = NULL;
- }
- }
-}
-
-
-void CMMCIFFile::write ( RCFile f ) {
-int i,k;
- f.WriteInt ( &nData );
- for (i=0;i<nData;i++)
- if (data[i]) {
- k = 1;
- f.WriteInt ( &k );
- data[i]->write ( f );
- } else {
- k = 0;
- f.WriteInt ( &k );
- }
-}
-
-void CMMCIFFile::read ( RCFile f ) {
-int i,k;
- FreeMemory();
- f.ReadInt ( &nData );
- nAllocData = nData;
- if (nData>0) {
- data = new PCMMCIFData[nData];
- for (i=0;i<nData;i++) {
- f.ReadInt ( &k );
- if (k) {
- data[i] = new CMMCIFData();
- data[i]->read ( f );
- } else
- data[i] = NULL;
- }
- }
-}
-
-
-MakeStreamFunctions(CMMCIFFile)
-
-
-int isCIF ( cpstr FName, byte gzipMode ) {
-CFile f;
-int rc;
-
- f.assign ( FName,True,False,gzipMode );
- if (f.reset(True)) {
- rc = isCIF ( f );
- f.shut();
- } else
- rc = -1;
-
- return rc;
-
-}
-
-int isCIF ( RCFile f ) {
-char S[_max_buf_len+1];
-Boolean Done;
-pstr p;
-
- f.ReadLine ( S,_max_buf_len );
- S[_max_buf_len] = char(0);
- Done = False;
- while (!Done) {
- p = &(S[0]);
- while ((*p==' ') || (*p==char(9))) p++;
- Done = !strncmp(p,"data_",5);
- if (!Done) {
- if (f.FileEnd()) {
- Done = True;
- p = NULL;
- } else {
- f.ReadLine ( S,_max_buf_len );
- S[_max_buf_len] = char(0);
- }
- }
- }
-
- if (!p) return 1;
- if (!strncmp(p,"data_",5)) return 0;
- else return 1;
-
-}
-
-
-pstr GetCIFMessage ( pstr M, int RC ) {
-int LineNo;
-pstr InputLine;
-
- InputLine = GetMMCIFInputBuffer ( LineNo );
-
- if (RC>10) {
- if (RC & CIFW_UnrecognizedItems)
- sprintf ( M,"unrecognized items found on %ith line\n%s",
- LineNo,InputLine );
- else if (RC & CIFW_MissingField)
- sprintf ( M,"expected data field not found; line %i reads\n%s",
- LineNo,InputLine );
- else if (RC & CIFW_EmptyLoop)
- sprintf ( M,"empty loop ('loop_') on %ith line\n%s",
- LineNo,InputLine );
- else if (RC & CIFW_UnexpectedEOF)
- sprintf ( M,"unexpected end of file; line %i reads\n%s",
- LineNo,InputLine );
- else if (RC & CIFW_LoopFieldMissing)
- sprintf ( M,"expected data field in a loop not found; "
- "line %i reads\n%s", LineNo,InputLine );
- else if (RC & CIFW_LoopFieldMissing)
- sprintf ( M,"expected data field in a loop not found; "
- "line %i reads\n%s", LineNo,InputLine );
- else if (RC & CIFW_NotAStructure)
- sprintf ( M,"a loop is used as a structure on line %i\n%s",
- LineNo,InputLine );
- else if (RC & CIFW_NotALoop)
- sprintf ( M,"a structure is used as a loop on line %i\n%s",
- LineNo,InputLine );
- else if (RC & CIFW_DuplicateTag)
- sprintf ( M,"duplicate tag was found on line %i\n%s",
- LineNo,InputLine );
- else
- sprintf ( M,"undocumented warning issued for line %i\n%s",
- LineNo,InputLine );
- } else if (RC<0)
- switch (RC) {
- case CIFRC_StructureNoTag : strcpy(M,"tag of a structure not "
- "found");
- break;
- case CIFRC_LoopNoTag : strcpy(M,"tag of a loop not found");
- break;
- case CIFRC_NoCategory : strcpy(M,"category not found");
- break;
- case CIFRC_WrongFormat : strcpy(M,"wrong format of a number");
- break;
- case CIFRC_NoTag : strcpy(M,"tag not found");
- break;
- case CIFRC_NotAStructure : strcpy(M,"category is not a "
- "structure");
- break;
- case CIFRC_NotALoop : strcpy(M,"category is not a loop");
- break;
- case CIFRC_WrongIndex : strcpy(M,"index outside the loop's "
- "limits");
- break;
- case CIFRC_NoField : strcpy(M,"data is absent");
- break;
- case CIFRC_Created : strcpy(M,"category created");
- break;
- case CIFRC_CantOpenFile : strcpy(M,"can't open CIF file");
- break;
- case CIFRC_NoDataLine : strcpy(M,"'data_' tag not found." );
- break;
- default : strcpy(M,"undocumented return code");
- }
-
- return M;
-
-}
diff --git a/mmdb/mmdb_mmcif.h b/mmdb/mmdb_mmcif.h
deleted file mode 100755
index 4b04ad5..0000000
--- a/mmdb/mmdb_mmcif.h
+++ /dev/null
@@ -1,2129 +0,0 @@
-// $Id: mmdb_mmcif.h,v 1.23 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 16.01.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_MMCIF <interface>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CMMCIFCategory ( mmCIF category )
-// ~~~~~~~~~ CMMCIFStruct ( mmCIF structure )
-// CMMCIFLoop ( mmCIF loop )
-// CMMCIFData ( mmCIF data block )
-// CMMCIFFile ( mmCIF file )
-//
-// (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-
-#ifndef __MMDB_MMCIF__
-#define __MMDB_MMCIF__
-
-
-#ifndef __Stream__
-#include "stream_.h"
-#endif
-
-
-
-// ====================== CMMCIFCategory ==========================
-
-#define MMCIF_Category 0
-#define MMCIF_Struct 1
-#define MMCIF_Loop 2
-#define MMCIF_Data 3
-
-DefineClass(CMMCIFCategory)
-DefineStreamFunctions(CMMCIFCategory)
-
-/// \brief CMMCIFCategory is a base class for CMMCIFStruct and
-/// CMMCIFLoop, implementations of mmCIF's "structure" and
-/// "loop" categories.
-/*!
-This class is not instantiated independently in any applications,
-however, it provides a few public functions which work for
-both CMMCIFStruct and CMMCIFLoop.
-
-All data in mmCIF hierarchy is addressed using construct
-"category.tag" plus row number (>=0) for loops. Category names
-should always start from underscore, while tags normally start
-with a letter, e.g. "_barrel.id".
-
-See general principles of working with mmCIF files and mmCIF
-hierarchies in Section \"\ref mmcif_handler\".
-*/
-
-class CMMCIFCategory : public CStream {
-
- friend class CMMCIFData;
-
- public :
-
- /// \brief Basic constructor.
- CMMCIFCategory ();
-
- /// \brief Constructor that assigns category name.
- /// \param[in] N category name (must start with underscore).
- CMMCIFCategory ( cpstr N );
-
- /// \brief Constructor for MMDB data streaming functions.
- CMMCIFCategory ( RPCStream Object );
-
- /// \brief Destructor.
- ~CMMCIFCategory();
-
- /// \brief Returns category name.
- /// \return NULL if name was not set
- /// \return pointer to character string if name was set
- pstr GetCategoryName() { return name; }
-
- /// \brief Sets category name.
- /// \param N new category name
- void SetCategoryName ( cpstr N );
-
- /// \brief Returns category type.
- /// This function may be used when retrieving categories
- /// (structures and loops) from data blocks (CMMCIFData).
- /// \return MMCIF_Category for CMMCIFCategory
- /// \return MMCIF_Struct for CMMCIFStruct
- /// \return MMCIF_Loop for CMMCIFLoop
- virtual int GetCategoryID() { return MMCIF_Category; }
-
- /// \brief Virtual function for writing category's content
- /// into mmCIF file.
- /// Default implementation does nothing.
- virtual void WriteMMCIF ( RCFile ) {}
-
- /// \brief Virtual function for optimizig data structures.
- /// Optimized data structures take less RAM and their indexes
- /// are sorted for quicker access. Sorting is done automatically
- /// as new data is added to the category. If the
- /// category is edited (fields/data removed), it may need
- /// optimization and re-sorting for efficiency.\n\n
- /// The sorting preserves the order of actual appearance of
- /// tags in mmCIF file. If a category is created
- /// programmatically, the order of tags in mmCIF file will be
- /// the same as order of adding them to the category.
- virtual void Optimize();
-
- /// \brief Sorts category's data for quicker access.
- /// The sorting is essentially re-indexing of data for quicker
- /// access. It does not change the order of data in both mmCIF
- /// hierarchy and mmCIF file. E.g., if tag "serial_no" was 2nd
- /// one in given category before sorting, it will remain on 2nd
- /// place after it, therefore no change in tag number passed
- /// to functions in CMMCIFStruct, CMMCIFLoop and CMMCIFData.
- void Sort();
-
- /// \brief Returns serial number of a tag in the category.
- /// \param[in] ttag tag (or name of a field in category)
- /// \return \b >=0 : the tag is in given position
- /// \return \b <0 : the tag was not found, but it could be
- /// inserted before tag with (-rc-1)th index, where
- /// 'rc' is the return.
- int GetTagNo ( cpstr ttag );
-
- /// \brief Adds a tag to the category.
- /// Adding a tag in CMMCIFCategory does not reserve any
- /// placeholder for the corresponding value. All tags get
- /// automatically sorted (reindexed) for quicker access.
- /// Tags will appear in mmCIF file in order of their addition
- /// to the category.
- /// \param[in] ttag tag to be added.
- /// \return \b >=0 the tag is already in the category, and return
- /// is its serial number. No changes to the category
- /// is done
- /// \return \b <0 the tag was added to the list of tags, and
- /// return is minus total number of tags in the
- /// category.
- int AddTag ( cpstr ttag );
-
- /// \brief Returns the total number of tags in the category
- int GetNofTags() { return nTags; }
-
- /// \brief Returns tag with the specified serial number.
- /// The tags are enumerated as 0..GetNofTags()-1.
- /// \param tagNo tag's serial number
- /// \return \b NULL: tagNo is outside the range
- /// of 0..GetNofTags()-1
- /// \return \b not \b NULL: tag in tagNo'th position
- pstr GetTag ( int tagNo ); // 0..nTags-1
-
- /// \brief Prints list of tags to stdout.
- /// Both sorted and unsorted tags are printed to standard
- /// output. This function may be used for debugging.
- void PrintTags();
-
- /// \brief Returns True if all tags from the list are found
- /// in the category.
- /// The size of the list of tags may be less than the number
- /// of tags in the category, and order of tags is disregarded.
- /// \param[in] tagList list of tags to be checked for presence
- /// in the category. The list must end with NULL
- /// pointer, or your program will crash.
- /// \return \b True if all tags from the list were found in the
- /// category
- /// \return \b False if one or more tags from the list were not
- /// found in the category.
- ///
- /// Example:
- /// \code
- /// cpstr tagList[] = {"id","type","date",NULL};
- /// CMMCIFStruct cifStruct;
- /// if (cifStruct.CheckTags(tagList))
- /// printf ( " all tags are found in category %s\n",
- /// cifStruct.GetCategoryName() );
- /// \endcode
- /// This function is useful for finding categories in
- /// "dirty cifs", where category name is not given.
- Boolean CheckTags ( cpstr * tagList );
-
- /// \brief Deep copy of categories.
- /// Deep copy duplicates all data and memory allocations,
- /// producing a genuine clone of the original. Only deep copy
- /// should be used for copying MMDB objects, a mere assignment
- /// operator will fail you.
- /// \param[in] Category a pointer to CMMCIFCategory, the content of
- /// which is copied into 'this' category.
- virtual void Copy ( PCMMCIFCategory Category );
-
- /// \brief MMDB stream writer.
- void write ( RCFile f );
-
- /// \brief MMDB stream reader.
- void read ( RCFile f );
-
- protected:
- int nTags;
- pstr name;
- psvector tag;
- ivector index;
- int nAllocTags;
-
- void InitMMCIFCategory ();
- virtual void FreeMemory ();
- void ExpandTags ( int nTagsNew );
- void PutCategoryName ( cpstr newName );
-
-};
-
-
-
-// ====================== CMMCIFStruct ============================
-
-DefineClass(CMMCIFStruct)
-DefineStreamFunctions(CMMCIFStruct)
-
-/// \brief Constants used to specify mmCIF's \"data not given\" and
-/// \"data not available\" data types.
-#define CIF_NODATA_DOT 0
-#define CIF_NODATA_QUESTION 1
-#define CIF_NODATA_DOT_FIELD pstr("\x02" ".")
-#define CIF_NODATA_QUESTION_FIELD pstr("\x02" "?")
-
-/// \brief CMMCIFStruct represents mmCIF's \"structure\" category,
-/// where data follows directly the corresponding tag.
-/*!
-mmCIF's \"structure\" category has the following form:
-\code
-_structure_name.tag0 value0
-_structure_name.tag1 value1
-...........
-_structure_name.tagN valueN
-\endcode
-CMMCIFStruct represents this construct by keeping category name
-(\"_structure_name\") and associated lists of tags
-(\"tag0,tag1...tagN\") and their values (\"value0,value1...valueN\").
-
-The structure is created automatically when an mmCIF file is read,
-or it may be created programatically and then pushed into file.
-
-Access to data is provided via tags. Internally, all values are kept
-as character fields, and it is only on the retrieval stage that they
-are converted to other data types (integers, floats or strings).
-If conversion is not possible, an error code is returned by the
-corresponding functions, which should be checked by the application.
-
-See general principles of working with mmCIF files and mmCIF
-hierarchies, as well as some code samples, in Section
-\"\ref mmcif_handler\".
-*/
-
-class CMMCIFStruct : public CMMCIFCategory {
-
- public :
-
- /// \brief Basic constructor
- CMMCIFStruct ();
-
- /// \brief Constructor that assigns structure name.
- /// \param[in] N structure name (must start with underscore).
- CMMCIFStruct ( cpstr N );
-
- /// \brief Constructor for MMDB data streaming functions
- CMMCIFStruct ( RPCStream Object );
-
- /// \brief Destructor
- ~CMMCIFStruct();
-
- /// \brief Adds field to the structure.
- /// \param[in] F field value
- /// \param[in] T tag name
- /// \param[in] Concatenate flag to concatenate existing field
- /// with the value of \b F. If tag \b T is already in
- /// the structure and \b Concatenate=True, then
- /// value of \b F is appended to the existing field.
- /// Otherwise, the field is replaced with the value
- /// of \b F
- void AddField ( cpstr F, cpstr T, Boolean Concatenate=False );
-
- /// \brief Returns category type \b MMCIF_Struct.
- int GetCategoryID() { return MMCIF_Struct; }
-
- /// \brief Optimizes structure for RAM and data access speed.
- /// Optimized data structures take less RAM and their indexes
- /// are sorted for quicker access. Sorting is done automatically
- /// as new data is added to the category. If the structure
- /// is edited (fields/data removed), it may need
- /// optimization and re-sorting for efficiency.\n\n
- /// The sorting preserves the order of actual appearance of
- /// tags in mmCIF file. If a structure is created
- /// programmatically, the order of tags in mmCIF file will be
- /// the same as order of adding them to the structure.
- void Optimize();
-
- /// \brief Returns value of field corresponding to tag in the
- /// specified position.
- /// Tag positions are defined by the order of their appearance in
- /// mmCIF file (if structure was read from a file), or by the
- /// order of their addition to the structure (if structure was
- /// created programmatically). Tags are numbered as
- /// 0...GetNofTags()-1.
- /// \param[in] tagNo tag number (position in the structure)
- /// \return \b NULL: tag does not exist
- /// \return \b CIF_NODATA_DOT_FIELD the field contains
- /// \"data not given\" value
- /// \return \b CIF_NODATA_QUESTION_FIELD the field contains
- /// \"data not available\" value
- /// \return \b not \b NULL: string value of the field
- pstr GetField ( int tagNo ); // 0..nTags-1
-
- /// \brief Fetches value, corresponding to the given tag, as
- /// a string
- /// \param[out] S pointer to string, which will point to newly
- /// allocated character string, containing value
- /// associated with tag \b TName. If tag or value
- /// is not found, or if value corresponds to
- /// mmCIF's \"data not given\" or
- /// \"data not available\", \b S returns NULL.
- /// \param[in] TName character string with tag name
- /// \param[in] Remove flag to remove the tag and its value from
- /// structure after it is read.
- /// \return \b CIFRC_NoTag: tag is not found
- /// \return \b CIFRC_NoField: value is not found
- /// \return \b CIFRC_Ok: success. If \b S returns NULL, then
- /// the value corresponds to either
- /// \"data not available\" or
- /// \"data not given\".
- /// \remarks If \b S!=NULL at time of call, the function will
- /// try to dispose the string it points on. This allows a slick
- /// re-use of the same pointer in consequitive calls. This also
- /// means that one should never pass unallocated pointer to
- /// this function. Safe use assumes the following patern:
- /// \code
- /// CMMCIFStruct mmCIFStruct;
- /// pstr S; // this is merely "char *S"
- /// int rc;
- ///
- /// S = NULL; // null pointer before first use
- /// rc = mmCIFStruct.GetString ( S,"id" );
- /// if (rc) CreateCopy ( S,"*** data not found" );
- /// if (!S) CreateCopy ( S,"*** data not given or not available" );
- /// printf ( " rc=%i, S='%s'\n",rc,S );
- ///
- /// rc = mmCIFStruct.GetString ( S,"property" );
- /// if (rc) CreateCopy ( S,"*** data not found" );
- /// if (!S) CreateCopy ( S,"*** data not given or not available" );
- /// printf ( " rc=%i, S='%s'\n",rc,S );
- ///
- /// // etc etc etc
- ///
- /// delete[] S; // application is responsible for final
- /// // disposal of memory
- /// \endcode
- int GetString ( pstr & S, cpstr TName, Boolean Remove=False );
-
- /// \brief Returns pointer to value associated with given tag.
- /// \param[in] TName character string with tag name
- /// \param[out] RC return code:
- /// \arg \b CIFRC_NoTag: tag is not found
- /// \arg \b CIFRC_NoField: value is not found
- /// \arg \b CIFRC_Ok: success. If function returns NULL, then
- /// the value corresponds to either
- /// \"data not available\" or
- /// \"data not given\".
- /// \return \b NULL: either tag or value is not found, or the
- /// value is \"data not available\" or \"data not given\".
- /// Read return code \b RC in order to interpret NULL return.
- /// \return \b not \b NULL: pointer (\c char \c *) to value
- /// associated with \b TName.
- /// \remarks Never try to dispose memory pointed by the return
- /// value, or your program will crash.
- pstr GetString ( cpstr TName, int & RC ); // NULL if TName
- // is not there
-
- /// \brief Deletes field associated with given tag.
- /// \param[in] TName character string with tag name
- /// \return \b >=0: field deleted
- /// \return \b <0: either field or tag is not found
- int DeleteField ( cpstr TName ); // <0 the field was not there
-
- /// \brief Fetches value, corresponding to the given tag, as
- /// a real number.
- /// \param[out] R reference to real number to accept the value.
- /// In case of failure, \b R returns zero.
- /// \param[in] TName character string with tag name
- /// \param[in] Remove flag to remove the tag and its value from
- /// structure after it is read.
- /// \return \b CIFRC_NoTag: tag is not found
- /// \return \b CIFRC_NoField: field is not found
- /// \return \b CIFRC_WrongFormat: value is not a real or integer
- /// number.
- /// \return \b CIFRC_NoData: value is either
- /// \"data not available\" or
- /// \"data not given\".
- /// \return \b CIFRC_Ok: success.
- int GetReal ( realtype & R, cpstr TName, Boolean Remove=False );
-
- /// \brief Fetches value, corresponding to the given tag, as
- /// an integer number.
- /// \param[out] I reference to integer number to accept the
- /// value. In case of failure, \b I returns zero, except
- /// when value is \"data not available\" or
- /// \"data not given\", when I returns \c MinInt4.
- /// \param[in] TName character string with tag name
- /// \param[in] Remove flag to remove the tag and its value from
- /// structure after it is read.
- /// \return \arg \b CIFRC_NoTag: tag is not found
- /// \return \b CIFRC_NoField: field is not found
- /// \return \b CIFRC_WrongFormat: value is not an integer number.
- /// \return \b CIFRC_NoData: value is either
- /// \"data not available\" or
- /// \"data not given\".
- /// \return \b CIFRC_Ok: success.
- int GetInteger ( int & I, cpstr TName, Boolean Remove=False );
-
- /// \brief Sets string value for given tag.
- /// \param[in] S character string with value to be set.
- /// If \b S==NULL, the \"data not given\" value
- /// will be set. If \b S==\"\" (empty string), the
- /// \"data not available\" value is stored.
- /// \param[in] TName character string with tag name. If tag
- /// is not found, it will be added to the structure.
- /// \param[in] NonBlankOnly flag to treat white-space-only
- /// strings:
- /// \arg \b False: set as is
- /// \arg \b True: set \"data not available\" value instead.
- void PutString ( cpstr S, cpstr TName,
- Boolean NonBlankOnly=False );
-
- /// \brief Sets current date in format YYYY-MM-DD as a value
- /// for given tag.
- /// \param[in] T character string with tag name. If tag
- /// is not found, it will be added to the structure.
- void PutDate ( cpstr T );
-
- /// \brief Sets \"data not given\" or \"data not available\"
- /// values for given tag.
- /// \param[in] NoDataType can be either
- /// \arg \b CIF_NODATA_DOT for \"data not given\"
- /// \arg \b CIF_NODATA_QUESTION for \"data not available\"
- /// \param[in] T character string with tag name. If tag
- /// is not found, it will be added to the structure.
- void PutNoData ( int NoDataType, cpstr T );
-
- /// \brief Sets float-point value for given tag.
- /// \param[in] R real number with value to be set.
- /// \param[in] TName character string with tag name. If tag
- /// is not found, it will be added to the structure.
- /// \param[in] prec float-point precision; g-format with given
- /// precision will be used
- void PutReal ( realtype R, cpstr TName, int prec=8 );
-
- /// \brief Sets float-point value for given tag.
- /// \param[in] R real number with value to be set.
- /// \param[in] TName character string with tag name. If tag
- /// is not found, it will be added to the structure.
- /// \param[in] format format string to convert \b R.
- void PutReal ( realtype R, cpstr TName, cpstr format );
-
- /// \brief Sets integer value for given tag.
- /// \param[in] I integer number with value to be set.
- /// \param[in] TName character string with tag name. If tag
- /// is not found, it will be added to the structure.
- void PutInteger ( int I, cpstr TName );
-
- /// \brief Writes structure data in mmCIF format into file.
- /// \param[in] FName character string with file name.
- /// \param[in] gzipMode flag to controll compression of files:
- /// \arg \b GZM_NONE: do not compress
- /// \arg \b GZM_CHECK: check file name suffix and compress
- /// (or not) accordingly
- /// \arg \b GZM_ENFORCE_GZIP: force gzip compression despite
- /// suffix
- /// \arg \b GZM_ENFORCE_COMPRESS: force using compress despite
- /// suffix
- /// \return \b True: success
- /// \return \b False: can not open file for writing.
- /// \remarks This function does not create a valid mmCIF file
- /// as \"data_XXX\" record will be missing. It may be used for
- /// debugging though.
- Boolean WriteMMCIFStruct ( cpstr FName,
- byte gzipMode=GZM_CHECK );
-
- /// \brief Writes structure into given file.
- /// \param f reference to MMDB's file class. The file should be
- /// opened and closed by application.
- /// \remarks There is a very limited use of this function on
- /// application level. It is primarily used by CMMCIFData class.
- void WriteMMCIF ( RCFile f );
-
- /// \brief Deep copy of structures.
- /// Deep copy duplicates all data and memory allocations,
- /// producing a genuine clone of the original. Only deep copy
- /// should be used for copying MMDB objects, a mere assignment
- /// operator will fail you.
- /// \param[in] Struct a pointer to CMMCIFStruct, the content of
- /// which is copied into 'this' structure.
- void Copy ( PCMMCIFCategory Struct );
-
- /// \brief MMDB stream writer.
- void write ( RCFile f );
-
- /// \brief MMDB stream reader.
- void read ( RCFile f );
-
- protected:
- psvector field;
-
- void InitMMCIFStruct();
- void FreeMemory();
-
-};
-
-
-
-// ====================== CMMCIFLoop ==============================
-
-DefineClass(CMMCIFLoop)
-DefineStreamFunctions(CMMCIFLoop)
-
-/// \brief CMMCIFLoop represents mmCIF's \"loop\" category, which keeps
-/// rows of data values associated with tags.
-/*!
-mmCIF's \"loop\" category has the following form:
-\code
-loop_
-_loop_name.tag0 value0
-_loop_name.tag1 value1
-...........
-_loop_name.tagN valueN
-value00 value10 ... valueN0
-value01 value11 ... valueN1
-...........
-value0M value1M ... valueNM
-\endcode
-CMMCIFLoop represents this construct by keeping category name
-(\"_loop_name\") and associated lists of tags
-(\"tag0,tag1...tagN\") and data vectors
-(\"[value00...value0M],[value10...value1M]...[valueN0...valueNM]\").
-
-The loop object is created automatically when an mmCIF file is read,
-or it may be created programatically and then pushed into file.
-
-Access to data is provided via tags and data indexes. Internally,
-all values are kept as character fields, and it is only on the
-retrieval stage that they are converted to other data types
-(integers, floats or strings). If conversion is not possible, an
-error code is returned by the corresponding functions, which should
-be checked by the application.
-
-The following code gives an example of creating mmCIF loop category
-and populating it with data:
-\code
-CMMCIFLoop loop;
-char S[100];
-int i;
-
- // Specify loop name:
- loop.SetCategoryName ( "_sample_loop" );
-
- // Create loop structure, i.e., list of tags first:
- loop.AddLoopTag ( "id" );
- loop.AddLoopTag ( "name" );
- loop.AddLoopTag ( "value" );
-
- // Now populate it with data. This my be done in 2 ways.
- // Here is how you write loop data in stream fashion,
- // value-after-value:
- for (i=0;i<3;i++) {
- loop.AddInteger ( i );
- sprintf ( S,"1st_way-%i",i );
- loop.AddString ( S );
- loop.AddReal ( 2.5*(i+1) );
- }
-
- // Here is how you populate loop data using direct-access
- // functions:
- for (i=3;i<6;i++) {
- loop.PutReal ( 2.5*(i+1),"value",i );
- loop.PutInteger ( i,"id" );
- sprintf ( S,"2nd way: %i",i );
- loop.PutString ( S,"name" );
- }
-
- loop.WriteMMCIFLoop ( "sample_loop.cif" );
-
-\endcode
-
-The resulting file \b sample_loop.cif will contain:
-
-\code
-
-loop_
-_sample_loop.id
-_sample_loop.name
-_sample_loop.value
-0 1st_way-0 2.5
-1 1st_way-1 5.0
-2 1st_way-2 7.5
-3 "2nd way: 3" 10.0
-4 "2nd way: 4" 12.5
-5 "2nd way: 5" 15.0
-
-\endcode
-
-See general principles of working with mmCIF files and mmCIF
-hierarchies, as well as some code samples, in Section
-\"\ref mmcif_handler\".
-*/
-
-class CMMCIFLoop : public CMMCIFCategory {
-
- friend class CMMCIFData;
-
- public :
-
- /// \brief Basic constructor
- CMMCIFLoop ();
-
- /// \brief Constructor that assigns structure name.
- /// \param[in] N structure name (must start with underscore).
- CMMCIFLoop ( cpstr N );
-
- /// \brief Constructor for MMDB data streaming functions
- CMMCIFLoop ( RPCStream Object );
-
- /// \brief Destructor
- ~CMMCIFLoop();
-
- /// \brief Adds tag to the loop.
- /// The tag is appended to the list of existing tags. The order
- /// of tags cannot be changed.
- /// \param[in] T tag name
- /// \param[in] Remove flag to remove all fields in the loop.
- void AddLoopTag ( cpstr T, Boolean Remove=True );
-
- /// \brief Sets string value at current loop position.
- /// When \b CMMCIFLoop::Add[Data] functions use internal loop
- /// pointer. When category is created or cleared (by using
- /// \b CMMCIFTLoop::AddLoopTag ( T,True )) the pointer is set to
- /// 0th row and 0th column (tag). After each call to
- /// \b CMMCIFLoop::Add[Data] function, internal pointer advances
- /// to next column (tag), and wraps over to next row, 0th tag,
- /// if list of tags is exhausted. Any remaining fields in last
- /// row will be populated with \"data not given\" value.
- /// \param[in] S character string with value to be set.
- /// If \b S==NULL, the \"data not given\" value
- /// will be set. If \b S==\"\" (empty string), the
- /// \"data not available\" value is stored.
- /// \param[in] NonBlankOnly flag to treat white-space-only
- /// strings:
- /// \arg \b False: set as is
- /// \arg \b True: set \"data not available\" value instead.
- void AddString ( cpstr S, Boolean NonBlankOnly=False );
-
- /// \brief Sets \"data not given\" or \"data not available\" at
- /// current loop position.
- /// When \b CMMCIFLoop::Add[Data] functions use internal loop
- /// pointer. When category is created or cleared (by using
- /// \b CMMCIFTLoop::AddLoopTag ( T,True )) the pointer is set to
- /// 0th row and 0th column (tag). After each call to
- /// \b CMMCIFLoop::Add[Data] function, internal pointer advances
- /// to next column (tag), and wraps over to next row, 0th tag,
- /// if list of tags is exhausted. Any remaining fields in last
- /// row will be populated with \"data not given\" value.
- /// \param[in] NoDataType integer key specifying which type of
- /// data absence should be set as a value:
- /// \arg \b CIF_NODATA_DOT for \"data not given\"
- /// \arg \b CIF_NODATA_QUESTION for \"data not available\"
- void AddNoData ( int NoDataType );
-
- /// \brief Sets float-point value at current loop position.
- /// When \b CMMCIFLoop::Add[Data] functions use internal loop
- /// pointer. When category is created or cleared (by using
- /// \b CMMCIFTLoop::AddLoopTag ( T,True )) the pointer is set to
- /// 0th row and 0th column (tag). After each call to
- /// \b CMMCIFLoop::Add[Data] function, internal pointer advances
- /// to next column (tag), and wraps over to next row, 0th tag,
- /// if list of tags is exhausted. Any remaining fields in last
- /// row will be populated with \"data not given\" value.
- /// \param[in] R real number with value to be set.
- /// \param[in] prec float-point precision; g-format with given
- /// precision will be used
- void AddReal ( realtype R, int prec=8 );
-
- /// \brief Sets float-point value at current loop position in
- /// given format.
- /// When \b CMMCIFLoop::Add[Data] functions use internal loop
- /// pointer. When category is created or cleared (by using
- /// \b CMMCIFTLoop::AddLoopTag ( T,True )) the pointer is set to
- /// 0th row and 0th column (tag). After each call to
- /// \b CMMCIFLoop::Add[Data] function, internal pointer advances
- /// to next column (tag), and wraps over to next row, 0th tag,
- /// if list of tags is exhausted. Any remaining fields in last
- /// row will be populated with \"data not given\" value.
- /// \brief Sets float-point value for given tag.
- /// \param[in] R real number with value to be set.
- /// \param[in] format format string to convert \b R.
- void AddReal ( realtype R, cpstr format );
-
- /// \brief Sets integer value at current loop position in given
- /// format.
- /// When \b CMMCIFLoop::Add[Data] functions use internal loop
- /// pointer. When category is created or cleared (by using
- /// \b CMMCIFTLoop::AddLoopTag ( T,True )) the pointer is set to
- /// 0th row and 0th column (tag). After each call to
- /// \b CMMCIFLoop::Add[Data] function, internal pointer advances
- /// to next column (tag), and wraps over to next row, 0th tag,
- /// if list of tags is exhausted. Any remaining fields in last
- /// row will be populated with \"data not given\" value.
- /// \param[in] I integer number with value to be set.
- void AddInteger ( int I );
-
- /// \brief Returns current length of the loop (i.e. the number
- /// of rows).
- /// \return number of data rows in the loop.
- int GetLoopLength() { return nRows; }
-
- /// \brief Returns string pointer on the field corresponding to
- /// tag in the specified position, in the specified row.
- /// Tag positions are defined by the order of their appearance in
- /// mmCIF file (if loop was read from a file), or by the
- /// order of their addition to the loop (if loop was
- /// created programmatically).
- /// \param[in] rowNo row number (0...GetLoopLength()-1)
- /// \param[in] tagNo tag number (0...GetNofTags()-1)
- /// \return \b NULL: tag or row do not exist
- /// \return \b CIF_NODATA_DOT_FIELD the field contains
- /// \"data not given\" value
- /// \return \b CIF_NODATA_QUESTION_FIELD the field contains
- /// \"data not available\" value
- /// \return \b not \b NULL: string value of the field
- /// \remarks Never try to dispose memory pointed by the return
- /// value, or your program will crash.
- pstr GetField ( int rowNo, int tagNo );
-
- /// \brief Fetches value, corresponding to the given tag, in
- /// the given row, as a string
- /// \param[out] S pointer to string, which will point to newly
- /// allocated character string, containing value
- /// associated with tag \b TName and row \b nrow.
- /// If tag, row or value
- /// is not found, or if value corresponds to
- /// mmCIF's \"data not given\" or
- /// \"data not available\", \b S returns NULL.
- /// \param[in] TName character string with tag name
- /// \param[in] nrow row number (0...GetLoopLength()-1)
- /// \param[in] Remove flag to remove the field from
- /// structure after it is read.
- /// \return \b CIFRC_NoTag: tag is not found
- /// \return \b CIFRC_WrongIndex: row is not found
- /// \return \b CIFRC_NoField: value is not found
- /// \return \b CIFRC_Ok: success. If \b S returns NULL, then
- /// the value corresponds to either
- /// \"data not available\" or
- /// \"data not given\".
- /// \remarks If \b S!=NULL at time of call, the function will
- /// try to dispose the string it points on. This allows a slick
- /// re-use of the same pointer in consequitive calls. This also
- /// means that one should never pass unallocated pointer to
- /// this function. Safe use assumes the following patern:
- /// \code
- /// CMMCIFLoop mmCIFLoop;
- /// pstr S; // this is merely "char *S"
- /// int rc;
- ///
- /// S = NULL; // null pointer before first use
- /// rc = mmCIFLoop.GetString ( S,"id",1 );
- /// if (rc) CreateCopy ( S,"*** data not found" );
- /// if (!S) CreateCopy ( S,"*** data not given or not available" );
- /// printf ( " rc=%i, S='%s'\n",rc,S );
- ///
- /// rc = mmCIFLoop.GetString ( S,"property",0 );
- /// if (rc) CreateCopy ( S,"*** data not found" );
- /// if (!S) CreateCopy ( S,"*** data not given or not available" );
- /// printf ( " rc=%i, S='%s'\n",rc,S );
- ///
- /// // etc etc etc
- ///
- /// delete[] S; // application is responsible for final
- /// // disposal of memory
- /// \endcode
- int GetString ( pstr & S, cpstr TName, int nrow,
- Boolean Remove=False );
-
- /// \brief Returns pointer to value associated with given tag,
- /// in the given row of the loop.
- /// \param[in] TName character string with tag name
- /// \param[in] nrow row number (0...GetLoopLength()-1)
- /// \param[out] RC return code:
- /// \arg \b CIFRC_NoTag: tag is not found
- /// \arg \b CIFRC_WrongIndex: row is not found
- /// \arg \b CIFRC_NoField: value is not found
- /// \arg \b CIFRC_Ok: success. If function returns NULL, then
- /// the value corresponds to either
- /// \"data not available\" or
- /// \"data not given\".
- /// \return \b NULL: either tag, row or value is not found, or the
- /// value is \"data not available\" or \"data not given\".
- /// Read return code \b RC in order to interpret NULL return.
- /// \return \b not \b NULL: pointer (\c char \c *) to value
- /// associated with \b TName.
- /// \remarks Never try to dispose memory pointed by the return
- /// value, or your program will crash.
- pstr GetString ( cpstr TName, int nrow, int & RC );
-
- /// \brief Copies value, associated with given tag,
- /// in the given row, into specified buffer.
- /// Terminating NULL character is appended.
- /// \param[out] buf character string to accept the value
- /// \param[in] maxlength maximum number of bytes to copy
- /// \param[in] TName character string with tag name
- /// \param[in] nrow row number (0...GetLoopLength()-1)
- /// \param[out] RC return code:
- /// \arg \b CIFRC_NoTag: tag is not found
- /// \arg \b CIFRC_WrongIndex: row is not found
- /// \arg \b CIFRC_NoField: value is not found
- /// \arg \b CIFRC_Ok: success.
- /// \remarks Destination string \b buf is not modified if
- /// \b RC!=CIFRC_Ok .
- void CopyString ( pstr buf, int maxlength,
- cpstr TName, int nrow, int & RC );
-
- /// \brief Deletes field associated with given tag in
- /// the given row.
- /// \param[in] TName character string with tag name
- /// \param[in] nrow row number (0...GetLoopLength()-1)
- /// \return \b >=0: field deleted
- /// \return \b <0: either field or tag is not found
- int DeleteField ( cpstr TName, int nrow );
-
- /// \brief Deletes all fields in given row.
- /// \param[in] nrow row number (0...GetLoopLength()-1)
- /// \return \b CIFRC_Ok: fields deleted
- /// \return \b CIFRC_WrongIndex: row not found
- /// \remarks Note that this function delets just the fields, but
- /// not the row. If you wish the row to be deleted, call
- /// CMMCIFLoop::Optimize() function after this one.
- int DeleteRow ( int nrow );
-
- /// \brief Fetches value, corresponding to the given tag,
- /// in the given row, as a real number.
- /// \param[out] R reference to real number to accept the value.
- /// In case of failure, \b R returns zero.
- /// \param[in] TName character string with tag name
- /// \param[in] nrow row number (0...GetLoopLength()-1)
- /// \param[in] Remove flag to remove the field from
- /// the loop after it is read.
- /// \return \b CIFRC_NoTag: tag is not found
- /// \return \b CIFRC_WrongIndex: row not found
- /// \return \b CIFRC_NoField: field is not found
- /// \return \b CIFRC_WrongFormat: value is not a real or integer
- /// number.
- /// \return \b CIFRC_NoData: value is either
- /// \"data not available\" or
- /// \"data not given\".
- /// \return \b CIFRC_Ok: success.
- int GetReal ( realtype & R, cpstr TName, int nrow,
- Boolean Remove=False );
-
- /// \brief Copies value, associated with given tag,
- /// in the given row, into specified destination as
- /// a real number.
- /// \param[out] R reference to real number to accept the value
- /// \param[in] TName character string with tag name
- /// \param[in] nrow row number (0...GetLoopLength()-1)
- /// \param[out] RC return code:
- /// \arg \b CIFRC_NoTag: tag is not found
- /// \arg \b CIFRC_WrongIndex: row is not found
- /// \arg \b CIFRC_NoField: value is not found
- /// \arg \b CIFRC_Ok: success.
- /// \remarks Destination \b R is set 0 if \b RC!=CIFRC_Ok.
- void CopyReal ( realtype & R, cpstr TName, int nrow, int & RC );
-
- /// \brief Copies value, associated with given tag,
- /// in the given row, into specified destination as
- /// an integer number.
- /// \param[out] I reference to integer number to accept the value
- /// \param[in] TName character string with tag name
- /// \param[in] nrow row number (0...GetLoopLength()-1)
- /// \param[out] RC return code:
- /// \arg \b CIFRC_NoTag: tag is not found
- /// \arg \b CIFRC_WrongIndex: row is not found
- /// \arg \b CIFRC_NoField: value is not found
- /// \arg \b CIFRC_Ok: success.
- /// \remarks Destination \b I is set 0 if \b RC!=CIFRC_Ok.
- void CopyInteger ( int & I, cpstr TName, int nrow, int & RC );
-
- /// \brief Fetches value, corresponding to the given tag,
- /// in the given row, as an integer number.
- /// \param[out] I reference to integer number to accept the value.
- /// In case of failure, \b R returns zero.
- /// \param[in] TName character string with tag name
- /// \param[in] nrow row number (0...GetLoopLength()-1)
- /// \param[in] Remove flag to remove the field from
- /// the loop after it is read.
- /// \return \b CIFRC_NoTag: tag is not found
- /// \return \b CIFRC_WrongIndex: row not found
- /// \return \b CIFRC_NoField: field is not found
- /// \return \b CIFRC_WrongFormat: value is not a real or integer
- /// number.
- /// \return \b CIFRC_NoData: value is either
- /// \"data not available\" or
- /// \"data not given\".
- /// \return \b CIFRC_Ok: success.
- int GetInteger ( int & I, cpstr TName, int nrow,
- Boolean Remove=False );
-
- /// \brief Fetches set of values, corresponding to the given
- /// tag, in the given range of rows, as a vector of
- /// strings.
- /// \param[out] S reference to string vector to accept
- /// the values. if \b S==NULL , the vector will be
- /// allocated with starting index of \b i1.
- /// \param[in] TName character string with tag name
- /// \param[in] i1 minimum row number to fetch, the actual
- /// index will be calculated as \b max(0,min(i1,i2))
- /// \param[in] i2 maximum row number to fetch, the actual
- /// index will be calculated as
- /// \b min(GetLoopLength()-1,max(i1,i2))
- /// \param[in] Remove flag to remove fetched fields from
- /// the loop after they are read.
- /// \return \b CIFRC_NoTag: tag is not found
- /// \return \b CIFRC_WrongIndex: invalid range of rows
- /// \return \b CIFRC_Ok: success.
- ///
- /// For safe use, \b S should be pre-allocated by calling
- /// process. Only elements \b S[i1] to \b S[i2] will contain
- /// fetched data, others remain untouched. The calling
- /// process is responsible for the disposal of \b S. Example:
- /// \code
- /// CMMCIFLoop loop;
- /// psvector S; // equivalent to char **S
- /// int i,i1,i2,rc,n;
- ///
- /// // ... get loop data
- ///
- /// n = loop.GetLoopLength();
- /// i1 = 5; i2 = n - 5; // could be wrong!
- ///
- /// // allocate vector of strings
- /// GetVectorMemory ( S,n,0 ); // "0" for starting index
- /// for (i=0;i<n;i++)
- /// S[i] = NULL; // initialize NULL string pointers
- ///
- /// loop.GetSVector ( S,"name",i1,i2 );
- /// printf ( " Fetched with return code rc=%i\n",rc );
- /// // you may want a more thorough treatment of
- /// // the return code here
- /// for (i=i1;i<=i2;i++)
- /// if (S[i]) printf ( " %4i. name='%s'\n",i,S[i] );
- /// else printf ( " %4i. name is not available\n",i );
- ///
- /// // S[] may be re-used for as many fetches as necessary
- /// // without cleaning or disposals
- ///
- /// // dispose of vector of strings
- /// for (i=0;i<n;i++)
- /// if (S[i]) delete[] S[i];
- /// FreeVectorMemory ( S,0 ); // "0" for starting index
- ///
- /// \endcode
- int GetSVector ( psvector & S, cpstr TName,
- int i1=0, int i2=MaxInt4,
- Boolean Remove=False );
-
- /// \brief Fetches set of values, corresponding to the given
- /// tag, in the given range of rows, as a vector of
- /// float-point numbers.
- /// \param[out] R reference to float-point vector to accept
- /// the values. if \b R==NULL , the vector will be
- /// allocated with starting index of \b i1.
- /// \param[in] TName character string with tag name
- /// \param[in] i1 minimum row number to fetch, the actual
- /// index will be calculated as \b max(0,min(i1,i2))
- /// \param[in] i2 maximum row number to fetch, the actual
- /// index will be calculated as
- /// \b min(GetLoopLength()-1,max(i1,i2))
- /// \param[in] Remove flag to remove fetched fields from
- /// the loop after they are read.
- /// \return \b CIFRC_NoTag: tag is not found
- /// \return \b CIFRC_WrongIndex: invalid range of rows
- /// \return \b CIFRC_Ok: success.
- ///
- /// For safe use, \b R should be pre-allocated by calling
- /// process. Only elements \b R[i1] to \b R[i2] will contain
- /// fetched data, others remain untouched. The calling
- /// process is responsible for the disposal of \b R. Example:
- /// \code
- /// CMMCIFLoop loop;
- /// rvector R; // equivalent to realtype *R
- /// int i,i1,i2,rc,n;
- ///
- /// // ... get loop data
- ///
- /// n = loop.GetLoopLength();
- /// i1 = 5; i2 = n - 5; // could be wrong!
- ///
- /// // allocate a vector of real numbers
- /// GetVectorMemory ( R,n,0 ); // "0" for starting index
- /// // no need to initiaize unless required for the
- /// // application
- ///
- /// rc = loop.GetRVector ( R,"value",i1,i2 );
- /// printf ( " Fetched with return code rc=%i\n",rc );
- /// // you may want a more thorough treatment of
- /// // the return code here
- /// for (i=i1;i<=i2;i++)
- /// printf ( " value[%4i] = %15.7g\n",i,R[i] );
- ///
- /// // R[] may be re-used for as many fetches as necessary
- /// // without cleaning or disposals
- ///
- /// // dispose of the vector
- /// FreeVectorMemory ( R,0 ); // "0" for starting index
- ///
- /// \endcode
- int GetRVector ( rvector & R, cpstr TName,
- int i1=0, int i2=MaxInt4,
- Boolean Remove=False );
-
- /// \brief Fetches set of values, corresponding to the given
- /// tag, in the given range of rows, as a vector of
- /// integer numbers.
- /// \param[out] I reference to float-point vector to accept
- /// the values. if \b I==NULL , the vector will be
- /// allocated with starting index of \b i1.
- /// \param[in] TName character string with tag name
- /// \param[in] i1 minimum row number to fetch, the actual
- /// index will be calculated as \b max(0,min(i1,i2))
- /// \param[in] i2 maximum row number to fetch, the actual
- /// index will be calculated as
- /// \b min(GetLoopLength()-1,max(i1,i2))
- /// \param[in] Remove flag to remove fetched fields from
- /// the loop after they are read.
- /// \return \b CIFRC_NoTag: tag is not found
- /// \return \b CIFRC_WrongIndex: invalid range of rows
- /// \return \b CIFRC_Ok: success.
- ///
- /// For safe use, \b I should be pre-allocated by calling
- /// process. Only elements \b I[i1] to \b I[i2] will contain
- /// fetched data, others remain untouched. The calling
- /// process is responsible for the disposal of \b I.
- /// See example in CMMCIFLoop::GetRVector documentation
- /// for details.
- int GetIVector ( ivector & I, cpstr TName,
- int i1=0, int i2=MaxInt4,
- Boolean Remove=False );
-
- /// \brief Sets string value for given tag and row.
- /// \param[in] S character string with value to be set.
- /// If \b S==NULL, the \"data not given\" value
- /// will be set. If \b S==\"\" (empty string), the
- /// \"data not available\" value is stored.
- /// \param[in] T character string with tag name. If tag
- /// is not found, it will be added, and all data in
- /// the loop will be reindexed accordingly.
- /// \param[in] nrow row number. If the row does not exist then
- /// it will be created, along with all other rows
- /// between GetLoopLength()-1 and \b nrow as
- /// necessary. All newly created fields will be
- /// initialised with \"data not given\" value.
- void PutString ( cpstr S, cpstr T, int nrow );
-
- /// \brief Sets \"data not given\" or \"data not available\"
- /// values for given tag and row.
- /// \param[in] NoDataType can be either
- /// \arg \b CIF_NODATA_DOT for \"data not given\"
- /// \arg \b CIF_NODATA_QUESTION for \"data not available\"
- /// \param[in] T character string with tag name. If tag
- /// is not found, it will be added, and all data in
- /// the loop will be reindexed accordingly.
- /// \param[in] nrow row number. If the row does not exist then
- /// it will be created, along with all other rows
- /// between GetLoopLength()-1 and \b nrow as
- /// necessary. All newly created fields will be
- /// initialised with \"data not given\" value.
- void PutNoData ( int NoDataType, cpstr T, int nrow );
-
- /// \brief Sets float-point value for given tag and row.
- /// \param[in] R real number with value to be set.
- /// \param[in] T character string with tag name. If tag
- /// is not found, it will be added, and all data in
- /// the loop will be reindexed accordingly.
- /// \param[in] nrow row number. If the row does not exist then
- /// it will be created, along with all other rows
- /// between GetLoopLength()-1 and \b nrow as
- /// necessary. All newly created fields will be
- /// initialised with \"data not given\" value.
- /// \param[in] prec float-point precision; g-format with given
- /// precision will be used
- void PutReal ( realtype R, cpstr T, int nrow, int prec=8 );
-
- /// \brief Sets float-point value for given tag and row.
- /// \param[in] R real number with value to be set.
- /// \param[in] T character string with tag name. If tag
- /// is not found, it will be added, and all data in
- /// the loop will be reindexed accordingly.
- /// \param[in] nrow row number. If the row does not exist then
- /// it will be created, along with all other rows
- /// between GetLoopLength()-1 and \b nrow as
- /// necessary. All newly created fields will be
- /// initialised with \"data not given\" value.
- /// \param[in] format format string to convert \b R.
- void PutReal ( realtype R, cpstr T, int nrow, cpstr format );
-
- /// \brief Sets integer value for given tag.
- /// \param[in] I integer number with value to be set.
- /// \param[in] T character string with tag name. If tag
- /// is not found, it will be added, and all data in
- /// the loop will be reindexed accordingly.
- /// \param[in] nrow row number. If the row does not exist then
- /// it will be created, along with all other rows
- /// between GetLoopLength()-1 and \b nrow as
- /// necessary. All newly created fields will be
- /// initialised with \"data not given\" value.
- void PutInteger ( int I, cpstr T, int nrow );
-
- /// \brief Sets a set of string values for the given tag and
- /// range of rows.
- /// \param[in] S string vector with values to store in the loop
- /// \param[in] T character string with tag name. If tag
- /// is not found, it will be added, and all data in
- /// the loop will be reindexed accordingly.
- /// \param[in] i1 minimum data index in \b S to set in the loop
- /// \param[in] i2 maximum data index in \b S to set in the loop.
- ///
- /// The data will be set in rows \b i1 to \b i2 (inclusive) in
- /// the loop. If range \b [i1,i2] is not contained in the loop,
- /// all missing rows will be created and initialised to
- /// \"data not given\" value. Example:
- /// \code
- /// CMMCIFLoop loop("_sample_loop");
- /// pstr S[100];
- /// int i;
- ///
- /// // initialize vector of strings
- /// for (i=0;i<100;i++) {
- /// S[i] = new char[20];
- /// sprintf ( S[i],"value i=%i",i );
- /// }
- ///
- /// // put data in loop
- /// loop.PutSVector ( S,"made_up_string_value",0,99 );
- ///
- /// // dispose of vector of strings
- /// for (i=0;i<100;i++)
- /// if (S[i]) delete[] S[i];
- ///
- /// \endcode
- void PutSVector ( psvector S, cpstr T, int i1, int i2 );
-
- /// \brief Sets a set of float-point values for the given tag and
- /// range of rows.
- /// \param[in] R vector of real numbers to store in the loop
- /// \param[in] T character string with tag name. If tag
- /// is not found, it will be added, and all data in
- /// the loop will be reindexed accordingly.
- /// \param[in] i1 minimum data index in \b S to set in the loop
- /// \param[in] i2 maximum data index in \b S to set in the loop
- /// \param[in] prec float-point precision; g-format with given
- /// precision will be used.
- ///
- /// The data will be set in rows \b i1 to \b i2 (inclusive) in
- /// the loop. If range \b [i1,i2] is not contained in the loop,
- /// all missing rows will be created and initialised to
- /// \"data not given\" value.
- void PutRVector ( rvector R, cpstr T, int i1, int i2,
- int prec=8 );
-
- /// \brief Sets a set of integer values for the given tag and
- /// range of rows.
- /// \param[in] I vector of integers to store in the loop
- /// \param[in] T character string with tag name. If tag
- /// is not found, it will be added, and all data in
- /// the loop will be reindexed accordingly.
- /// \param[in] i1 minimum data index in \b S to set in the loop
- /// \param[in] i2 maximum data index in \b S to set in the loop.
- ///
- /// The data will be set in rows \b i1 to \b i2 (inclusive) in
- /// the loop. If range \b [i1,i2] is not contained in the loop,
- /// all missing rows will be created and initialised to
- /// \"data not given\" value.
- void PutIVector ( ivector I, cpstr T, int i1, int i2 );
-
- /// \brief Returns category type \b MMCIF_Loop.
- int GetCategoryID() { return MMCIF_Loop; }
-
- /// \brief Optimizes loop for RAM and data access speed.
- /// Optimized data structures take less RAM and their indexes
- /// are sorted for quicker access. Sorting is done automatically
- /// as new data is added to the category. If the structure
- /// is edited (fields/data removed), it may need
- /// optimization and re-sorting for efficiency.\n\n
- /// The sorting preserves the order of actual appearance of
- /// tags and rows in mmCIF file. If a loop is created
- /// programmatically, the order of tags and rows in mmCIF file
- /// will be the same as order of adding them to the loop.
- void Optimize();
-
- /// \brief Writes loop data in mmCIF format into file.
- /// \param[in] FName character string with file name.
- /// \param[in] gzipMode flag to controll compression of files:
- /// \arg \b GZM_NONE: do not compress
- /// \arg \b GZM_CHECK: check file name suffix and compress
- /// (or not) accordingly
- /// \arg \b GZM_ENFORCE_GZIP: force gzip compression despite
- /// suffix
- /// \arg \b GZM_ENFORCE_COMPRESS: force using compress despite
- /// suffix
- /// \return \b True: success
- /// \return \b False: can not open file for writing.
- /// \remarks This function does not create a valid mmCIF file
- /// as \"data_XXX\" record will be missing. It may be used for
- /// debugging though.
- Boolean WriteMMCIFLoop ( cpstr FName,
- byte gzipMode=GZM_CHECK );
-
- /// \brief Writes loop data into given file.
- /// \param f reference to MMDB's file class. The file should be
- /// opened and closed by application.
- /// \remarks There is a very limited use of this function on
- /// application level. It is primarily used by CMMCIFData class.
- void WriteMMCIF ( RCFile f );
-
- /// \brief Deep copy of loops.
- /// Deep copy duplicates all data and memory allocations,
- /// producing a genuine clone of the original. Only deep copy
- /// should be used for copying MMDB objects, a mere assignment
- /// operator will fail you.
- /// \param[in] Loop a pointer to CMMCIFLoop, the content of
- /// which is copied into 'this' loop.
- void Copy ( PCMMCIFCategory Loop );
-
- /// \brief MMDB stream writer.
- void write ( RCFile f );
-
- /// \brief MMDB stream reader.
- void read ( RCFile f );
-
- protected:
- int nRows;
- psmatrix field;
- int iColumn,nAllocRows;
-
- void InitMMCIFLoop();
- void FreeMemory ();
- void DeleteFields ();
- void ExpandRows ( int nRowsNew );
-
-};
-
-
-
-// ====================== CMMCIFData =============================
-
-
-// CIFW are warnings which may be issued on reading the CIF file.
-// Each of them means actually a CIF syntax error.
-#define CIFW_UnrecognizedItems 0x00000020
-#define CIFW_MissingField 0x00000040
-#define CIFW_EmptyLoop 0x00000080
-#define CIFW_UnexpectedEOF 0x00000100
-#define CIFW_LoopFieldMissing 0x00000200
-#define CIFW_NotAStructure 0x00000400
-#define CIFW_NotALoop 0x00000800
-#define CIFW_DuplicateTag 0x00001000
-
-// CIFRC are return codes from procedures of extracting data from
-// the read CIF file. Negative returns reflect unsuccessful and
-// not accomplished operation.
-#define CIFRC_Loop 2
-#define CIFRC_Structure 1
-#define CIFRC_Ok 0
-#define CIFRC_StructureNoTag -1
-#define CIFRC_LoopNoTag -2
-#define CIFRC_NoCategory -3
-#define CIFRC_WrongFormat -4
-#define CIFRC_NoTag -5
-#define CIFRC_NotAStructure -6
-#define CIFRC_NotALoop -7
-#define CIFRC_WrongIndex -8
-#define CIFRC_NoField -9
-#define CIFRC_Created -12
-#define CIFRC_CantOpenFile -13
-#define CIFRC_NoDataLine -14
-#define CIFRC_NoData -15
-
-
-//
-// Functional flags:
-// ~~~~~~~~~~~~~~~~~
-//
-// CIFFL_PrintWarnings when reading CIF file, all warning
-// messages will be printed. If the flag
-// is off, the warnings will be bit-encoded
-// in the return code
-// CIFFL_StopOnWarnings reading CIF file will stop at first
-// warning issued
-// CIFFL_SuggestCategories allows reading CIF file with loops having
-// no categories. Hidden category names
-// will be automatically generated for
-// internal consistency of the system.
-// These names will not appear in output.
-// As these names are hidden, they cannot
-// be used to access data. It is therefore
-// assumed that all tags in all loops without
-// categories are unique. Simply specify ""
-// for category when accessing such data
-// (it cannot be accessed through CMMCIFLoop,
-// but only through CMMCIFData functions
-// taking both Category and Tag; note that
-// CIFFL_SuggestCategories flag must be on
-// while accessing such data).
-// CIFFL_SuggestTags allows for identical tags in a category
-// (including a hidden category). Hidden
-// suffixes to tag names will be generated
-// for internal consistency. At present,
-// only data for first non-unique tag may be
-// accessed.
-//
-#define CIFFL_PrintWarnings 0x00000001
-#define CIFFL_StopOnWarnings 0x00000002
-#define CIFFL_SuggestCategories 0x00000004
-#define CIFFL_SuggestTags 0x00000008
-
-
-DefineClass(CMMCIFData)
-DefineStreamFunctions(CMMCIFData)
-
-
-/// \brief CMMCIFData represents mmCIF's \"data\" category, which keeps
-/// structures and loops and is mandatory element of mmCIF file.
-/*!
-mmCIF's \"data\" category has the following form:
-\code
-data_DataName
-
-_structure1.tag1 value1
-..........
-
-loop_
-..........
-
-\endcode
-In the above example, all structures and loops that follow \b data_
-keyword until next \b data_ or end of file are part of data category
-with name \b DataName.
-
-CMMCIFData represents this construct by keeping a list of CMMCIFStruct
-and CMMCIFLoop class instances associated with the corresponding
-categories in the data block.
-
-The data object is created automatically when an mmCIF file is read,
-or it may be created programatically and then pushed into file.
-
-Access to data is provided via category (structures and loops) names,
-tags and data indexes (in case of loops). Alternatively, pointers to
-contained structures and loops may be obtained first, an used for
-fetching data using CMMCIFStruct's and CMMCIFLoop's interface
-functions.
-
-The following code gives an example of creating mmCIF's data category
-and populating it:
-\code
-CMMCIFData data;
-
- // Specify data name:
- data.PutDataName ( "Sample_Data" );
-
- // the following statement:
- data.PutInteger ( 12345,"_category1","id" );
- // creates structure "_category1" with tag "id" and assigns it
- // the integer value of 12345.
-
- data.PutString ( "a name","_category1","name" );
-
- // Loops may be created quite similarly:
- data.PutLoopInteger ( 12345 ,"_loop1","id" ,2 );
- data.PutLoopInteger ( "a name","_loop1","name",0 );
-
- // push data into a file
- data.WriteMMCIFData ( "sample.cif" );
-
-\endcode
-
-The resulting file \b sample.cif will contain:
-
-\code
-data_Sample_Data
-
-_category1.id 12345
-_category1.name "a name"
-
-loop_
-_loop1.id
-_loop1.name
-. "a name"
-. .
-12345 .
-\endcode
-
-The same result may be achieved differently:
-
-\code
-CMMCIFData data;
-PCMMCIFStruct mmCIFStruct; // equivalent to CMMCIFStruct *mmCIFStruct
-PCMMCIFLoop mmCIFLoop; // equivalent to CMMCIFLoop *mmCIFLoop
-
- // Specify data name:
- data.PutDataName ( "Sample_Data" );
-
- // create new mmCIF's structure in the data block:
- data.AddStructure ( "_category1",mmCIFStruct );
- if (mmCIFStruct) {
- mmCIFStruct->PutInteger ( 12345 ,"id" );
- mmCIFStruct->PutString ( "a name","name" );
- }
-
- // similarly for the loop:
- data.AddLoop ( "_loop1",mmCIFLoop );
- if (mmCIFLoop) {
- mmCIFLoop->PutInteger ( 12345 ,"id" ,2 );
- mmCIFLoop->PutString ( "a name","name",0 );
- }
-
- // push data into a file
- data.WriteMMCIFData ( "sample.cif" );
-
-\endcode
-
-See general principles of working with mmCIF files and mmCIF
-hierarchies, as well as some code samples, in Section
-\"\ref mmcif_handler\".
-*/
-
-class CMMCIFData : public CStream {
-
- friend class CMMCIFFile;
-
- public :
-
- /// \brief Basic constructor.
- CMMCIFData ();
-
- /// \brief Constructor that assigns data block name.
- /// \param[in] N data block name.
- CMMCIFData ( cpstr N );
-
- /// \brief Constructor for MMDB data streaming functions.
- CMMCIFData ( RPCStream Object );
-
- /// \brief Destructor.
- ~CMMCIFData();
-
-
- // -------- General I/O functions
-
- /// \brief Sets flag to print warnings on reading mmCIF files.
- /// \param[in] SPW flag to print warnings:
- /// \arg \b True : warnings will be printed to stdout
- /// \arg \b False : warnings will not be printed but returned
- /// in return code (default)
- void SetPrintWarnings ( Boolean SPW );
-
- /// \brief Sets flag to stop on warning when reading an mmCIF file.
- /// \param[in] SOW flag to stop on warning:
- /// \arg \b True : reading will stop on first warning encountered
- /// \arg \b False : warnings will not stop reading (default)
- void SetStopOnWarning ( Boolean SOW );
-
- /// \brief Sets optional flag(s) for reading mmCIF files.
- /// By default, no flags are set.
- /// \param[in] F flag or logical \"or\" of several flags to be set:
- /// \arg \b CIFFL_PrintWarnings toggles printing warning messages
- /// at reading an mmCIF file, in stdout. If this
- /// flag is not set (default), the warnings will
- /// be returned in the bit-encoded return code
- /// \arg \b CIFFL_StopOnWarnings if set, reading an mmCIF file
- /// will stop at first warning issued
- /// \arg \b CIFFL_SuggestCategories allows for reading of mmCIF
- /// files with loops and structures having no
- /// category names (\"dirty CIFs\"). If this flag is
- /// set, then hidden category names will be
- /// automatically generated. These names will not
- /// appear in the output. As these names are hidden,
- /// they cannot be used to access data. In order to
- /// access data in such categories, consider whether
- /// they are structures or loops. In case of a
- /// unnamed structure, simply specify \"\" (empty
- /// string) for structure name in all access
- /// functions ( note that \b CIFFL_SuggestCategories
- /// flag must be on while accessing such data). In
- /// case of a loop, first use the CMMCIFData::FindLoop
- /// function to retrieve pointer on the hidden loop,
- /// and then use CMMCIFLoop's interface function to
- /// fetch data from the loop.
- /// \arg \b CIFFL_SuggestTags allows for duplicate tags in a
- /// category (structure or loop, including hidden
- /// categories). This may help reading \"dirty CIFs\".
- /// At present, only data for first non-unique tag
- /// may be accessed.
- void SetFlag ( int F );
-
- /// \brief Removes optional flag(s) for reading mmCIF files.
- /// By default, no flags are set.
- /// \param[in] F flag or logical \"or\" of several flags to be
- /// removed (unset):
- /// \arg \b CIFFL_PrintWarnings no wornings will be printed in
- /// stdout, but rather returned in the bit-encoded
- /// return code
- /// \arg \b CIFFL_StopOnWarnings warnings will not stop reading
- /// \arg \b CIFFL_SuggestCategories loops without names will
- /// count as errors and stop reading
- /// \arg \b CIFFL_SuggestTags duplicate tags in structures and
- /// loops will count as errors and stop reading.
- ///
- /// See more detail flag description in CMMCIFData::SetFlag().
- void RemoveFlag ( int F );
-
- /// \brief Returns bit-encoded warnings issued at last file read.
- /// \return an integer number, which is an or-superposition of
- /// warning flags:
- /// \arg \b CIFW_UnrecognizedItems: unrecognized items were found
- /// \arg \b CIFW_MissingField: expected data field not found
- /// \arg \b CIFW_EmptyLoop: loop category was defined but has no
- /// data
- /// \arg \b CIFW_UnexpectedEOF: mmCIF construct finished prematurely
- /// \arg \b CIFW_LoopFieldMissing: loop category has wrong number
- /// of data fields
- /// \arg \b CIFW_NotAStructure: attempt to use a category name,
- /// which was once defined as a structure,
- /// as a loop
- /// \arg \b CIFW_NotALoop: attempt to use a category name, which was
- /// once defined as a loop, as a structure
- /// \arg \b CIFW_DuplicateTag: duplicate tag was found in a
- /// structure or loop
- int GetWarnings() { return Warning; }
-
- /// \brief Sets category names and tags that are to be ignored
- /// on file read.
- /// \param[in] cats list of categories, terminated by NULL
- /// \param[in] tags list of tags, terminated by NULL.
- ///
- /// This special function is to aid reading corrupt mmCIF files.
- /// The input lists should be of equal length 'n', and specify
- /// 'n' \"wrong fields\" that should be ignored on input. E.g.,
- /// ith \"wrong field\" is identified as \"cats[i].taga[i]\".
- /// If \"wrong field\" belongs to a loop, then all the corresponding
- /// column is assumed to be absent. This corrects for mmCIF errors
- /// when defined tags in loops or structures do not have actual data
- /// associated with them.
- ///
- /// In order to remove settings, call SetWrongFields(NULL,NULL).
- ///
- /// Example:
- /*!
- \code
- // assume data for "_category.item1" and "_category.item2"
- // missed in a file to-be-read
- CMMCIFData data;
- cpstr cats[] = { "_category", "_category", NULL };
- cpstr tags[] = { "item1" , "item2" , NULL };
-
- data.SetWrongFields ( cats,tags );
- data.ReadMMCIFData ( "corrupt.cif" );
- \endcode
- */
- void SetWrongFields ( cpstr *cats, cpstr *tags );
-
- /// \brief Reads mmCIF data block from file.
- /// \param FName character null-terminated string with file name
- /// \param gzipMode flag to read compressed files:
- /// \arg \b GZM_NONE: do not assume any compression
- /// \arg \b GZM_CHECK: check compression type by file extension
- /// \arg \b GZM_ENFORCE: same as \b GZM_ENFORCE_GZIP
- /// \arg \b GZM_ENFORCE_GZIP: assume gzip compression (*.gz files)
- /// \arg \b GZM_ENFORCE_COMPRESS: assume compression with 'compress'
- /// (*.Z files).
- /// \return \b CIFRC_Ok: no errors
- /// \return \b negative: there were errors
- /// \return \b positive: there were warnings.
- ///
- /// This function will read 1st data block from the specified file.
- /// In case of non-zero return, use GetCIFMessage() function to
- /// print the corresponding error message or warning:
- /*!
- \code
- CMMCIFData data;
- char errLog[500];
- int rc;
- rc = data.ReadMMCIFData ( "myfile.cif" );
- if (rc<0)
- printf ( " There was an error:\n %s\n",
- GetCIFMessage(errLog,rc) );
- else if (rc>0)
- printf ( " There were warnings:\n %s\n",
- GetCIFMessage(errLog,rc) );
- else
- printf ( " mmCIF file has be read in successfully.\n" );
- \endcode
- */
- int ReadMMCIFData ( cpstr FName, byte gzipMode=GZM_CHECK );
-
- /// \brief Reads sequential mmCIF data blocks from file.
- /// \param RCFile reference to a CFile object opened on a file
- /// \param S buffer string which represent a sliding read window.
- /// The string should be at least 500 characters long,
- /// initialized with empty-string value before first read,
- /// and passed unchanged between the reads
- /// \param lcount line counter, should be set zero before first
- /// read and passed unchanged between the reads.
- /// \return \b CIFRC_Ok: no errors
- /// \return \b negative: there were errors
- /// \return \b positive: there were warnings.
- ///
- /// This function will read 1st data block from the current position
- /// of the file. The function is useful if a file contains more than
- /// a single data block, which should be read sequentially.
- ///
- /// \note Alternatively, files with multiple data blocks can be
- /// read using CMMCIFFile class.
- ///
- /// In case of non-zero return, use GetCIFMessage() function to
- /// print the corresponding error message or warning:
- /*!
- \code
- CMMCIFData mmCIFData;
- CFile f;
- char S[1000];
- int rc,lcount;
-
- // open file first
- f.assign ( "/path/example.cif" );
- if (!f.reset(True)) {
- printf ( " *** cannot open file '%s' for reading.\n",
- f.FileName() );
- return -1;
- }
-
- lcount = 0; // global line counter through the file
- S[0] = char(0); // buffer string
- while (!f.FileEnd()) {
-
- rc = mmCIFData.ReadMMCIFData ( f,S,lcount );
-
- if (rc!=CIFRC_Ok) { // error or warning
- if ((rc<0) && (!f.FileEnd())) { // error
- printf ( " *** error reading file %s:\n"
- " %s\n",f.FileName(),GetCIFMessage(S,rc) );
- return rc;
- } else if (rc>0) { // warning
- printf ( " ... warning on reading file %s:\n"
- " %s\n",f.FileName(),GetCIFMessage(S,rc) );
- }
- } else {
- // fetch needful values from the data block
- // ........
- }
-
- }
-
- f.shut(); // close file
-
- // NOTE: do not delete CMMCIFStruct/CMMCIFLoop
- // classes obtained from CMMCIFData. If you do, get a crash.
- // All these structures are containers that dispose their
- // content automatically.
- \endcode
- */
- int ReadMMCIFData ( RCFile f, pstr S, int & lcount );
-
- /// \brief Writes mmCIF data block into file.
- /// \param FName character null-terminated string with file name
- /// \param gzipMode flag to read compressed files:
- /// \arg \b GZM_NONE: do not compress
- /// \arg \b GZM_CHECK: compress according to file extension
- /// \arg \b GZM_ENFORCE: same as \b GZM_ENFORCE_GZIP
- /// \arg \b GZM_ENFORCE_GZIP: compress with gzip
- /// \arg \b GZM_ENFORCE_COMPRESS: compression with 'compress'.
- /// \return \b True: no errors
- /// \return \b False: file cannot be open for writing.
- Boolean WriteMMCIFData ( cpstr FName,
- byte gzipMode=GZM_CHECK );
-
- /// \brief Writes (next) mmCIF data block into file.
- /// \param RCFile reference to a CFile object opened on a file.
- ///
- /// This function allows for sequential write of mmCIF data blocks
- /// into a file.
- ///
- /// \note Alternatively, files with multiple data blocks can be
- /// created using CMMCIFFile class.
- ///
- /// Example:
- /*!
- \code
- CFile f;
- CMMCIFData cifData;
-
- // open file first
- f.assign ( "/path/example.cif" );
- if (!f.rewrite()) {
- printf ( " *** cannot open file '%s' for writing.\n",
- f.FileName() );
- return -1;
- }
-
- cifData.PutDataName ( "name1" );
- // fill cifData with all data needed
- cifData.WriteMMCIF ( f ); // first data block written
-
- cifData.FreeMemory ( 0 ); // reset data block to empty
- cifData.PutDataName ( "name2" );
- // fill cifData with all data needed
- cifData.WriteMMCIF ( f ); // second data block written
-
- // add as many data blocks as needed
-
- // now close the file
- f.shut();
-
- \endcode
-
- */
- void WriteMMCIF ( RCFile f );
-
-
- // -------- Retrieving data
-
- /// \brief Returns the number of categories (structures and loops)
- /// in data block.
- int GetNumberOfCategories () { return nCategories; }
-
- /// \brief Retrieves pointer to category (a structure or a loop) by
- /// category number.
- /// \param categoryNo category number to retrieve. Categories are
- /// numbered from 0 to GetNumberOfCategories()-1.
- /// \return pointer to category, if \b categoryNo is in the right
- /// range, or \b NULL otherwise.
- ///
- /// \note The category type (structure or loop) is returned by
- /// function CMMCIFCategory::GetCategoryID().
- /// \note The application should never attempt to deallocate
- /// the category returned. It will be properly disposed of by
- /// CMMCIFData's destructor.
- PCMMCIFCategory GetCategory ( int categoryNo ); // 0..nCategories-1
-
- /// \brief Retrieves mmCIF structure with given name.
- /// \param CName character string with name of the structure (must
- /// start with underscore).
- /// \return pointer to structure if structure with given name was
- /// found, and \b NULL otherwise.
- /// \note The application should never attempt to deallocate
- /// the structure returned. It will be properly disposed of by
- /// CMMCIFData's destructor.
- PCMMCIFStruct GetStructure ( cpstr CName );
-
- /// \brief Retrieves mmCIF loop with given name.
- /// \param CName character string with name of the loop (must
- /// start with underscore).
- /// \return pointer to loop if loop with given name was
- /// found, and \b NULL otherwise.
- /// \note The application should never attempt to deallocate
- /// the loop returned. It will be properly disposed of by
- /// CMMCIFData's destructor.
- PCMMCIFLoop GetLoop ( cpstr CName );
-
- /// \brief Finds loop containing all tags from the tag list
- /// provided.
- /// \param tagList list of tags to be looked for. The list should
- /// be terminated by empty string \"\". The order of tags
- /// is not significant.
- /// \return pointer to loop if loop with given tags was found, and
- /// \b NULL otherwise.
- ///
- /// The function will look for first loop that includes all tags
- /// from the list. The list does not have to include all tags for
- /// that loop in order for function to succeed. This function is
- /// useful for reading \"dirty cifs\" that may contain loops without
- /// a name.
- PCMMCIFLoop FindLoop ( cpstr * tagList );
-
- /// \brief Retrieves data block name into dynamically-allocated
- /// string.
- /// \param dname pointer reference to a string that accepts data
- /// block name. If \b dname is not \b NULL, it is treated
- /// as a pre-allocated string, which is disposed before
- /// copying. The application is responsible for deallocating
- /// \b dname.
- /// \param Remove flag to remove name from the data block.
- void GetDataName ( pstr & dname, Boolean Remove=False );
-
- /// \brief Returns data block name.
- pstr GetDataName() { return name; }
-
- // CheckData(..) returns positive value if the field is in the
- // file:
- // CIFRC_Structure category CName is a structure
- // CIFRC_Loop category CName is a loop
- // Negative returns mean:
- // CIFRC_StructureNoTag category CName is present,
- // it is a structure, but it does not
- // have tag TName
- // CIFRC_LoopNoTag category CName is present,
- // it is a loop, but it does not have
- // tag TName
- // CIFRC_NoCategory category CName is not present.
- // If TName is set to NULL then only the CName is checked and
- // possible returns are CIFRC_Structure, CIFRC_Loop and
- // CIFRC_NoCategory.
- int CheckData ( cpstr CName, cpstr TName );
-
- int DeleteCategory ( cpstr CName );
- int DeleteStructure ( cpstr CName );
- int DeleteLoop ( cpstr CName );
-
- // Optimize() optimizes the CIF data in memory allocation. It is
- // a good idea to call it once after extraction of data (GetXXXXXX
- // functions) with Remove flag set on has been completed.
- void Optimize();
-
- // GetString(..), GetReal(..) and GetInteger(..) return 0 if the
- // requested field was found and successfully converted. Negative
- // returns mean:
- // CIFRC_WrongFormat the field was found but failed to convert
- // due to improper numeric format
- // CIFRC_NoTag category CName was found, but it does not
- // have tag TName
- // CIFRC_NoCategory category CName was not found
- // CIFRC_NotAStructure category CName was found, but it is
- // a loop rather than a structure.
- // GetString(..) will try to dispose Dest unless it is assigned
- // NULL value before the call. The string will be then dynamically
- // allocated and copied.
- // If Remove is set to True, the field will be removed after
- // extraction.
- int GetString ( pstr & Dest, cpstr CName, cpstr TName,
- Boolean Remove=False );
- pstr GetString ( cpstr CName, cpstr TName, int & RC );
- int DeleteField ( cpstr CName, cpstr TName );
- int GetReal ( realtype & R, cpstr CName,
- cpstr TName, Boolean Remove=False );
- int GetInteger ( int & I, cpstr CName, cpstr TName,
- Boolean Remove=False );
-
- // GetLoopLength(..) returns CIFRC_NotALoop if the category CName
- // is not a loop, CIFRC_NoCategory if the category CName is not
- // found. Non-negative returns give the length of the loop (may be
- // 0 if the loop is empty).
- int GetLoopLength ( cpstr CName );
-
- // GetLoopString(..), GetLoopReal(..) and GetLoopInteger(..) act
- // like GetString(..), GetReal(..) and GetInteger(..) above for
- // nrow-th element of the 'loop_' (indexed like 0..N-1 where N
- // is obtained through GetLoopLength(..)). They will return
- // CIFRC_WrongIndex if nrow is out of range.
- // If Remove is set to True, the field will be removed after
- // extraction.
- int GetLoopString ( pstr & Dest, cpstr CName,
- cpstr TName, int nrow,
- Boolean Remove=False );
- pstr GetLoopString ( cpstr CName, cpstr TName,
- int nrow, int & RC );
- int DeleteLoopField ( cpstr CName, cpstr TName,
- int nrow );
- int GetLoopReal ( realtype & R, cpstr CName,
- cpstr TName, int nrow,
- Boolean Remove=False );
- int GetLoopInteger ( int & I, cpstr CName,
- cpstr TName, int nrow,
- Boolean Remove=False );
-
- // GetLoopSVector(..), GetLoopRVector(..) and GetLoopIVector(..)
- // read CIF 'loop_' data into allocated vectors of strings, reals
- // and integers, correspondingly. The vectors may be deallocated
- // prior to call and assigned NULL, in which case they will be
- // allocated with offsets of i1, which is also the lower index of
- // the 'loop_' data transferred into it. The upper vector index is
- // given by i2 or by the loop's length whichever is less. If
- // vectors are not assigned NULL prior the call, it is assumed
- // that they are properly (i1-offset, i2-i1+1 length) allocated.
- // The return codes are same as those of GetLoopString(..),
- // GetLoopReal(..) and GetLoopInteger(..).
- int GetLoopSVector ( psvector & S, cpstr CName,
- cpstr TName, int i1=0, int i2=MaxInt4,
- Boolean Remove=False );
- int GetLoopRVector ( rvector & R, cpstr CName,
- cpstr TName, int i1=0, int i2=MaxInt4,
- Boolean Remove=False );
- int GetLoopIVector ( ivector & I, cpstr CName,
- cpstr TName, int i1=0, int i2=MaxInt4,
- Boolean Remove=False );
-
-
- // -------- Storing data
-
- // Unless the data are to be added to the existing CIF structure,
- // FreeMemory() should be called once before creating a new
- // CIF data set.
- void FreeMemory ( int key );
-
- void PutDataName ( cpstr dname ); // stores name for 'data_'
- // record
-
- // PutString(..), PutReal(..) and PutInteger(..) will put the
- // values given into the specified category (CName) under the
- // specified tag (TName). The category, tag and field are created
- // automatically; the field will be replaced silently if identical
- // CName.TName is specified in two calls. Calls of these functions
- // may follow in random order; however CIF file will have all tags
- // grouped by categories and catgories will follow in the order
- // of first appearance in PutString(..), PutReal(..) or
- // PutInteger(..).
- // Return code - one of CIFRC_Ok or CIFRC_NotAStruct
- int PutNoData ( int NoDataType, cpstr CName,
- cpstr TName );
- int PutString ( cpstr S, cpstr CName,
- cpstr TName, Boolean Concatenate=False );
- int PutDate ( cpstr CName, cpstr TName );
- int PutReal ( realtype R, cpstr CName, cpstr TName,
- int prec=8 );
- int PutInteger ( int I, cpstr CName, cpstr TName );
-
- // If loop category CName is not present in the CIF data
- // structure, AddLoop(..) creates an empty one and returns
- // its pointer in Loop. If loop category CName is already in
- // the CIF data structure, its pointer is returned, and any
- // data which might be contained in it, remains untouched.
- // To stuff the loop with data, first the data tags have to
- // be specified by calling Loop->AddLoopTag(..). After all
- // tags are given, the data comes as a stream of calls
- // Loop->AddString(..), Loop->AddReal(..) and
- // Loop->AddInteger(..) which should provide data for every
- // tag in sequence in strictly the same order as the tags
- // were given. This essentially reflects reading a CIF loop
- // from a file.
- // Alternatively, the loop data may be stored with PutLoopXXX()
- // functions given below, although this way may be less
- // efficient (but more flexible).
- // AddLoop(..) may return
- // CIFRC_Ok category was present
- // CIFRC_Created category was not present but it has
- // been created; the category is empty
- // CIFRC_NotALoop category was present as a structure, but
- // has been replaced for a loop;
- // the category is empty.
- int AddLoop ( cpstr CName, PCMMCIFLoop & Loop );
- int AddStructure ( cpstr CName, PCMMCIFStruct & Struct );
-
- // PutLoopString(..), PutLoopReal(..) and PutLoopInteger(..) act
- // like PutString(..), PutReal(..) and PutInteger(..) above for
- // nrow-th element of the 'loop_' CName (indexed begining from 0).
- // In consequitive calls, given values of nrow does not have to be
- // ordered; the most efficient way is to start with HIGHEST value
- // for nrow in the loop and move down to 0. The least efficient way
- // is to start with nrow=0 and move up.
- // These functions allow to form loops in arbitrary way.
- // The functions may return CIFRC_Ok or CIFRC_NotALoop.
- int PutLoopNoData ( int NoDataType, cpstr CName,
- cpstr TName, int nrow );
- int PutLoopString ( cpstr S, cpstr CName,
- cpstr TName, int nrow );
- int PutLoopReal ( realtype R, cpstr CName,
- cpstr TName, int nrow,
- int prec=8 );
- int PutLoopInteger ( int I, cpstr CName, cpstr TName,
- int nrow );
-
- // PutLoopSVector(..), PutLoopRVector(..) and PutLoopIVector(..)
- // put vectors of values into specified loop fields. Parameters i1
- // and i2 give the range of indices of values which are to be
- // transfered. To transfer an entire vector allocated as [0..N-1]
- // i1 shoudl be set to 0 and i2 - to N-1. Note that the loop is
- // always indexed as starting form 0 on, therefore negative i1 and
- // i2 are not allowed, and specifying i1>0 will leave first i1
- // elements of the CIF loop for the corresponding tag undefined
- // (will be output like '?').
- // These functions allow to form loops in arbitrary way.
- int PutLoopSVector ( psvector S, cpstr CName,
- cpstr TName, int i1, int i2 );
- int PutLoopRVector ( rvector R, cpstr CName,
- cpstr TName, int i1, int i2,
- int prec=8 );
- int PutLoopIVector ( ivector I, cpstr CName,
- cpstr TName, int i1, int i2 );
-
- int RenameCategory ( cpstr CName, cpstr newCName );
-
- // --------
-
- void Copy ( PCMMCIFData Data );
- int CopyCategory ( PCMMCIFData Data, cpstr CName,
- cpstr newCName=NULL );
-
- void PrintCategories(); // for debuging only
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected:
- pstr name;
- int nCategories;
- PPCMMCIFCategory Category;
- ivector index;
- int flags;
- int Warning;
- int loopNo; // used locally for suggesting categories
- int tagNo; // used locally for suggesting tags
- psvector WrongCat;
- psvector WrongTag;
- int nWrongFields;
-
- void InitMMCIFData ();
- void FreeWrongFields ();
- Boolean CheckWrongField ( cpstr C, cpstr T );
- void Sort ();
-
- // GetCategoryNo searches for index of category cname
- // in Category[]. Return:
- // >=0 : position of the category found
- // <0 : the category was not found, it could be inserted before
- // (-RC-1)th element, where RC is the return value
- int GetCategoryNo ( cpstr cname );
- int AddCategory ( cpstr cname );
- int DeleteCategory ( int CatNo );
-
- void GetDataItem ( RCFile f, pstr S, pstr & L, pstr & p,
- int & lcount, int & llen );
- void GetLoop ( RCFile f, pstr S, pstr & L, pstr & p,
- int & lcount, int & llen );
- int GetField ( RCFile f, pstr S, pstr & L, pstr & p,
- int & lcount, int & llen );
-
-};
-
-
-
-// ====================== CMMCIFFile =============================
-
-DefineClass(CMMCIFFile)
-DefineStreamFunctions(CMMCIFFile)
-
-class CMMCIFFile : public CStream {
-
- public :
- int nData;
- ivector index;
- PPCMMCIFData data;
-
- CMMCIFFile ();
- CMMCIFFile ( cpstr FName, byte gzipMode=GZM_CHECK );
- CMMCIFFile ( RPCStream Object );
- ~CMMCIFFile();
-
- void SetPrintWarnings ( Boolean SPW ) { PrintWarnings = SPW; }
- void SetStopOnWarning ( Boolean SOW ) { StopOnWarning = SOW; }
-
- int ReadMMCIFFile ( cpstr FName,byte gzipMode=GZM_CHECK);
- int WriteMMCIFFile ( cpstr FName,byte gzipMode=GZM_CHECK);
-
- int GetNofData() { return nData; }
- PCMMCIFData GetCIFData ( int dataNo ); // 0..nData-1
- PCMMCIFData GetCIFData ( cpstr DName );
- int AddMMCIFData ( cpstr DName );
- int DeleteMMCIFData ( cpstr DName );
- int DeleteMMCIFData ( int dataNo );
- int GetCIFDataNo ( cpstr DName );
-
- void WriteMMCIF ( RCFile f );
-
- void Copy ( PCMMCIFFile File );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected:
- int nAllocData;
- Boolean PrintWarnings;
- Boolean StopOnWarning;
-
- void InitMMCIFFile();
- void FreeMemory ();
- void Sort ();
- void ExpandData ( int nDataNew );
-
-};
-
-extern pstr GetMMCIFInputBuffer ( int & LineNo );
-
-// isCIF will return
-// -1 if file FName does not exist
-// 0 if file FName is likely a CIF file ( 'data_' is present )
-// 1 if file FName is not a CIF file ( 'data_' is absent )
-extern int isCIF ( cpstr FName, byte gzipMode=GZM_CHECK );
-extern int isCIF ( RCFile f );
-
-pstr GetCIFMessage ( pstr M, int RC );
-
-
-#endif
-
-
diff --git a/mmdb/mmdb_model.cpp b/mmdb/mmdb_model.cpp
deleted file mode 100755
index e20ec40..0000000
--- a/mmdb/mmdb_model.cpp
+++ /dev/null
@@ -1,5313 +0,0 @@
-// $Id: mmdb_model.cpp,v 1.27 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 30.04.10 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_Model <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CHetCompound ( description of het compounds )
-// ~~~~~~~~~ CHetCompounds ( HETNAM, HETSYN, FORMULA records )
-// CSSContainer ( container for helixes and turns )
-// CHelix ( helix info )
-// CStrand ( strand info )
-// CSheet ( sheet info )
-// CSheets ( container for sheets )
-// CTurn ( turn info )
-// CLinkContainer ( container for link data )
-// CLink ( link data )
-// CLinkRContainer ( container for refmac link )
-// CLinkR ( link data )
-// CCisPepContainer ( container for CisPep data )
-// CCisPep ( CisPep data )
-// CModel ( PDB model )
-//
-// Copyright (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifndef __MMDB_Model__
-#include "mmdb_model.h"
-#endif
-
-#ifndef __MMDB_Manager__
-#include "mmdb_manager.h"
-#endif
-
-#ifndef __MMDB_CIFDefs__
-#include "mmdb_cifdefs.h"
-#endif
-
-
-
-// =================== CHetCompound =========================
-
-
-CHetCompound::CHetCompound ( cpstr HetName ) : CStream() {
- InitHetCompound ( HetName );
-}
-
-CHetCompound::CHetCompound ( RPCStream Object ) : CStream(Object) {
- InitHetCompound ( pstr("---") );
-}
-
-CHetCompound::~CHetCompound() {
- FreeMemory();
-}
-
-void CHetCompound::InitHetCompound ( cpstr HetName ) {
- strcpy_n0 ( hetID,HetName,sizeof(ResName) );
- comment = NULL;
- nSynonyms = 0;
- hetSynonym = NULL;
- compNum = MinInt4;
- wc = ' ';
- Formula = NULL;
-}
-
-void CHetCompound::FreeMemory() {
-int i;
- if (comment) {
- delete[] comment;
- comment = NULL;
- }
- if (hetSynonym) {
- for (i=0;i<nSynonyms;i++)
- if (hetSynonym[i]) delete[] hetSynonym[i];
- delete[] hetSynonym;
- hetSynonym = NULL;
- }
- nSynonyms = 0;
- if (Formula) {
- delete[] Formula;
- Formula = NULL;
- }
-}
-
-void CHetCompound::AddKeyWord ( cpstr W, Boolean Closed ) {
-psvector HS1;
-int i;
- if (Closed || (!hetSynonym)) {
- // first synonym orthe previous synonym was closed by semicolon
- // -- add a new one
- HS1 = new pstr[nSynonyms+1];
- for (i=0;i<nSynonyms;i++)
- HS1[i] = hetSynonym[i];
- if (hetSynonym) delete[] hetSynonym;
- hetSynonym = HS1;
- hetSynonym[nSynonyms] = NULL;
- CreateCopy ( hetSynonym[nSynonyms],W );
- nSynonyms++;
- } else {
- // just add W to the last synonym
- CreateConcat ( hetSynonym[nSynonyms-1],pstr(" "),W );
- }
-}
-
-
-void CHetCompound::HETNAM_PDBDump ( RCFile f ) {
-char S[100];
-pstr p1,p2;
-char c;
-int N,i;
-
- if (!comment) return;
-
- c = ' ';
- N = 0;
- p1 = comment;
- do {
- N++;
- if (N==1) sprintf ( S,"HETNAM %3s " ,hetID );
- else sprintf ( S,"HETNAM %2i %3s ",N,hetID );
- while (*p1==' ') p1++;
- p2 = strchr(p1,'\n');
- if (p2) {
- c = *p2;
- *p2 = char(0);
- } else if (strlen(p1)>53) {
- i = 0;
- while (p1[i] && (i<53) && (p1[i]!=' ')) i++;
- p2 = &(p1[i]);
- c = *p2;
- *p2 = char(0);
- }
- if (*p1) {
- strcat ( S,p1 );
- PadSpaces ( S,80 );
- f.WriteLine ( S );
- } else
- N--;
- if (p2) {
- *p2 = c;
- if (c) p1 = p2+1;
- else p2 = NULL;
- }
- } while (p2);
-
-}
-
-
-void CHetCompound::HETSYN_PDBDump ( RCFile f ) {
-char S[100];
-pstr p;
-char c;
-int N,k,i,l;
- if (!hetSynonym) return;
- N = 0;
- k = 0;
- p = &(hetSynonym[0][0]);
- do {
- N++;
- if (N==1) sprintf ( S,"HETSYN %3s " ,hetID );
- else sprintf ( S,"HETSYN %2i %3s ",N,hetID );
- i = 0;
- do {
- l = strlen(p)+2;
- if (i+l<54) {
- strcat ( S,p );
- if (k<nSynonyms-1) strcat ( S,"; " );
- k++;
- i += l;
- if (k<nSynonyms) p = &(hetSynonym[k][0]);
- else i = 60; // break loop
- } else {
- if (i==0) {
- // too long synonym, has to be split over several lines
- i = l-3;
- while (i>51) {
- i--;
- while ((i>0) && (p[i]!=' ')) i--;
- }
- if (i<2) i = 51; // no spaces!
- c = p[i];
- p[i] = char(0);
- strcat ( S,p );
- p[i] = c;
- p = &(p[i]);
- while (*p==' ') p++;
- }
- i = 60; // break loop
- }
- } while (i<54);
- PadSpaces ( S,80 );
- f.WriteLine ( S );
- } while (k<nSynonyms);
-}
-
-
-void CHetCompound::FORMUL_PDBDump ( RCFile f ) {
-char S[100];
-pstr p1,p2;
-char c;
-int N,i;
- if (!Formula) return;
- N = 0;
- p1 = Formula;
- do {
- N++;
- if (compNum>MinInt4) {
- if (N==1) sprintf ( S,"FORMUL %2i %3s " ,compNum,hetID );
- else sprintf ( S,"FORMUL %2i %3s %2i ",compNum,hetID,N );
- } else {
- if (N==1) sprintf ( S,"FORMUL %3s " ,hetID );
- else sprintf ( S,"FORMUL %3s %2i ",hetID,N );
- }
- S[18] = wc;
- p2 = strchr(p1,'\n');
- if (p2) {
- c = *p2;
- *p2 = char(0);
- } else if (strlen(p1)>50) {
- while (*p1==' ') p1++;
- i = 0;
- while (p1[i] && (i<50) && (p1[i]!=' ')) i++;
- p2 = &(p1[i]);
- c = *p2;
- *p2 = char(0);
- }
- strcat ( S,p1 );
- if (p2) {
- *p2 = c;
- p1 = p2+1;
- }
- PadSpaces ( S,80 );
- f.WriteLine ( S );
- } while (p2);
-}
-
-
-void CHetCompound::FormComString ( pstr & F ) {
-pstr p;
-int i;
- if (F) {
- delete[] F;
- F = NULL;
- }
- if (comment) {
- CreateCopy ( F,comment );
- i = 0;
- p = comment;
- while (*p) {
- p++;
- if (*p=='\n') i = 0;
- else i++;
- if (i>68) {
- F[i] = char(0);
- CreateConcat ( F,pstr("\n"),p );
- i = 0;
- }
- }
- }
-}
-
-
-void CHetCompound::FormSynString ( pstr & F ) {
-pstr p;
-char c;
-int i,k,l;
- if (F) {
- delete[] F;
- F = NULL;
- }
- if (hetSynonym) {
- CreateCopy ( F,pstr(" ") );
- k = 0;
- p = &(hetSynonym[0][0]);
- do {
- l = strlen(p)+2;
- if (l<=60) {
- if (k<nSynonyms-1) CreateConcat ( F,p,pstr(";\n ") );
- else CreateConcat ( F,p );
- k++;
- if (k<nSynonyms) p = &(hetSynonym[k][0]);
- } else {
- // too long synonym, has to be split over several lines
- i = l-3;
- while (i>60) {
- i--;
- while ((i>0) && (p[i]!=' ')) i--;
- }
- if (i<2) i = 60; // no spaces!
- c = p[i];
- p[i] = char(0);
- CreateConcat ( F,p,pstr("\n ") );
- p[i] = c;
- p = &(p[i]);
- while (*p==' ') p++;
- }
- } while (k<nSynonyms);
- }
-}
-
-void CHetCompound::FormForString ( pstr & F ) {
-pstr p;
-int i;
- if (F) {
- delete[] F;
- F = NULL;
- }
- if (Formula) {
- CreateCopy ( F,Formula );
- i = 0;
- p = &(Formula[0]);
- while (*p) {
- p++;
- if (*p=='\n') i = 0;
- else i++;
- if (i>68) {
- F[i] = char(0);
- CreateConcat ( F,pstr("\n"),p );
- i = 0;
- }
- }
- }
-}
-
-
-void CHetCompound::Copy ( PCHetCompound HetCompound ) {
-int i;
- FreeMemory ();
- strcpy ( hetID ,HetCompound->hetID );
- CreateCopy ( comment,HetCompound->comment );
- nSynonyms = HetCompound->nSynonyms;
- if (nSynonyms>0) {
- hetSynonym = new pstr[nSynonyms];
- for (i=0;i<nSynonyms;i++) {
- hetSynonym[i] = NULL;
- CreateCopy ( hetSynonym[i],HetCompound->hetSynonym[i] );
- }
- }
- compNum = HetCompound->compNum;
- wc = HetCompound->wc;
- CreateCopy ( Formula,HetCompound->Formula );
-}
-
-void CHetCompound::write ( RCFile f ) {
-int i;
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteTerLine ( hetID,False );
- f.CreateWrite ( comment );
- f.WriteInt ( &nSynonyms );
- for (i=0;i<nSynonyms;i++)
- f.CreateWrite ( hetSynonym[i] );
- f.WriteInt ( &compNum );
- f.WriteFile ( &wc,sizeof(wc) );
- f.CreateWrite ( Formula );
-}
-
-void CHetCompound::read ( RCFile f ) {
-int i;
-byte Version;
- FreeMemory();
- f.ReadByte ( &Version );
- f.ReadTerLine ( hetID,False );
- f.CreateRead ( comment );
- f.ReadInt ( &nSynonyms );
- if (nSynonyms>0) {
- hetSynonym = new pstr[nSynonyms];
- for (i=0;i<nSynonyms;i++) {
- hetSynonym[i] = NULL;
- f.CreateRead ( hetSynonym[i] );
- }
- }
- f.ReadInt ( &compNum );
- f.ReadFile ( &wc,sizeof(wc) );
- f.CreateRead ( Formula );
-}
-
-MakeStreamFunctions(CHetCompound)
-
-
-// ==================== CHetCompounds =======================
-
-
-CHetCompounds::CHetCompounds() : CStream() {
- InitHetCompounds();
-}
-
-CHetCompounds::CHetCompounds ( RPCStream Object ) : CStream(Object) {
- InitHetCompounds();
-}
-
-CHetCompounds::~CHetCompounds() {
- FreeMemory();
-}
-
-void CHetCompounds::InitHetCompounds() {
- nHets = 0;
- hetCompound = NULL;
- Closed = False;
-}
-
-void CHetCompounds::FreeMemory() {
-int i;
- if (hetCompound) {
- for (i=0;i<nHets;i++)
- if (hetCompound[i]) delete hetCompound[i];
- delete[] hetCompound;
- hetCompound = NULL;
- }
- nHets = 0;
-}
-
-void CHetCompounds::ConvertHETNAM ( cpstr S ) {
-ResName hetID;
-char L[100];
-int l,i;
- l = strlen(S);
- if (l>12) {
- strcpy_n0 ( hetID,&(S[11]),3 );
- i = AddHetName ( hetID );
- if (l>15) {
- if (hetCompound[i]->comment) strcpy ( L,"\n" );
- else L[0] = char(0);
- strcat ( L,&(S[15]) );
- CutSpaces ( L,SCUTKEY_END );
- CreateConcat ( hetCompound[i]->comment,L );
- }
- }
-}
-
-void CHetCompounds::ConvertHETSYN ( cpstr S ) {
-ResName hetID;
-char L[100];
-int l,i,j,k;
- l = strlen(S);
- if (l>12) {
- strcpy_n0 ( hetID,&(S[11]),3 );
- i = AddHetName ( hetID );
- if (l>15) {
- j = 15;
- do {
- while (S[j]==' ') j++;
- k = 0;
- if (S[j]) {
- while (S[j] && (S[j]!=';'))
- L[k++] = S[j++];
- L[k--] = char(0);
- while ((k>0) && (L[k]==' ')) L[k--] = char(0);
- if (L[0]) {
- hetCompound[i]->AddKeyWord ( L,Closed );
- Closed = (S[j]==';');
- }
- if (S[j]) j++;
- }
- } while (S[j]);
- /*
- p1 = &(S[15]);
- do {
- p2 = strchr ( p1,';' );
- if (p2) {
- c = *p2;
- *p2 = char(0);
- }
- strcpy_css ( L,p1 );
- if (L[0])
- hetCompound[i]->AddKeyWord ( L,Closed );
- if (p2) {
- if (L[0]) Closed = True;
- *p2 = c;
- p1 = p2+1;
- } else if (L[0])
- Closed = False;
- } while (p2);
- */
- }
- }
-}
-
-void CHetCompounds::ConvertFORMUL ( cpstr S ) {
-ResName hetID;
-char L[100];
-int l,i;
- l = strlen(S);
- if (l>13) {
- strcpy_n0 ( hetID,&(S[12]),3 );
- i = AddHetName ( hetID );
- if (l>18) {
- GetInteger ( hetCompound[i]->compNum,&(S[9]),2 );
- hetCompound[i]->wc = S[18];
- if (strlen(S)>19) {
- if (hetCompound[i]->Formula) strcpy ( L,"\n" );
- else L[0] = char(0);
- strcat ( L,&(S[19]) );
- CutSpaces ( L,SCUTKEY_END );
- CreateConcat ( hetCompound[i]->Formula,L );
- }
- }
- }
-}
-int CHetCompounds::AddHetName ( cpstr H ) {
-PPCHetCompound HC1;
-int i;
- i = 0;
- while (i<nHets) {
- if (hetCompound[i]) {
- if (!strcmp(hetCompound[i]->hetID,H)) break;
- }
- i++;
- }
- if (i>=nHets) {
- HC1 = new PCHetCompound[nHets+1];
- for (i=0;i<nHets;i++)
- HC1[i] = hetCompound[i];
- if (hetCompound) delete[] hetCompound;
- hetCompound = HC1;
- hetCompound[nHets] = new CHetCompound ( H );
- i = nHets;
- nHets++;
- }
- return i;
-}
-
-void CHetCompounds::PDBASCIIDump ( RCFile f ) {
-int i;
-
- for (i=0;i<nHets;i++)
- if (hetCompound[i])
- hetCompound[i]->HETNAM_PDBDump ( f );
-
- for (i=0;i<nHets;i++)
- if (hetCompound[i])
- hetCompound[i]->HETSYN_PDBDump ( f );
-
- for (i=0;i<nHets;i++)
- if (hetCompound[i])
- hetCompound[i]->FORMUL_PDBDump ( f );
-
-}
-
-
-void CHetCompounds::MakeCIF ( PCMMCIFData CIF ) {
-PCMMCIFLoop Loop;
-pstr F;
-int RC;
-int i;
-
- if (!hetCompound) return;
-
- RC = CIF->AddLoop ( CIFCAT_CHEM_COMP,Loop );
- if (RC!=CIFRC_Ok) {
- Loop->AddLoopTag ( CIFTAG_ID );
- Loop->AddLoopTag ( CIFTAG_NAME );
- Loop->AddLoopTag ( CIFTAG_NDB_SYNONYMS );
- Loop->AddLoopTag ( CIFTAG_NDB_COMPONENT_NO );
- Loop->AddLoopTag ( CIFTAG_FORMULA );
- }
-
- F = NULL;
- for (i=0;i<nHets;i++)
- if (hetCompound[i]) {
- Loop->AddString ( hetCompound[i]->hetID );
- hetCompound[i]->FormComString ( F );
- Loop->AddString ( F );
- hetCompound[i]->FormSynString ( F );
- Loop->AddString ( F );
- if (hetCompound[i]->compNum>MinInt4)
- Loop->AddInteger ( hetCompound[i]->compNum );
- else Loop->AddNoData ( CIF_NODATA_QUESTION );
- hetCompound[i]->FormForString ( F );
- Loop->AddString ( F );
- }
-
- if (F) delete[] F;
-
-}
-
-void CHetCompounds::GetCIF ( PCMMCIFData CIF ) {
-PCMMCIFLoop Loop;
-char L[100];
-ResName hetID;
-pstr F,p1,p2;
-char c;
-int i,l,k,RC;
-
- FreeMemory();
-
- Loop = CIF->GetLoop ( CIFCAT_CHEM_COMP );
- if (!Loop) return;
-
- l = Loop->GetLoopLength();
- F = NULL;
-
- for (i=0;i<l;i++) {
- CIFGetString ( hetID,Loop,CIFTAG_ID,i,sizeof(hetID),
- pstr("---") );
- k = AddHetName ( hetID );
- Loop->GetString ( hetCompound[k]->comment,CIFTAG_NAME,i,True );
- RC = Loop->GetInteger ( hetCompound[k]->compNum,
- CIFTAG_NDB_COMPONENT_NO,i,True );
- if (RC) hetCompound[i]->compNum = MinInt4;
- Loop->GetString ( hetCompound[k]->Formula,CIFTAG_FORMULA,i,True );
- RC = Loop->GetString ( F,CIFTAG_NDB_SYNONYMS,i,True );
- if ((!RC) && F ) {
- p1 = &(F[0]);
- while (*p1) {
- if (*p1=='\n') *p1 = ' ';
- p1++;
- }
- p1 = &(F[0]);
- do {
- p2 = strchr ( p1,';' );
- if (p2) {
- c = *p2;
- *p2 = char(0);
- }
- strcpy_css ( L,p1 );
- hetCompound[i]->AddKeyWord ( L,True );
- if (p2) {
- *p2 = c;
- p1 = p2+1;
- }
- } while (p2);
- }
- hetCompound[i]->wc = ' ';
- }
-
-// CIF->DeleteLoop ( CIFCAT_CHEM_COMP );
-
- if (F) delete[] F;
-
-}
-
-void CHetCompounds::Copy ( PCHetCompounds HetCompounds ) {
-int i;
- FreeMemory();
- nHets = HetCompounds->nHets;
- if (nHets>0) {
- hetCompound = new PCHetCompound[nHets];
- for (i=0;i<nHets;i++) {
- hetCompound[i] = new CHetCompound ( "" );
- hetCompound[i]->Copy ( HetCompounds->hetCompound[i] );
- }
- }
-}
-
-void CHetCompounds::write ( RCFile f ) {
-int i;
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &nHets );
- for (i=0;i<nHets;i++)
- hetCompound[i]->write ( f );
-}
-
-void CHetCompounds::read ( RCFile f ) {
-int i;
-byte Version;
- FreeMemory();
- f.ReadByte ( &Version );
- f.ReadInt ( &nHets );
- if (nHets>0) {
- hetCompound = new PCHetCompound[nHets];
- for (i=0;i<nHets;i++) {
- hetCompound[i] = new CHetCompound ( "---" );
- hetCompound[i]->read ( f );
- }
- }
-}
-
-MakeStreamFunctions(CHetCompounds)
-
-
-
-// ==================== CSSContainer =========================
-
-PCContainerClass CSSContainer::MakeContainerClass ( int ClassID ) {
- switch (ClassID) {
- default :
- case ClassID_Template : return
- CClassContainer::MakeContainerClass(ClassID);
- case ClassID_Helix : return new CHelix();
- case ClassID_Turn : return new CTurn ();
- }
-}
-
-MakeStreamFunctions(CSSContainer)
-
-
-
-// ================ CHelix ===================
-
-CHelix::CHelix() : CContainerClass() {
- InitHelix();
-}
-
-CHelix::CHelix ( cpstr S ) : CContainerClass() {
- InitHelix();
- ConvertPDBASCII ( S );
-}
-
-CHelix::CHelix ( RPCStream Object ) : CContainerClass(Object) {
- InitHelix();
-}
-
-CHelix::~CHelix() {
- if (comment) delete[] comment;
-}
-
-void CHelix::InitHelix() {
-
- serNum = 0; // serial number
- strcpy ( helixID ,"---" ); // helix ID
- strcpy ( initResName,"---" ); // name of the helix's initial residue
- strcpy ( initChainID,"" ); // chain ID for the chain
- // containing the helix
- initSeqNum = 0; // sequence number of the initial
- // residue
- strcpy ( initICode ,"" ); // insertion code of the initial
- // residue
- strcpy ( endResName ,"---" ); // name of the helix's terminal residue
- strcpy ( endChainID ,"" ); // chain ID for the chain
- // containing the helix
- endSeqNum = 0; // sequence number of the terminal
- // residue
- strcpy ( endICode ,"" ); // insertion code of the terminal
- // residue
- helixClass = 0; // helix class
- comment = NULL; // comment about the helix
- length = 0; // length of the helix
-
-}
-
-void CHelix::PDBASCIIDump ( pstr S, int N ) {
-UNUSED_ARGUMENT(N);
-// makes the ASCII PDB OBSLTE line number N
-// from the class' data
- strcpy ( S,"HELIX" );
- PadSpaces ( S,80 );
- PutInteger ( &(S[7]) ,serNum ,3 );
- strcpy_n1 ( &(S[11]),helixID ,3 );
- strcpy_n1 ( &(S[15]),initResName,3 );
- if (initChainID[0]) S[19] = initChainID[0];
- PutIntIns ( &(S[21]),initSeqNum ,4,initICode );
- strcpy_n1 ( &(S[27]),endResName ,3 );
- if (endChainID[0]) S[31] = endChainID[0];
- PutIntIns ( &(S[33]),endSeqNum ,4,endICode );
- PutInteger ( &(S[38]),helixClass ,2 );
- if (comment)
- strcpy_n ( &(S[40]),comment ,30 );
- PutInteger ( &(S[71]),length ,5 );
-}
-
-void AddStructConfTags ( PCMMCIFLoop Loop ) {
- Loop->AddLoopTag ( CIFTAG_CONF_TYPE_ID );
- Loop->AddLoopTag ( CIFTAG_ID );
- Loop->AddLoopTag ( CIFTAG_PDB_ID );
- Loop->AddLoopTag ( CIFTAG_BEG_LABEL_COMP_ID );
- Loop->AddLoopTag ( CIFTAG_BEG_LABEL_ASYM_ID );
- Loop->AddLoopTag ( CIFTAG_BEG_LABEL_SEQ_ID );
- Loop->AddLoopTag ( CIFTAG_NDB_BEG_LABEL_INS_CODE_PDB );
- Loop->AddLoopTag ( CIFTAG_END_LABEL_COMP_ID );
- Loop->AddLoopTag ( CIFTAG_END_LABEL_ASYM_ID );
- Loop->AddLoopTag ( CIFTAG_END_LABEL_SEQ_ID );
- Loop->AddLoopTag ( CIFTAG_NDB_END_LABEL_INS_CODE_PDB );
- Loop->AddLoopTag ( CIFTAG_NDB_HELIX_CLASS_PDB );
- Loop->AddLoopTag ( CIFTAG_DETAILS );
- Loop->AddLoopTag ( CIFTAG_NDB_LENGTH );
-}
-
-#define HelixTypeID "HELX_P"
-
-void CHelix::MakeCIF ( PCMMCIFData CIF, int N ) {
-UNUSED_ARGUMENT(N);
-PCMMCIFLoop Loop;
-int RC;
- RC = CIF->AddLoop ( CIFCAT_STRUCT_CONF,Loop );
- if (RC!=CIFRC_Ok)
- // the category was (re)created, provide tags
- AddStructConfTags ( Loop );
- Loop->AddString ( pstr(HelixTypeID) );
- Loop->AddInteger ( serNum );
- Loop->AddString ( helixID );
- Loop->AddString ( initResName );
- Loop->AddString ( initChainID );
- Loop->AddInteger ( initSeqNum );
- Loop->AddString ( initICode,True );
- Loop->AddString ( endResName );
- Loop->AddString ( endChainID );
- Loop->AddInteger ( endSeqNum );
- Loop->AddString ( endICode ,True );
- Loop->AddInteger ( helixClass );
- Loop->AddString ( comment );
- Loop->AddInteger ( length );
-}
-
-int CHelix::ConvertPDBASCII ( cpstr S ) {
-char L[100];
- GetInteger ( serNum ,&(S[7]) ,3 );
- strcpy_ncss ( helixID ,&(S[11]),3 );
- strcpy_ncss ( initResName,&(S[15]),3 );
- strcpy_ncss ( initChainID,&(S[19]),1 );
- GetIntIns ( initSeqNum,initICode,&(S[21]),4 );
- strcpy_ncss ( endResName ,&(S[27]),3 );
- strcpy_ncss ( endChainID ,&(S[31]),1 );
- GetIntIns ( endSeqNum ,endICode ,&(S[33]),4 );
- GetInteger ( helixClass ,&(S[38]),2 );
- strcpy_ncss ( L ,&(S[40]),30 );
- CreateCopy ( comment ,L );
- GetInteger ( length ,&(S[71]),5 );
- return 0;
-}
-
-void CHelix::GetCIF ( PCMMCIFData CIF, int & Signal ) {
-PCMMCIFLoop Loop;
-int RC,l;
-pstr F;
-Boolean Done;
-
- Loop = CIF->GetLoop ( CIFCAT_STRUCT_CONF );
- if (!Loop) {
- Signal = -1; // signal to finish processing of this structure
- return;
- }
-
- l = Loop->GetLoopLength();
- Done = Signal>=l;
- while (!Done) {
- F = Loop->GetString ( CIFTAG_CONF_TYPE_ID,Signal,RC );
- if ((!RC) && F) Done = (strcmp(F,HelixTypeID)==0);
- else Done = False;
- if (!Done) {
- Signal++;
- Done = Signal>=l;
- }
- }
-
- if (Signal>=l) {
- Signal = -1; // finish processing of Helix
- return;
- }
-
- Loop->DeleteField ( CIFTAG_CONF_TYPE_ID,Signal );
-
- if (CIFGetInteger(serNum,Loop,CIFTAG_ID,Signal)) return;
-
-
- CIFGetString ( helixID ,Loop,CIFTAG_PDB_ID,
- Signal,sizeof(helixID),pstr(" ") );
-
- CIFGetString ( initResName,Loop,CIFTAG_BEG_LABEL_COMP_ID,
- Signal,sizeof(initResName),pstr(" ") );
- CIFGetString ( initChainID,Loop,CIFTAG_BEG_LABEL_ASYM_ID,
- Signal,sizeof(initChainID),pstr("") );
- CIFGetString ( initICode ,Loop,CIFTAG_NDB_BEG_LABEL_INS_CODE_PDB,
- Signal,sizeof(initICode),pstr("") );
- if (CIFGetInteger(initSeqNum,Loop,CIFTAG_BEG_LABEL_SEQ_ID,Signal))
- return;
-
- CIFGetString ( endResName,Loop,CIFTAG_END_LABEL_COMP_ID,
- Signal,sizeof(endResName),pstr(" ") );
- CIFGetString ( endChainID,Loop,CIFTAG_END_LABEL_ASYM_ID,
- Signal,sizeof(endChainID),pstr("") );
- CIFGetString ( endICode ,Loop,CIFTAG_NDB_END_LABEL_INS_CODE_PDB,
- Signal,sizeof(endICode),pstr("") );
- if (CIFGetInteger(endSeqNum,Loop,CIFTAG_END_LABEL_SEQ_ID,Signal))
- return;
-
- if (CIFGetInteger(helixClass,Loop,
- CIFTAG_NDB_HELIX_CLASS_PDB,Signal)) return;
- CreateCopy ( comment,Loop->GetString(CIFTAG_DETAILS,Signal,RC));
- Loop->DeleteField ( CIFTAG_DETAILS,Signal );
- if (CIFGetInteger(length,Loop,CIFTAG_NDB_LENGTH,Signal)) return;
-
- Signal++;
-
-}
-
-void CHelix::Copy ( PCContainerClass Helix ) {
- serNum = PCHelix(Helix)->serNum;
- initSeqNum = PCHelix(Helix)->initSeqNum;
- endSeqNum = PCHelix(Helix)->endSeqNum;
- helixClass = PCHelix(Helix)->helixClass;
- length = PCHelix(Helix)->length;
- strcpy ( helixID ,PCHelix(Helix)->helixID );
- strcpy ( initResName,PCHelix(Helix)->initResName );
- strcpy ( initChainID,PCHelix(Helix)->initChainID );
- strcpy ( initICode ,PCHelix(Helix)->initICode );
- strcpy ( endResName ,PCHelix(Helix)->endResName );
- strcpy ( endChainID ,PCHelix(Helix)->endChainID );
- strcpy ( endICode ,PCHelix(Helix)->endICode );
- CreateCopy ( comment,PCHelix(Helix)->comment );
-}
-
-void CHelix::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &serNum );
- f.WriteInt ( &initSeqNum );
- f.WriteInt ( &endSeqNum );
- f.WriteInt ( &helixClass );
- f.WriteInt ( &length );
- f.WriteTerLine ( helixID ,False );
- f.WriteTerLine ( initResName,False );
- f.WriteTerLine ( initChainID,False );
- f.WriteTerLine ( initICode ,False );
- f.WriteTerLine ( endResName ,False );
- f.WriteTerLine ( endChainID ,False );
- f.WriteTerLine ( endICode ,False );
- f.CreateWrite ( comment );
-}
-
-void CHelix::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- f.ReadInt ( &serNum );
- f.ReadInt ( &initSeqNum );
- f.ReadInt ( &endSeqNum );
- f.ReadInt ( &helixClass );
- f.ReadInt ( &length );
- f.ReadTerLine ( helixID ,False );
- f.ReadTerLine ( initResName,False );
- f.ReadTerLine ( initChainID,False );
- f.ReadTerLine ( initICode ,False );
- f.ReadTerLine ( endResName ,False );
- f.ReadTerLine ( endChainID ,False );
- f.ReadTerLine ( endICode ,False );
- f.CreateRead ( comment );
-}
-
-MakeStreamFunctions(CHelix)
-
-
-
-// ================ CStrand =====================
-
-CStrand::CStrand () : CStream() {
- InitStrand();
-}
-
-CStrand::CStrand ( RPCStream Object ) : CStream(Object) {
- InitStrand();
-}
-
-CStrand::~CStrand() {
-}
-
-void CStrand::InitStrand() {
- initSeqNum = MinInt4;
- endSeqNum = MinInt4;
- sense = 0;
- curResSeq = MinInt4;
- prevResSeq = MinInt4;
- strandNo = 0;
- strcpy ( sheetID ,"sheet_0" );
- strcpy ( initResName," " );
- strcpy ( initChainID,"" );
- strcpy ( initICode ,"" );
- strcpy ( endResName ," " );
- strcpy ( endChainID ,"" );
- strcpy ( endICode ,"" );
- strcpy ( curAtom ," " );
- strcpy ( curResName ," " );
- strcpy ( curChainID ,"" );
- strcpy ( curICode ,"" );
- strcpy ( prevAtom ," " );
- strcpy ( prevResName," " );
- strcpy ( prevChainID,"" );
- strcpy ( prevICode ,"" );
-}
-
-void CStrand::PDBASCIIDump ( pstr S ) {
-// Finishes making the ASCII PDB SHEET line number N
-// from the class' data. Making is initiated by CSheet.
-
- strcpy_n1 ( &(S[17]),initResName,3 );
- if (initChainID[0]) S[21] = initChainID[0];
- PutIntIns ( &(S[22]),initSeqNum ,4,initICode );
-
- strcpy_n1 ( &(S[28]),endResName ,3 );
- if (endChainID[0]) S[32] = endChainID[0];
- PutIntIns ( &(S[33]),endSeqNum ,4,endICode );
-
- PutInteger ( &(S[38]),sense ,2 );
-
- strcpy_n1 ( &(S[41]),curAtom ,4 );
- strcpy_n1 ( &(S[45]),curResName ,3 );
- if (curChainID[0]) S[49] = curChainID[0];
- PutIntIns ( &(S[50]),curResSeq ,4,curICode );
-
- strcpy_n1 ( &(S[56]),prevAtom ,4 );
- strcpy_n1 ( &(S[60]),prevResName,3 );
- if (prevChainID[0]) S[64] = prevChainID[0];
- PutIntIns ( &(S[65]),prevResSeq ,4,prevICode );
-
-}
-
-
-void CStrand::MakeCIF ( PCMMCIFData CIF ) {
-PCMMCIFLoop Loop;
-int RC;
-
- RC = CIF->AddLoop ( CIFCAT_STRUCT_SHEET_RANGE,Loop );
- if (RC!=CIFRC_Ok) {
- // the category was (re)created, provide tags
- Loop->AddLoopTag ( CIFTAG_SHEET_ID );
- Loop->AddLoopTag ( CIFTAG_ID );
- Loop->AddLoopTag ( CIFTAG_BEG_LABEL_COMP_ID );
- Loop->AddLoopTag ( CIFTAG_BEG_LABEL_ASYM_ID );
- Loop->AddLoopTag ( CIFTAG_BEG_LABEL_SEQ_ID );
- Loop->AddLoopTag ( CIFTAG_NDB_BEG_LABEL_INS_CODE_PDB );
- Loop->AddLoopTag ( CIFTAG_END_LABEL_COMP_ID );
- Loop->AddLoopTag ( CIFTAG_END_LABEL_ASYM_ID );
- Loop->AddLoopTag ( CIFTAG_END_LABEL_SEQ_ID );
- Loop->AddLoopTag ( CIFTAG_NDB_END_LABEL_INS_CODE_PDB );
- }
- Loop->AddString ( sheetID );
- Loop->AddInteger ( strandNo );
- Loop->AddString ( initResName );
- Loop->AddString ( initChainID );
- Loop->AddInteger ( initSeqNum );
- Loop->AddString ( initICode,True );
- Loop->AddString ( endResName );
- Loop->AddString ( endChainID );
- Loop->AddInteger ( endSeqNum );
- Loop->AddString ( endICode ,True );
-
-}
-
-
-int CStrand::ConvertPDBASCII ( cpstr S ) {
-
- GetInteger ( strandNo ,&(S[7]) ,3 );
- strcpy_ncss ( sheetID ,&(S[11]) ,3 );
-
- strcpy_ncss ( initResName,&(S[17]) ,3 );
- strcpy_ncss ( initChainID,&(S[21]) ,1 );
- GetIntIns ( initSeqNum ,initICode,&(S[22]),4 );
-
- strcpy_ncss ( endResName ,&(S[28]) ,3 );
- strcpy_ncss ( endChainID ,&(S[32]) ,1 );
- GetIntIns ( endSeqNum ,endICode ,&(S[33]),4 );
-
- GetInteger ( sense ,&(S[38]) ,2 );
-
- GetString ( curAtom ,&(S[41]) ,4 );
- strcpy_ncss ( curResName ,&(S[45]) ,3 );
- strcpy_ncss ( curChainID ,&(S[49]) ,1 );
- GetIntIns ( curResSeq ,curICode ,&(S[50]),4 );
-
- GetString ( prevAtom ,&(S[56]) ,4 );
- strcpy_ncss ( prevResName,&(S[60]) ,3 );
- strcpy_ncss ( prevChainID,&(S[64]) ,1 );
- GetIntIns ( prevResSeq ,prevICode,&(S[65]),4 );
-
- return 0;
-
-}
-
-int CStrand::GetCIF ( PCMMCIFData CIF, cpstr sheet_id ) {
-PCMMCIFLoop Loop;
-int RC,l,i,sNo;
-pstr F;
-
- Loop = CIF->GetLoop ( CIFCAT_STRUCT_SHEET_RANGE );
- if (Loop) {
- l = Loop->GetLoopLength();
- i = 0;
- while (i<l) {
- F = Loop->GetString ( CIFTAG_SHEET_ID,i,RC );
- if (F && (!RC)) {
- if (!strcmp(F,sheet_id)) {
- strcpy ( sheetID,sheet_id );
- if (CIFGetInteger(sNo,Loop,CIFTAG_ID,i)) return i;
- if (sNo==strandNo) {
- CIFGetString ( initResName,Loop,CIFTAG_BEG_LABEL_COMP_ID,
- i,sizeof(initResName),pstr(" ") );
- CIFGetString ( initChainID,Loop,CIFTAG_BEG_LABEL_ASYM_ID,
- i,sizeof(initChainID),pstr("") );
- CIFGetString ( initICode,Loop,
- CIFTAG_NDB_BEG_LABEL_INS_CODE_PDB,
- i,sizeof(initICode),pstr("") );
- if (CIFGetInteger(initSeqNum,Loop,
- CIFTAG_BEG_LABEL_SEQ_ID,i))
- return i;
- CIFGetString ( endResName,Loop,CIFTAG_END_LABEL_COMP_ID,
- i,sizeof(endResName),pstr(" ") );
- CIFGetString ( endChainID,Loop,CIFTAG_END_LABEL_ASYM_ID,
- i,sizeof(endChainID),pstr("") );
- CIFGetString ( endICode ,Loop,
- CIFTAG_NDB_END_LABEL_INS_CODE_PDB,
- i,sizeof(endICode),pstr("") );
- if (CIFGetInteger(endSeqNum,Loop,
- CIFTAG_END_LABEL_SEQ_ID,i))
- return i;
- Loop->DeleteRow ( i );
- i = l+100; // break the loop
- }
- }
- }
- i++;
- }
- }
-
- return 0;
-
-}
-
-void CStrand::Copy ( PCStrand Strand ) {
- initSeqNum = Strand->initSeqNum;
- endSeqNum = Strand->endSeqNum;
- sense = Strand->sense;
- curResSeq = Strand->curResSeq;
- prevResSeq = Strand->prevResSeq;
- strcpy ( initResName,Strand->initResName );
- strcpy ( initChainID,Strand->initChainID );
- strcpy ( initICode ,Strand->initICode );
- strcpy ( endResName ,Strand->endResName );
- strcpy ( endChainID ,Strand->endChainID );
- strcpy ( endICode ,Strand->endICode );
- strcpy ( curAtom ,Strand->curAtom );
- strcpy ( curResName ,Strand->curResName );
- strcpy ( curChainID ,Strand->curChainID );
- strcpy ( curICode ,Strand->curICode );
- strcpy ( prevAtom ,Strand->prevAtom );
- strcpy ( prevResName,Strand->prevResName );
- strcpy ( prevChainID,Strand->prevChainID );
- strcpy ( prevICode ,Strand->prevICode );
-}
-
-void CStrand::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &initSeqNum );
- f.WriteInt ( &endSeqNum );
- f.WriteInt ( &sense );
- f.WriteInt ( &curResSeq );
- f.WriteInt ( &prevResSeq );
- f.WriteTerLine ( initResName,False );
- f.WriteTerLine ( initChainID,False );
- f.WriteTerLine ( initICode ,False );
- f.WriteTerLine ( endResName ,False );
- f.WriteTerLine ( endChainID ,False );
- f.WriteTerLine ( endICode ,False );
- f.WriteTerLine ( curAtom ,False );
- f.WriteTerLine ( curResName ,False );
- f.WriteTerLine ( curChainID ,False );
- f.WriteTerLine ( curICode ,False );
- f.WriteTerLine ( prevAtom ,False );
- f.WriteTerLine ( prevResName,False );
- f.WriteTerLine ( prevChainID,False );
- f.WriteTerLine ( prevICode ,False );
-}
-
-void CStrand::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- f.ReadInt ( &initSeqNum );
- f.ReadInt ( &endSeqNum );
- f.ReadInt ( &sense );
- f.ReadInt ( &curResSeq );
- f.ReadInt ( &prevResSeq );
- f.ReadTerLine ( initResName,False );
- f.ReadTerLine ( initChainID,False );
- f.ReadTerLine ( initICode ,False );
- f.ReadTerLine ( endResName ,False );
- f.ReadTerLine ( endChainID ,False );
- f.ReadTerLine ( endICode ,False );
- f.ReadTerLine ( curAtom ,False );
- f.ReadTerLine ( curResName ,False );
- f.ReadTerLine ( curChainID ,False );
- f.ReadTerLine ( curICode ,False );
- f.ReadTerLine ( prevAtom ,False );
- f.ReadTerLine ( prevResName,False );
- f.ReadTerLine ( prevChainID,False );
- f.ReadTerLine ( prevICode ,False );
-}
-
-MakeStreamFunctions(CStrand)
-
-
-
-
-// ================ CSheet ===================
-
-CSheet::CSheet() : CStream() {
- InitSheet();
-}
-
-CSheet::CSheet ( RPCStream Object ) : CStream(Object) {
- InitSheet();
-}
-
-CSheet::~CSheet() {
- FreeMemory();
-}
-
-void CSheet::InitSheet() {
- nStrands = 0;
- sheetID[0] = char(0);
- Strand = NULL;
-}
-
-void CSheet::FreeMemory() {
-int i;
- if (Strand) {
- for (i=0;i<nStrands;i++)
- if (Strand[i]) delete Strand[i];
- delete[] Strand;
- Strand = NULL;
- }
- nStrands = 0;
- sheetID[0] = char(0);
-}
-
-void CSheet::PDBASCIIDump ( RCFile f ) {
-char S[100];
-int i;
- if (Strand)
- for (i=0;i<nStrands;i++)
- if (Strand[i]) {
- strcpy ( S,"SHEET" );
- PadSpaces ( S,80 );
- PutInteger ( &(S[7]) ,i+1 ,3 );
- strcpy_n1 ( &(S[11]),sheetID ,3 );
- PutInteger ( &(S[14]),nStrands,2 );
- Strand[i]->PDBASCIIDump ( S );
- f.WriteLine ( S );
- }
-}
-
-void CSheet::OrderSheet() {
-int i,k;
-PPCStrand Strand1;
- k = 0;
- for (i=0;i<nStrands;i++)
- if (Strand[i]) k++;
- if (k<nStrands) {
- Strand1 = new PCStrand[k];
- k = 0;
- for (i=0;i<nStrands;i++)
- if (Strand[i]) Strand1[k++] = Strand[i];
- if (Strand) delete[] Strand;
- Strand = Strand1;
- nStrands = k;
- }
-}
-
-void CSheet::MakeCIF ( PCMMCIFData CIF ) {
-PCMMCIFLoop Loop;
-int RC;
-int i;
-Boolean isSense;
-
- OrderSheet();
-
- RC = CIF->AddLoop ( CIFCAT_STRUCT_SHEET,Loop );
- if (RC!=CIFRC_Ok) {
- // the category was (re)created, provide tags
- Loop->AddLoopTag ( CIFTAG_SHEET_ID );
- Loop->AddLoopTag ( CIFTAG_NUMBER_STRANDS );
- }
- Loop->AddString ( sheetID );
- Loop->AddInteger ( nStrands );
-
- for (i=0;i<nStrands;i++) {
- Strand[i]->MakeCIF ( CIF );
- if (Strand[i]->sense!=0) isSense = True;
- }
-
- if (nStrands>1) {
-
- if (isSense) {
- RC = CIF->AddLoop ( CIFCAT_STRUCT_SHEET_ORDER,Loop );
- if (RC!=CIFRC_Ok) {
- // the category was (re)created, provide tags
- Loop->AddLoopTag ( CIFTAG_SHEET_ID );
- Loop->AddLoopTag ( CIFTAG_RANGE_ID_1 );
- Loop->AddLoopTag ( CIFTAG_RANGE_ID_2 );
- Loop->AddLoopTag ( CIFTAG_SENSE );
- }
- for (i=1;i<nStrands;i++) {
- Loop->AddString ( sheetID );
- Loop->AddInteger ( Strand[i-1]->strandNo );
- Loop->AddInteger ( Strand[i] ->strandNo );
- if (Strand[i]->sense>0)
- Loop->AddString ( pstr("parallel") );
- else Loop->AddString ( pstr("anti-parallel") );
- }
- }
-
- RC = CIF->AddLoop ( CIFCAT_STRUCT_SHEET_HBOND,Loop );
- if (RC!=CIFRC_Ok) {
- // the category was (re)created, provide tags
- Loop->AddLoopTag ( CIFTAG_SHEET_ID );
- Loop->AddLoopTag ( CIFTAG_RANGE_ID_1 );
- Loop->AddLoopTag ( CIFTAG_RANGE_ID_2 );
- Loop->AddLoopTag ( CIFTAG_RANGE_1_BEG_LABEL_ATOM_ID );
- Loop->AddLoopTag ( CIFTAG_NDB_RANGE_1_BEG_LABEL_COMP_ID );
- Loop->AddLoopTag ( CIFTAG_NDB_RANGE_1_BEG_LABEL_ASYM_ID );
- Loop->AddLoopTag ( CIFTAG_RANGE_1_BEG_LABEL_SEQ_ID );
- Loop->AddLoopTag ( CIFTAG_NDB_RANGE_1_BEG_LABEL_INS_CODE );
- Loop->AddLoopTag ( CIFTAG_RANGE_1_END_LABEL_ATOM_ID );
- Loop->AddLoopTag ( CIFTAG_NDB_RANGE_1_END_LABEL_COMP_ID );
- Loop->AddLoopTag ( CIFTAG_NDB_RANGE_1_END_LABEL_ASYM_ID );
- Loop->AddLoopTag ( CIFTAG_RANGE_1_END_LABEL_SEQ_ID );
- Loop->AddLoopTag ( CIFTAG_NDB_RANGE_1_END_LABEL_INS_CODE );
- }
- for (i=1;i<nStrands;i++) {
- Loop->AddString ( sheetID );
- Loop->AddInteger ( Strand[i-1]->strandNo );
- Loop->AddInteger ( Strand[i]->strandNo );
- Loop->AddString ( Strand[i]->curAtom );
- Loop->AddString ( Strand[i]->curResName );
- Loop->AddString ( Strand[i]->curChainID );
- Loop->AddInteger ( Strand[i]->curResSeq );
- Loop->AddString ( Strand[i]->curICode ,True );
- Loop->AddString ( Strand[i]->prevAtom );
- Loop->AddString ( Strand[i]->prevResName );
- Loop->AddString ( Strand[i]->prevChainID );
- Loop->AddInteger ( Strand[i]->prevResSeq );
- Loop->AddString ( Strand[i]->prevICode,True );
- }
- }
-
-}
-
-
-int CSheet::ConvertPDBASCII ( cpstr S ) {
-int i,k,ns;
-SheetID SID;
-PPCStrand Strand1;
-
- GetInteger ( k ,&(S[7]) ,3 );
- strcpy_ncss ( SID,&(S[11]),3 );
- GetInteger ( ns ,&(S[14]),2 );
-
-// if (!SID[0]) return Error_NoSheetID;
- if (!sheetID[0]) strcpy ( sheetID,SID );
- else if (strcmp(sheetID,SID))
- return Error_WrongSheetID;
-
- if (k<=0) return Error_WrongStrandNo;
-
- ns = IMax(k,ns);
- if (!Strand) {
- Strand = new PCStrand[ns];
- for (i=0;i<ns;i++)
- Strand[i] = NULL;
- } else if (ns>nStrands) {
- Strand1 = new PCStrand[ns];
- for (i=0;i<nStrands;i++)
- Strand1[i] = Strand[i];
- for (i=nStrands;i<ns;i++)
- Strand1[i] = NULL;
- if (Strand) delete[] Strand;
- Strand = Strand1;
- }
- nStrands = ns;
-
- k--;
- if (!Strand[k]) Strand[k] = new CStrand();
-
- return Strand[k]->ConvertPDBASCII ( S );
-
-}
-
-void CSheet::TryStrand ( int strand_no ) {
-int i,k;
-PPCStrand Strand1;
- k = -1;
- for (i=0;(i<nStrands) && (k<0);i++)
- if (Strand[i])
- if (Strand[i]->strandNo==strand_no) k = i;
- if (k<0) {
- Strand1 = new PCStrand[nStrands+1];
- for (i=0;i<nStrands;i++)
- Strand1[i] = Strand[i];
- if (Strand) delete[] Strand;
- Strand = Strand1;
- Strand[nStrands] = new CStrand();
- Strand[nStrands]->strandNo = strand_no;
- nStrands++;
- }
-}
-
-
-void CSheet::CIFFindStrands ( PCMMCIFData CIF, cpstr Category ) {
-// just look for all strands mentioned for the sheet
-PCMMCIFLoop Loop;
-pstr F;
-int RC,i,l,sNo;
- Loop = CIF->GetLoop ( Category );
- if (Loop) {
- l = Loop->GetLoopLength();
- for (i=0;i<l;i++) {
- F = Loop->GetString ( CIFTAG_SHEET_ID,i,RC );
- if (F && (!RC)) {
- if (!strcmp(F,sheetID)) {
- if (!Loop->GetInteger(sNo,CIFTAG_ID,i))
- TryStrand ( sNo );
- if (!Loop->GetInteger(sNo,CIFTAG_RANGE_ID_1,i))
- TryStrand ( sNo );
- if (!Loop->GetInteger(sNo,CIFTAG_RANGE_ID_2,i))
- TryStrand ( sNo );
- }
- }
- }
- }
-}
-
-int CSheet::GetStrand ( int strand_no ) {
-int i;
- for (i=0;i<nStrands;i++)
- if (Strand[i]) {
- if (Strand[i]->strandNo==strand_no)
- return i;
- }
- return -1;
-}
-
-int CSheet::GetCIF ( PCMMCIFData CIF ) {
-PCMMCIFLoop Loop;
-int i,ns,l,k,k2,RC,sNo;
-pstr F;
-ivector pair;
-Boolean Ok;
-
- pair = NULL;
-
- // First find all strands and create
- // the corresponding classes. The CIF fields
- // are not removed at this stage.
-
- CIFFindStrands ( CIF,CIFCAT_STRUCT_SHEET_ORDER );
- CIFFindStrands ( CIF,CIFCAT_STRUCT_SHEET_RANGE );
- CIFFindStrands ( CIF,CIFCAT_STRUCT_SHEET_HBOND );
-
- // Check number of strands
- Loop = CIF->GetLoop ( CIFCAT_STRUCT_SHEET );
- if (Loop) {
- l = Loop->GetLoopLength();
- i = 0;
- while (i<l) {
- F = Loop->GetString ( CIFTAG_SHEET_ID,i,RC );
- if (F && (!RC)) {
- if (!strcmp(F,sheetID)) {
- RC = CIFGetInteger1 ( ns,Loop,CIFTAG_NUMBER_STRANDS,i );
- if ((!RC) && (ns!=nStrands))
- return Error_WrongNumberOfStrands;
- Loop->DeleteRow ( i );
- i = l+100; // break loop
- }
- }
- i++;
- }
- }
-
- // Read each strand
- RC = 0;
- for (i=0;(i<nStrands) && (!RC);i++)
- RC = Strand[i]->GetCIF ( CIF,sheetID );
-
- if (RC) return RC;
-
- if (nStrands>1) {
-
- GetVectorMemory ( pair,nStrands,0 );
- for (i=0;i<nStrands;i++)
- pair[i] = -1;
-
- Loop = CIF->GetLoop ( CIFCAT_STRUCT_SHEET_ORDER );
- if (Loop) {
- Ok = True;
- l = Loop->GetLoopLength();
- for (i=0;(i<l) && Ok;i++) {
- F = Loop->GetString ( CIFTAG_SHEET_ID,i,RC );
- if (F && (!RC)) {
- if (!strcmp(F,sheetID)) {
- if (!Loop->GetInteger(sNo,CIFTAG_RANGE_ID_1,i)) {
- k = GetStrand ( sNo );
- if ((k>=0) &&
- (!Loop->GetInteger(sNo,CIFTAG_RANGE_ID_2,i))) {
- pair[k] = GetStrand ( sNo );
- if (pair[k]>=0) {
- F = Loop->GetString ( CIFTAG_SENSE,i,RC );
- if (F && (!RC)) {
- if (!strcasecmp(F,"anti-parallel"))
- Strand[pair[k]]->sense = -1;
- else if (!strcasecmp(F,"parallel"))
- Strand[pair[k]]->sense = 1;
- }
- Loop->DeleteRow ( i );
- } else
- Ok = False;
- } else
- Ok = False;
- } else
- Ok = False;
- }
- }
- }
- if (!Ok) {
- FreeVectorMemory ( pair,0 );
- return Error_WrongSheetOrder;
- }
- }
-
- Loop = CIF->GetLoop ( CIFCAT_STRUCT_SHEET_HBOND );
- if (Loop) {
- Ok = True;
- l = Loop->GetLoopLength();
- for (i=0;(i<l) && Ok;i++) {
- F = Loop->GetString ( CIFTAG_SHEET_ID,i,RC );
- if (F && (!RC)) {
- if (!strcmp(F,sheetID)) {
- if (!Loop->GetInteger(sNo,CIFTAG_RANGE_ID_1,i)) {
- k = GetStrand ( sNo );
- if ((k>=0) &&
- (!Loop->GetInteger(sNo,CIFTAG_RANGE_ID_1,i))) {
- k2 = GetStrand ( sNo );
- if (k2>=0) {
- if (pair[k]==k2) {
- CIFGetString ( Strand[k2]->curAtom,Loop,
- CIFTAG_RANGE_1_BEG_LABEL_ATOM_ID,
- i,sizeof(Strand[k2]->curAtom),
- pstr(" ") );
- CIFGetString ( Strand[k2]->curResName,Loop,
- CIFTAG_NDB_RANGE_1_BEG_LABEL_COMP_ID,
- i,sizeof(Strand[k2]->curResName),
- pstr(" ") );
- CIFGetString ( Strand[k2]->curChainID,Loop,
- CIFTAG_NDB_RANGE_1_BEG_LABEL_ASYM_ID,
- i,sizeof(Strand[k2]->curChainID),
- pstr(" ") );
- if (CIFGetInteger(Strand[k2]->curResSeq,Loop,
- CIFTAG_RANGE_1_BEG_LABEL_SEQ_ID,i)) {
- FreeVectorMemory ( pair,0 );
- return i;
- }
- CIFGetString ( Strand[k2]->curICode,Loop,
- CIFTAG_NDB_RANGE_1_BEG_LABEL_INS_CODE,
- i,sizeof(Strand[k2]->curICode),
- pstr(" ") );
- CIFGetString ( Strand[k2]->prevAtom,Loop,
- CIFTAG_RANGE_1_END_LABEL_ATOM_ID,
- i,sizeof(Strand[k2]->prevAtom),
- pstr(" ") );
- CIFGetString ( Strand[k2]->prevResName,Loop,
- CIFTAG_NDB_RANGE_1_END_LABEL_COMP_ID,
- i,sizeof(Strand[k2]->prevResName),
- pstr(" ") );
- CIFGetString ( Strand[k2]->prevChainID,Loop,
- CIFTAG_NDB_RANGE_1_END_LABEL_ASYM_ID,
- i,sizeof(Strand[k2]->prevChainID),
- pstr(" ") );
- if (CIFGetInteger(Strand[k2]->prevResSeq,Loop,
- CIFTAG_RANGE_1_END_LABEL_SEQ_ID,i)) {
- FreeVectorMemory ( pair,0 );
- return i;
- }
- CIFGetString ( Strand[k2]->prevICode,Loop,
- CIFTAG_NDB_RANGE_1_END_LABEL_INS_CODE,
- i,sizeof(Strand[k2]->prevICode),
- pstr(" ") );
- Loop->DeleteRow ( i );
- } else
- Ok = False;
- } else
- Ok = False;
- } else
- Ok = False;
- } else
- Ok = False;
- }
- }
- }
- if (!Ok) {
- FreeVectorMemory ( pair,0 );
- return Error_HBondInconsistency;
- }
- }
- }
-
- FreeVectorMemory ( pair,0 );
-
- return 0;
-
-}
-
-
-void CSheet::Copy ( PCSheet Sheet ) {
-int i;
- FreeMemory();
- nStrands = Sheet->nStrands;
- if (nStrands>0) {
- Strand = new PCStrand[nStrands];
- for (i=0;i<nStrands;i++)
- if (Sheet->Strand[i]) {
- Strand[i] = new CStrand();
- Strand[i]->Copy ( Sheet->Strand[i] );
- } else
- Strand[i] = NULL;
- }
- strcpy ( sheetID,Sheet->sheetID );
-}
-
-void CSheet::write ( RCFile f ) {
-int i;
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &nStrands );
- for (i=0;i<nStrands;i++)
- StreamWrite ( f,Strand[i] );
- f.WriteTerLine ( sheetID,False );
-}
-
-void CSheet::read ( RCFile f ) {
-int i;
-byte Version;
- FreeMemory();
- f.ReadByte ( &Version );
- f.ReadInt ( &nStrands );
- if (nStrands>0) {
- Strand = new PCStrand[nStrands];
- for (i=0;i<nStrands;i++) {
- Strand[i] = NULL;
- StreamRead ( f,Strand[i] );
- }
- }
- f.ReadTerLine ( sheetID,False );
-}
-
-MakeStreamFunctions(CSheet)
-
-
-
-// ==================== CSheets ============================
-
-
-CSheets::CSheets() : CStream() {
- InitSheets();
-}
-
-
-CSheets::CSheets ( RPCStream Object ) : CStream ( Object ) {
- InitSheets();
-}
-
-
-CSheets::~CSheets() {
- FreeMemory();
-}
-
-
-void CSheets::InitSheets() {
- nSheets = 0;
- Sheet = NULL;
-}
-
-
-void CSheets::FreeMemory() {
-int i;
- if (Sheet) {
- for (i=0;i<nSheets;i++)
- if (Sheet[i]) delete Sheet[i];
- delete[] Sheet;
- Sheet = NULL;
- }
- nSheets = 0;
-}
-
-
-void CSheets::PDBASCIIDump ( RCFile f ) {
-int i;
- if (Sheet)
- for (i=0;i<nSheets;i++)
- if (Sheet[i]) Sheet[i]->PDBASCIIDump ( f );
-}
-
-
-void CSheets::MakeCIF ( PCMMCIFData CIF ) {
-int i;
- if (Sheet)
- for (i=0;i<nSheets;i++)
- if (Sheet[i]) Sheet[i]->MakeCIF ( CIF );
-}
-
-
-int CSheets::ConvertPDBASCII ( cpstr S ) {
-SheetID sheetID;
-int i,k;
-PPCSheet Sheet1;
- strcpy_ncss ( sheetID,&(S[11]),3 );
- // if (!sheetID[0]) return Error_NoSheetID;
- k = -1;
- for (i=0;i<nSheets;i++)
- if (Sheet[i]) {
- if (!strcmp(sheetID,Sheet[i]->sheetID)) {
- k = i;
- break;
- }
- }
- if (k<0) {
- Sheet1 = new PCSheet[nSheets+1];
- for (i=0;i<nSheets;i++)
- Sheet1[i] = Sheet[i];
- if (Sheet) delete[] Sheet;
- Sheet = Sheet1;
- Sheet[nSheets] = new CSheet();
- k = nSheets;
- nSheets++;
- }
- return Sheet[k]->ConvertPDBASCII ( S );
-}
-
-
-void CSheets::CIFFindSheets ( PCMMCIFData CIF, cpstr Category ) {
-PCMMCIFLoop Loop;
-int RC,i,j,k,l;
-pstr F;
-PPCSheet Sheet1;
- Loop = CIF->GetLoop ( Category );
- if (Loop) {
- l = Loop->GetLoopLength();
- for (i=0;i<l;i++) {
- F = Loop->GetString ( CIFTAG_SHEET_ID,i,RC );
- if (F && (!RC)) {
- k = -1;
- j = 0;
- while ((j<nSheets) && (k<0)) {
- if (Sheet[j]) {
- if (!strcmp(F,Sheet[j]->sheetID)) k = j;
- }
- j++;
- }
- if (k<0) {
- Sheet1 = new PCSheet[nSheets+1];
- for (i=0;i<nSheets;i++)
- Sheet1[i] = Sheet[i];
- if (Sheet) delete[] Sheet;
- Sheet = Sheet1;
- Sheet[nSheets] = new CSheet();
- strcpy ( Sheet[nSheets]->sheetID,F );
- nSheets++;
- }
- }
- }
- }
-}
-
-int CSheets::GetCIF ( PCMMCIFData CIF ) {
-int i,RC;
-
- FreeMemory();
-
- // First find all sheet names and create
- // the corresponding classes. The CIF fields
- // are not removed at this stage.
-
- CIFFindSheets ( CIF,CIFCAT_STRUCT_SHEET );
- CIFFindSheets ( CIF,CIFCAT_STRUCT_SHEET_ORDER );
- CIFFindSheets ( CIF,CIFCAT_STRUCT_SHEET_RANGE );
- CIFFindSheets ( CIF,CIFCAT_STRUCT_SHEET_HBOND );
-
- // Read each sheet
- i = 0;
- RC = 0;
- while ((i<nSheets) && (!RC)) {
- RC = Sheet[i]->GetCIF ( CIF );
- i++;
- }
-
- return RC;
-
-}
-
-
-void CSheets::Copy ( PCSheets Sheets ) {
-int i;
- FreeMemory();
- if (Sheets->nSheets>0) {
- nSheets = Sheets->nSheets;
- Sheet = new PCSheet[nSheets];
- for (i=0;i<nSheets;i++)
- if (Sheets->Sheet[i]) {
- Sheet[i] = new CSheet();
- Sheet[i]->Copy ( Sheets->Sheet[i] );
- } else
- Sheet[i] = NULL;
- }
-}
-
-
-void CSheets::write ( RCFile f ) {
-int i;
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &nSheets );
- for (i=0;i<nSheets;i++)
- StreamWrite ( f,Sheet[i] );
-}
-
-
-void CSheets::read ( RCFile f ) {
-int i;
-byte Version;
- FreeMemory();
- f.ReadByte ( &Version );
- f.ReadInt ( &nSheets );
- if (nSheets>0) {
- Sheet = new PCSheet[nSheets];
- for (i=0;i<nSheets;i++) {
- Sheet[i] = NULL;
- StreamRead ( f,Sheet[i] );
- }
- }
-}
-
-
-MakeStreamFunctions(CSheets)
-
-
-
-// ================ CTurn ===================
-
-CTurn::CTurn() : CContainerClass() {
- InitTurn();
-}
-
-CTurn::CTurn ( cpstr S ) : CContainerClass() {
- InitTurn();
- ConvertPDBASCII ( S );
-}
-
-CTurn::CTurn ( RPCStream Object ) : CContainerClass(Object) {
- InitTurn();
-}
-
-CTurn::~CTurn() {
- if (comment) delete[] comment;
-}
-
-void CTurn::InitTurn() {
- serNum = 0; // serial number
- strcpy ( turnID ,"---" ); // turn ID
- strcpy ( initResName,"---" ); // name of the turn's initial residue
- strcpy ( initChainID," " ); // chain ID for the chain
- // containing the turn
- initSeqNum = 0; // sequence number of the initial
- // residue
- strcpy ( initICode ," " ); // insertion code of the initial
- // residue
- strcpy ( endResName ,"---" ); // name of the turn's terminal residue
- strcpy ( endChainID ," " ); // chain ID for the chain
- // containing the turn
- endSeqNum = 0; // sequence number of the terminal
- // residue
- strcpy ( endICode ," " ); // insertion code of the terminal
- // residue
- comment = NULL; // comment about the helix
-}
-
-void CTurn::PDBASCIIDump ( pstr S, int N ) {
-UNUSED_ARGUMENT(N);
-// makes the ASCII PDB OBSLTE line number N
-// from the class' data
- strcpy ( S,"TURN" );
- PadSpaces ( S,80 );
- PutInteger ( &(S[7]) ,serNum ,3 );
- strcpy_n1 ( &(S[11]),turnID ,3 );
- strcpy_n1 ( &(S[15]),initResName,3 );
- strcpy_n1 ( &(S[19]),initChainID,1 );
- PutIntIns ( &(S[20]),initSeqNum ,4,initICode );
- strcpy_n1 ( &(S[26]),endResName ,3 );
- strcpy_n1 ( &(S[30]),endChainID ,1 );
- PutIntIns ( &(S[31]),endSeqNum ,4,endICode );
- if (comment)
- strcpy_n ( &(S[40]),comment ,30 );
-}
-
-
-#define TurnTypeID "TURN_P"
-
-void CTurn::MakeCIF ( PCMMCIFData CIF, int N ) {
-UNUSED_ARGUMENT(N);
-PCMMCIFLoop Loop;
-int RC;
- RC = CIF->AddLoop ( CIFCAT_STRUCT_CONF,Loop );
- if (RC!=CIFRC_Ok)
- // the category was (re)created, provide tags
- AddStructConfTags ( Loop );
- Loop->AddString ( pstr(TurnTypeID) );
- Loop->AddInteger ( serNum );
- Loop->AddString ( turnID );
- Loop->AddString ( initResName );
- Loop->AddString ( initChainID );
- Loop->AddInteger ( initSeqNum );
- Loop->AddString ( initICode,True );
- Loop->AddString ( endResName );
- Loop->AddString ( endChainID );
- Loop->AddInteger ( endSeqNum );
- Loop->AddString ( endICode ,True );
- Loop->AddNoData ( CIF_NODATA_QUESTION );
- Loop->AddString ( comment );
- Loop->AddNoData ( CIF_NODATA_QUESTION );
-}
-
-int CTurn::ConvertPDBASCII ( cpstr S ) {
-char L[100];
- GetInteger ( serNum ,&(S[7]) ,3 );
- strcpy_ncss ( turnID ,&(S[11]),3 );
- strcpy_ncss ( initResName,&(S[15]),3 );
- strcpy_ncss ( initChainID,&(S[19]),1 );
- GetIntIns ( initSeqNum,initICode,&(S[20]),4 );
- strcpy_ncss ( endResName ,&(S[26]),3 );
- strcpy_ncss ( endChainID ,&(S[30]),1 );
- GetIntIns ( endSeqNum ,endICode ,&(S[31]),4 );
- strcpy_ncss ( L ,&(S[40]),30 );
- CreateCopy ( comment ,L );
- return 0;
-}
-
-void CTurn::GetCIF ( PCMMCIFData CIF, int & Signal ) {
-PCMMCIFLoop Loop;
-int RC,l;
-pstr F;
-Boolean Done;
-
- Loop = CIF->GetLoop ( CIFCAT_STRUCT_CONF );
- if (!Loop) {
- Signal = -1; // signal to finish processing of this structure
- return;
- }
-
- l = Loop->GetLoopLength();
- Done = Signal>=l;
- while (!Done) {
- F = Loop->GetString ( CIFTAG_CONF_TYPE_ID,Signal,RC );
- if ((!RC) && F) Done = (strcmp(F,TurnTypeID)==0);
- else Done = False;
- if (!Done) {
- Signal++;
- Done = Signal>=l;
- }
- }
-
- if (Signal>=l) {
- Signal = -1; // finish processing of Turn
- return;
- }
-
- Loop->DeleteField ( CIFTAG_CONF_TYPE_ID,Signal );
-
- if (CIFGetInteger(serNum,Loop,CIFTAG_ID,Signal)) return;
-
-
- CIFGetString ( turnID,Loop,CIFTAG_PDB_ID,Signal,
- sizeof(turnID),pstr(" ") );
-
- CIFGetString ( initResName,Loop,CIFTAG_BEG_LABEL_COMP_ID,
- Signal,sizeof(initResName),pstr(" ") );
- CIFGetString ( initChainID,Loop,CIFTAG_BEG_LABEL_ASYM_ID,
- Signal,sizeof(initChainID),pstr(" ") );
- CIFGetString ( initICode ,Loop,CIFTAG_NDB_BEG_LABEL_INS_CODE_PDB,
- Signal,sizeof(initICode),pstr(" ") );
- if (CIFGetInteger(initSeqNum,Loop,CIFTAG_BEG_LABEL_SEQ_ID,Signal))
- return;
-
- CIFGetString ( endResName,Loop,CIFTAG_END_LABEL_COMP_ID,
- Signal,sizeof(endResName),pstr(" ") );
- CIFGetString ( endChainID,Loop,CIFTAG_END_LABEL_ASYM_ID,
- Signal,sizeof(endChainID),pstr(" ") );
- CIFGetString ( endICode ,Loop,CIFTAG_NDB_END_LABEL_INS_CODE_PDB,
- Signal,sizeof(endICode),pstr(" ") );
- if (CIFGetInteger(endSeqNum,Loop,CIFTAG_END_LABEL_SEQ_ID,Signal))
- return;
-
- CreateCopy ( comment,Loop->GetString(CIFTAG_DETAILS,Signal,RC));
- Loop->DeleteField ( CIFTAG_DETAILS,Signal );
-
- Signal++;
-
-}
-
-void CTurn::Copy ( PCContainerClass Turn ) {
- serNum = PCTurn(Turn)->serNum;
- initSeqNum = PCTurn(Turn)->initSeqNum;
- endSeqNum = PCTurn(Turn)->endSeqNum;
- strcpy ( turnID ,PCTurn(Turn)->turnID );
- strcpy ( initResName,PCTurn(Turn)->initResName );
- strcpy ( initChainID,PCTurn(Turn)->initChainID );
- strcpy ( initICode ,PCTurn(Turn)->initICode );
- strcpy ( endResName ,PCTurn(Turn)->endResName );
- strcpy ( endChainID ,PCTurn(Turn)->endChainID );
- strcpy ( endICode ,PCTurn(Turn)->endICode );
- CreateCopy ( comment,PCTurn(Turn)->comment );
-}
-
-void CTurn::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &serNum );
- f.WriteInt ( &initSeqNum );
- f.WriteInt ( &endSeqNum );
- f.WriteTerLine ( turnID ,False );
- f.WriteTerLine ( initResName,False );
- f.WriteTerLine ( initChainID,False );
- f.WriteTerLine ( initICode ,False );
- f.WriteTerLine ( endResName ,False );
- f.WriteTerLine ( endChainID ,False );
- f.WriteTerLine ( endICode ,False );
- f.CreateWrite ( comment );
-}
-
-void CTurn::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- f.ReadInt ( &serNum );
- f.ReadInt ( &initSeqNum );
- f.ReadInt ( &endSeqNum );
- f.ReadTerLine ( turnID ,False );
- f.ReadTerLine ( initResName,False );
- f.ReadTerLine ( initChainID,False );
- f.ReadTerLine ( initICode ,False );
- f.ReadTerLine ( endResName ,False );
- f.ReadTerLine ( endChainID ,False );
- f.ReadTerLine ( endICode ,False );
- f.CreateRead ( comment );
-}
-
-MakeStreamFunctions(CTurn)
-
-
-// =================== CLinkContainer ========================
-
-PCContainerClass CLinkContainer::MakeContainerClass ( int ClassID ) {
- switch (ClassID) {
- default :
- case ClassID_Template : return
- CClassContainer::MakeContainerClass(ClassID);
- case ClassID_Link : return new CLink();
- }
-}
-
-MakeStreamFunctions(CLinkContainer)
-
-
-
-// ======================== CLink ===========================
-
-CLink::CLink() : CContainerClass() {
- InitLink();
-}
-
-CLink::CLink ( cpstr S ) : CContainerClass() {
- InitLink();
- ConvertPDBASCII ( S );
-}
-
-CLink::CLink ( RPCStream Object ) : CContainerClass(Object) {
- InitLink();
-}
-
-CLink::~CLink() {}
-
-void CLink::InitLink() {
- strcpy ( atName1 ,"----" ); // name of 1st linked atom
- strcpy ( aloc1 ," " ); // alternative location of 1st atom
- strcpy ( resName1,"---" ); // residue name of 1st linked atom
- strcpy ( chainID1," " ); // chain ID of 1st linked atom
- seqNum1 = 0; // sequence number of 1st linked atom
- strcpy ( insCode1," " ); // insertion code of 1st linked atom
- strcpy ( atName2 ,"----" ); // name of 2nd linked atom
- strcpy ( aloc2 ," " ); // alternative location of 2nd atom
- strcpy ( resName2,"---" ); // residue name of 2nd linked atom
- strcpy ( chainID2," " ); // chain ID of 2nd linked atom
- seqNum2 = 0; // sequence number of 2nd linked atom
- strcpy ( insCode2," " ); // insertion code of 2nd linked atom
- s1 = 1; // sym id of 1st atom
- i1 = 5;
- j1 = 5;
- k1 = 5;
- s2 = 1; // sym id of 2nd atom
- i2 = 5;
- j2 = 5;
- k2 = 5;
-}
-
-
-void CLink::PDBASCIIDump ( pstr S, int N ) {
-UNUSED_ARGUMENT(N);
-// makes the ASCII PDB OBSLTE line number N
-// from the class' data
-
- strcpy ( S,"LINK" );
- PadSpaces ( S,80 );
-
- strcpy_n1 ( &(S[12]),atName1 ,4 );
- strcpy_n1 ( &(S[16]),aloc1 ,1 );
- strcpy_n1 ( &(S[17]),resName1,3 );
- strcpy_n1 ( &(S[21]),chainID1,1 );
- PutIntIns ( &(S[22]),seqNum1 ,4,insCode1 );
-
- strcpy_n1 ( &(S[42]),atName2 ,4 );
- strcpy_n1 ( &(S[46]),aloc2 ,1 );
- strcpy_n1 ( &(S[47]),resName2,3 );
- strcpy_n1 ( &(S[51]),chainID2,1 );
- PutIntIns ( &(S[52]),seqNum2 ,4,insCode2 );
-
- PutInteger ( &(S[59]),s1,3 );
- PutInteger ( &(S[62]),i1,1 );
- PutInteger ( &(S[63]),j1,1 );
- PutInteger ( &(S[64]),k1,1 );
-
- PutInteger ( &(S[66]),s2,3 );
- PutInteger ( &(S[69]),i2,1 );
- PutInteger ( &(S[70]),j2,1 );
- PutInteger ( &(S[71]),k2,1 );
-
-}
-
-
-#define LinkTypeID "LINK"
-
-void AddStructConnTags ( PCMMCIFLoop Loop ) {
-
- Loop->AddLoopTag ( CIFTAG_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_TYPE_ID );
-
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_AUTH_ATOM_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PDBX_PTNR1_AUTH_ALT_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_AUTH_COMP_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_AUTH_ASYM_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_AUTH_SEQ_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PDBX_PTNR1_PDB_INS_CODE );
-
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_AUTH_ATOM_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PDBX_PTNR2_AUTH_ALT_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_AUTH_COMP_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_AUTH_ASYM_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_AUTH_SEQ_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PDBX_PTNR2_PDB_INS_CODE );
-
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_SYMMETRY );
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_SYMMETRY );
-
-}
-
-
-void CLink::MakeCIF ( PCMMCIFData CIF, int N ) {
-UNUSED_ARGUMENT(N);
-PCMMCIFLoop Loop;
-char S[100];
-int RC;
-
- RC = CIF->AddLoop ( CIFCAT_STRUCT_CONN,Loop );
- if (RC!=CIFRC_Ok) // the category was (re)created, provide tags
- AddStructConnTags ( Loop );
-
- Loop->AddString ( "1" ); // should be a counter
- Loop->AddString ( pstr(LinkTypeID) );
-
- Loop->AddString ( atName1 );
- Loop->AddString ( aloc1 );
- Loop->AddString ( resName1 );
- Loop->AddString ( chainID1 );
- Loop->AddInteger ( seqNum1 );
- Loop->AddString ( insCode1 );
-
- Loop->AddString ( atName2 );
- Loop->AddString ( aloc2 );
- Loop->AddString ( resName2 );
- Loop->AddString ( chainID2 );
- Loop->AddInteger ( seqNum2 );
- Loop->AddString ( insCode2 );
-
- sprintf ( S,"%i%i%i%i",s1,i1,j1,k1 );
- Loop->AddString ( S );
- sprintf ( S,"%i%i%i%i",s2,i2,j2,k2 );
- Loop->AddString ( S );
-
-}
-
-int CLink::ConvertPDBASCII ( cpstr S ) {
-
- GetString ( atName1 ,&(S[12]),4 );
- strcpy_ncss ( aloc1 ,&(S[16]),1 );
- strcpy_ncss ( resName1,&(S[17]),3 );
- strcpy_ncss ( chainID1,&(S[21]),1 );
- GetIntIns ( seqNum1,insCode1,&(S[22]),4 );
-
- GetString ( atName2 ,&(S[42]),4 );
- strcpy_ncss ( aloc2 ,&(S[46]),1 );
- strcpy_ncss ( resName2,&(S[47]),3 );
- strcpy_ncss ( chainID2,&(S[51]),1 );
- GetIntIns ( seqNum2,insCode2,&(S[52]),4 );
-
- GetInteger ( s1,&(S[59]),3 );
- GetInteger ( i1,&(S[62]),1 );
- GetInteger ( j1,&(S[63]),1 );
- GetInteger ( k1,&(S[64]),1 );
-
- GetInteger ( s2,&(S[66]),3 );
- GetInteger ( i2,&(S[69]),1 );
- GetInteger ( j2,&(S[70]),1 );
- GetInteger ( k2,&(S[71]),1 );
-
- return 0;
-
-}
-
-void CLink::GetCIF ( PCMMCIFData CIF, int & Signal ) {
-PCMMCIFLoop Loop;
-pstr F;
-char S[100];
-int RC,l;
-Boolean Done;
-
- Loop = CIF->GetLoop ( CIFCAT_STRUCT_CONN );
- if (!Loop) {
- Signal = -1; // signal to finish processing of this structure
- return;
- }
-
- l = Loop->GetLoopLength();
- Done = (Signal>=l);
- while (!Done) {
- F = Loop->GetString ( CIFTAG_CONN_TYPE_ID,Signal,RC );
- if ((!RC) && F) Done = (strcmp(F,LinkTypeID)==0);
- else Done = False;
- if (!Done) {
- Signal++;
- Done = (Signal>=l);
- }
- }
-
- if (Signal>=l) {
- Signal = -1; // finish processing of Turn
- return;
- }
-
- Loop->DeleteField ( CIFTAG_CONN_TYPE_ID,Signal );
-
-// CIFGetInteger ( l,Loop,CIFTAG_ID,Signal );
-
- CIFGetString ( atName1,Loop,CIFTAG_CONN_PTNR1_AUTH_ATOM_ID,Signal,
- sizeof(atName1),pstr(" ") );
- CIFGetString ( aloc1,Loop,CIFTAG_CONN_PDBX_PTNR1_AUTH_ALT_ID,Signal,
- sizeof(aloc1),pstr(" ") );
- CIFGetString ( resName1,Loop,CIFTAG_CONN_PTNR1_AUTH_COMP_ID,Signal,
- sizeof(resName1),pstr(" ") );
- CIFGetString ( chainID1,Loop,CIFTAG_CONN_PTNR1_AUTH_ASYM_ID,Signal,
- sizeof(chainID1),pstr(" ") );
- if (CIFGetInteger(seqNum1,Loop,CIFTAG_CONN_PTNR1_AUTH_SEQ_ID,Signal))
- return;
- CIFGetString ( insCode1,Loop,CIFTAG_CONN_PDBX_PTNR1_PDB_INS_CODE,
- Signal,sizeof(insCode1),pstr(" ") );
-
- CIFGetString ( atName2,Loop,CIFTAG_CONN_PTNR2_AUTH_ATOM_ID,Signal,
- sizeof(atName2),pstr(" ") );
- CIFGetString ( aloc2,Loop,CIFTAG_CONN_PDBX_PTNR2_AUTH_ALT_ID,Signal,
- sizeof(aloc2),pstr(" ") );
- CIFGetString ( resName2,Loop,CIFTAG_CONN_PTNR2_AUTH_COMP_ID,Signal,
- sizeof(resName2),pstr(" ") );
- CIFGetString ( chainID2,Loop,CIFTAG_CONN_PTNR2_AUTH_ASYM_ID,Signal,
- sizeof(chainID2),pstr(" ") );
- if (CIFGetInteger(seqNum2,Loop,CIFTAG_CONN_PTNR2_AUTH_SEQ_ID,Signal))
- return;
- CIFGetString ( insCode2,Loop,CIFTAG_CONN_PDBX_PTNR2_PDB_INS_CODE,
- Signal,sizeof(insCode2),pstr(" ") );
-
- CIFGetString ( S,Loop,CIFTAG_CONN_PTNR1_SYMMETRY,Signal,
- sizeof(S),pstr("") );
- if (S[0]) {
- l = strlen(S)-1;
- k1 = int(S[l--]) - int('0');
- j1 = int(S[l--]) - int('0');
- i1 = int(S[l--]) - int('0');
- S[l] = char(0);
- s1 = atoi(S);
- }
-
- CIFGetString ( S,Loop,CIFTAG_CONN_PTNR2_SYMMETRY,Signal,
- sizeof(S),pstr("") );
- if (S[0]) {
- l = strlen(S)-1;
- k2 = int(S[l--]) - int('0');
- j2 = int(S[l--]) - int('0');
- i2 = int(S[l--]) - int('0');
- S[l] = char(0);
- s2 = atoi(S);
- }
-
- Signal++;
-
-}
-
-void CLink::Copy ( PCContainerClass Link ) {
-
- strcpy ( atName1 ,PCLink(Link)->atName1 );
- strcpy ( aloc1 ,PCLink(Link)->aloc1 );
- strcpy ( resName1,PCLink(Link)->resName1 );
- strcpy ( chainID1,PCLink(Link)->chainID1 );
- seqNum1 = PCLink(Link)->seqNum1;
- strcpy ( insCode1,PCLink(Link)->insCode1 );
-
- strcpy ( atName2 ,PCLink(Link)->atName2 );
- strcpy ( aloc2 ,PCLink(Link)->aloc2 );
- strcpy ( resName2,PCLink(Link)->resName2 );
- strcpy ( chainID2,PCLink(Link)->chainID2 );
- seqNum2 = PCLink(Link)->seqNum2;
- strcpy ( insCode2,PCLink(Link)->insCode2 );
-
- s1 = PCLink(Link)->s1;
- i1 = PCLink(Link)->i1;
- j1 = PCLink(Link)->j1;
- k1 = PCLink(Link)->k1;
-
- s2 = PCLink(Link)->s2;
- i2 = PCLink(Link)->i2;
- j2 = PCLink(Link)->j2;
- k2 = PCLink(Link)->k2;
-
-}
-
-void CLink::write ( RCFile f ) {
-byte Version=1;
-
- f.WriteByte ( &Version );
-
- f.WriteTerLine ( atName1 ,False );
- f.WriteTerLine ( aloc1 ,False );
- f.WriteTerLine ( resName1,False );
- f.WriteTerLine ( chainID1,False );
- f.WriteInt ( &seqNum1 );
- f.WriteTerLine ( insCode1,False );
-
- f.WriteTerLine ( atName2 ,False );
- f.WriteTerLine ( aloc2 ,False );
- f.WriteTerLine ( resName2,False );
- f.WriteTerLine ( chainID2,False );
- f.WriteInt ( &seqNum2 );
- f.WriteTerLine ( insCode2,False );
-
- f.WriteInt ( &s1 );
- f.WriteInt ( &i1 );
- f.WriteInt ( &j1 );
- f.WriteInt ( &k1 );
-
- f.WriteInt ( &s2 );
- f.WriteInt ( &i2 );
- f.WriteInt ( &j2 );
- f.WriteInt ( &k2 );
-
-}
-
-void CLink::read ( RCFile f ) {
-byte Version;
-
- f.ReadByte ( &Version );
-
- f.ReadTerLine ( atName1 ,False );
- f.ReadTerLine ( aloc1 ,False );
- f.ReadTerLine ( resName1,False );
- f.ReadTerLine ( chainID1,False );
- f.ReadInt ( &seqNum1 );
- f.ReadTerLine ( insCode1,False );
-
- f.ReadTerLine ( atName2 ,False );
- f.ReadTerLine ( aloc2 ,False );
- f.ReadTerLine ( resName2,False );
- f.ReadTerLine ( chainID2,False );
- f.ReadInt ( &seqNum2 );
- f.ReadTerLine ( insCode2,False );
-
- f.ReadInt ( &s1 );
- f.ReadInt ( &i1 );
- f.ReadInt ( &j1 );
- f.ReadInt ( &k1 );
-
- f.ReadInt ( &s2 );
- f.ReadInt ( &i2 );
- f.ReadInt ( &j2 );
- f.ReadInt ( &k2 );
-
-}
-
-MakeStreamFunctions(CLink)
-
-
-// =================== CLinkRContainer =======================
-
-PCContainerClass CLinkRContainer::MakeContainerClass ( int ClassID ) {
- switch (ClassID) {
- default :
- case ClassID_Template : return
- CClassContainer::MakeContainerClass(ClassID);
- case ClassID_LinkR : return new CLinkR();
- }
-}
-
-MakeStreamFunctions(CLinkRContainer)
-
-
-// ======================== CLinkR ===========================
-
-CLinkR::CLinkR() : CContainerClass() {
- InitLinkR();
-}
-
-CLinkR::CLinkR ( cpstr S ) : CContainerClass() {
- InitLinkR();
- ConvertPDBASCII ( S );
-}
-
-CLinkR::CLinkR ( RPCStream Object ) : CContainerClass(Object) {
- InitLinkR();
-}
-
-CLinkR::~CLinkR() {}
-
-void CLinkR::InitLinkR() {
- strcpy ( linkRID ,"----" ); // link name
- strcpy ( atName1 ,"----" ); // name of 1st linked atom
- strcpy ( aloc1 ," " ); // alternative location of 1st atom
- strcpy ( resName1,"---" ); // residue name of 1st linked atom
- strcpy ( chainID1," " ); // chain ID of 1st linked atom
- seqNum1 = 0; // sequence number of 1st linked atom
- strcpy ( insCode1," " ); // insertion code of 1st linked atom
- strcpy ( atName2 ,"----" ); // name of 2nd linked atom
- strcpy ( aloc2 ," " ); // alternative location of 2nd atom
- strcpy ( resName2,"---" ); // residue name of 2nd linked atom
- strcpy ( chainID2," " ); // chain ID of 2nd linked atom
- seqNum2 = 0; // sequence number of 2nd linked atom
- strcpy ( insCode2," " ); // insertion code of 2nd linked atom
- dist = 0.0; // link distance
-}
-
-/*
-LINK LYS A 27 PLP A 255 PLPLYS
-LINK MAN S 3 MAN S 4 BETA1-4
-LINK C6 BBEN B 1 O1 BMAF S 2 BEN-MAF
-LINK OE2 AGLU A 320 C1 AMAF S 2 GLU-MAF
-LINK OE2 GLU A 67 1.895 ZN ZN R 5 GLU-ZN
-LINK NE2 HIS A 71 2.055 ZN ZN R 5 HIS-ZN
-LINK O ARG A 69 2.240 NA NA R 9 ARG-NA
-012345678901234567890123456789012345678901234567890123456789012345678901234567890
- 1 2 3 4 5 6 7
-*/
-
-void CLinkR::PDBASCIIDump ( pstr S, int N ) {
-UNUSED_ARGUMENT(N);
-// makes the ASCII PDB OBSLTE line number N
-// from the class' data
-
- strcpy ( S,"LINKR" );
- PadSpaces ( S,80 );
-
- strcpy_n1 ( &(S[12]),atName1 ,4 );
- strcpy_n1 ( &(S[16]),aloc1 ,1 );
- strcpy_n1 ( &(S[17]),resName1,3 );
- strcpy_n1 ( &(S[21]),chainID1,1 );
- PutIntIns ( &(S[22]),seqNum1 ,4,insCode1 );
-
- if (dist>0.0)
- PutRealF ( &(S[32]),dist,7,3 );
-
- strcpy_n1 ( &(S[42]),atName2 ,4 );
- strcpy_n1 ( &(S[46]),aloc2 ,1 );
- strcpy_n1 ( &(S[47]),resName2,3 );
- strcpy_n1 ( &(S[51]),chainID2,1 );
- PutIntIns ( &(S[52]),seqNum2 ,4,insCode2 );
-
- strcpy_ns ( &(S[72]),linkRID,8 );
-
-}
-
-
-#define LinkRTypeID "LINKR"
-
-void AddStructConnLinkRTags ( PCMMCIFLoop Loop ) {
-
- Loop->AddLoopTag ( CIFTAG_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_TYPE_ID );
-
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_AUTH_ATOM_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PDBX_PTNR1_AUTH_ALT_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_AUTH_COMP_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_AUTH_ASYM_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_AUTH_SEQ_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PDBX_PTNR1_PDB_INS_CODE );
-
- Loop->AddLoopTag ( CIFTAG_CONN_DIST );
-
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_AUTH_ATOM_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PDBX_PTNR2_AUTH_ALT_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_AUTH_COMP_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_AUTH_ASYM_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_AUTH_SEQ_ID );
- Loop->AddLoopTag ( CIFTAG_CONN_PDBX_PTNR2_PDB_INS_CODE );
-
- Loop->AddLoopTag ( CIFTAG_CONN_NAME );
-
-}
-
-void CLinkR::MakeCIF ( PCMMCIFData CIF, int N ) {
-UNUSED_ARGUMENT(N);
-PCMMCIFLoop Loop;
-int RC;
-
- RC = CIF->AddLoop ( CIFCAT_STRUCT_LINKR,Loop );
- if (RC!=CIFRC_Ok) // the category was (re)created, provide tags
- AddStructConnLinkRTags ( Loop );
-
- Loop->AddString ( "1" ); // should be a counter
- Loop->AddString ( pstr(LinkTypeID) );
-
- Loop->AddString ( atName1 );
- Loop->AddString ( aloc1 );
- Loop->AddString ( resName1 );
- Loop->AddString ( chainID1 );
- Loop->AddInteger ( seqNum1 );
- Loop->AddString ( insCode1 );
-
- Loop->AddReal ( dist );
-
- Loop->AddString ( atName2 );
- Loop->AddString ( aloc2 );
- Loop->AddString ( resName2 );
- Loop->AddString ( chainID2 );
- Loop->AddInteger ( seqNum2 );
- Loop->AddString ( insCode2 );
-
- Loop->AddString ( linkRID );
-
-}
-
-int CLinkR::ConvertPDBASCII ( cpstr S ) {
-
- GetString ( atName1 ,&(S[12]),4 );
- strcpy_ncss ( aloc1 ,&(S[16]),1 );
- strcpy_ncss ( resName1,&(S[17]),3 );
- strcpy_ncss ( chainID1,&(S[21]),1 );
- GetIntIns ( seqNum1,insCode1,&(S[22]),4 );
-
- if (!GetReal(dist,&(S[32]),7)) dist = 0.0;
-
- GetString ( atName2 ,&(S[42]),4 );
- strcpy_ncss ( aloc2 ,&(S[46]),1 );
- strcpy_ncss ( resName2,&(S[47]),3 );
- strcpy_ncss ( chainID2,&(S[51]),1 );
- GetIntIns ( seqNum2,insCode2,&(S[52]),4 );
-
- strcpy_ncss ( linkRID,&(S[72]),8 );
-
- return 0;
-
-}
-
-void CLinkR::GetCIF ( PCMMCIFData CIF, int & Signal ) {
-PCMMCIFLoop Loop;
-pstr F;
-int RC,l;
-Boolean Done;
-
- Loop = CIF->GetLoop ( CIFCAT_STRUCT_CONN );
- if (!Loop) {
- Signal = -1; // signal to finish processing of this structure
- return;
- }
-
- l = Loop->GetLoopLength();
- Done = (Signal>=l);
- while (!Done) {
- F = Loop->GetString ( CIFTAG_CONN_TYPE_ID,Signal,RC );
- if ((!RC) && F) Done = (strcmp(F,LinkTypeID)==0);
- else Done = False;
- if (!Done) {
- Signal++;
- Done = (Signal>=l);
- }
- }
-
- if (Signal>=l) {
- Signal = -1; // finish processing of Turn
- return;
- }
-
- Loop->DeleteField ( CIFTAG_CONN_TYPE_ID,Signal );
-
- // CIFGetInteger ( l,Loop,CIFTAG_ID,Signal );
-
- CIFGetString ( atName1,Loop,CIFTAG_CONN_PTNR1_AUTH_ATOM_ID,Signal,
- sizeof(atName1),pstr(" ") );
- CIFGetString ( aloc1,Loop,CIFTAG_CONN_PDBX_PTNR1_AUTH_ALT_ID,Signal,
- sizeof(aloc1),pstr(" ") );
- CIFGetString ( resName1,Loop,CIFTAG_CONN_PTNR1_AUTH_COMP_ID,Signal,
- sizeof(resName1),pstr(" ") );
- CIFGetString ( chainID1,Loop,CIFTAG_CONN_PTNR1_AUTH_ASYM_ID,Signal,
- sizeof(chainID1),pstr(" ") );
- if (CIFGetInteger(seqNum1,Loop,CIFTAG_CONN_PTNR1_AUTH_SEQ_ID,Signal))
- return;
- CIFGetString ( insCode1,Loop,CIFTAG_CONN_PDBX_PTNR1_PDB_INS_CODE,
- Signal,sizeof(insCode1),pstr(" ") );
-
- if (CIFGetReal(dist,Loop,CIFTAG_CONN_DIST,Signal))
- return;
-
- CIFGetString ( atName2,Loop,CIFTAG_CONN_PTNR2_AUTH_ATOM_ID,Signal,
- sizeof(atName2),pstr(" ") );
- CIFGetString ( aloc2,Loop,CIFTAG_CONN_PDBX_PTNR2_AUTH_ALT_ID,Signal,
- sizeof(aloc2),pstr(" ") );
- CIFGetString ( resName2,Loop,CIFTAG_CONN_PTNR2_AUTH_COMP_ID,Signal,
- sizeof(resName2),pstr(" ") );
- CIFGetString ( chainID2,Loop,CIFTAG_CONN_PTNR2_AUTH_ASYM_ID,Signal,
- sizeof(chainID2),pstr(" ") );
- if (CIFGetInteger(seqNum2,Loop,CIFTAG_CONN_PTNR2_AUTH_SEQ_ID,Signal))
- return;
- CIFGetString ( insCode2,Loop,CIFTAG_CONN_PDBX_PTNR2_PDB_INS_CODE,
- Signal,sizeof(insCode2),pstr(" ") );
-
- CIFGetString ( linkRID,Loop,CIFTAG_CONN_NAME,Signal,
- sizeof(linkRID),pstr(" ") );
-
- Signal++;
-
-}
-
-void CLinkR::Copy ( PCContainerClass LinkR ) {
-
- strcpy ( atName1 ,PCLinkR(LinkR)->atName1 );
- strcpy ( aloc1 ,PCLinkR(LinkR)->aloc1 );
- strcpy ( resName1,PCLinkR(LinkR)->resName1 );
- strcpy ( chainID1,PCLinkR(LinkR)->chainID1 );
- seqNum1 = PCLinkR(LinkR)->seqNum1;
- strcpy ( insCode1,PCLinkR(LinkR)->insCode1 );
-
- dist = PCLinkR(LinkR)->dist;
-
- strcpy ( atName2 ,PCLinkR(LinkR)->atName2 );
- strcpy ( aloc2 ,PCLinkR(LinkR)->aloc2 );
- strcpy ( resName2,PCLinkR(LinkR)->resName2 );
- strcpy ( chainID2,PCLinkR(LinkR)->chainID2 );
- seqNum2 = PCLinkR(LinkR)->seqNum2;
- strcpy ( insCode2,PCLinkR(LinkR)->insCode2 );
-
- strcpy ( linkRID,PCLinkR(LinkR)->linkRID );
-
-}
-
-void CLinkR::write ( RCFile f ) {
-byte Version=1;
-
- f.WriteByte ( &Version );
-
- f.WriteTerLine ( atName1 ,False );
- f.WriteTerLine ( aloc1 ,False );
- f.WriteTerLine ( resName1,False );
- f.WriteTerLine ( chainID1,False );
- f.WriteInt ( &seqNum1 );
- f.WriteTerLine ( insCode1,False );
-
- f.WriteReal ( &dist );
-
- f.WriteTerLine ( atName2 ,False );
- f.WriteTerLine ( aloc2 ,False );
- f.WriteTerLine ( resName2,False );
- f.WriteTerLine ( chainID2,False );
- f.WriteInt ( &seqNum2 );
- f.WriteTerLine ( insCode2,False );
-
- f.WriteTerLine ( linkRID,False );
-
-}
-
-void CLinkR::read ( RCFile f ) {
-byte Version;
-
- f.ReadByte ( &Version );
-
- f.ReadTerLine ( atName1 ,False );
- f.ReadTerLine ( aloc1 ,False );
- f.ReadTerLine ( resName1,False );
- f.ReadTerLine ( chainID1,False );
- f.ReadInt ( &seqNum1 );
- f.ReadTerLine ( insCode1,False );
-
- f.ReadReal ( &dist );
-
- f.ReadTerLine ( atName2 ,False );
- f.ReadTerLine ( aloc2 ,False );
- f.ReadTerLine ( resName2,False );
- f.ReadTerLine ( chainID2,False );
- f.ReadInt ( &seqNum2 );
- f.ReadTerLine ( insCode2,False );
-
- f.ReadTerLine ( linkRID,False );
-
-}
-
-MakeStreamFunctions(CLinkR)
-
-
-// =================== CCisPepContainer ======================
-
-PCContainerClass CCisPepContainer::MakeContainerClass ( int ClassID ) {
- switch (ClassID) {
- default :
- case ClassID_Template : return
- CClassContainer::MakeContainerClass(ClassID);
- case ClassID_CisPep : return new CCisPep();
- }
-}
-
-MakeStreamFunctions(CCisPepContainer)
-
-
-// ======================== CCisPep ==========================
-
-CCisPep::CCisPep() : CContainerClass() {
- InitCisPep();
-}
-
-CCisPep::CCisPep ( cpstr S ) : CContainerClass() {
- InitCisPep();
- ConvertPDBASCII ( S );
-}
-
-CCisPep::CCisPep ( RPCStream Object ) : CContainerClass(Object) {
- InitCisPep();
-}
-
-CCisPep::~CCisPep() {}
-
-void CCisPep::InitCisPep() {
- serNum = 1; // record serial number
- strcpy ( pep1 ,"---" ); // residue name
- strcpy ( chainID1," " ); // chain identifier 1
- seqNum1 = 0; // residue sequence number 1
- strcpy ( icode1 ," " ); // insertion code 1
- strcpy ( pep2 ,"---" ); // residue name 2
- strcpy ( chainID2," " ); // chain identifier 2
- seqNum2 = 0; // residue sequence number 2
- strcpy ( icode2 ," " ); // insertion code 2
- modNum = 0; // model number
- measure = 0.0; // measure of the angle in degrees.
-}
-
-void CCisPep::PDBASCIIDump ( pstr S, int N ) {
-UNUSED_ARGUMENT(N);
-
- strcpy ( S,"CISPEP" );
- PadSpaces ( S,80 );
-
- PutInteger ( &(S[7]),serNum,3 );
-
- strcpy_n1 ( &(S[11]),pep1 ,3 );
- strcpy_n1 ( &(S[15]),chainID1,1 );
- PutIntIns ( &(S[17]),seqNum1 ,4,icode1 );
-
- strcpy_n1 ( &(S[25]),pep2 ,3 );
- strcpy_n1 ( &(S[29]),chainID2,1 );
- PutIntIns ( &(S[31]),seqNum2 ,4,icode1 );
-
- PutInteger ( &(S[43]),modNum,3 );
- PutRealF ( &(S[53]),measure,6,2 );
-
-}
-
-
-int CCisPep::ConvertPDBASCII ( cpstr S ) {
-
- GetInteger ( serNum ,&(S[7]) ,3 );
-
- strcpy_ncss ( pep1 ,&(S[11]),3 );
- strcpy_ncss ( chainID1,&(S[15]),1 );
- GetIntIns ( seqNum1,icode1,&(S[17]),4 );
-
- strcpy_ncss ( pep2 ,&(S[25]),3 );
- strcpy_ncss ( chainID2,&(S[29]),1 );
- GetIntIns ( seqNum2,icode2,&(S[31]),4 );
-
- GetInteger ( modNum ,&(S[43]),3 );
- GetReal ( measure ,&(S[53]),6 );
-
- return 0;
-
-}
-
-
-void CCisPep::Copy ( PCContainerClass CisPep ) {
-
- serNum = PCCisPep(CisPep)->serNum;
-
- strcpy ( pep1 ,PCCisPep(CisPep)->pep1 );
- strcpy ( chainID1,PCCisPep(CisPep)->chainID1 );
- seqNum1 = PCCisPep(CisPep)->seqNum1;
- strcpy ( icode1 ,PCCisPep(CisPep)->icode1 );
-
- strcpy ( pep2 ,PCCisPep(CisPep)->pep2 );
- strcpy ( chainID2,PCCisPep(CisPep)->chainID2 );
- seqNum2 = PCCisPep(CisPep)->seqNum2;
- strcpy ( icode2 ,PCCisPep(CisPep)->icode2 );
-
- modNum = PCCisPep(CisPep)->modNum;
- measure = PCCisPep(CisPep)->measure;
-
-}
-
-void CCisPep::write ( RCFile f ) {
-byte Version=1;
-
- f.WriteByte ( &Version );
-
- f.WriteInt ( &serNum );
-
- f.WriteTerLine ( pep1 ,False );
- f.WriteTerLine ( chainID1,False );
- f.WriteInt ( &seqNum1 );
- f.WriteTerLine ( icode1 ,False );
-
- f.WriteTerLine ( pep2 ,False );
- f.WriteTerLine ( chainID2,False );
- f.WriteInt ( &seqNum2 );
- f.WriteTerLine ( icode2 ,False );
-
- f.WriteInt ( &modNum );
- f.WriteReal ( &measure );
-
-}
-
-void CCisPep::read ( RCFile f ) {
-byte Version;
-
- f.ReadByte ( &Version );
-
- f.ReadInt ( &serNum );
-
- f.ReadTerLine ( pep1 ,False );
- f.ReadTerLine ( chainID1,False );
- f.ReadInt ( &seqNum1 );
- f.ReadTerLine ( icode1 ,False );
-
- f.ReadTerLine ( pep2 ,False );
- f.ReadTerLine ( chainID2,False );
- f.ReadInt ( &seqNum2 );
- f.ReadTerLine ( icode2 ,False );
-
- f.ReadInt ( &modNum );
- f.ReadReal ( &measure );
-
-}
-
-MakeStreamFunctions(CCisPep)
-
-
-
-// ===================== CModel =======================
-
-CModel::CModel() : CProModel() {
- InitModel();
-}
-
-CModel::CModel ( PCMMDBManager MMDBM, int serialNum ) : CProModel() {
- InitModel();
- manager = MMDBM;
- serNum = serialNum;
-}
-
-CModel::CModel ( RPCStream Object ) : CProModel(Object) {
- InitModel();
-}
-
-void CModel::InitModel() {
- serNum = 0;
- nChains = 0;
- nChainsAlloc = 0;
- Chain = NULL;
- manager = NULL;
- Exclude = True;
-}
-
-CModel::~CModel() {
- FreeMemory();
- if (manager) manager->_ExcludeModel ( serNum );
-}
-
-void CModel::FreeMemory() {
-
- DeleteAllChains();
- if (Chain) delete[] Chain;
- Chain = NULL;
- nChains = 0;
- nChainsAlloc = 0;
-
- RemoveSecStructure();
- RemoveHetInfo ();
- RemoveLinks ();
- RemoveLinkRs ();
- RemoveCisPeps ();
-
-}
-
-
-void CModel::SetMMDBManager ( PCMMDBManager MMDBM, int serialNum ) {
- manager = MMDBM;
- serNum = serialNum;
-}
-
-void CModel::CheckInAtoms() {
-int i;
- if (manager)
- for (i=0;i<nChains;i++)
- if (Chain[i])
- Chain[i]->CheckInAtoms();
-}
-
-
-int CModel::GetNumberOfAtoms ( Boolean countTers ) {
-// returns number of atoms in the model
-int i,na;
- na = 0;
- for (i=0;i<nChains;i++)
- if (Chain[i]) na += Chain[i]->GetNumberOfAtoms ( countTers );
- return na;
-}
-
-int CModel::GetNumberOfResidues() {
-// returns number of residues in the model
-PCChain chain;
-int ic,ir,nr;
- nr = 0;
- for (ic=0;ic<nChains;ic++) {
- chain = Chain[ic];
- if (chain)
- for (ir=0;ir<chain->nResidues;ir++)
- if (chain->Residue[ir]) nr++;
- }
- return nr;
-}
-
-
-// ---------------- Extracting chains --------------------------
-
-int CModel::GetNumberOfChains() {
- return nChains;
-}
-
-PCChain CModel::GetChain ( int chainNo ) {
- if ((0<=chainNo) && (chainNo<nChains))
- return Chain[chainNo];
- else return NULL;
-}
-
-
-void CModel::ExpandChainArray ( int nOfChains ) {
-PPCChain Chain1;
-int i;
- if (nOfChains>=nChainsAlloc) {
- nChainsAlloc = nOfChains+10;
- Chain1 = new PCChain[nChainsAlloc];
- for (i=0;i<nChains;i++)
- Chain1[i] = Chain[i];
- for (i=nChains;i<nChainsAlloc;i++)
- Chain1[i] = NULL;
- if (Chain) delete[] Chain;
- Chain = Chain1;
- }
-}
-
-PCChain CModel::GetChainCreate ( const ChainID chID,
- Boolean enforceUniqueChainID ) {
-// Returns pointer on chain, whose identifier is
-// given in chID. If such a chain is absent in the
-// model, it is created.
-PCChain chain;
-ChainID chainID;
-int i,k;
-
- // check if such a chain is already in the model
- chain = NULL;
- if (enforceUniqueChainID) {
- k = 0;
- for (i=0;i<nChains;i++)
- if (Chain[i]) {
- // here we check only first letter as it is kept in all
- // derived names
- if (chID[0]==Chain[i]->chainID[0]) {
- chain = Chain[i];
- if (chain->GetNumberOfResidues()>0) k++;
- }
- }
- if (k) sprintf ( chainID,"%s%i",chID,k-1 );
- else if (!chain) strcpy ( chainID,chID ); // chain is absent
- else return chain; // the only empty chain
- } else {
- if (chID[0]) {
- for (i=0;(i<nChains) && (!chain);i++)
- if (Chain[i]) {
- if (!strcmp(chID,Chain[i]->chainID))
- chain = Chain[i]; // it is there; just return the pointer
- }
- } else {
- for (i=0;(i<nChains) && (!chain);i++)
- if (Chain[i]) {
- if (!Chain[i]->chainID[0])
- chain = Chain[i]; // it is there; just return the pointer
- }
- }
- if (chain) return chain;
- strcpy ( chainID,chID );
- }
-
- ExpandChainArray ( nChains );
-
- // create new chain
- Chain[nChains] = newCChain();
- Chain[nChains]->SetChain ( chainID );
- Chain[nChains]->SetModel ( this );
- nChains++;
-
- return Chain[nChains-1];
-
-}
-
-PCChain CModel::CreateChain ( const ChainID chID ) {
-// CreateChain() creates a new chain with chain ID regardless
-// the presence of same-ID chains in the model. This function
-// was introduced only for compatibility with older CCP4
-// applications and using it in any new developments should be
-// strictly discouraged.
-
- ExpandChainArray ( nChains );
-
- // create new chain
- Chain[nChains] = newCChain();
- Chain[nChains]->SetChain ( chID );
- Chain[nChains]->SetModel ( this );
- nChains++;
-
- return Chain[nChains-1];
-
-}
-
-
-void CModel::GetChainTable ( PPCChain & chainTable,
- int & NumberOfChains ) {
- chainTable = Chain;
- NumberOfChains = nChains;
-}
-
-Boolean CModel::GetNewChainID ( ChainID chID, int length ) {
-int i,k;
-Boolean found;
-
- memset ( chID,0,sizeof(ChainID) );
- chID[0] = 'A';
-
- do {
- found = False;
- for (i=0;(i<nChains) && (!found);i++)
- if (Chain[i])
- found = (!strcmp(chID,Chain[i]->chainID));
- if (found) {
- k = 0;
- while (k<length)
- if (!chID[k]) {
- chID[k] = 'A';
- break;
- } else if (chID[k]<'Z') {
- chID[k]++;
- break;
- } else {
- chID[k] = 'A';
- k++;
- }
- } else
- k = 0;
- } while (found && (k<length));
-
- if (found) {
- k = strlen(chID);
- while (k<length)
- chID[k++] = 'A';
- }
-
- return (!found);
-
-}
-
-
-PCChain CModel::GetChain ( const ChainID chID ) {
-// Returns pointer on chain, whose identifier is
-// given in chID. If such a chain is absent in the
-// model, returns NULL.
-int i;
-Boolean isChainID;
- if (chID) isChainID = (chID[0]!=char(0));
- else isChainID = False;
- if (isChainID) {
- for (i=0;i<nChains;i++)
- if (Chain[i]) {
- if (!strcmp(chID,Chain[i]->chainID))
- return Chain[i]; // it is there; just return the pointer
- }
- } else {
- for (i=0;i<nChains;i++)
- if (Chain[i]) {
- if (!Chain[i]->chainID[0])
- return Chain[i]; // it is there; just return the pointer
- }
- }
- return NULL;
-}
-
-
-// ------------------ Deleting chains --------------------------
-
-int CModel::DeleteChain ( int chainNo ) {
- if ((0<=chainNo) && (chainNo<nChains)) {
- if (Chain[chainNo]) {
- Exclude = False;
- delete Chain[chainNo];
- Chain[chainNo] = NULL;
- Exclude = True;
- return 1;
- }
- }
- return 0;
-}
-
-int CModel::DeleteChain ( const ChainID chID ) {
-int i;
- if (chID[0]) {
- for (i=0;i<nChains;i++)
- if (Chain[i]) {
- if (!strcmp(chID,Chain[i]->chainID)) {
- Exclude = False;
- delete Chain[i];
- Chain[i] = NULL;
- Exclude = True;
- return 1;
- }
- }
- } else {
- for (i=0;i<nChains;i++)
- if (Chain[i]) {
- if (!Chain[i]->chainID[0]) {
- Exclude = False;
- delete Chain[i];
- Chain[i] = NULL;
- Exclude = True;
- return 1;
- }
- }
- }
- return 0;
-}
-
-
-int CModel::DeleteAllChains() {
-int i,k;
- Exclude = False;
- k = 0;
- for (i=0;i<nChains;i++)
- if (Chain[i]) {
- delete Chain[i];
- Chain[i] = NULL;
- k++;
- }
- nChains = 0;
- Exclude = True;
- return k;
-}
-
-int CModel::DeleteSolventChains() {
-int i,k;
- Exclude = False;
- k = 0;
- for (i=0;i<nChains;i++)
- if (Chain[i]) {
- if (Chain[i]->isSolventChain()) {
- delete Chain[i];
- Chain[i] = NULL;
- k++;
- }
- }
- Exclude = True;
- return k;
-}
-
-void CModel::TrimChainTable() {
-int i,j;
- Exclude = False;
- j = 0;
- for (i=0;i<nChains;i++)
- if (Chain[i]) {
- if (Chain[i]->nResidues>0) {
- if (j<i) {
- Chain[j] = Chain[i];
- Chain[i] = NULL;
- }
- j++;
- } else {
- delete Chain[i];
- Chain[i] = NULL;
- }
- }
- nChains = j;
- Exclude = True;
-}
-
-
-int CModel::GetNumberOfResidues ( const ChainID chainID ) {
-PCChain chain;
- chain = GetChain ( chainID );
- if (chain) return chain->nResidues;
- return 0;
-}
-
-int CModel::GetNumberOfResidues ( int chainNo ) {
- if ((0<=chainNo) && (chainNo<nChains)) {
- if (Chain[chainNo])
- return Chain[chainNo]->nResidues;
- }
- return 0;
-}
-
-PCResidue CModel::GetResidue ( const ChainID chainID, int seqNo,
- const InsCode insCode ) {
-PCChain chain;
- chain = GetChain ( chainID );
- if (chain)
- return chain->GetResidue ( seqNo,insCode );
- return NULL;
-}
-
-PCResidue CModel::GetResidue ( const ChainID chainID, int resNo ) {
-PCChain chain;
- chain = GetChain ( chainID );
- if (chain) {
- if ((0<=resNo) && (resNo<chain->nResidues))
- return chain->Residue[resNo];
- }
- return NULL;
-}
-
-PCResidue CModel::GetResidue ( int chainNo, int seqNo,
- const InsCode insCode ) {
- if ((0<=chainNo) && (chainNo<nChains)) {
- if (Chain[chainNo])
- return Chain[chainNo]->GetResidue ( seqNo,insCode );
- }
- return NULL;
-}
-
-PCResidue CModel::GetResidue ( int chainNo, int resNo ) {
- if ((0<=chainNo) && (chainNo<nChains)) {
- if (Chain[chainNo]) {
- if ((0<=resNo) && (resNo<Chain[chainNo]->nResidues))
- return Chain[chainNo]->Residue[resNo];
- }
- }
- return NULL;
-}
-
-int CModel::GetResidueNo ( const ChainID chainID, int seqNo,
- const InsCode insCode ) {
-PCChain chain;
- chain = GetChain ( chainID );
- if (chain)
- return chain->GetResidueNo ( seqNo,insCode );
- return -2;
-}
-
-int CModel::GetResidueNo ( int chainNo, int seqNo,
- const InsCode insCode ) {
- if ((0<=chainNo) && (chainNo<nChains)) {
- if (Chain[chainNo])
- return Chain[chainNo]->GetResidueNo ( seqNo,insCode );
- }
- return -2;
-}
-
-
-void CModel::GetResidueTable ( PPCResidue & resTable,
- int & NumberOfResidues ) {
-// resTable has to be NULL or it will be reallocated. The application
-// is responsible for deallocating the resTable (but not of its
-// residues!). This does not apply to other GetResidueTable
-// functions.
-PPCChain chain;
-PPCResidue res;
-int i,j,k,nChns,nResidues;
-
- if (resTable) {
- delete[] resTable;
- resTable = NULL;
- }
-
- NumberOfResidues = 0;
- GetChainTable ( chain,nChns );
- for (i=0;i<nChns;i++)
- if (chain[i]) {
- chain[i]->GetResidueTable ( res,nResidues );
- NumberOfResidues += nResidues;
- }
-
- if (NumberOfResidues>0) {
- resTable = new PCResidue[NumberOfResidues];
- k = 0;
- GetChainTable ( chain,nChns );
- for (i=0;i<nChns;i++)
- if (chain[i]) {
- chain[i]->GetResidueTable ( res,nResidues );
- for (j=0;j<nResidues;j++)
- if (res[j]) resTable[k++] = res[j];
- }
- NumberOfResidues = k;
- }
-
-}
-
-void CModel::GetResidueTable ( const ChainID chainID,
- PPCResidue & resTable,
- int & NumberOfResidues ) {
-PCChain chain;
- resTable = NULL;
- NumberOfResidues = 0;
- chain = GetChain ( chainID );
- if (chain) {
- resTable = chain->Residue;
- NumberOfResidues = chain->nResidues;
- }
-}
-
-void CModel::GetResidueTable ( int chainNo, PPCResidue & resTable,
- int & NumberOfResidues ) {
- resTable = NULL;
- NumberOfResidues = 0;
- if ((0<=chainNo) && (chainNo<nChains)) {
- if (Chain[chainNo]) {
- resTable = Chain[chainNo]->Residue;
- NumberOfResidues = Chain[chainNo]->nResidues;
- }
- }
-}
-
-
-int CModel::DeleteResidue ( const ChainID chainID, int seqNo,
- const InsCode insCode ) {
-PCChain chain;
- chain = GetChain ( chainID );
- if (chain) return chain->DeleteResidue ( seqNo,insCode );
- return 0;
-}
-
-int CModel::DeleteResidue ( const ChainID chainID, int resNo ) {
-PCChain chain;
- chain = GetChain ( chainID );
- if (chain) return chain->DeleteResidue ( resNo );
- return 0;
-}
-
-int CModel::DeleteResidue ( int chainNo, int seqNo,
- const InsCode insCode ) {
- if ((0<=chainNo) && (chainNo<nChains)) {
- if (Chain[chainNo])
- return Chain[chainNo]->DeleteResidue ( seqNo,insCode );
- }
- return 0;
-}
-
-int CModel::DeleteResidue ( int chainNo, int resNo ) {
- if ((0<=chainNo) && (chainNo<nChains)) {
- if (Chain[chainNo])
- return Chain[chainNo]->DeleteResidue ( resNo );
- }
- return 0;
-}
-
-int CModel::DeleteAllResidues ( const ChainID chainID ) {
-PCChain chain;
- chain = GetChain ( chainID );
- if (chain) return chain->DeleteAllResidues();
- return 0;
-}
-
-int CModel::DeleteAllResidues ( int chainNo ) {
- if ((0<=chainNo) && (chainNo<nChains)) {
- if (Chain[chainNo])
- return Chain[chainNo]->DeleteAllResidues();
- }
- return 0;
-}
-
-int CModel::DeleteAllResidues() {
-int i,k;
- k = 0;
- for (i=0;i<nChains;i++)
- if (Chain[i])
- k += Chain[i]->DeleteAllResidues();
- return k;
-}
-
-
-int CModel::DeleteSolvent() {
-int i,k;
- Exclude = False;
- k = 0;
- for (i=0;i<nChains;i++)
- if (Chain[i]) {
- k += Chain[i]->DeleteSolvent();
- Chain[i]->TrimResidueTable();
- if (Chain[i]->nResidues<=0) {
- delete Chain[i];
- Chain[i] = NULL;
- }
- }
- Exclude = True;
- return k;
-}
-
-
-int CModel::AddResidue ( const ChainID chainID, PCResidue res ) {
-PCChain chain;
- chain = GetChain ( chainID );
- if (chain) return chain->AddResidue ( res );
- return 0;
-}
-
-int CModel::AddResidue ( int chainNo, PCResidue res ) {
- if ((0<=chainNo) && (chainNo<nChains)) {
- if (Chain[chainNo])
- return Chain[chainNo]->AddResidue ( res );
- }
- return 0;
-}
-
-
-int CModel::_ExcludeChain ( const ChainID chainID ) {
-// _ExcludeChain(..) excludes (but does not dispose!) a chain
-// from the model. Returns 1 if the model gets empty and 0 otherwise.
-int i,k;
-
- if (!Exclude) return 0;
-
- // find the chain
- k = -1;
- for (i=0;(i<nChains) && (k<0);i++)
- if (!strcmp(chainID,Chain[i]->chainID))
- k = i;
-
- if (k>=0) {
- for (i=k+1;i<nChains;i++)
- Chain[i-1] = Chain[i];
- nChains--;
- Chain[nChains] = NULL;
- }
-
- if (nChains<=0) return 1;
- else return 0;
-
-}
-
-
-// -------------------- Sort chains ----------------------------
-
-DefineClass(CSortChains)
-
-class CSortChains : public CQuickSort {
- public :
- CSortChains() : CQuickSort() { sKey = 0; }
- int Compare ( int i, int j );
- void Swap ( int i, int j );
- void Sort ( PPCChain chain, int nChains, int sortKey );
- private :
- int sKey;
-};
-
-int CSortChains::Compare ( int i, int j ) {
-int diff;
-
- diff = strcmp ( (PPCChain(data))[i]->GetChainID(),
- (PPCChain(data))[j]->GetChainID() );
- if (diff>0) diff = 1;
- if (diff<0) diff = -1;
-
- if (sKey==SORT_CHAIN_ChainID_Desc) return -diff;
-
- return diff;
-
-}
-
-void CSortChains::Swap ( int i, int j ) {
-PCChain chn;
- chn = ((PPCChain)data)[i];
- ((PPCChain)data)[i] = ((PPCChain)data)[j];
- ((PPCChain)data)[j] = chn;
-}
-
-void CSortChains::Sort ( PPCChain chain, int nChains, int sortKey ) {
- sKey = sortKey;
- CQuickSort::Sort ( &(chain[0]),nChains );
-}
-
-void CModel::SortChains ( int sortKey ) {
-CSortChains SC;
- TrimChainTable();
- SC.Sort ( Chain,nChains,sortKey );
-}
-
-
-// -------------------- Extracting atoms -----------------------
-
-
-int CModel::GetNumberOfAtoms ( const ChainID chainID, int seqNo,
- const InsCode insCode ) {
-PCChain chain;
-PCResidue res;
- chain = GetChain ( chainID );
- if (chain) {
- res = chain->GetResidue ( seqNo,insCode );
- if (res) return res->nAtoms;
- }
- return 0;
-}
-
-int CModel::GetNumberOfAtoms ( int chainNo, int seqNo,
- const InsCode insCode ) {
-PCChain chain;
-PCResidue res;
- chain = GetChain ( chainNo );
- if (chain) {
- res = chain->GetResidue ( seqNo,insCode );
- if (res) return res->nAtoms;
- }
- return 0;
-}
-
-int CModel::GetNumberOfAtoms ( const ChainID chainID, int resNo ) {
-PCChain chain;
-PCResidue res;
- chain = GetChain ( chainID );
- if (chain) {
- if ((0<=resNo) && (resNo<chain->nResidues)) {
- res = chain->Residue[resNo];
- if (res) return res->nAtoms;
- }
- }
- return 0;
-}
-
-int CModel::GetNumberOfAtoms ( int chainNo, int resNo ) {
-PCChain chain;
-PCResidue res;
- if ((0<=chainNo) && (chainNo<nChains)) {
- chain = Chain[chainNo];
- if (chain) {
- if ((0<=resNo) && (resNo<chain->nResidues)) {
- res = chain->Residue[resNo];
- if (res) return res->nAtoms;
- }
- }
- }
- return 0;
-}
-
-PCAtom CModel::GetAtom ( const ChainID chID,
- int seqNo,
- const InsCode insCode,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc
- ) {
-PCChain chn;
-PCResidue res;
- chn = GetChain ( chID );
- if (chn) {
- res = chn->GetResidue ( seqNo,insCode );
- if (res)
- return res->GetAtom ( aname,elmnt,aloc );
- }
- return NULL;
-}
-
-PCAtom CModel::GetAtom ( const ChainID chID, int seqNo,
- const InsCode insCode, int atomNo ) {
-PCChain chn;
-PCResidue res;
- chn = GetChain ( chID );
- if (chn) {
- res = chn->GetResidue ( seqNo,insCode );
- if (res) {
- if ((0<=atomNo) && (atomNo<res->nAtoms))
- return res->atom[atomNo];
- }
- }
- return NULL;
-}
-
-PCAtom CModel::GetAtom ( const ChainID chID,
- int resNo,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc ) {
-PCChain chn;
-PCResidue res;
- chn = GetChain ( chID );
- if (chn) {
- if ((0<=resNo) && (resNo<chn->nResidues)) {
- res = chn->Residue[resNo];
- if (res)
- return res->GetAtom ( aname,elmnt,aloc );
- }
- }
- return NULL;
-}
-
-PCAtom CModel::GetAtom ( const ChainID chID, int resNo, int atomNo ) {
-PCChain chn;
-PCResidue res;
- chn = GetChain ( chID );
- if (chn) {
- if ((0<=resNo) && (resNo<chn->nResidues)) {
- res = chn->Residue[resNo];
- if (res) {
- if ((0<=atomNo) && (atomNo<res->nAtoms))
- return res->atom[atomNo];
- }
- }
- }
- return NULL;
-}
-
-PCAtom CModel::GetAtom ( int chNo, int seqNo,
- const InsCode insCode,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc ) {
-PCResidue res;
- if ((0<=chNo) && (chNo<nChains)) {
- if (Chain[chNo]) {
- res = Chain[chNo]->GetResidue ( seqNo,insCode );
- if (res)
- return res->GetAtom ( aname,elmnt,aloc );
- }
- }
- return NULL;
-}
-
-PCAtom CModel::GetAtom ( int chNo, int seqNo, const InsCode insCode,
- int atomNo ) {
-PCResidue res;
- if ((0<=chNo) && (chNo<nChains)) {
- if (Chain[chNo]) {
- res = Chain[chNo]->GetResidue ( seqNo,insCode );
- if (res) {
- if ((0<=atomNo) && (atomNo<res->nAtoms))
- return res->atom[atomNo];
- }
- }
- }
- return NULL;
-}
-
-PCAtom CModel::GetAtom ( int chNo, int resNo,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc ) {
-PCResidue res;
- if ((0<=chNo) && (chNo<nChains)) {
- if (Chain[chNo]) {
- if ((0<=resNo) && (resNo<Chain[chNo]->nResidues)) {
- res = Chain[chNo]->Residue[resNo];
- if (res)
- return res->GetAtom ( aname,elmnt,aloc );
- }
- }
- }
- return NULL;
-}
-
-PCAtom CModel::GetAtom ( int chNo, int resNo, int atomNo ) {
-PCResidue res;
- if ((0<=chNo) && (chNo<nChains)) {
- if (Chain[chNo]) {
- if ((0<=resNo) && (resNo<Chain[chNo]->nResidues)) {
- res = Chain[chNo]->Residue[resNo];
- if (res) {
- if ((0<=atomNo) && (atomNo<res->nAtoms))
- return res->atom[atomNo];
- }
- }
- }
- }
- return NULL;
-}
-
-
-void CModel::GetAtomTable ( const ChainID chainID, int seqNo,
- const InsCode insCode,
- PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- atomTable = NULL;
- NumberOfAtoms = 0;
- res = GetResidue ( chainID,seqNo,insCode );
- if (res) {
- atomTable = res->atom;
- NumberOfAtoms = res->nAtoms;
- }
-}
-
-void CModel::GetAtomTable ( int chainNo, int seqNo,
- const InsCode insCode,
- PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- atomTable = NULL;
- NumberOfAtoms = 0;
- res = GetResidue ( chainNo,seqNo,insCode );
- if (res) {
- atomTable = res->atom;
- NumberOfAtoms = res->nAtoms;
- }
-}
-
-void CModel::GetAtomTable ( const ChainID chainID, int resNo,
- PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- atomTable = NULL;
- NumberOfAtoms = 0;
- res = GetResidue ( chainID,resNo );
- if (res) {
- atomTable = res->atom;
- NumberOfAtoms = res->nAtoms;
- }
-}
-
-void CModel::GetAtomTable ( int chainNo, int resNo,
- PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- atomTable = NULL;
- NumberOfAtoms = 0;
- res = GetResidue ( chainNo,resNo );
- if (res) {
- atomTable = res->atom;
- NumberOfAtoms = res->nAtoms;
- }
-}
-
-
-void CModel::GetAtomTable1 ( const ChainID chainID, int seqNo,
- const InsCode insCode,
- PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- res = GetResidue ( chainID,seqNo,insCode );
- if (res)
- res->GetAtomTable1 ( atomTable,NumberOfAtoms );
- else {
- if (atomTable) delete[] atomTable;
- atomTable = NULL;
- NumberOfAtoms = 0;
- }
-}
-
-void CModel::GetAtomTable1 ( int chainNo, int seqNo,
- const InsCode insCode,
- PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- res = GetResidue ( chainNo,seqNo,insCode );
- if (res)
- res->GetAtomTable1 ( atomTable,NumberOfAtoms );
- else {
- if (atomTable) delete[] atomTable;
- atomTable = NULL;
- NumberOfAtoms = 0;
- }
-}
-
-void CModel::GetAtomTable1 ( const ChainID chainID, int resNo,
- PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- res = GetResidue ( chainID,resNo );
- if (res)
- res->GetAtomTable1 ( atomTable,NumberOfAtoms );
- else {
- if (atomTable) delete[] atomTable;
- atomTable = NULL;
- NumberOfAtoms = 0;
- }
-}
-
-void CModel::GetAtomTable1 ( int chainNo, int resNo,
- PPCAtom & atomTable,
- int & NumberOfAtoms ) {
-PCResidue res;
- res = GetResidue ( chainNo,resNo );
- if (res)
- res->GetAtomTable1 ( atomTable,NumberOfAtoms );
- else {
- if (atomTable) delete[] atomTable;
- atomTable = NULL;
- NumberOfAtoms = 0;
- }
-}
-
-
-
-int CModel::DeleteAtom ( const ChainID chID,
- int seqNo,
- const InsCode insCode,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc
- ) {
-PCChain chn;
- chn = GetChain ( chID );
- if (chn)
- return chn->DeleteAtom ( seqNo,insCode,aname,elmnt,aloc );
- return 0;
-}
-
-int CModel::DeleteAtom ( const ChainID chID, int seqNo,
- const InsCode insCode, int atomNo ) {
-PCChain chn;
- chn = GetChain ( chID );
- if (chn) return chn->DeleteAtom ( seqNo,insCode,atomNo );
- return 0;
-}
-
-int CModel::DeleteAtom ( const ChainID chID,
- int resNo,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc ) {
-PCChain chn;
- chn = GetChain ( chID );
- if (chn) return chn->DeleteAtom ( resNo,aname,elmnt,aloc );
- return 0;
-}
-
-int CModel::DeleteAtom ( const ChainID chID, int resNo, int atomNo ) {
-PCChain chn;
- chn = GetChain ( chID );
- if (chn) return chn->DeleteAtom ( resNo,atomNo );
- return 0;
-}
-
-int CModel::DeleteAtom ( int chNo, int seqNo,
- const InsCode insCode,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc ) {
- if ((0<=chNo) && (chNo<nChains)) {
- if (Chain[chNo])
- return Chain[chNo]->DeleteAtom ( seqNo,insCode,aname,
- elmnt,aloc );
- }
- return 0;
-}
-
-int CModel::DeleteAtom ( int chNo, int seqNo, const InsCode insCode,
- int atomNo ) {
- if ((0<=chNo) && (chNo<nChains)) {
- if (Chain[chNo])
- return Chain[chNo]->DeleteAtom ( seqNo,insCode,atomNo );
- }
- return 0;
-}
-
-int CModel::DeleteAtom ( int chNo, int resNo,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc ) {
- if ((0<=chNo) && (chNo<nChains)) {
- if (Chain[chNo])
- return Chain[chNo]->DeleteAtom ( resNo,aname,elmnt,aloc );
- }
- return 0;
-}
-
-int CModel::DeleteAtom ( int chNo, int resNo, int atomNo ) {
- if ((0<=chNo) && (chNo<nChains)) {
- if (Chain[chNo])
- return Chain[chNo]->DeleteAtom ( resNo,atomNo );
- }
- return 0;
-}
-
-int CModel::DeleteAllAtoms ( const ChainID chID, int seqNo,
- const InsCode insCode ) {
-PCChain chn;
- chn = GetChain ( chID );
- if (chn) return chn->DeleteAllAtoms ( seqNo,insCode );
- return 0;
-}
-
-int CModel::DeleteAllAtoms ( const ChainID chID, int resNo ) {
-PCChain chn;
- chn = GetChain ( chID );
- if (chn) return chn->DeleteAllAtoms ( resNo );
- return 0;
-}
-
-int CModel::DeleteAllAtoms ( const ChainID chID ) {
-PCChain chn;
- chn = GetChain ( chID );
- if (chn) return chn->DeleteAllAtoms();
- return 0;
-}
-
-int CModel::DeleteAllAtoms ( int chNo, int seqNo,
- const InsCode insCode ) {
- if ((0<=chNo) && (chNo<nChains)) {
- if (Chain[chNo])
- return Chain[chNo]->DeleteAllAtoms ( seqNo,insCode );
- }
- return 0;
-}
-
-int CModel::DeleteAllAtoms ( int chNo, int resNo ) {
- if ((0<=chNo) && (chNo<nChains)) {
- if (Chain[chNo])
- return Chain[chNo]->DeleteAllAtoms ( resNo );
- }
- return 0;
-}
-
-int CModel::DeleteAllAtoms ( int chNo ) {
- if ((0<=chNo) && (chNo<nChains)) {
- if (Chain[chNo])
- return Chain[chNo]->DeleteAllAtoms();
- }
- return 0;
-}
-
-int CModel::DeleteAllAtoms() {
-int i,k;
- k = 0;
- for (i=0;i<nChains;i++)
- if (Chain[i]) k += Chain[i]->DeleteAllAtoms();
- return k;
-}
-
-int CModel::DeleteAltLocs() {
-// This function leaves only alternative location with maximal
-// occupancy, if those are equal or unspecified, the one with
-// "least" alternative location indicator.
-// The function returns the number of deleted. All tables remain
-// untrimmed, so that explicit trimming or calling FinishStructEdit()
-// is required.
-int i,n;
-
- n = 0;
- for (i=0;i<nChains;i++)
- if (Chain[i]) n += Chain[i]->DeleteAltLocs();
-
- return n;
-
-}
-
-
-int CModel::AddAtom ( const ChainID chID, int seqNo,
- const InsCode insCode,
- PCAtom atom ) {
-PCChain chn;
- chn = GetChain ( chID );
- if (chn) return chn->AddAtom ( seqNo,insCode,atom );
- return 0;
-}
-
-int CModel::AddAtom ( const ChainID chID, int resNo, PCAtom atom ) {
-PCChain chn;
- chn = GetChain ( chID );
- if (chn) return chn->AddAtom ( resNo,atom );
- return 0;
-}
-
-int CModel::AddAtom ( int chNo, int seqNo, const InsCode insCode,
- PCAtom atom ) {
- if ((0<=chNo) && (chNo<nChains)) {
- if (Chain[chNo])
- return Chain[chNo]->AddAtom ( seqNo,insCode,atom );
- }
- return 0;
-}
-
-int CModel::AddAtom ( int chNo, int resNo, PCAtom atom ) {
- if ((0<=chNo) && (chNo<nChains)) {
- if (Chain[chNo])
- return Chain[chNo]->AddAtom ( resNo,atom );
- }
- return 0;
-}
-
-
-
-void CModel::GetAtomStatistics ( RSAtomStat AS ) {
- AS.Init();
- CalcAtomStatistics ( AS );
- AS.Finish();
-}
-
-void CModel::CalcAtomStatistics ( RSAtomStat AS ) {
-int i;
- for (i=0;i<nChains;i++)
- if (Chain[i]) Chain[i]->CalcAtomStatistics ( AS );
-}
-
-
-
-int CModel::ConvertPDBString ( pstr PDBString ) {
-// Interprets PDB records DBREF, SEQADV, SEQRES, MODRES.
-// Returns zero if the line was converted, otherwise returns a
-// non-negative value of Error_XXXX.
-// PDBString must be not shorter than 81 characters.
-ChainID chainID;
-PCChain chain;
-PCHelix helix;
-PCTurn turn;
-PCLink link;
-PCLinkR linkR;
-PCCisPep cispep;
-int RC;
-
- // pad input line with spaces, if necessary
- PadSpaces ( PDBString,80 );
-
- chainID[0] = char(0);
- chainID[1] = char(0);
-
- if (!strncmp(PDBString,"DBREF ",6)) {
-
- if (PDBString[12]!=' ') chainID[0] = PDBString[12];
- chain = GetChainCreate ( chainID,False );
- return chain->ConvertDBREF ( PDBString );
-
- } else if (!strncmp(PDBString,"SEQADV",6)) {
-
- if (PDBString[16]!=' ') chainID[0] = PDBString[16];
- chain = GetChainCreate ( chainID,False );
- return chain->ConvertSEQADV ( PDBString );
-
- } else if (!strncmp(PDBString,"SEQRES",6)) {
-
- if (PDBString[11]!=' ') chainID[0] = PDBString[11];
- chain = GetChainCreate ( chainID,False );
- return chain->ConvertSEQRES ( PDBString );
-
- } else if (!strncmp(PDBString,"MODRES",6)) {
-
- if (PDBString[16]!=' ') chainID[0] = PDBString[16];
- chain = GetChainCreate ( chainID,False );
- return chain->ConvertMODRES ( PDBString );
-
- } else if (!strncmp(PDBString,"HET ",6)) {
-
- if (PDBString[12]!=' ') chainID[0] = PDBString[12];
- chain = GetChainCreate ( chainID,False );
- return chain->ConvertHET ( PDBString );
-
- } else if (!strncmp(PDBString,"HETNAM",6)) {
-
- HetCompounds.ConvertHETNAM ( PDBString );
- return 0;
-
- } else if (!strncmp(PDBString,"HETSYN",6)) {
-
- HetCompounds.ConvertHETSYN ( PDBString );
- return 0;
-
- } else if (!strncmp(PDBString,"FORMUL",6)) {
-
- HetCompounds.ConvertFORMUL ( PDBString );
- return 0;
-
- } else if (!strncmp(PDBString,"HELIX ",6)) {
-
- helix = new CHelix();
- RC = helix->ConvertPDBASCII(PDBString);
- if (RC==0) Helices.AddData ( helix );
- else delete helix;
- return RC;
-
- } else if (!strncmp(PDBString,"SHEET ",6)) {
-
- return Sheets.ConvertPDBASCII ( PDBString );
-
- } else if (!strncmp(PDBString,"TURN ",6)) {
-
- turn = new CTurn();
- RC = turn->ConvertPDBASCII(PDBString);
- if (RC==0) Turns.AddData ( turn );
- else delete turn;
- return RC;
-
- } else if (!strncmp(PDBString,"LINK ",6)) {
-
- link = new CLink();
- RC = link->ConvertPDBASCII(PDBString);
- if (RC==0) Links.AddData ( link );
- else delete link;
- return RC;
-
-
- } else if (!strncmp(PDBString,"LINKR ",6)) {
-
- linkR = new CLinkR();
- RC = linkR->ConvertPDBASCII(PDBString);
- if (RC==0) LinkRs.AddData ( linkR );
- else delete linkR;
- return RC;
-
- } else if (!strncmp(PDBString,"CISPEP",6)) {
-
- cispep = new CCisPep();
- RC = cispep->ConvertPDBASCII(PDBString);
- if (RC==0) CisPeps.AddData ( cispep );
- else delete cispep;
- return RC;
-
- } else
- return Error_WrongSection;
-
-}
-
-
-void CModel::PDBASCIIDumpPS ( RCFile f ) {
-int i;
-
- for (i=0;i<nChains;i++)
- if (Chain[i])
- Chain[i]->DBReference.PDBASCIIDump ( f );
-
- for (i=0;i<nChains;i++)
- if (Chain[i])
- Chain[i]->SeqAdv.PDBASCIIDump ( f );
-
- for (i=0;i<nChains;i++)
- if (Chain[i])
- Chain[i]->SeqRes.PDBASCIIDump ( f );
-
- for (i=0;i<nChains;i++)
- if (Chain[i])
- Chain[i]->ModRes.PDBASCIIDump ( f );
-
- for (i=0;i<nChains;i++)
- if (Chain[i])
- Chain[i]->Het.PDBASCIIDump ( f );
-
- HetCompounds.PDBASCIIDump ( f );
- Helices .PDBASCIIDump ( f );
- Sheets .PDBASCIIDump ( f );
- Turns .PDBASCIIDump ( f );
- Links .PDBASCIIDump ( f );
- LinkRs .PDBASCIIDump ( f );
-
-}
-
-void CModel::PDBASCIIDumpCP ( RCFile f ) {
- CisPeps.PDBASCIIDump ( f );
-}
-
-void CModel::PDBASCIIDump ( RCFile f ) {
-char S[100];
-int i;
-Boolean singleModel = True;
-
- if (manager)
- singleModel = (manager->nModels<=1);
-
- if (!singleModel) {
- strcpy ( S,"MODEL " );
- PadSpaces ( S,80 );
- PutInteger ( &(S[10]),serNum,4 );
- f.WriteLine ( S );
- }
-
- for (i=0;i<nChains;i++)
- if (Chain[i])
- Chain[i]->PDBASCIIAtomDump ( f );
-
- if (!singleModel) {
- strcpy ( S,"ENDMDL" );
- PadSpaces ( S,80 );
- f.WriteLine ( S );
- }
-
-}
-
-
-void CModel::MakeAtomCIF ( PCMMCIFData CIF ) {
-int i;
- for (i=0;i<nChains;i++)
- if (Chain[i])
- Chain[i]->MakeAtomCIF ( CIF );
-}
-
-
-void CModel::MakePSCIF ( PCMMCIFData CIF ) {
-int i;
-
- for (i=0;i<nChains;i++)
- if (Chain[i])
- Chain[i]->DBReference.MakeCIF ( CIF );
-
- for (i=0;i<nChains;i++)
- if (Chain[i])
- Chain[i]->SeqAdv.MakeCIF ( CIF );
-
- for (i=0;i<nChains;i++)
- if (Chain[i])
- Chain[i]->SeqRes.MakeCIF ( CIF );
-
- for (i=0;i<nChains;i++)
- if (Chain[i])
- Chain[i]->ModRes.MakeCIF ( CIF );
-
- for (i=0;i<nChains;i++)
- if (Chain[i])
- Chain[i]->Het.MakeCIF ( CIF );
-
- HetCompounds.MakeCIF ( CIF );
- Helices .MakeCIF ( CIF );
- Sheets .MakeCIF ( CIF );
- Turns .MakeCIF ( CIF );
- Links .MakeCIF ( CIF );
- LinkRs .MakeCIF ( CIF );
-
-}
-
-int CModel::GetCIFPSClass ( PCMMCIFData CIF, int ClassID ) {
-CChainContainer PSClass;
-PCChainContainer Dest;
-int RC;
-cpstr chainID;
-PCChain chain;
- PSClass.SetChain ( NULL );
- RC = PSClass.GetCIF ( CIF,ClassID );
- if (RC) return RC;
- chainID = PSClass.Get1stChainID();
- while (chainID) {
- chain = GetChainCreate ( chainID,False );
- switch (ClassID) {
- case ClassID_DBReference : Dest = &(chain->DBReference); break;
- case ClassID_SeqAdv : Dest = &(chain->SeqAdv); break;
- case ClassID_ModRes : Dest = &(chain->ModRes); break;
- case ClassID_Het : Dest = &(chain->Het); break;
- default : Dest = NULL;
- }
- if (Dest) {
- PSClass.MoveByChainID ( chainID,Dest );
- Dest->SetChain ( chain );
- } else
- printf ( " **** PROGRAM ERROR: wrong call to"
- " CModel::GetCIFPSClass(..)\n" );
- chainID = PSClass.Get1stChainID();
- }
- return 0;
-}
-
-int CModel::GetCIF ( PCMMCIFData CIF ) {
-CSeqRes SeqRes;
-int RC;
-PCChain chain;
-
- RC = GetCIFPSClass ( CIF,ClassID_DBReference );
- if (RC) return RC;
-
- RC = GetCIFPSClass ( CIF,ClassID_SeqAdv );
- if (RC) return RC;
-
- RC = SeqRes.GetCIF ( CIF );
- while (!RC) {
- chain = GetChainCreate ( SeqRes.chainID,False );
- chain->SeqRes.Copy ( &SeqRes );
- RC = SeqRes.GetCIF ( CIF );
- }
-
- RC = GetCIFPSClass ( CIF,ClassID_ModRes );
- if (RC) return RC;
-
- RC = GetCIFPSClass ( CIF,ClassID_Het );
- if (RC) return RC;
-
- HetCompounds.GetCIF ( CIF );
- Helices .GetCIF ( CIF,ClassID_Helix );
- Sheets .GetCIF ( CIF );
- Turns .GetCIF ( CIF,ClassID_Turn );
- Links .GetCIF ( CIF,ClassID_Link );
- LinkRs .GetCIF ( CIF,ClassID_LinkR );
-
- return RC;
-
-}
-
-cpstr CModel::GetEntryID() {
- if (manager) return manager->Title.idCode;
- else return pstr("");
-}
-
-void CModel::SetEntryID ( const IDCode idCode ) {
- if (manager)
- manager->SetEntryID ( idCode );
-}
-
-int CModel::GetNumberOfAllAtoms() {
- if (manager) return manager->nAtoms;
- else return 0;
-}
-
-int CModel::GetSerNum() {
- return serNum;
-}
-
-PCAtom * CModel::GetAllAtoms() {
- if (manager) return manager->Atom;
- else return NULL;
-}
-
-
-cpstr CModel::GetModelID ( pstr modelID ) {
- modelID[0] = char(0);
- sprintf ( modelID,"/%i",serNum );
- return modelID;
-}
-
-int CModel::GetNumberOfModels() {
- if (manager) return manager->nModels;
- else return 0;
-}
-
-
-void CModel::Copy ( PCModel Model ) {
-// modify both CModel::_copy and CModel::Copy methods simultaneously!
-int i;
-
- FreeMemory();
-
- if (Model) {
-
- serNum = Model->serNum;
- nChains = Model->nChains;
- nChainsAlloc = nChains;
- if (nChains>0) {
- Chain = new PCChain[nChainsAlloc];
- for (i=0;i<nChains;i++) {
- if (Model->Chain[i]) {
- Chain[i] = newCChain();
- Chain[i]->SetModel ( this );
- Chain[i]->Copy ( Model->Chain[i] );
- } else
- Chain[i] = NULL;
- }
- }
-
- HetCompounds.Copy ( &(Model->HetCompounds) );
- Helices .Copy ( &(Model->Helices) );
- Sheets .Copy ( &(Model->Sheets) );
- Turns .Copy ( &(Model->Turns) );
- Links .Copy ( &(Model->Links) );
- LinkRs .Copy ( &(Model->LinkRs) );
- CisPeps .Copy ( &(Model->CisPeps) );
-
- }
-
-}
-
-void CModel::CopyHets ( PCModel Model ) {
- if (Model) HetCompounds.Copy ( &(Model->HetCompounds) );
-}
-
-void CModel::CopySecStructure ( PCModel Model ) {
- if (Model) {
- Helices.Copy ( &(Model->Helices) );
- Sheets .Copy ( &(Model->Sheets) );
- Turns .Copy ( &(Model->Turns) );
- }
-}
-
-void CModel::CopyLinks ( PCModel Model ) {
- if (Model) Links.Copy ( &(Model->Links) );
-}
-
-void CModel::CopyLinkRs ( PCModel Model ) {
- if (Model) LinkRs.Copy ( &(Model->LinkRs) );
-}
-
-void CModel::CopyCisPeps ( PCModel Model ) {
- if (Model) CisPeps.Copy ( &(Model->CisPeps) );
-}
-
-void CModel::_copy ( PCModel Model ) {
-// modify both CModel::_copy and CModel::Copy methods simultaneously!
-int i;
-
- FreeMemory();
-
- if (Model) {
-
- serNum = Model->serNum;
- nChains = Model->nChains;
- nChainsAlloc = nChains;
- if (nChains>0) {
- Chain = new PCChain[nChainsAlloc];
- for (i=0;i<nChains;i++) {
- if (Model->Chain[i]) {
- Chain[i] = newCChain();
- Chain[i]->SetModel ( this );
- Chain[i]->_copy ( Model->Chain[i] );
- } else
- Chain[i] = NULL;
- }
- }
-
- HetCompounds.Copy ( &(Model->HetCompounds) );
- Helices .Copy ( &(Model->Helices) );
- Sheets .Copy ( &(Model->Sheets) );
- Turns .Copy ( &(Model->Turns) );
- Links .Copy ( &(Model->Links) );
- LinkRs .Copy ( &(Model->LinkRs) );
- CisPeps .Copy ( &(Model->CisPeps) );
-
- }
-
-}
-
-
-void CModel::_copy ( PCModel Model, PPCAtom atom, int & atom_index ) {
-// modify both CModel::_copy and CModel::Copy methods simultaneously!
-//
-// _copy(PCModel,PPCAtom,int&) does copy atoms into array 'atom'
-// starting from position atom_index. 'atom' should be able to
-// accept all new atoms - no checks on the length of 'atom'
-// is being made. This function should not be used in applications.
-int i;
-
- FreeMemory();
-
- if (Model) {
-
- serNum = Model->serNum;
- nChains = Model->nChains;
- nChainsAlloc = nChains;
- if (nChains>0) {
- Chain = new PCChain[nChainsAlloc];
- for (i=0;i<nChains;i++) {
- if (Model->Chain[i]) {
- Chain[i] = newCChain();
- Chain[i]->SetModel ( this );
- Chain[i]->_copy ( Model->Chain[i],atom,atom_index );
- } else
- Chain[i] = NULL;
- }
- }
-
- HetCompounds.Copy ( &(Model->HetCompounds) );
- Helices .Copy ( &(Model->Helices) );
- Sheets .Copy ( &(Model->Sheets) );
- Turns .Copy ( &(Model->Turns) );
- Links .Copy ( &(Model->Links) );
- LinkRs .Copy ( &(Model->LinkRs) );
-
- }
-
-}
-
-
-int CModel::AddChain ( PCChain chain ) {
-// modify both CModel::Copy methods simultaneously!
-//
-// Copy(PCModel,PPCAtom,int&) copies atoms into array 'atom'
-// starting from position atom_index. 'atom' should be able to
-// accept all new atoms - no checks on the length of 'atom'
-// is being made. This function should not be used in applications.
-PCModel model1;
-int i;
-
- for (i=0;i<nChains;i++)
- if (Chain[i]==chain) return -i; // this chain is already there
-
- if (chain) {
-
- // get space for new chain
- ExpandChainArray ( nChains );
-
- if (chain->GetCoordHierarchy()) {
- // The chain is associated with a coordinate hierarchy. It should
- // remain there, therefore we physically copy all its residues
- // and atoms.
- Chain[nChains] = newCChain();
- Chain[nChains]->SetModel ( this );
- if (manager) {
- // get space for new atoms
- manager->AddAtomArray ( chain->GetNumberOfAtoms(True) );
- Chain[nChains]->_copy ( chain,manager->Atom,manager->nAtoms );
- } else {
- for (i=0;i<chain->nResidues;i++)
- Chain[nChains]->AddResidue ( chain->Residue[i] );
- }
- } else {
- // The chain is not associated with a coordinate hierarchy. Such
- // unregistered objects are simply taken over, i.e. moved into
- // the new destination (model).
- Chain[nChains] = chain;
- // remove chain from its model:
- model1 = chain->GetModel();
- if (model1)
- for (i=0;i<model1->nChains;i++)
- if (model1->Chain[i]==chain) {
- model1->Chain[i] = NULL;
- break;
- }
- Chain[nChains]->SetModel ( this );
- if (manager)
- Chain[nChains]->CheckInAtoms();
- }
-
- nChains++;
-
- }
-
- return nChains;
-
-}
-
-
-void CModel::MoveChain ( PCChain & m_chain, PPCAtom m_atom,
- PPCAtom atom, int & atom_index,
- int chain_ext ) {
-// MoveChain(..) adds chain m_chain on the top Chain array.
-// The pointer on chain is then set to NULL (m_chain=NULL).
-// If chain_ext is greater than 0, the moved chain will be
-// forcefully renamed; the new name is composed as the previous
-// one + underscore + chain_ext (e.g. A_1). If thus generated
-// name duplicates any of existing chain IDs, or if chain_ext
-// was set to 0 and there is a duplication of chain IDs, the
-// name is again modified as above, with the extension number
-// generated automatically (this may result in IDs like
-// A_1_10).
-// m_atom must give pointer to the Atom array, from which
-// the atoms belonging to m_chain, are moved to Atom array
-// given by 'atom', starting from poisition 'atom_index'.
-// 'atom_index' is then automatically updated to the next
-// free position in 'atom'.
-// Note1: the moved atoms will occupy a continuous range
-// in 'atom' array; no checks on whether the corresponding
-// cells are occupied or not, are performed.
-// Note2: the 'atom_index' is numbered from 0 on, i.e.
-// it is equal to atom[atom_index]->index-1; atom[]->index
-// is assigned automatically.
-ChainID chainID;
-int i,j,k,Ok;
-PPCChain Chain1;
-PCResidue crRes;
-
- if (!m_chain) return;
-
- // modify chain ID with the extension given
- if (chain_ext>0)
- sprintf ( chainID,"%s_%i",m_chain->chainID,chain_ext );
- else strcpy ( chainID,m_chain->chainID );
-
- // Choose the chain ID. If a chain with such ID is
- // already present in the model, it will be assigned
- // a new ID 'ID_n', where 'ID' stands for the original
- // chain ID and 'n' is the minimum (integer) number
- // chosen such that 'name_n' represents a new chain ID
- // (in the model).
- k = 0;
- do {
- Ok = True;
- for (i=0;(i<nChains) && (Ok);i++)
- if (Chain[i])
- if (!strcmp(chainID,Chain[i]->chainID)) Ok = False;
- if (!Ok) {
- k++;
- if (chain_ext>0)
- sprintf ( chainID,"%s_%i_%i",m_chain->chainID,
- chain_ext,k );
- else sprintf ( chainID,"%s_%i",m_chain->chainID,k );
- }
- } while (!Ok);
-
- // add chain on the top of Chain array.
- strcpy ( m_chain->chainID,chainID );
- if (nChains>=nChainsAlloc) {
- nChainsAlloc = nChains+10;
- Chain1 = new PCChain[nChainsAlloc];
- k = 0;
- for (i=0;i<nChains;i++)
- if (Chain[i]) Chain1[k++] = Chain[i];
- for (i=k;i<nChainsAlloc;i++)
- Chain1[i] = NULL;
- if (Chain) delete[] Chain;
- Chain = Chain1;
- }
- Chain[nChains] = m_chain;
- Chain[nChains]->SetModel ( this );
- nChains++;
-
- // Move all atoms of the chain. While residues belong
- // atoms belong to the chain's manager class. Therefore
- // they should be moved from one manager to another.
- for (i=0;i<m_chain->nResidues;i++) {
- crRes = m_chain->Residue[i];
- if (crRes)
- for (j=0;j<crRes->nAtoms;j++)
- if (crRes->atom[j]) {
- k = crRes->atom[j]->index-1;
- atom[atom_index] = m_atom[k];
- atom[atom_index]->index = atom_index+1;
- atom_index++;
- m_atom[k] = NULL; // moved!
- }
- }
-
- m_chain = NULL; // moved!
-
-}
-
-void CModel::GetAIndexRange ( int & i1, int & i2 ) {
-PCChain chain;
-PCResidue res;
-int ic,ir,ia;
- i1 = MaxInt4;
- i2 = MinInt4;
- for (ic=0;ic<nChains;ic++) {
- chain = Chain[ic];
- if (chain) {
- for (ir=0;ir<chain->nResidues;ir++) {
- res = chain->Residue[ir];
- if (res) {
- for (ia=0;ia<res->nAtoms;ia++)
- if (res->atom[ia]) {
- if (res->atom[ia]->index<i1) i1 = res->atom[ia]->index;
- if (res->atom[ia]->index>i2) i2 = res->atom[ia]->index;
- }
- }
- }
- }
- }
-
-}
-
-
-void CModel::MaskAtoms ( PCMask Mask ) {
-int i;
- for (i=0;i<nChains;i++)
- if (Chain[i]) Chain[i]->MaskAtoms ( Mask );
-}
-
-void CModel::MaskResidues ( PCMask Mask ) {
-int i;
- for (i=0;i<nChains;i++)
- if (Chain[i]) Chain[i]->MaskResidues ( Mask );
-}
-
-void CModel::MaskChains ( PCMask Mask ) {
-int i;
- for (i=0;i<nChains;i++)
- if (Chain[i]) Chain[i]->SetMask ( Mask );
-}
-
-void CModel::UnmaskAtoms ( PCMask Mask ) {
-int i;
- for (i=0;i<nChains;i++)
- if (Chain[i]) Chain[i]->UnmaskAtoms ( Mask );
-}
-
-void CModel::UnmaskResidues ( PCMask Mask ) {
-int i;
- for (i=0;i<nChains;i++)
- if (Chain[i]) Chain[i]->UnmaskResidues ( Mask );
-}
-
-void CModel::UnmaskChains ( PCMask Mask ) {
-int i;
- for (i=0;i<nChains;i++)
- if (Chain[i]) Chain[i]->RemoveMask ( Mask );
-}
-
-
-// ------ Getting Secondary Structure Elements
-
-int CModel::GetNumberOfHelices() {
- return Helices.Length();
-}
-
-int CModel::GetNumberOfSheets() {
- return Sheets.nSheets;
-}
-
-PCHelix CModel::GetHelix ( int serialNum ) {
- return (PCHelix)Helices.GetContainerClass ( serialNum-1 );
-}
-
-void CModel::GetSheetID ( int serialNum, SheetID sheetID ) {
- if ((1<=serialNum) && (serialNum<=Sheets.nSheets)) {
- if (Sheets.Sheet[serialNum-1]) {
- strcpy ( sheetID,Sheets.Sheet[serialNum-1]->sheetID );
- return;
- }
- }
- sheetID[0] = char(0);
-}
-
-PCSheet CModel::GetSheet ( int serialNum ) {
- if ((1<=serialNum) && (serialNum<=Sheets.nSheets))
- return Sheets.Sheet[serialNum-1];
- else return NULL;
-}
-
-PCSheet CModel::GetSheet ( const SheetID sheetID ) {
-int i;
- for (i=0;i<Sheets.nSheets;i++)
- if (Sheets.Sheet[i]) {
- if (!strcmp(Sheets.Sheet[i]->sheetID,sheetID))
- return Sheets.Sheet[i];
- }
- return NULL;
-}
-
-int CModel::GetNumberOfStrands ( int sheetSerNum ) {
- if ((1<=sheetSerNum) && (sheetSerNum<=Sheets.nSheets)) {
- if (Sheets.Sheet[sheetSerNum-1])
- return Sheets.Sheet[sheetSerNum-1]->nStrands;
- }
- return 0;
-}
-
-int CModel::GetNumberOfStrands ( const SheetID sheetID ) {
-int i;
- for (i=0;i<Sheets.nSheets;i++)
- if (Sheets.Sheet[i]) {
- if (!strcmp(Sheets.Sheet[i]->sheetID,sheetID))
- return Sheets.Sheet[i]->nStrands;
- }
- return 0;
-}
-
-PCStrand CModel::GetStrand ( int sheetSerNum, int strandSerNum ) {
-PCSheet Sheet;
- if ((1<=sheetSerNum) && (sheetSerNum<=Sheets.nSheets)) {
- Sheet = Sheets.Sheet[sheetSerNum-1];
- if (Sheet) {
- if ((1<=strandSerNum) && (strandSerNum<=Sheet->nStrands))
- return Sheet->Strand[strandSerNum-1];
- }
- }
- return NULL;
-}
-
-PCStrand CModel::GetStrand ( const SheetID sheetID,
- int strandSerNum ) {
-int i;
-PCSheet Sheet;
- for (i=0;i<Sheets.nSheets;i++)
- if (Sheets.Sheet[i]) {
- if (!strcmp(Sheets.Sheet[i]->sheetID,sheetID)) {
- Sheet = Sheets.Sheet[i];
- if (Sheet) {
- if ((1<=strandSerNum) && (strandSerNum<=Sheet->nStrands))
- return Sheet->Strand[strandSerNum-1];
- }
- }
- }
- return NULL;
-}
-
-void CModel::RemoveSecStructure() {
- Helices.FreeContainer();
- Sheets .FreeMemory ();
- Turns .FreeContainer();
-}
-
-void CModel::RemoveHetInfo() {
- HetCompounds.FreeMemory();
-}
-
-
-
-int CModel::GetNumberOfLinks() {
- return Links.Length();
-}
-
-PCLink CModel::GetLink ( int serialNum ) {
- return (PCLink)Links.GetContainerClass ( serialNum-1 );
-}
-
-void CModel::RemoveLinks() {
- Links.FreeContainer();
-}
-
-void CModel::AddLink ( PCLink Link ) {
- Links.AddData ( Link );
-}
-
-
-int CModel::GetNumberOfLinkRs() {
- return LinkRs.Length();
-}
-
-PCLinkR CModel::GetLinkR ( int serialNum ) {
- return (PCLinkR)LinkRs.GetContainerClass ( serialNum-1 );
-}
-
-void CModel::RemoveLinkRs() {
- LinkRs.FreeContainer();
-}
-
-void CModel::AddLinkR ( PCLinkR LinkR ) {
- LinkRs.AddData ( LinkR );
-}
-
-
-
-int CModel::GetNumberOfCisPeps() {
- return CisPeps.Length();
-}
-
-PCCisPep CModel::GetCisPep ( int CisPepNum ) {
- return (PCCisPep)CisPeps.GetContainerClass ( CisPepNum-1 );
-}
-
-void CModel::RemoveCisPeps() {
- CisPeps.FreeContainer();
-}
-
-void CModel::AddCisPep ( PCCisPep CisPep ) {
- CisPeps.AddData ( CisPep );
-}
-
-
-void CModel::ApplyTransform ( mat44 & TMatrix ) {
-// transforms all coordinates by multiplying with matrix TMatrix
-int i;
- for (i=0;i<nChains;i++)
- if (Chain[i]) Chain[i]->ApplyTransform ( TMatrix );
-}
-
-Boolean CModel::isInSelection ( int selHnd ) {
-PCMask Mask;
- if (manager) {
- Mask = PCMMDBFile(manager)->GetSelMask ( selHnd );
- if (Mask) return CheckMask ( Mask );
- }
- return False;
-}
-
-
-
-// ------- user-defined data handlers
-
-int CModel::PutUDData ( int UDDhandle, int iudd ) {
- if (UDDhandle & UDRF_MODEL)
- return CUDData::putUDData ( UDDhandle,iudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CModel::PutUDData ( int UDDhandle, realtype rudd ) {
- if (UDDhandle & UDRF_MODEL)
- return CUDData::putUDData ( UDDhandle,rudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CModel::PutUDData ( int UDDhandle, cpstr sudd ) {
- if (UDDhandle & UDRF_MODEL)
- return CUDData::putUDData ( UDDhandle,sudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CModel::GetUDData ( int UDDhandle, int & iudd ) {
- if (UDDhandle & UDRF_MODEL)
- return CUDData::getUDData ( UDDhandle,iudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CModel::GetUDData ( int UDDhandle, realtype & rudd ) {
- if (UDDhandle & UDRF_MODEL)
- return CUDData::getUDData ( UDDhandle,rudd );
- else return UDDATA_WrongUDRType;
-}
-
-int CModel::GetUDData ( int UDDhandle, pstr sudd, int maxLen ) {
- if (UDDhandle & UDRF_MODEL)
- return CUDData::getUDData ( UDDhandle,sudd,maxLen );
- else return UDDATA_WrongUDRType;
-}
-
-int CModel::GetUDData ( int UDDhandle, pstr & sudd ) {
- if (UDDhandle & UDRF_MODEL)
- return CUDData::getUDData ( UDDhandle,sudd );
- else return UDDATA_WrongUDRType;
-}
-
-
-// ------- calculation of Secondary Structure
-
-
-int CModel::CalcSecStructure ( Boolean flagBulge, int aminoSelHnd ) {
-// This function is contributed by Liz Potterton, University of York
-//------------------------------------------------------------------
-// Define a secondary structure type of each amino acid residue in the
-// structure.
-// Procedure:
-// Find all amino acids
-// Find all pairs of amino acids which have inter-Ca distance < 10.0A
-// Test for hydrogen bonds between the main chain N and O of the close
-// residues and store the information in the hbonds matrix
-// Analyse the info in hbonds matrix to assign secondary structure to
-// secstr vector
-PPCResidue Res;
-PPCAtom Ca;
-PCChain chain;
-PSContact contact;
-imatrix hbonds;
-PPCAtom * hbond_atoms;
-int nres, ncontacts;
-int ir1,ir2, irdif;
-int i,j,k,l;
-
- // 1a. Get protein residues from selection handle
-
- if (aminoSelHnd>=0) {
-
- manager->GetSelIndex(aminoSelHnd,Res,nres);
-// printf ( " nres %3i " ,nres );
- if (nres<=0) return SSERC_noResidues;
-
- } else {
-
- // 1b. Get all protein residues
-
- nres = 0;
- for (i=0;i<nChains;i++)
- if (Chain[i])
- nres += Chain[i]->nResidues;
-
- if (nres<=0) return SSERC_noResidues;
-
- Res = new PCResidue[nres];
- nres = 0;
- for (i=0;i<nChains;i++) {
- chain = Chain[i];
- if (chain) {
- k = chain->nResidues;
- for (j=0;j<k;j++)
- Res[nres++] = chain->Residue[j];
- }
- }
-
-
- if (nres<=0) {
- delete[] Res;
- return SSERC_noResidues;
- }
-
- }
-
- // 2. Get C-alphas of all aminoacids
-
- Ca = new PCAtom[nres];
- k = 0;
- for (i=0;i<nres;i++)
- if (Res[i]) {
- if (aminoSelHnd>=0 || Res[i]->isAminoacid()) {
- Ca[i] = Res[i]->GetAtom("CA", " C", "*");
- k++;
- } else
- Ca[i] = NULL;
- Res[i]->SSE = SSE_None;
- } else
- Ca[i] = NULL;
-
- if (k<=0) {
- delete[] Res;
- delete[] Ca;
- return SSERC_noAminoacids;
- }
-
-
- // 3. Find all close Calphas - i.e. find the contacts between
- // the two equivalent sets of Ca atoms
-
- contact = NULL;
- ncontacts = 0;
- manager->SeekContacts ( Ca,nres, Ca,nres, 2.0,10.0, 2,
- contact,ncontacts,0 );
- if (ncontacts<=0) {
- delete[] Res;
- delete[] Ca;
- if (contact) delete[] contact;
- return SSERC_noSSE;
- }
-
-
- // 4. Get and initialize memory for analysing the SSE
-
- GetMatrixMemory ( hbonds,nres,3,0,0 );
- hbond_atoms = new PPCAtom[nres];
- for (i=0;i<nres;i++) {
- hbond_atoms[i] = new PCAtom[6];
- for (j=0;j<6;j++) hbond_atoms[i][j] = NULL;
- for (j=0;j<3;j++) hbonds [i][j] = 0;
- }
-
-
- // 5. Loop over all close (in space) residues - excluding those
- // that are close in sequence
-
- for (i=0;i<ncontacts;i++) {
- ir1 = contact[i].id2;
- ir2 = contact[i].id1;
- irdif = ir1 - ir2;
- if (irdif>2) {
- // test if there is donor Hbond from residue ir1
- if (Res[ir1]->isMainchainHBond(Res[ir2])) {
- k = 0;
- while ((hbonds[ir1][k]!=0) && (k<2)) k++;
- hbonds [ir1][k] = -irdif;
- hbond_atoms[ir1][k] = Res[ir1]->GetAtom ( "N" );
- hbond_atoms[ir1][k+3] = Res[ir2]->GetAtom ( "O" );
- }
- // test if there is donor Hbond from residue ir2
- if (Res[ir2]->isMainchainHBond(Res[ir1])) {
- k = 0;
- while ((hbonds[ir2][k]!=0) && (k<2)) k++;
- hbonds [ir2][k] = irdif;
- hbond_atoms[ir2][k] = Res[ir2]->GetAtom ( "N" );
- hbond_atoms[ir2][k+3] = Res[ir1]->GetAtom ( "O" );
- }
- }
- }
-
- // 6. Assign the turns - if there is bifurcated bond then the 4-turn
- // takes precedence - read the paper to make sense of this
-
- for (i=0;i<nres;i++) {
- k = 0;
- while ((k<=2) && (hbonds[i][k]!=0)) {
- if (hbonds[i][k]==-5) {
- Res[i-1]->SSE = SSE_5Turn;
- Res[i-2]->SSE = SSE_5Turn;
- Res[i-3]->SSE = SSE_5Turn;
- Res[i-4]->SSE = SSE_5Turn;
- }
- if (hbonds[i][k]==-3) {
- Res[i-1]->SSE = SSE_3Turn;
- Res[i-2]->SSE = SSE_3Turn;
- }
- k++;
- }
- }
- for (i=0;i<nres;i++) {
- k = 0;
- while ((k<=2) && (hbonds[i][k]!=0)) {
- if (hbonds[i][k]==-4) {
- Res[i-1]->SSE = SSE_4Turn;
- Res[i-2]->SSE = SSE_4Turn;
- Res[i-3]->SSE = SSE_4Turn;
- }
- k++;
- }
- }
-
-
- // 7. Look for consecutive 4-turns which make alpha helix
-
- for (i=1;i<nres-3;i++) {
- if (((Res[i ]->SSE==SSE_Helix) || (Res[i ]->SSE==SSE_4Turn)) &&
- ((Res[i+1]->SSE==SSE_Helix) || (Res[i+1]->SSE==SSE_4Turn)) &&
- ((Res[i+2]->SSE==SSE_Helix) || (Res[i+2]->SSE==SSE_4Turn)) &&
- ((Res[i+3]->SSE==SSE_Helix) || (Res[i+3]->SSE==SSE_4Turn)))
- for (j=i;j<=i+3;j++) Res[j]->SSE = SSE_Helix;
- }
-
- for (i=0;i<nres;i++) {
-
- k = 0;
- while ((k<=2) && (hbonds[i][k]!=0)) {
-
- irdif = hbonds[i][k];
- // Test for 'close' hbond
- j = i + irdif;
- l = 0;
- while ((l<=2) && (hbonds[j][l]!=0)) {
- // Antiparallel strands
- if (hbonds[j][l]==-irdif) {
- Res[i]->SSE = SSE_Strand;
- Res[j]->SSE = SSE_Strand;
- }
- // Parallel strand
- if (hbonds[j][l]==-irdif-2) {
- Res[i-1]->SSE = SSE_Strand;
- Res[j ]->SSE = SSE_Strand;
- }
- // Parallel beta bulge
- if (hbonds[j][l]==-irdif-3) {
- if (flagBulge) {
- if (Res[i-1]->SSE==SSE_None) Res[i-1]->SSE = SSE_Bulge;
- if (Res[i-2]->SSE==SSE_None) Res[i-2]->SSE = SSE_Bulge;
- if (Res[j ]->SSE==SSE_None) Res[j ]->SSE = SSE_Bulge;
- } else {
- if (Res[i-1]->SSE==SSE_None) Res[i-1]->SSE = SSE_Strand;
- if (Res[i-2]->SSE==SSE_None) Res[i-2]->SSE = SSE_Strand;
- if (Res[j ]->SSE==SSE_None) Res[j ]->SSE = SSE_Strand;
- }
- }
- l++;
- }
- // Test for 'wide' hbond
- j = i + hbonds[i][k] + 2;
- if (j<nres) {
- l = 0;
- while ((l<=2) && (hbonds[j][l]!=0)) {
- // Antiaprallel strands
- if (hbonds[j][l]==-irdif-4) {
- Res[i-1]->SSE = SSE_Strand;
- Res[j-1]->SSE = SSE_Strand;
- }
- // Parallel strands
- if (hbonds[j][l]==-irdif-2) {
- Res[i ]->SSE = SSE_Strand;
- Res[j-1]->SSE = SSE_Strand;
- }
- l++;
- }
- }
-
- // test for anti-parallel B-bulge between 'close' hbonds
- j = i + hbonds[i][k] - 1;
- if (j>=0) {
- l = 0;
- while ((l<=2) && (hbonds[j][l]!=0)) {
- if (hbonds[j][l]==-irdif+1) {
- if (flagBulge) {
- if (Res[i ]->SSE==SSE_None) Res[i ]->SSE = SSE_Bulge;
- if (Res[j+1]->SSE==SSE_None) Res[j+1]->SSE = SSE_Bulge;
- if (Res[j ]->SSE==SSE_None) Res[j ]->SSE = SSE_Bulge;
- } else {
- if (Res[i ]->SSE==SSE_None) Res[i ]->SSE = SSE_Strand;
- if (Res[j+1]->SSE==SSE_None) Res[j+1]->SSE = SSE_Strand;
- if (Res[j ]->SSE==SSE_None) Res[j ]->SSE = SSE_Strand;
- }
- }
- l++;
- }
- }
-
- // test for anti-parallel B-bulge between 'wide' hbonds
- j = i + hbonds[i][k] + 3;
- if (j<nres) {
- l = 0;
- while ((l<=2) && (hbonds[j][l]!=0)) {
- if ((hbonds[j][l]==-irdif+5) && (i>0)) {
- if (flagBulge) {
- if (Res[i-1]->SSE==SSE_None) Res[i-1]->SSE = SSE_Bulge;
- if (Res[j-1]->SSE==SSE_None) Res[j-1]->SSE = SSE_Bulge;
- if (Res[j-2]->SSE==SSE_None) Res[j-2]->SSE = SSE_Bulge;
- } else {
- if (Res[i-1]->SSE==SSE_None) Res[i-1]->SSE = SSE_Strand;
- if (Res[j-1]->SSE==SSE_None) Res[j-1]->SSE = SSE_Strand;
- if (Res[j-2]->SSE==SSE_None) Res[j-2]->SSE = SSE_Strand;
- }
- } else if (hbonds[j][l]==-irdif-3) {
- // and bulge in parallel strand
- if (flagBulge) {
- if (Res[i ]->SSE==SSE_None) Res[i ]->SSE = SSE_Bulge;
- if (Res[j-1]->SSE==SSE_None) Res[j-1]->SSE = SSE_Bulge;
- if (Res[j-2]->SSE==SSE_None) Res[j-2]->SSE = SSE_Bulge;
- }
- else {
- if (Res[i ]->SSE==SSE_None) Res[i ]->SSE = SSE_Strand;
- if (Res[j-1]->SSE==SSE_None) Res[j-1]->SSE = SSE_Strand;
- if (Res[j-2]->SSE==SSE_None) Res[j-2]->SSE = SSE_Strand;
- }
- }
- l++;
- }
- }
- k++;
-
- } // Finish looping over Hbonds for residue (k loop)
-
- } // Finish looping over residues ( i loop)
-
-
- // 8. Free memory
-
- if (hbond_atoms) {
- for (i=0;i<nres;i++)
- if (hbond_atoms[i]) delete[] hbond_atoms[i];
- delete[] hbond_atoms;
- }
- FreeMatrixMemory ( hbonds,nres,0,0 );
- if (contact) delete[] contact;
- if (Res && aminoSelHnd<0) delete[] Res;
- if (Ca) delete[] Ca;
-
- return SSERC_Ok;
-
-}
-
-
-// ------- streaming
-
-void CModel::write ( RCFile f ) {
-int i,k;
-byte Version=3;
-
- f.WriteByte ( &Version );
-
- CProModel::write ( f );
-
- f.WriteInt ( &serNum );
- f.WriteInt ( &nChains );
-
- for (i=0;i<nChains;i++) {
- if (Chain[i]) k = 1;
- else k = 0;
- f.WriteInt ( &k );
- if (Chain[i]) Chain[i]->write ( f );
- }
-
- HetCompounds.write ( f );
- Helices .write ( f );
- Sheets .write ( f );
- Turns .write ( f );
- Links .write ( f );
- LinkRs .write ( f );
-
-}
-
-void CModel::read ( RCFile f ) {
-int i,k;
-byte Version;
-
- FreeMemory();
-
- f.ReadByte ( &Version );
-
- CProModel::read ( f );
-
- f.ReadInt ( &serNum );
- f.ReadInt ( &nChains );
- nChainsAlloc = nChains;
- if (nChains>0) {
- Chain = new PCChain[nChainsAlloc];
- for (i=0;i<nChains;i++) {
- f.ReadInt ( &k );
- if (k) {
- Chain[i] = newCChain();
- Chain[i]->SetModel ( this );
- Chain[i]->read ( f );
- }
- }
- }
-
- HetCompounds.read ( f );
- Helices .read ( f );
- Sheets .read ( f );
- Turns .read ( f );
- if (Version>1) Links .read ( f );
- if (Version>2) LinkRs.read ( f );
-
-}
-
-MakeFactoryFunctions(CModel)
-
-
diff --git a/mmdb/mmdb_model.h b/mmdb/mmdb_model.h
deleted file mode 100755
index fabb1cc..0000000
--- a/mmdb/mmdb_model.h
+++ /dev/null
@@ -1,1085 +0,0 @@
-// $Id: mmdb_model.h,v 1.25 2012/01/26 17:52:20 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 30.04.10 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_Model <interface>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CHetCompound ( description of het compounds )
-// ~~~~~~~~~ CHetCompounds ( HETNAM, HETSYN, FORMULA records )
-// CSSContainer ( container for helixes and turns )
-// CHelix ( helix info )
-// CStrand ( strand info )
-// CSheet ( sheet info )
-// CSheets ( container for sheets )
-// CTurn ( turn info )
-// CLinkContainer ( container for link data )
-// CLink ( link data )
-// CLinkRContainer ( container for refmac link )
-// CLinkR ( link data )
-// CCisPepContainer ( container for CisPep data )
-// CCisPep ( CisPep data )
-// CModel ( PDB model )
-//
-// Copyright (C) E. Krissinel 2000-2010
-//
-// =================================================================
-//
-
-#ifndef __MMDB_Model__
-#define __MMDB_Model__
-
-
-#ifndef __Stream__
-#include "stream_.h"
-#endif
-
-#ifndef __MMDB_Defs__
-#include "mmdb_defs.h"
-#endif
-
-#ifndef __MMDB_Utils__
-#include "mmdb_utils.h"
-#endif
-
-#ifndef __MMDB_Chain__
-#include "mmdb_chain.h"
-#endif
-
-
-
-// ==================== CHetCompound =======================
-
-
-DefineClass(CHetCompound);
-DefineStreamFunctions(CHetCompound);
-
-class CHetCompound : public CStream {
-
- public :
-
- ResName hetID; // Het identifiers, right-justified
- pstr comment;
- int nSynonyms;
- psvector hetSynonym; // synonyms
- int compNum; // component number
- char wc; // '*' for water, otherwise space
- pstr Formula; // formulas
-
- CHetCompound ( cpstr HetName );
- CHetCompound ( RPCStream Object );
- ~CHetCompound();
-
- void AddKeyWord ( cpstr W, Boolean Closed );
- void HETNAM_PDBDump ( RCFile f );
- void HETSYN_PDBDump ( RCFile f );
- void FORMUL_PDBDump ( RCFile f );
-
- void FormComString ( pstr & F );
- void FormSynString ( pstr & F );
- void FormForString ( pstr & F );
-
- void Copy ( PCHetCompound HetCompound );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitHetCompound ( cpstr HetName );
- void FreeMemory ();
-
-};
-
-
-// ==================== CSSContainer ======================
-
-DefineClass(CSSContainer);
-DefineStreamFunctions(CSSContainer);
-
-class CSSContainer : public CClassContainer {
-
- public :
-
- CSSContainer () : CClassContainer() {}
- CSSContainer ( RPCStream Object )
- : CClassContainer ( Object ) {}
- ~CSSContainer () {}
-
- PCContainerClass MakeContainerClass ( int ClassID );
-
-};
-
-
-// ==================== CHelix ============================
-
-DefineClass(CHelix);
-DefineStreamFunctions(CHelix);
-
-class CHelix : public CContainerClass {
-
- public :
- int serNum; // serial number
- HelixID helixID; // helix ID
- ResName initResName; // name of the helix's initial residue
- ChainID initChainID; // chain ID for the chain containing the helix
- int initSeqNum; // sequence number of the initial residue
- InsCode initICode; // insertion code of the initial residue
- ResName endResName; // name of the helix's terminal residue
- ChainID endChainID; // chain ID for the chain containing the helix
- int endSeqNum; // sequence number of the terminal residue
- InsCode endICode; // insertion code of the terminal residue
- int helixClass; // helix class
- pstr comment; // comment about the helix
- int length; // length of the helix
-
- CHelix ();
- CHelix ( cpstr S );
- CHelix ( RPCStream Object );
- ~CHelix();
-
- void PDBASCIIDump ( pstr S, int N );
- void MakeCIF ( PCMMCIFData CIF, int N );
- int ConvertPDBASCII ( cpstr S );
- void GetCIF ( PCMMCIFData CIF, int & Signal );
- int GetClassID () { return ClassID_Helix; }
-
- void Copy ( PCContainerClass Helix );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitHelix();
-
-};
-
-
-
-// ==================== CStrand ============================
-
-DefineClass(CStrand);
-DefineStreamFunctions(CStrand);
-
-class CStrand : public CStream {
-
- public :
-
- StrandID sheetID; // sheet ID
- int strandNo; // strand number
- ResName initResName; // name of the strand's initial residue
- ChainID initChainID; // chain ID of initial residue in the strand
- int initSeqNum; // sequence number of the initial residue
- InsCode initICode; // insertion code of the initial residue
- ResName endResName; // name of the strand's terminal residue
- ChainID endChainID; // chain ID of terminal residue in the strand
- int endSeqNum; // sequence number of the terminal residue
- InsCode endICode; // insertion code of the terminal residue
- int sense; // sense of strand with respect to previous
- // strand
- AtomName curAtom; // registration; atom name in current strand
- ResName curResName; // registration; residue name in current
- // strand
- ChainID curChainID; // registration; chain ID in current strand
- int curResSeq; // registration; res-e seq numb in current
- // strand
- InsCode curICode; // registration; ins code in current strand
- AtomName prevAtom; // registration; atom name in previous strand
- ResName prevResName; // registration; residue name in previous
- // strand
- ChainID prevChainID; // registration; chain ID in previous strand
- int prevResSeq; // registration; res-e seq numb in previous
- // strand
- InsCode prevICode; // registration; ins code in previous strand
-
- CStrand ();
- CStrand ( RPCStream Object );
- ~CStrand();
-
- void PDBASCIIDump ( pstr S );
- void MakeCIF ( PCMMCIFData CIF );
- int ConvertPDBASCII ( cpstr S );
- int GetCIF ( PCMMCIFData CIF, cpstr sheet_id );
-
- void Copy ( PCStrand Strand );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitStrand();
-
-};
-
-
-// ==================== CSheet ============================
-
-DefineClass(CSheet);
-DefineStreamFunctions(CSheet);
-
-class CSheet : public CStream {
-
- public :
- SheetID sheetID; // sheet ID
- int nStrands; // number of strands in the sheet
- PPCStrand Strand; // array of strands
-
- CSheet ();
- CSheet ( RPCStream Object );
- ~CSheet();
-
- void FreeMemory();
- void OrderSheet();
-
- void PDBASCIIDump ( RCFile f );
- void MakeCIF ( PCMMCIFData CIF );
- int ConvertPDBASCII ( cpstr S );
- int GetCIF ( PCMMCIFData CIF );
-
- void Copy ( PCSheet Sheet );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
- void InitSheet ();
- void CIFFindStrands ( PCMMCIFData CIF, cpstr Category );
- void TryStrand ( int strand_no );
- int GetStrand ( int strand_no );
-
-};
-
-
-// ==================== CSheets ============================
-
-DefineClass(CSheets);
-DefineStreamFunctions(CSheets);
-
-class CSheets : public CStream {
-
- public :
- int nSheets;
- PPCSheet Sheet;
-
- CSheets ();
- CSheets ( RPCStream Object );
- ~CSheets();
-
- void FreeMemory();
-
- void PDBASCIIDump ( RCFile f );
- void MakeCIF ( PCMMCIFData CIF );
- int ConvertPDBASCII ( cpstr S );
- int GetCIF ( PCMMCIFData CIF );
-
- void Copy ( PCSheets Sheets );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
- void InitSheets ();
- void CIFFindSheets ( PCMMCIFData CIF, cpstr Category );
-
-};
-
-
-// ==================== CTurn ============================
-
-DefineClass(CTurn);
-DefineStreamFunctions(CTurn);
-
-class CTurn : public CContainerClass {
-
- public :
- int serNum; // serial number
- TurnID turnID; // turn ID
- ResName initResName; // name of the turn's initial residue
- ChainID initChainID; // chain ID for the chain containing the turn
- int initSeqNum; // sequence number of the initial residue
- InsCode initICode; // insertion code of the initial residue
- ResName endResName; // name of the turn's terminal residue
- ChainID endChainID; // chain ID for the chain containing the turn
- int endSeqNum; // sequence number of the terminal residue
- InsCode endICode; // insertion code of the terminal residue
- pstr comment; // comment about the helix
-
- CTurn ();
- CTurn ( cpstr S );
- CTurn ( RPCStream Object );
- ~CTurn();
-
- void PDBASCIIDump ( pstr S, int N );
- void MakeCIF ( PCMMCIFData CIF, int N );
- int ConvertPDBASCII ( cpstr S );
- void GetCIF ( PCMMCIFData CIF, int & Signal );
- int GetClassID () { return ClassID_Turn; }
-
- void Copy ( PCContainerClass Turn );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitTurn();
-
-};
-
-
-
-// ==================== CHetCompounds =======================
-
-DefineClass(CHetCompounds);
-DefineStreamFunctions(CHetCompounds);
-
-class CHetCompounds : public CStream {
-
- public :
-
- int nHets;
- PPCHetCompound hetCompound;
-
- CHetCompounds ();
- CHetCompounds ( RPCStream Object );
- ~CHetCompounds();
-
- void FreeMemory ();
-
- void PDBASCIIDump ( RCFile f );
- void ConvertHETNAM ( cpstr S );
- void ConvertHETSYN ( cpstr S );
- void ConvertFORMUL ( cpstr S );
-
- void MakeCIF ( PCMMCIFData CIF );
- void GetCIF ( PCMMCIFData CIF );
-
- void Copy ( PCHetCompounds HetCompounds );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
- Boolean Closed;
-
- void InitHetCompounds();
- int AddHetName ( cpstr H );
-
-};
-
-
-// =================== CLinkContainer =====================
-
-DefineClass(CLinkContainer);
-DefineStreamFunctions(CLinkContainer);
-
-class CLinkContainer : public CClassContainer {
-
- public :
-
- CLinkContainer () : CClassContainer() {}
- CLinkContainer ( RPCStream Object )
- : CClassContainer ( Object ) {}
- ~CLinkContainer () {}
-
- PCContainerClass MakeContainerClass ( int ClassID );
-
-};
-
-
-// ==================== CLink ============================
-
-DefineClass(CLink);
-DefineStreamFunctions(CLink);
-
-class CLink : public CContainerClass {
-
- public :
- AtomName atName1; // name of 1st linked atom
- AltLoc aloc1; // alternative location of 1st linked atom
- ResName resName1; // residue name of 1st linked atom
- ChainID chainID1; // chain ID of 1st linked atom
- int seqNum1; // sequence number of 1st linked atom
- InsCode insCode1; // insertion code of 1st linked atom
- AtomName atName2; // name of 2nd linked atom
- AltLoc aloc2; // alternative location of 2nd linked atom
- ResName resName2; // residue name of 2nd linked atom
- ChainID chainID2; // chain ID of 2nd linked atom
- int seqNum2; // sequence number of 2nd linked atom
- InsCode insCode2; // insertion code of 2nd linked atom
- int s1,i1,j1,k1; // sym id of 1st atom
- int s2,i2,j2,k2; // sym id of 2nd atom
-
- CLink ();
- CLink ( cpstr S );
- CLink ( RPCStream Object );
- ~CLink();
-
- void PDBASCIIDump ( pstr S, int N );
- void MakeCIF ( PCMMCIFData CIF, int N );
- int ConvertPDBASCII ( cpstr S );
- void GetCIF ( PCMMCIFData CIF, int & Signal );
- int GetClassID () { return ClassID_Link; }
-
- void Copy ( PCContainerClass Link );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitLink();
-
-};
-
-// =================== CLinkRContainer ====================
-
-DefineClass(CLinkRContainer);
-DefineStreamFunctions(CLinkRContainer);
-
-class CLinkRContainer : public CClassContainer {
-
- public :
-
- CLinkRContainer () : CClassContainer() {}
- CLinkRContainer ( RPCStream Object )
- : CClassContainer ( Object ) {}
- ~CLinkRContainer () {}
-
- PCContainerClass MakeContainerClass ( int ClassID );
-
-};
-
-
-// ==================== CLinkR ============================
-
-DefineClass(CLinkR);
-DefineStreamFunctions(CLinkR);
-
-
-/*
-
-Garib's
-LINK LYS A 27 PLP A 255 PLPLYS
-LINK MAN S 3 MAN S 4 BETA1-4
-LINK C6 BBEN B 1 O1 BMAF S 2 BEN-MAF
-LINK OE2 AGLU A 320 C1 AMAF S 2 GLU-MAF
-LINK OE2 GLU A 67 1.895 ZN ZN R 5 GLU-ZN
-LINK NE2 HIS A 71 2.055 ZN ZN R 5 HIS-ZN
-LINK O ARG A 69 2.240 NA NA R 9 ARG-NA
-
-Coot's
-LINKR O VAL C 103 NA NA C 401 VAL-NA
-LINKR OD1 ASP D 58 NA NA D 401 ASP-NA
-LINKR O ALA D 97 NA NA D 401 ALA-NA
-LINKR OG1 THR D 99 NA NA D 401 THR-NA
-LINKR O SER D 101 NA NA D 401 SER-NA
-LINKR O VAL D 103 NA NA D 401 VAL-NA
-
-PDB's
-LINK O GLY A 49 NA NA A6001 1555 1555 2.98
-LINK OG1 THR A 51 NA NA A6001 1555 1555 2.72
-LINK OD2 ASP A 66 NA NA A6001 1555 1555 2.72
-LINK NE ARG A 68 NA NA A6001 1555 1555 2.93
-
-LINK NE ARG A 68 NA NA A6001 1555 1555 2.93
-LINK C21 2EG A 7 C22 2EG B 19 1555 1555 1.56
-*/
-
-class CLinkR : public CContainerClass {
-
- public :
- LinkRID linkRID; // link name
- AtomName atName1; // name of 1st linked atom
- AltLoc aloc1; // alternative location of 1st linked atom
- ResName resName1; // residue name of 1st linked atom
- ChainID chainID1; // chain ID of 1st linked atom
- int seqNum1; // sequence number of 1st linked atom
- InsCode insCode1; // insertion code of 1st linked atom
- AtomName atName2; // name of 2nd linked atom
- AltLoc aloc2; // alternative location of 2nd linked atom
- ResName resName2; // residue name of 2nd linked atom
- ChainID chainID2; // chain ID of 2nd linked atom
- int seqNum2; // sequence number of 2nd linked atom
- InsCode insCode2; // insertion code of 2nd linked atom
- realtype dist; // link distance
-
- CLinkR ();
- CLinkR ( cpstr S );
- CLinkR ( RPCStream Object );
- ~CLinkR();
-
- void PDBASCIIDump ( pstr S, int N );
- void MakeCIF ( PCMMCIFData CIF, int N );
- int ConvertPDBASCII ( cpstr S );
- void GetCIF ( PCMMCIFData CIF, int & Signal );
- int GetClassID () { return ClassID_LinkR; }
-
- void Copy ( PCContainerClass LinkR );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitLinkR();
-
-};
-
-
-
-// =================== CCisPepContainer =====================
-
-DefineClass(CCisPepContainer);
-DefineStreamFunctions(CCisPepContainer);
-
-class CCisPepContainer : public CClassContainer {
-
- public :
-
- CCisPepContainer () : CClassContainer() {}
- CCisPepContainer ( RPCStream Object )
- : CClassContainer ( Object ) {}
- ~CCisPepContainer () {}
-
- PCContainerClass MakeContainerClass ( int ClassID );
-
-};
-
-
-// ===================== CCisPep ===========================
-
-DefineClass(CCisPep);
-DefineStreamFunctions(CCisPep);
-
-class CCisPep : public CContainerClass {
-
- public :
- int serNum; // record serial number
- ResName pep1; // residue name
- ChainID chainID1; // chain identifier 1
- int seqNum1; // residue sequence number 1
- InsCode icode1; // insertion code 1
- ResName pep2; // residue name 2
- ChainID chainID2; // chain identifier 2
- int seqNum2; // residue sequence number 2
- InsCode icode2; // insertion code 2
- int modNum; // model number
- realtype measure; // measure of the angle in degrees.
-
- CCisPep ();
- CCisPep ( cpstr S );
- CCisPep ( RPCStream Object );
- ~CCisPep();
-
- void PDBASCIIDump ( pstr S, int N );
- int ConvertPDBASCII ( cpstr S );
-
-// void MakeCIF ( PCMMCIFData CIF, int N );
-// void GetCIF ( PCMMCIFData CIF, int & Signal );
-
- int GetClassID () { return ClassID_CisPep; }
-
- void Copy ( PCContainerClass CisPep );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitCisPep();
-
-};
-
-
-
-// ==================== CModel ===============================
-
-#define SSERC_Ok 0
-#define SSERC_noResidues 1
-#define SSERC_noAminoacids 2
-#define SSERC_noSSE 3
-
-#define SORT_CHAIN_ChainID_Asc 0
-#define SORT_CHAIN_ChainID_Desc 1
-
-DefineFactoryFunctions(CModel);
-
-class CModel : public CProModel {
-
- friend class CMMDBManager;
- friend class CMMDBBondManager;
- friend class CMMDBSelManager;
- friend class CMMDBCoorManager;
- friend class CMMDBFile;
- friend class CChain;
- friend class CResidue;
- friend class CAtom;
-
- public :
-
- CModel (); // SetMMDBFile() MUST be used after this constructor!
- CModel ( PCMMDBManager MMDBF, int serialNum );
- CModel ( RPCStream Object );
- ~CModel();
-
- void SetMMDBManager ( PCMMDBManager MMDBM, int serialNum );
- PCMMDBManager GetCoordHierarchy() { return manager; }
-
- // GetChainCreate() returns pointer on chain, whose identifier
- // is given in chID. If such a chain is absent in the model,
- // it is created. If enforceUniqueChainID is True and chain with
- // the same first letter in chain ID already exists in the model,
- // then the new chain ID will be appended with a serial number
- // in order to keep it unique. The model will contain chains like
- // A, A0, A1, A2, ... in such cases.
- PCChain GetChainCreate ( const ChainID chID,
- Boolean enforceUniqueChainID );
-
- // CreateChain() creates a new chain with chain ID regardless
- // the presence of same-ID chains in the model. This function
- // was introduced only for compatibility with older CCP4
- // applications and using it in any new developments should be
- // strictly discouraged.
- PCChain CreateChain ( const ChainID chID );
-
- cpstr GetEntryID ();
- void SetEntryID ( const IDCode idCode );
-
- int GetSerNum (); // returns the model's serial number
-
- cpstr GetModelID ( pstr modelID ); // returns "/mdl"
-
- int GetNumberOfModels (); // returns TOTAL number of models
- int GetNumberOfAtoms ( Boolean countTers ); // returns number
- // of atoms in the model
- int GetNumberOfResidues(); // returns number of residues in
- // the model
-
-
- // ---------------- Extracting chains --------------------------
-
- int GetNumberOfChains(); // returns number of chains in the model
- Boolean GetNewChainID ( ChainID chID, int length=1 );
- // GetChain() returns pointer on chain, whose identifier
- // is given in chID. If such a chain is absent in the model,
- // returns NULL.
- PCChain GetChain ( const ChainID chID );
- PCChain GetChain ( int chainNo ); // returns chainNo-th chain
- // in the model;
- // 0<=chainNo<nChains
- void GetChainTable ( PPCChain & chainTable,
- int & NumberOfChains );
-
- // ------------------ Deleting chains --------------------------
-
- int DeleteChain ( const ChainID chID );
- int DeleteChain ( int chainNo );
- int DeleteAllChains ();
- int DeleteSolventChains();
- void TrimChainTable ();
-
- // ------------------- Adding chains ---------------------------
-
- int AddChain ( PCChain chain );
-
- // -------------------- Sort chains ----------------------------
-
- void SortChains ( int sortKey ); // SORT_CHAIN_XXXX
-
- // ---------------- Extracting residues ------------------------
-
- int GetNumberOfResidues ( const ChainID chainID );
- int GetNumberOfResidues ( int chainNo );
- PCResidue GetResidue ( const ChainID chainID, int seqNo,
- const InsCode insCode );
- PCResidue GetResidue ( const ChainID chainID, int resNo );
- PCResidue GetResidue ( int chainNo, int seqNo,
- const InsCode insCode );
- PCResidue GetResidue ( int chainNo, int resNo );
- int GetResidueNo ( const ChainID chainID, int seqNo,
- const InsCode insCode );
- int GetResidueNo ( int chainNo, int seqNo,
- const InsCode insCode );
- void GetResidueTable ( PPCResidue & resTable,
- int & NumberOfResidues );
- void GetResidueTable ( const ChainID chainID,
- PPCResidue & resTable,
- int & NumberOfResidues );
- void GetResidueTable ( int chainNo, PPCResidue & resTable,
- int & NumberOfResidues );
-
- // ----------------- Deleting residues -------------------------
-
- int DeleteResidue ( const ChainID chainID, int seqNo,
- const InsCode insCode );
- int DeleteResidue ( const ChainID chainID, int resNo );
- int DeleteResidue ( int chainNo, int seqNo,
- const InsCode insCode );
- int DeleteResidue ( int chainNo, int resNo );
- int DeleteAllResidues ( const ChainID chainID );
- int DeleteAllResidues ( int chainNo );
- int DeleteSolvent (); // in difference of DeleteSolventChains,
- // this will remove all solvent molecules
- // from the file rather then
- // solely-solvent chains
- int DeleteAllResidues ();
-
- // ------------------ Adding residues --------------------------
-
- int AddResidue ( const ChainID chainID, PCResidue res );
- int AddResidue ( int chainNo, PCResidue res );
-
- // ------------------- Extracting atoms ------------------------
-
- int GetNumberOfAllAtoms(); // returns TOTAL number of atoms in all
- // models
- PPCAtom GetAllAtoms (); // returns pointer to Atom array
-
- int GetNumberOfAtoms ( const ChainID chainID, int seqNo,
- const InsCode insCode );
- int GetNumberOfAtoms ( int chainNo, int seqNo,
- const InsCode insCode );
- int GetNumberOfAtoms ( const ChainID chainID, int resNo );
- int GetNumberOfAtoms ( int chainNo, int resNo );
-
- PCAtom GetAtom ( const ChainID chID,
- int seqNo,
- const InsCode insCode,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc );
- PCAtom GetAtom ( const ChainID chID, int seqNo,
- const InsCode insCode, int atomNo );
- PCAtom GetAtom ( const ChainID chID,
- int resNo,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc );
- PCAtom GetAtom ( const ChainID chID, int resNo, int atomNo );
- PCAtom GetAtom ( int chNo, int seqNo,
- const InsCode insCode,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc );
- PCAtom GetAtom ( int chNo, int seqNo, const InsCode insCode,
- int atomNo );
- PCAtom GetAtom ( int chNo, int resNo,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc );
- PCAtom GetAtom ( int chNo, int resNo, int atomNo );
-
- void GetAtomTable ( const ChainID chainID, int seqNo,
- const InsCode insCode,
- PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable ( int chainNo, int seqNo,
- const InsCode insCode,
- PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable ( const ChainID chainID, int resNo,
- PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable ( int chainNo, int resNo,
- PPCAtom & atomTable, int & NumberOfAtoms );
-
- // GetAtomTable1(..) returns atom table without TER atoms and
- // without NULL atom pointers. NumberOfAtoms returns the actual
- // number of atom pointers in atomTable.
- // atomTable is allocated withing the function. If it was
- // not set to NULL before calling the function, the latter will
- // attempt to deallocate it first.
- // The application is responsible for deleting atomTable,
- // however it must not touch atom pointers, i.e. use simply
- // "delete atomTable;". Never pass atomTable from GetAtomTable(..)
- // into this function, unless you set it to NULL before doing that.
- void GetAtomTable1 ( const ChainID chainID, int seqNo,
- const InsCode insCode,
- PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable1 ( int chainNo, int seqNo,
- const InsCode insCode,
- PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable1 ( const ChainID chainID, int resNo,
- PPCAtom & atomTable, int & NumberOfAtoms );
- void GetAtomTable1 ( int chainNo, int resNo,
- PPCAtom & atomTable, int & NumberOfAtoms );
-
- void GetAtomStatistics ( RSAtomStat AS );
- void CalcAtomStatistics ( RSAtomStat AS );
-
-
- // -------------------- Deleting atoms -------------------------
-
- int DeleteAtom ( const ChainID chID,
- int seqNo,
- const InsCode insCode,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc );
- int DeleteAtom ( const ChainID chID, int seqNo,
- const InsCode insCode, int atomNo );
- int DeleteAtom ( const ChainID chID,
- int resNo,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc );
- int DeleteAtom ( const ChainID chID, int resNo, int atomNo );
- int DeleteAtom ( int chNo, int seqNo,
- const InsCode insCode,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc );
- int DeleteAtom ( int chNo, int seqNo, const InsCode insCode,
- int atomNo );
- int DeleteAtom ( int chNo, int resNo,
- const AtomName aname,
- const Element elmnt,
- const AltLoc aloc );
- int DeleteAtom ( int chNo, int resNo, int atomNo );
-
- int DeleteAllAtoms ( const ChainID chID, int seqNo,
- const InsCode insCode );
- int DeleteAllAtoms ( const ChainID chID, int resNo );
- int DeleteAllAtoms ( const ChainID chID );
- int DeleteAllAtoms ( int chNo, int seqNo, const InsCode insCode );
- int DeleteAllAtoms ( int chNo, int resNo );
- int DeleteAllAtoms ( int chNo );
- int DeleteAllAtoms ();
-
- // DeleteAltLocs() leaves only alternative location with maximal
- // occupancy, if those are equal or unspecified, the one with
- // "least" alternative location indicator.
- // The function returns the number of deleted. All tables remain
- // untrimmed, so that explicit trimming or calling
- // FinishStructEdit() is required.
- int DeleteAltLocs();
-
-
- // --------------------- Adding atoms --------------------------
-
- int AddAtom ( const ChainID chID, int seqNo,
- const InsCode insCode, PCAtom atom );
- int AddAtom ( const ChainID chID, int resNo, PCAtom atom );
- int AddAtom ( int chNo, int seqNo, const InsCode insCode,
- PCAtom atom );
- int AddAtom ( int chNo, int resNo, PCAtom atom );
-
-
- // ---------------------------------------------------------------
-
- // ConvertPDBString(..) interprets PDB records DBREF, SEQADV,
- // SEQRES, MODRES.
- // Returns zero if the line was converted, otherwise returns a
- // non-negative value of Error_XXXX.
- // PDBString must be not shorter than 81 characters.
- int ConvertPDBString ( pstr PDBString );
-
- // PDBASCIIDumpPS(..) makes output of PDB primary structure records
- // excluding cispeps
- void PDBASCIIDumpPS ( RCFile f );
-
- // PDBASCIIDumpCP(..) makes output of cispep records
- void PDBASCIIDumpCP ( RCFile f );
-
- // PDBASCIIDump(..) makes output of PDB coordinate (ATOM etc.)
- // records
- void PDBASCIIDump ( RCFile f );
-
- void MakeAtomCIF ( PCMMCIFData CIF );
- void MakePSCIF ( PCMMCIFData CIF );
- int GetCIF ( PCMMCIFData CIF );
-
- // MoveChain(..) adds chain m_chain on the top Chain array.
- // The pointer on chain is then set to NULL (m_chain=NULL).
- // If chain_ext is greater than 0, the moved chain will be
- // forcefully renamed; the new name is composed as the previous
- // one + underscore + chain_ext (e.g. A_1). If thus generated
- // name duplicates any of existing chain IDs, or if chain_ext
- // was set to 0 and there is a duplication of chain IDs, the
- // name is again modified as above, with the extension number
- // generated automatically (this may result in IDs like
- // A_1_10).
- // m_atom must give pointer to the Atom array, from which
- // the atoms belonging to m_chain, are moved to Atom array
- // given by 'atom', starting from poisition 'atom_index'.
- // 'atom_index' is then automatically updated to the next
- // free position in 'atom'.
- // Note1: the moved atoms will occupy a continuous range
- // in 'atom' array; no checks on whether the corresponding
- // cells are occupied or not, are performed.
- // Note2: the 'atom_index' is numbered from 0 on, i.e.
- // it is equal to atom[atom_index]->index-1; atom[]->index
- // is assigned automatically.
- void MoveChain ( PCChain & m_chain, PPCAtom m_atom,
- PPCAtom atom, int & atom_index,
- int chain_ext );
-
- void GetAIndexRange ( int & i1, int & i2 );
-
- void MaskAtoms ( PCMask Mask );
- void MaskResidues ( PCMask Mask );
- void MaskChains ( PCMask Mask );
- void UnmaskAtoms ( PCMask Mask );
- void UnmaskResidues ( PCMask Mask );
- void UnmaskChains ( PCMask Mask );
-
-
- // ---- Getting Secondary Structure Elements
-
- int GetNumberOfHelices ();
- int GetNumberOfSheets ();
-
- PCHelix GetHelix ( int serialNum ); // 1<=serNum<=NofHelices
-
- void GetSheetID ( int serialNum, SheetID sheetID );
- // '\0' for none
-
- PCSheet GetSheet ( int serialNum ); //1<=serNum<=NofSheets
- PCSheet GetSheet ( const SheetID sheetID ); // NULL for none
- int GetNumberOfStrands ( int sheetSerNum );
- int GetNumberOfStrands ( const SheetID sheetID );
- PCStrand GetStrand ( int sheetSerNum,
- int strandSerNum );
- PCStrand GetStrand ( const SheetID sheetID,
- int strandSerNum );
-
- PCSSContainer GetHelices() { return &Helices; }
- PCSheets GetSheets () { return &Sheets; }
-
- void RemoveSecStructure();
- int CalcSecStructure ( Boolean flagBulge=True,
- int aminoSelHnd=-1 );
-// int CalcSecStructure ( Boolean flagBulge=True );
-
- void RemoveHetInfo ();
-
-
- // ---- Working Links
-
- int GetNumberOfLinks ();
- PCLink GetLink ( int serialNum ); // 1<=serNum<=NofLinks
- PCLinkContainer GetLinks() { return &Links; }
-
- void RemoveLinks();
- void AddLink ( PCLink Link );
-
- // ---- Working Refmac Links
-
- int GetNumberOfLinkRs ();
- PCLinkR GetLinkR ( int serialNum ); // 1<=serNum<=NofLinks
- PCLinkRContainer GetLinkRs() { return &LinkRs; }
-
- void RemoveLinkRs();
- void AddLinkR ( PCLinkR LinkR );
-
-
- // ---- Working CisPeps
-
- int GetNumberOfCisPeps();
- PCCisPep GetCisPep ( int CisPepNum );
- PCCisPepContainer GetCisPeps() { return &CisPeps; }
-
- void RemoveCisPeps();
- void AddCisPep ( PCCisPep CisPep );
-
-
-
- void ApplyTransform ( mat44 & TMatrix ); // transforms all
- // coordinates by multiplying
- // with matrix TMatrix
-
- Boolean isInSelection ( int selHnd );
-
-
- // ------- user-defined data handlers
- int PutUDData ( int UDDhandle, int iudd );
- int PutUDData ( int UDDhandle, realtype rudd );
- int PutUDData ( int UDDhandle, cpstr sudd );
-
- int GetUDData ( int UDDhandle, int & iudd );
- int GetUDData ( int UDDhandle, realtype & rudd );
- int GetUDData ( int UDDhandle, pstr sudd, int maxLen );
- int GetUDData ( int UDDhandle, pstr & sudd );
-
-
- void Copy ( PCModel Model );
- void CopyHets ( PCModel Model );
- void CopySecStructure ( PCModel Model );
- void CopyLinks ( PCModel Model );
- void CopyLinkRs ( PCModel Model );
- void CopyCisPeps ( PCModel Model );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- int serNum; // the model serial number
- PCMMDBManager manager; // pointer to mmdbmanager class
-
- CHetCompounds HetCompounds; // information on heterocompounds
- CSSContainer Helices; // information on helices
- CSheets Sheets; // information on sheets
- CSSContainer Turns; // information on turns
- CLinkContainer Links; // information on links
- CLinkRContainer LinkRs; // information on refmac links
- CCisPepContainer CisPeps; // information on cispeps
-
- int nChains; // number of chains
- int nChainsAlloc; // actual length of Chain[]
- PPCChain Chain; // array of chains
-
- Boolean Exclude; // used internally
-
- void InitModel ();
- void FreeMemory ();
- void ExpandChainArray ( int nOfChains );
- int GetCIFPSClass ( PCMMCIFData CIF, int ClassID );
-
- // _ExcludeChain(..) excludes (but does not dispose!) a chain
- // from the model. Returns 1 if the chain gets empty and 0
- // otherwise.
- int _ExcludeChain ( const ChainID chainID );
-
- // _copy(PCModel) does not copy atoms! -- not for use in
- // applications
- void _copy ( PCModel Model );
-
- // _copy(PCModel,PPCAtom,int&) does copy atoms into array 'atom'
- // starting from position atom_index. 'atom' should be able to
- // accept all new atoms - no checks on the length of 'atom'
- // is being made. This function should not be used in applications.
- void _copy ( PCModel Model, PPCAtom atom, int & atom_index );
-
- void CheckInAtoms ();
-
-};
-
-
-#endif
-
diff --git a/mmdb/mmdb_sbase.cpp b/mmdb/mmdb_sbase.cpp
deleted file mode 100755
index 2fa9418..0000000
--- a/mmdb/mmdb_sbase.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
-// $Id: mmdb_sbase.cpp,v 1.22 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 21.02.06 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : mmdb_sbase <implementation>
-// ~~~~~~~~~
-// **** Classes : CSBase ( structure base manager )
-// ~~~~~~~~~ CSBAtom ( SB atom class )
-// CSBBond ( SB bond class )
-// CSBStructure ( SB structure (monomer) class )
-// CSBIndex ( SB index class )
-//
-// (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __MMDB_SBase__
-#include "mmdb_sbase.h"
-#endif
-
-
-// ========================= CSBase =============================
-
-CSBase::CSBase() : CSBase0() {
- InitSBase();
-}
-
-
-CSBase::~CSBase() {
- FreeMemory();
-}
-
-void CSBase::InitSBase() {
- minDAdist = 2.0;
- maxDAdist = 3.9; // max distance for H-bonds
- maxSBdist = 4.0; // max distance for salt bridges
- maxHAdist2 = 2.5*2.5;
- maxDHAcos = 0.0;
- maxHAAcos = 0.0;
- maxDAAcos = 0.0;
- maxDDAcos = 0.0;
-}
-
-void CSBase::FreeMemory() {
-}
-
-void addAtomPair ( PCAtom a1, PCAtom a2,
- PSAtomPair & Pair, int & nPairs, int & nPAlloc ) {
-PSAtomPair AP;
-int i,i1,i2,j1,j2;
-Boolean Found;
-
- Found = False;
- i1 = a1->GetIndex();
- i2 = a2->GetIndex();
- for (i=0;(i<nPairs) && (!Found);i++) {
- j1 = Pair[i].a1->GetIndex();
- j2 = Pair[i].a2->GetIndex();
- Found = (((i1==j1) && (i2==j2)) ||
- ((i1==j2) && (i2==j1)));
- }
-
- if (!Found) {
- if (nPairs>=nPAlloc) {
- nPAlloc = nPairs+20;
- AP = new SAtomPair[nPAlloc];
- for (i=0;i<nPairs;i++) {
- AP[i].a1 = Pair[i].a1;
- AP[i].a2 = Pair[i].a2;
- }
- if (Pair) delete[] Pair;
- Pair = AP;
- }
- Pair[nPairs].a1 = a1;
- Pair[nPairs].a2 = a2;
- nPairs++;
- }
-
-}
-
-int CSBase::CalcHBonds ( PPCResidue Res1, int nres1,
- PPCResidue Res2, int nres2,
- RPSAtomPair HBond, int & nHBonds,
- RPSAtomPair SBridge, int & nSBridges,
- PCFile structFile, pstr altLoc,
- Boolean ignoreNegSigOcc ) {
-PCFile sFile;
-PCMMDBManager MMDB;
-PPCAtom Donor1,Acceptor1, Donor2,Acceptor2;
-PCAtom D,A,H;
-PSContact Contact;
-PSAtomBond ABond,DBond;
-SDASelHandles selHandles1,selHandles2;
-pstr resName;
-int nDonors1,nAcceptors1, nDonors2,nAcceptors2, nContacts;
-int i,j,k,nDBonds,nABonds,nHBAlloc,nSBAlloc;
-Boolean isHBond,isSBridge;
-
- if (HBond) {
- delete[] HBond;
- HBond = NULL;
- }
- nHBonds = 0;
- nHBAlloc = 0;
-
- if (SBridge) {
- delete[] SBridge;
- SBridge = NULL;
- }
- nSBridges = 0;
- nSBAlloc = 0;
-
- // 1. Calculate bonds between atoms in given residues and
- // select donors and acceptors
-
- i = 0;
- while ((i<nres1) && (!Res1[i])) i++;
- if (i>=nres1) return SBASE_EmptyResSet;
-
- MMDB = PCMMDBManager(Res1[i]->GetCoordHierarchy());
- if (!MMDB) return SBASE_noCoordHierarchy;
-
- if (structFile) sFile = structFile;
- else sFile = GetStructFile();
-
- if (!sFile) return SBASE_FileNotFound;
-
- selHandles1.getNewHandles ( MMDB );
- for (i=0;i<nres1;i++)
- if (Res1[i])
- MakeBonds ( Res1[i],altLoc,sFile,&selHandles1,ignoreNegSigOcc );
- selHandles1.makeSelIndexes ( MMDB );
-
- selHandles2.getNewHandles ( MMDB );
- for (i=0;i<nres2;i++)
- if (Res2[i])
- MakeBonds ( Res2[i],altLoc,sFile,&selHandles2,ignoreNegSigOcc );
- selHandles2.makeSelIndexes ( MMDB );
-
- if (!structFile) delete sFile;
-
- // 2. Calculate contacts between donors and acceptors as
- // potential hydrogen bond contacts
-
- MMDB->GetSelIndex ( selHandles1.selHndDonor,Donor1,nDonors1 );
- MMDB->GetSelIndex ( selHandles2.selHndDonor,Donor2,nDonors2 );
- if ((nDonors1<=0) && (nDonors2<=0)) {
- selHandles1.deleteSelections ( MMDB );
- selHandles2.deleteSelections ( MMDB );
- return SBASE_noDonors;
- }
-
- MMDB->GetSelIndex(selHandles1.selHndAcceptor,Acceptor1,nAcceptors1);
- MMDB->GetSelIndex(selHandles2.selHndAcceptor,Acceptor2,nAcceptors2);
- if ((nAcceptors1<=0) && (nAcceptors2<=0)) {
- selHandles1.deleteSelections ( MMDB );
- selHandles2.deleteSelections ( MMDB );
- return SBASE_noAcceptors;
- }
-
- if ((nDonors1*nAcceptors2<=0) && (nDonors2*nAcceptors1<=0)) {
- selHandles1.deleteSelections ( MMDB );
- selHandles2.deleteSelections ( MMDB );
- return SBASE_noHBonds;
- }
-
- // We now calculate contacts such that 1st contacting atom, either
- // acceptor or donor, belongs to 1st set of residues, and the second
- // one - to 2nd set of residues. Therefore we run SeekContacts on
- // two sets of donors and acceptors, identified by different group
- // id, merging the array of contacts for convenience.
- Contact = NULL;
- nContacts = 0;
- MMDB->SeekContacts ( Donor1,nDonors1,Acceptor2,nAcceptors2,
- minDAdist,RMax(maxDAdist,maxSBdist),0,Contact,
- nContacts,0,NULL,1,0 );
- MMDB->SeekContacts ( Acceptor1,nAcceptors1,Donor2,nDonors2,
- minDAdist,RMax(maxDAdist,maxSBdist),0,Contact,
- nContacts,0,NULL,2,0 );
- if (nContacts<=0) {
- selHandles1.deleteSelections ( MMDB );
- selHandles2.deleteSelections ( MMDB );
- return SBASE_noHBonds;
- }
-
-
- // 3. Check all contacts for h-bond geometry
-
- // merge all hydrogens into one selection as it is used
- // for checking with only
- MMDB->Select ( selHandles1.selHndHydrogen,STYPE_ATOM,
- selHandles2.selHndHydrogen,SKEY_OR );
-
- for (i=0;i<nContacts;i++) {
- if (Contact[i].group<=1) {
- D = Donor1 [Contact[i].id1];
- A = Acceptor2[Contact[i].id2];
- } else {
- A = Acceptor1[Contact[i].id1];
- D = Donor2 [Contact[i].id2];
- }
- if (Contact[i].dist<=maxDAdist) {
- // Check for H-bond
- D->GetBonds ( DBond,nDBonds );
- A->GetBonds ( ABond,nABonds );
- if (nABonds>0) {
- // Check whether there are hydrogens bound to the donor,
- // and if they are then calculate h-bonds using them
- H = NULL;
- for (j=0;j<nDBonds;j++)
- if ((DBond[j].atom->occupancy>0.0) &&
- DBond[j].atom->isInSelection(
- selHandles1.selHndHydrogen)) {
- H = DBond[j].atom;
- if ((H->GetDist2(A)<maxHAdist2) &&
- (H->GetCosine(D,A)<=maxDHAcos)) {
- // Check angles with all acceptor neighbours
- isHBond = True;
- for (k=0;(k<nABonds) && isHBond;k++)
- isHBond = (A->GetCosine(H,ABond[k].atom)<=maxHAAcos);
- if (isHBond) {
- if (Contact[i].group<=1)
- addAtomPair ( H,A,HBond,nHBonds,nHBAlloc );
- else addAtomPair ( A,H,HBond,nHBonds,nHBAlloc );
- }
- }
- }
- if ((!H) && (nDBonds>0)) {
- // There were no hydrogens bonded to donor, assume that
- // the structure is incomplete and check donor-acceptor
- // geometry for possible h-bonding.
- isHBond = True;
- for (j=0;(j<nDBonds) && isHBond;j++)
- isHBond = (D->GetCosine(DBond[j].atom,A)<=maxDDAcos);
- for (j=0;(j<nABonds) && isHBond;j++)
- isHBond = (A->GetCosine(D,ABond[j].atom)<=maxDAAcos);
- if (isHBond) {
- if (Contact[i].group<=1)
- addAtomPair ( D,A,HBond,nHBonds,nHBAlloc );
- else addAtomPair ( A,D,HBond,nHBonds,nHBAlloc );
- }
- }
- }
- }
- if ((Contact[i].dist<=maxSBdist) &&
- (D->GetResidue()!=A->GetResidue()) &&
- (!strcmp(D->element," N")) && (!strcmp(A->element," O"))) {
- // Check for salt bridge, which may be formed only by N-O
- // pairs of aminoacid atoms at distances less then maxSBdist
- if (!strcmp(D->name," N ")) {
- // mainchain nitrogen can form salt bridge only at N-terminus
- isSBridge = D->isNTerminus();
- } else {
- // other nitrogens can form salt bridge only in LYS, ARG
- // and HIS
- resName = D->GetResName();
- isSBridge = ((!strcmp(resName,"LYS")) ||
- (!strcmp(resName,"ARG")) ||
- (!strcmp(resName,"HIS")));
- }
- if (isSBridge) {
- if ((!strcmp(A->name," O ")) || (!strcmp(A->name," OXT"))) {
- // mainchain oxygens can form salt bridge only at C-terminus
- isSBridge = A->isCTerminus();
- } else {
- // other oxygens can form salt bridge only in GLU and ASP
- resName = A->GetResName();
- isSBridge = ((!strcmp(resName,"GLU")) ||
- (!strcmp(resName,"ASP")));
- }
- if (isSBridge) {
- if (Contact[i].group<=1)
- addAtomPair ( D,A,SBridge,nSBridges,nSBAlloc );
- else addAtomPair ( A,D,SBridge,nSBridges,nSBAlloc );
- }
- }
- }
- }
-
- if (Contact) delete[] Contact;
-
- selHandles1.deleteSelections ( MMDB );
- selHandles2.deleteSelections ( MMDB );
-
- return SBASE_Ok;
-
-}
diff --git a/mmdb/mmdb_sbase.h b/mmdb/mmdb_sbase.h
deleted file mode 100755
index 32224f3..0000000
--- a/mmdb/mmdb_sbase.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// $Id: mmdb_sbase.h,v 1.21 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 21.02.06 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : mmdb_sbase <implementation>
-// ~~~~~~~~~
-// **** Classes : CSBase ( structure base manager )
-// ~~~~~~~~~ CSBAtom ( SB atom class )
-// CSBBond ( SB bond class )
-// CSBStructure ( SB structure (monomer) class )
-// CSBIndex ( SB index class )
-//
-// (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-#ifndef __MMDB_SBase__
-#define __MMDB_SBase__
-
-#ifndef __MMDB_Manager__
-#include "mmdb_manager.h"
-#endif
-
-#ifndef __MMDB_SBase0__
-#include "mmdb_sbase0.h"
-#endif
-
-
-
-// =========================== CSBase ============================
-
-DefineStructure(SAtomPair);
-
-struct SAtomPair {
- PCAtom a1,a2;
-};
-
-
-DefineClass(CSBase);
-
-class CSBase : public CSBase0 {
-
- public :
-
- CSBase ();
- ~CSBase();
-
- // CalcHBonds(..) calculates hydrogen bonds and salt bridges
- // between atoms of residues given in Res1[0..nres1-1] and
- // Res2[0..nres2-1]. H-bonds are returned in HBond[0..nHBonds-1]
- // and salt bridges are returned in SBridge[0..nSBridges-1].
- //
- // On input:
- // Res1, Res2 must belong to the same MMDB
- // HBond, SBridge should be set NULL, otherwise the
- // function attempts to deallocate them
- // nHBonds, nSBridges ignored
- // structFile may be a pointer to open SBase stucture
- // file in order to save on file open
- // operation. If structFile is set NULL,
- // the function will open the SBase
- // structure file by itself
- // altLoc specifies the alternative location for
- // donors and acceptors.
- // altLoc==NULL the highest occupancy
- // atoms are taken. If all
- // occupancies are equal
- // equal then atom with
- // first altLoc taken
- // altLoc!=NULL atoms with given altLoc
- // are taken. If such
- // altLoc is not found,
- // the function acts as
- // if NULL value for altLoc
- // were given.
- // ignoreNegSigOcc if it is set True, then the function
- // ignores atoms with negative occupancy
- // standard deviation. Such atoms may be
- // hydrogens added by
- // CSBase0::AddHydrogen(..) function, in
- // general any atoms added by
- // CSBAtom::MakeCAtom(..) function. Such
- // added hydrogens are note guaranteed to
- // be in correct place, therefore the
- // function may mistake on some hydrogen
- // bonds if they are not neglected.
- //
- // On output:
- // Allocated arrays HBond[0..nHBonds-1] and
- // SBridge[0..nSBridges-1]. If no bonds/bridges were found,
- // the corresponding array is not allocated and set NULL.
- // Application is responsible for deallocation of the arrays,
- // when not needed, using statements
- // if (HBond) delete[] HBond;
- // if (SBridge) delete[] SBridge;
- // HBond[i].a1, SBridge[i].a1 always refer atom from Res1[],
- // and HBond[i].a2, SBridge[i].a2 always refer atom from
- // Res2[].
- //
- int CalcHBonds ( PPCResidue Res1, int nres1,
- PPCResidue Res2, int nres2,
- RPSAtomPair HBond, int & nHBonds,
- RPSAtomPair SBridge, int & nSBridges,
- PCFile structFile=NULL, pstr altLoc=NULL,
- Boolean ignoreNegSigOcc=False );
-
- protected :
- // Geometry parameters for H-bond calculations
- realtype minDAdist,maxSBdist,maxDAdist,maxHAdist2;
- realtype maxDHAcos,maxHAAcos,maxDAAcos,maxDDAcos;
-
- void InitSBase ();
- void FreeMemory();
-
-};
-
-#endif
diff --git a/mmdb/mmdb_sbase0.cpp b/mmdb/mmdb_sbase0.cpp
deleted file mode 100755
index c7a5451..0000000
--- a/mmdb/mmdb_sbase0.cpp
+++ /dev/null
@@ -1,3124 +0,0 @@
-// $Id: mmdb_sbase0.cpp,v 1.19 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 29.01.10 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : mmdb_sbase0 <implementation>
-// ~~~~~~~~~
-// **** Classes : CSBase0 ( structure base manager 0 )
-// ~~~~~~~~~ CSBAtom ( SB atom class )
-// CSBBond ( SB bond class )
-// CSBStructure ( SB structure (monomer) class )
-// CSBIndex ( SB index class )
-//
-// (C) E. Krissinel 2000-2010
-//
-// =================================================================
-//
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-
-#ifndef __LinAlg__
-#include "linalg_.h"
-#endif
-
-#ifndef __MMDB_SBase0__
-#include "mmdb_sbase0.h"
-#endif
-
-#ifndef __MMDB_Tables__
-#include "mmdb_tables.h"
-#endif
-
-
-
-// ====================== SB Atom Class =========================
-
-CSBAtom::CSBAtom() : CStream() {
- SBAtomInit();
-}
-
-CSBAtom::CSBAtom ( RPCStream Object ) : CStream(Object) {
- SBAtomInit();
-}
-
-CSBAtom::~CSBAtom() {}
-
-void CSBAtom::SBAtomInit() {
- sca_name [0] = char(0);
- pdb_name [0] = char(0);
- old_pdb_name[0] = char(0);
- element [0] = char(0);
- energyType [0] = char(0);
- x = -MaxReal;
- y = -MaxReal;
- z = -MaxReal;
- x_esd = 0.0;
- y_esd = 0.0;
- z_esd = 0.0;
- ccp4_charge = 0.0; // atom charge from ccp4 libs
- sca_charge = 0.0; // formal atom charge (MSD)
- partial_charge = 0.0; // partial atom charge (MSD)
- vdw_radius = 0.0;
- vdwh_radius = 0.0;
- ion_radius = 0.0;
- valency = 0;
- chirality = 'N';
- leaving = 'N';
- hb_type = 'N';
-}
-
-void CSBAtom::Copy ( PCSBAtom A ) {
- strcpy ( sca_name ,A->sca_name );
- strcpy ( pdb_name ,A->pdb_name );
- strcpy ( old_pdb_name,A->old_pdb_name );
- strcpy ( element ,A->element );
- strcpy ( energyType ,A->energyType );
- x = A->x;
- y = A->y;
- z = A->z;
- x_esd = A->x_esd;
- y_esd = A->y_esd;
- z_esd = A->z_esd;
- ccp4_charge = A->ccp4_charge;
- sca_charge = A->sca_charge;
- partial_charge = A->partial_charge;
- vdw_radius = A->vdw_radius;
- vdwh_radius = A->vdwh_radius;
- ion_radius = A->ion_radius;
- valency = A->valency;
- chirality = A->chirality;
- leaving = A->leaving;
- hb_type = A->hb_type;
-}
-
-void CSBAtom::makeCAtom ( RPCAtom a ) {
- if (!a) a = newCAtom();
- a->SetAtomName ( 0,0,pdb_name,"","",element );
- a->SetCharge ( ccp4_charge );
- a->SetCoordinates ( x,y,z,1.0,0.0 );
- strcpy ( a->energyType,energyType );
- a->sigOcc = -1.0; // signal that atom was added from SBase
-}
-
-PCAtom CSBAtom::makeCAtom() {
-PCAtom a;
- a = newCAtom();
- a->SetAtomName ( 0,0,pdb_name,"","",element );
- a->SetCharge ( ccp4_charge );
- a->SetCoordinates ( x,y,z,1.0,0.0 );
- strcpy ( a->energyType,energyType );
- a->sigOcc = -1.0; // signal that atom was added from SBase
- return a;
-}
-
-
-void CSBAtom::write ( RCFile f ) {
-int Version=5;
- f.WriteInt ( &Version );
- f.WriteFile ( sca_name ,sizeof(sca_name) );
- f.WriteFile ( pdb_name ,sizeof(pdb_name) );
- f.WriteFile ( old_pdb_name,sizeof(old_pdb_name) );
- f.WriteFile ( element ,sizeof(element) );
- f.WriteFile ( energyType ,sizeof(energyType) );
- f.WriteReal ( &x );
- f.WriteReal ( &y );
- f.WriteReal ( &z );
- f.WriteReal ( &x_esd );
- f.WriteReal ( &y_esd );
- f.WriteReal ( &z_esd );
- f.WriteReal ( &ccp4_charge );
- f.WriteReal ( &sca_charge );
- f.WriteReal ( &partial_charge );
- f.WriteReal ( &vdw_radius );
- f.WriteReal ( &vdwh_radius );
- f.WriteReal ( &ion_radius );
- f.WriteInt ( &valency );
- f.WriteFile ( &chirality,sizeof(chirality) );
- f.WriteFile ( &leaving ,sizeof(leaving) );
- f.WriteFile ( &hb_type ,sizeof(hb_type) );
-}
-
-void CSBAtom::read ( RCFile f ) {
-int Version;
- f.ReadInt ( &Version );
- f.ReadFile ( sca_name ,sizeof(sca_name) );
- f.ReadFile ( pdb_name ,sizeof(pdb_name) );
- if (Version>4)
- f.ReadFile ( old_pdb_name,sizeof(old_pdb_name) );
- else strcpy ( old_pdb_name,pdb_name );
- f.ReadFile ( element ,sizeof(element) );
- f.ReadFile ( energyType,sizeof(energyType) );
- f.ReadReal ( &x );
- f.ReadReal ( &y );
- f.ReadReal ( &z );
- f.ReadReal ( &x_esd );
- f.ReadReal ( &y_esd );
- f.ReadReal ( &z_esd );
- if (Version>2)
- f.ReadReal ( &ccp4_charge );
- if (Version>3) {
- f.ReadReal ( &sca_charge );
- f.ReadReal ( &partial_charge );
- }
- if (Version>1) {
- f.ReadReal ( &vdw_radius );
- f.ReadReal ( &vdwh_radius );
- f.ReadReal ( &ion_radius );
- f.ReadInt ( &valency );
- }
- f.ReadFile ( &chirality,sizeof(chirality) );
- f.ReadFile ( &leaving ,sizeof(leaving) );
- if (Version>1)
- f.ReadFile ( &hb_type,sizeof(hb_type) );
-}
-
-MakeStreamFunctions(CSBAtom)
-
-
-
-// ======================= SB Bond Class =======================
-
-CSBBond::CSBBond() : CStream() {
- SBBondInit();
-}
-
-CSBBond::CSBBond ( RPCStream Object ) : CStream(Object) {
- SBBondInit();
-}
-
-CSBBond::~CSBBond() {}
-
-void CSBBond::SBBondInit() {
- atom1 = -1;
- atom2 = -1;
- order = BOND_SINGLE;
- length = 0.0;
- length_esd = 0.0;
-}
-
-void CSBBond::SetBond ( int at1, int at2, int ord ) {
- atom1 = at1;
- atom2 = at2;
- order = ord;
-}
-
-void CSBBond::Copy ( PCSBBond B ) {
- atom1 = B->atom1;
- atom2 = B->atom2;
- order = B->order;
- length = B->length;
- length_esd = B->length_esd;
-}
-
-void CSBBond::write ( RCFile f ) {
-int Version=1;
- f.WriteInt ( &Version );
- f.WriteInt ( &atom1 );
- f.WriteInt ( &atom2 );
- f.WriteInt ( &order );
- f.WriteReal ( &length );
- f.WriteReal ( &length_esd );
-}
-
-void CSBBond::read ( RCFile f ) {
-int Version;
- f.ReadInt ( &Version );
- f.ReadInt ( &atom1 );
- f.ReadInt ( &atom2 );
- f.ReadInt ( &order );
- f.ReadReal ( &length );
- f.ReadReal ( &length_esd );
-}
-
-
-MakeStreamFunctions(CSBBond)
-
-
-
-// ======================= SB Angle Class =====================
-
-CSBAngle::CSBAngle() : CStream() {
- SBAngleInit();
-}
-
-CSBAngle::CSBAngle ( RPCStream Object ) : CStream(Object) {
- SBAngleInit();
-}
-
-CSBAngle::~CSBAngle() {}
-
-void CSBAngle::SBAngleInit() {
- atom1 = -1;
- atom2 = -1;
- atom3 = -1;
- angle = 0.0;
- angle_esd = 0.0;
-}
-
-void CSBAngle::Copy ( PCSBAngle G ) {
- atom1 = G->atom1;
- atom2 = G->atom2;
- atom3 = G->atom3;
- angle = G->angle;
- angle_esd = G->angle_esd;
-}
-
-void CSBAngle::write ( RCFile f ) {
-int Version=1;
- f.WriteInt ( &Version );
- f.WriteInt ( &atom1 );
- f.WriteInt ( &atom2 );
- f.WriteInt ( &atom3 );
- f.WriteReal ( &angle );
- f.WriteReal ( &angle_esd );
-}
-
-void CSBAngle::read ( RCFile f ) {
-int Version;
- f.ReadInt ( &Version );
- f.ReadInt ( &atom1 );
- f.ReadInt ( &atom2 );
- f.ReadInt ( &atom3 );
- f.ReadReal ( &angle );
- f.ReadReal ( &angle_esd );
-}
-
-
-MakeStreamFunctions(CSBAngle)
-
-
-
-// ====================== SB Torsion Class ===================
-
-CSBTorsion::CSBTorsion() : CStream() {
- SBTorsionInit();
-}
-
-CSBTorsion::CSBTorsion ( RPCStream Object ) : CStream(Object) {
- SBTorsionInit();
-}
-
-CSBTorsion::~CSBTorsion() {}
-
-void CSBTorsion::SBTorsionInit() {
- atom1 = -1;
- atom2 = -1;
- atom3 = -1;
- atom4 = -1;
- torsion = 0.0;
- torsion_esd = 0.0;
-}
-
-void CSBTorsion::Copy ( PCSBTorsion T ) {
- atom1 = T->atom1;
- atom2 = T->atom2;
- atom3 = T->atom3;
- atom4 = T->atom4;
- torsion = T->torsion;
- torsion_esd = T->torsion_esd;
-}
-
-void CSBTorsion::write ( RCFile f ) {
-int Version=1;
- f.WriteInt ( &Version );
- f.WriteInt ( &atom1 );
- f.WriteInt ( &atom2 );
- f.WriteInt ( &atom3 );
- f.WriteInt ( &atom4 );
- f.WriteReal ( &torsion );
- f.WriteReal ( &torsion_esd );
-}
-
-void CSBTorsion::read ( RCFile f ) {
-int Version;
- f.ReadInt ( &Version );
- f.ReadInt ( &atom1 );
- f.ReadInt ( &atom2 );
- f.ReadInt ( &atom3 );
- f.ReadInt ( &atom4 );
- f.ReadReal ( &torsion );
- f.ReadReal ( &torsion_esd );
-}
-
-
-MakeStreamFunctions(CSBTorsion)
-
-
-
-// ==================== Structure Class =========================
-
-CSBStructure::CSBStructure() : CStream() {
- SBStructureInit();
-}
-
-CSBStructure::CSBStructure ( RPCStream Object ) : CStream(Object) {
- SBStructureInit();
-}
-
-CSBStructure::~CSBStructure() {
- FreeMemory();
-}
-
-void CSBStructure::Reset() {
- FreeMemory();
- SBStructureInit();
-}
-
-void CSBStructure::FreeMemory() {
-int i;
-
- if (Formula) delete[] Formula;
- if (Name) delete[] Name;
- if (Synonym) delete[] Synonym;
- if (Charge) delete[] Charge;
- Formula = NULL;
- Name = NULL;
- Synonym = NULL;
- Charge = NULL;
-
- FreeVectorMemory ( leavingAtom,0 );
- FreeVectorMemory ( bondedAtom ,0 );
- nLeavingAtoms = 0;
-
- for (i=0;i<nAAlloc;i++)
- if (Atom[i]) delete Atom[i];
- if (Atom) delete[] Atom;
- Atom = NULL;
- nAtoms = 0;
- nAAlloc = 0;
-
- for (i=0;i<nBAlloc;i++)
- if (Bond[i]) delete Bond[i];
- if (Bond) delete[] Bond;
- Bond = NULL;
- nBonds = 0;
- nBAlloc = 0;
-
- for (i=0;i<nGAlloc;i++)
- if (Angle[i]) delete Angle[i];
- if (Angle) delete[] Angle;
- Angle = NULL;
- nAngles = 0;
- nGAlloc = 0;
-
- for (i=0;i<nTAlloc;i++)
- if (Torsion[i]) delete Torsion[i];
- if (Torsion) delete[] Torsion;
- Torsion = NULL;
- nTorsions = 0;
- nTAlloc = 0;
-
-}
-
-void CSBStructure::SBStructureInit() {
-
- compoundID[0] = char(0);
-
- Formula = NULL;
- Name = NULL;
- Synonym = NULL;
- Charge = NULL;
-
- nLeavingAtoms = 0;
- leavingAtom = NULL;
- bondedAtom = NULL;
-
- Atom = NULL;
- nAtoms = 0;
- nAAlloc = 0;
-
- Bond = NULL;
- nBonds = 0;
- nBAlloc = 0;
-
- Angle = NULL;
- nAngles = 0;
- nGAlloc = 0;
-
- Torsion = NULL;
- nTorsions = 0;
- nTAlloc = 0;
-
- xyz_source = 'N';
-
-}
-
-void CSBStructure::PutFormula ( cpstr F ) {
- CreateCopy ( Formula,F );
-}
-
-void CSBStructure::PutName ( cpstr N ) {
- CreateCopy ( Name,N );
-}
-
-void CSBStructure::PutSynonym ( cpstr S ) {
- CreateCopy ( Synonym,S );
-}
-
-void CSBStructure::PutCharge ( cpstr G ) {
- CreateCopy ( Charge,G );
-}
-
-void CSBStructure::AddAtom ( PCSBAtom atom ) {
-PPCSBAtom Atom1;
-int i;
- if (nAtoms>=nAAlloc) {
- nAAlloc += 50;
- Atom1 = new PCSBAtom[nAAlloc];
- for (i=0;i<nAtoms;i++)
- Atom1[i] = Atom[i];
- for (i=nAtoms;i<nAAlloc;i++)
- Atom1[i] = NULL;
- if (Atom) delete[] Atom;
- Atom = Atom1;
- }
- Atom[nAtoms++] = atom;
-}
-
-void CSBStructure::AddBond ( PCSBBond bond ) {
-// should be called after all atoms are set up
-PPCSBBond Bond1;
-int i;
- if (nBonds>=nBAlloc) {
- nBAlloc += 50;
- Bond1 = new PCSBBond[nBAlloc];
- for (i=0;i<nBonds;i++)
- Bond1[i] = Bond[i];
- for (i=nBonds;i<nBAlloc;i++)
- Bond1[i] = NULL;
- if (Bond) delete[] Bond;
- Bond = Bond1;
- }
- Bond[nBonds++] = bond;
-}
-
-void CSBStructure::MakeLeavingAtoms() {
-// should be called after all atoms and bonds are set up
-int i,j;
-
- FreeVectorMemory ( leavingAtom,0 );
- FreeVectorMemory ( bondedAtom ,0 );
-
- nLeavingAtoms = 0;
- for (i=0;i<nAtoms;i++)
- if (Atom[i]->leaving=='Y')
- nLeavingAtoms++;
-
- if (nLeavingAtoms>0) {
- GetVectorMemory ( leavingAtom,nLeavingAtoms,0 );
- GetVectorMemory ( bondedAtom ,nLeavingAtoms,0 );
- j = 0;
- for (i=0;i<nAtoms;i++)
- if (Atom[i]->leaving=='Y') {
- leavingAtom[j] = i+1;
- bondedAtom [j] = 0;
- j++;
- }
- for (i=0;i<nLeavingAtoms;i++)
- for (j=0;j<nBonds;j++) {
- if ((leavingAtom[i]==Bond[j]->atom1) &&
- (strcmp(Atom[Bond[j]->atom2-1]->element," H")))
- bondedAtom[i] = Bond[j]->atom2;
- else if ((leavingAtom[i]==Bond[j]->atom2) &&
- (strcmp(Atom[Bond[j]->atom1-1]->element," H")))
- bondedAtom[i] = Bond[j]->atom1;
- }
- }
-
-}
-
-void CSBStructure::AddAngle ( PCSBAngle angle ) {
-PPCSBAngle Angle1;
-int i;
- if (nAngles>=nGAlloc) {
- nGAlloc += 50;
- Angle1 = new PCSBAngle[nGAlloc];
- for (i=0;i<nAngles;i++)
- Angle1[i] = Angle[i];
- for (i=nAngles;i<nGAlloc;i++)
- Angle1[i] = NULL;
- if (Angle) delete[] Angle;
- Angle = Angle1;
- }
- Angle[nAngles++] = angle;
-}
-
-void CSBStructure::AddTorsion ( PCSBTorsion torsion ) {
-PPCSBTorsion Torsion1;
-int i;
- if (nTorsions>=nTAlloc) {
- nTAlloc += 50;
- Torsion1 = new PCSBTorsion[nTAlloc];
- for (i=0;i<nTorsions;i++)
- Torsion1[i] = Torsion[i];
- for (i=nTorsions;i<nTAlloc;i++)
- Torsion1[i] = NULL;
- if (Torsion) delete[] Torsion;
- Torsion = Torsion1;
- }
- Torsion[nTorsions++] = torsion;
-}
-
-void CSBStructure::RemoveEnergyTypes() {
-int i;
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) Atom[i]->energyType[0] = char(0);
-}
-
-int CSBStructure::SetEnergyType ( cpstr sca_name,
- cpstr energyType,
- realtype partial_charge ) {
-int n;
- n = GetAtomNo ( sca_name );
- if (n>0) {
- strcpy ( Atom[n-1]->energyType,energyType );
- Atom[n-1]->partial_charge = partial_charge;
- }
- return n;
-}
-
-int CSBStructure::GetAtomNo ( cpstr sca_name ) {
-int n,i;
- n = 0;
- for (i=0;(i<nAtoms) && (!n);i++)
- if (Atom[i]) {
- if (!strcmp(sca_name,Atom[i]->sca_name))
- n = i+1;
- }
- return n;
-}
-
-int CSBStructure::GetAtomNo_nss ( cpstr sca_name ) {
-// disregards leading and trailing spaces
-AtomName name_0;
-AtomName name_i;
-int n,i;
- strcpy_css ( name_0,sca_name );
-// printf ( " name_0 = '%s'\n",name_0 );
- n = 0;
- for (i=0;(i<nAtoms) && (!n);i++)
- if (Atom[i]) {
- strcpy_css ( name_i,Atom[i]->sca_name );
-// printf ( " name_i = '%s'\n",name_i );
- if (!strcmp(name_0,name_i))
- n = i+1;
- }
- return n;
-}
-
-PCSBAtom CSBStructure::GetAtom ( cpstr sca_name ) {
-int n;
- n = GetAtomNo ( sca_name );
- if (n>0) return Atom[n-1];
- else return NULL;
-}
-
-
-void CSBStructure::GetAtomTable ( PPCAtom & atomTable,
- int & nOfAtoms ) {
-int i;
- nOfAtoms = nAtoms;
- if (nAtoms>0) {
- atomTable = new PCAtom[nAtoms];
- for (i=0;i<nAtoms;i++) {
- atomTable[i] = NULL;
- if (Atom[i]) Atom[i]->makeCAtom ( atomTable[i] );
- }
- } else
- atomTable = NULL;
-}
-
-void CSBStructure::GetAtomNameMatch ( PPCAtom A, int nat, pstr altLoc,
- ivector anmatch ) {
-// GetAtomNameMatch(..) returns anmatch[i], i=0..nAtoms-1, equal
-// to j such that name(Atom[i])==name(A[j]). Note that atom names
-// are similarly aligned and space-padded in both MMDb and SBase.
-// If ith atom in the structue is not found in A, anmatch[i] is
-// set -1.
-// If array A contains atoms in different alternative conformations,
-// the the value of altLoc is interpreted as follows:
-// NULL - the highest occupancy atom will be taken
-// if all occupancies are equal then atom with
-// first altLoc taken
-// other - atoms with given altLoc are taken. If such
-// altLoc is not found, the function does as if
-// NULL value for altLoc is given.
-// A clean PDB file is anticipated, so that atoms with alternative
-// conformations are grouped together.
-// It is Ok to have NULL pointers in A.
-int i,j,k;
-Boolean done;
-
- for (i=0;i<nAtoms;i++) {
- k = -1;
- j = 0;
- done = False;
- while ((j<nat) && (!done)) {
- if (A[j]) {
- if ((!A[j]->Ter) && (!strcmp(A[j]->name,Atom[i]->pdb_name))) {
- k = j; // atom found
- // check now for altLocs
- j++;
- while ((j<nat) && (!done)) {
- if (A[j]) {
- done = (A[j]->Ter ||
- (strcmp(A[j]->name,Atom[i]->pdb_name)));
- if (!done) {
- if (A[j]->occupancy>A[k]->occupancy) k = j;
- if (altLoc) {
- if (!strcmp(A[j]->altLoc,altLoc)) {
- k = j;
- done = True;
- }
- }
- }
- }
- j++;
- }
- }
- }
- j++;
- }
- anmatch[i] = k;
- }
-
-}
-
-int CSBStructure::CheckAtoms() {
-// CheckAtoms() returns -1 if there is no atoms
-// -2 if not all atoms are annotated
-// -3 if not all coordinates are set
-// 0 otherwise
-int i,rc;
- if (nAtoms<=0) return -1;
- for (i=0;i<nAtoms;i++)
- if (!Atom[i]) {
- rc = -2;
- break;
- } else if (Atom[i]->x==-MaxReal)
- rc = -3;
- return rc;
-}
-
-PCResidue CSBStructure::makeCResidue ( Boolean includeHydrogens,
- Boolean makeTer ) {
-PCResidue Res;
-int i;
- Res = newCResidue();
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- if ((makeTer || strcmp(&(Atom[i]->pdb_name[2]),"XT")) &&
- (includeHydrogens || strcmp(Atom[i]->element," H")))
- Res->AddAtom ( Atom[i]->makeCAtom() );
- }
- return Res;
-}
-
-
-
-int superpose_atoms ( mat44 & T, PPCSBAtom A1, PPCAtom A2, int nAtoms,
- rmatrix & A, rmatrix & U, rmatrix & V,
- rvector & W, rvector & RV1 ) {
-// Given two sets of atoms, A1 and A2, superpose_atoms(...)
-// calculates the rotational-translational matrix T such that
-// |T*A1 - A2| is minimal in least-square terms. The transfomation
-// superposes exactly the atoms A1[0] and A2[0].
-realtype det,B;
-vect3 vc1,vc2;
-int i,j,k;
-
- // 1. Calculate the correlation matrix. The rotation will be
- // done around
-
- for (i=1;i<=3;i++)
- for (j=1;j<=3;j++)
- A[i][j] = 0.0;
-
- for (k=1;k<nAtoms;k++) {
- vc1[0] = A1[k]->x - A1[0]->x;
- vc1[1] = A1[k]->y - A1[0]->y;
- vc1[2] = A1[k]->z - A1[0]->z;
- vc2[0] = A2[k]->x - A2[0]->x;
- vc2[1] = A2[k]->y - A2[0]->y;
- vc2[2] = A2[k]->z - A2[0]->z;
- for (i=1;i<=3;i++)
- for (j=1;j<=3;j++)
- A[i][j] += vc1[j-1]*vc2[i-1];
- }
-
- // 2. Calculate transformation matrix (to be applied to A1)
-
- det = A[1][1]*A[2][2]*A[3][3] +
- A[1][2]*A[2][3]*A[3][1] +
- A[2][1]*A[3][2]*A[1][3] -
- A[1][3]*A[2][2]*A[3][1] -
- A[1][1]*A[2][3]*A[3][2] -
- A[3][3]*A[1][2]*A[2][1];
-
- // 2.1 SV-decompose the correlation matrix
-
- SVD ( 3,3,3,A,U,V,W,RV1,True,True,i );
-
- if (i!=0) return SPOSEAT_SVD_Fail;
-
- // 2.2 Check for parasite inversion and fix it if found
-
- if (det<=0.0) {
- k = 0;
- B = MaxReal;
- for (j=1;j<=3;j++)
- if (W[j]<B) {
- B = W[j];
- k = j;
- }
- for (j=1;j<=3;j++)
- V[j][k] = -V[j][k];
- }
-
- // 2.3 Calculate rotational part of T
-
- for (j=1;j<=3;j++)
- for (k=1;k<=3;k++) {
- B = 0.0;
- for (i=1;i<=3;i++)
- B += U[j][i]*V[k][i];
- T[j-1][k-1] = B;
- }
-
- // 2.4 Add translational part to T
-
- T[0][3] = A2[0]->x - T[0][0]*A1[0]->x - T[0][1]*A1[0]->y -
- T[0][2]*A1[0]->z;
- T[1][3] = A2[0]->y - T[1][0]*A1[0]->x - T[1][1]*A1[0]->y -
- T[1][2]*A1[0]->z;
- T[2][3] = A2[0]->z - T[2][0]*A1[0]->x - T[2][1]*A1[0]->y -
- T[2][2]*A1[0]->z;
-
- return SPOSEAT_Ok;
-
-}
-
-
-int CSBStructure::AddHydrogens ( PCResidue R ) {
-//
-// Return:
-// SBASE_Ok success
-// SBASE_EmptyResidue residue R does not contain atoms
-// SBASE_NoAtomsFound SBStructure does not contain atoms
-// SBASE_NoBonds SBStructure does not contain bonds
-// SBASE_NoAtomsData SBStructure is not complete
-// SBASE_NoSimilarity too few coomon atom names in R and SBase
-// entry with the same structure name
-// SBASE_SuperpositionFailed failed residue superposition
-//
-// NOTE1: the function does not rearranges existing atoms in the
-// residue, but places the hydrogens on top of them (leaving the
-// Ter pseudoatom, if found, on top of the list).
-//
-// NOTE2: in case of alternative locations, the first one in the
-// residue is chosen.
-//
-PPCAtom H;
-PCSBAtom sa1[10];
-PCAtom sa2[10];
-rmatrix D,U,V;
-rvector W,RV1;
-imatrix c;
-ivector A,nb;
-mat44 T;
-int i,j,k,m,n,mm,nTer,nH;
-
- // 1. Make simple checks
-
- if (nAtoms<=2) return SBASE_NoAtomsFound;
- if (nBonds<=0) return SBASE_NoBonds;
- if (R->nAtoms<=2) return SBASE_EmptyResidue;
- if (nAtoms==R->nAtoms) return SBASE_Ok;
-
- // 2. Map existing atoms from the residue onto a local array
-
- GetVectorMemory ( A,nAtoms,0 );
- nTer = 20000;
- for (i=0;i<nAtoms;i++) {
- A[i] = -1; // signal "no atom"
- for (j=0;(j<R->nAtoms) && (A[i]<0);j++)
- if (R->atom[j]) {
- if (R->atom[j]->Ter)
- nTer = j;
- else if (!strcmp(Atom[i]->pdb_name,R->atom[j]->name))
- A[i] = j; // here is the place to check for altlocs
- }
- }
-
- // 3. Make bond matrix
-
- GetMatrixMemory ( c ,nAtoms,10,0,0 );
- GetVectorMemory ( nb,nAtoms,0 );
-
- for (i=0;i<nAtoms;i++)
- nb[i] = 0; // number of bonds at ith atom
-
- for (i=0;i<nBonds;i++) {
- j = Bond[i]->atom1-1;
- k = Bond[i]->atom2-1;
- c[j][nb[j]] = k;
- c[k][nb[k]] = j;
- nb[j]++;
- nb[k]++;
- }
-
- // 4. Loop over all hydrogens. Locate core atoms bonded to
- // hydrogen in SBStructure and superpose them with the
- // corresponding atoms in the residue. Using the superposition
- // matrix, add hydrogens to the residue.
-
- GetMatrixMemory ( D ,3,3,1,1 );
- GetMatrixMemory ( U ,3,3,1,1 );
- GetMatrixMemory ( V ,3,3,1,1 );
- GetVectorMemory ( W ,3,1 );
- GetVectorMemory ( RV1,3,1 );
-
- H = new PCAtom[nAtoms];
- nH = 0;
-
- for (i=0;i<nAtoms;i++)
- if ((!strcmp(Atom[i]->element," H")) && (A[i]<0) && (nb[i]>0) &&
- (Atom[i]->x>-MaxReal)) {
- // ith atom is a hydrogen which is not found in the residue.
- // Find 3+ core atoms that are most closely bonded to this one.
- n = c[i][0]; // core atom bonded to the hydrogen
- if (A[n]>=0) {
- sa1[0] = Atom[n];
- sa2[0] = R->atom[A[n]];
- mm = 1;
- m = 1;
- while ((m<3) && (mm<2)) {
- k = n;
- for (j=0;(j<nb[k]) && (m<10);j++) {
- n = c[k][j];
- if (A[n]>=0) {
- sa1[m] = Atom[n];
- sa2[m] = R->atom[A[n]];
- m++;
- }
- }
- mm++;
- }
- if (m>=3) {
- // superpose atoms and add the hydrogen to the residue
- k = superpose_atoms ( T,sa1,sa2,m,D,U,V,W,RV1 );
- if (k==SPOSEAT_Ok) {
- H[nH] = Atom[i]->makeCAtom();
- H[nH]->Transform ( T );
- nH++;
- }
- }
- }
- }
-
- // 5. Put hydrogens into the residue
-
- for (i=0;i<nH;i++) {
- R->InsertAtom ( H[i],nTer );
- nTer++;
- }
-
- // 6. Release memory and return
-
- if (H) delete[] H;
- FreeVectorMemory ( A,0 );
-
- FreeVectorMemory ( RV1,1 );
- FreeVectorMemory ( W ,1 );
- FreeMatrixMemory ( V ,3,1,1 );
- FreeMatrixMemory ( U ,3,1,1 );
- FreeMatrixMemory ( D ,3,1,1 );
-
- FreeVectorMemory ( nb,0 );
- FreeMatrixMemory ( c ,nAtoms,0,0 );
-
- return SBASE_Ok;
-
-}
-
-void CSBStructure::Copy ( PCSBStructure S ) {
-int i;
-
- FreeMemory();
-
- strcpy ( compoundID,S->compoundID );
- CreateCopy ( Formula ,S->Formula );
- CreateCopy ( Name ,S->Name );
- CreateCopy ( Synonym ,S->Synonym );
- CreateCopy ( Charge ,S->Charge );
- xyz_source = S->xyz_source;
-
- nLeavingAtoms = S->nLeavingAtoms;
- if (nLeavingAtoms>0) {
- GetVectorMemory ( leavingAtom,nLeavingAtoms,0 );
- GetVectorMemory ( bondedAtom ,nLeavingAtoms,0 );
- for (i=0;i<nLeavingAtoms;i++) {
- leavingAtom[i] = S->leavingAtom[i];
- bondedAtom [i] = S->bondedAtom [i];
- }
- }
-
- nAtoms = S->nAtoms;
- nAAlloc = nAtoms;
- if (nAtoms>0) {
- Atom = new PCSBAtom[nAtoms];
- for (i=0;i<nAtoms;i++) {
- Atom[i] = new CSBAtom();
- Atom[i]->Copy ( S->Atom[i] );
- }
- }
-
- nBonds = S->nBonds;
- nBAlloc = nBonds;
- if (nBonds>0) {
- Bond = new PCSBBond[nBonds];
- for (i=0;i<nBonds;i++) {
- Bond[i] = new CSBBond();
- Bond[i]->Copy ( S->Bond[i] );
- }
- }
-
- nAngles = S->nAngles;
- nGAlloc = nAngles;
- if (nAngles>0) {
- Angle = new PCSBAngle[nAngles];
- for (i=0;i<nAngles;i++) {
- Angle[i] = new CSBAngle();
- Angle[i]->Copy ( S->Angle[i] );
- }
- }
-
- nTorsions = S->nTorsions;
- nTAlloc = nTorsions;
- if (nTorsions>0) {
- Torsion = new PCSBTorsion[nTorsions];
- for (i=0;i<nTorsions;i++) {
- Torsion[i] = new CSBTorsion();
- Torsion[i]->Copy ( S->Torsion[i] );
- }
- }
-
-}
-
-
-void CSBStructure::write ( RCFile f ) {
-int i,Version=1;
-
- f.WriteInt ( &Version );
-
- f.WriteFile ( compoundID,sizeof(compoundID) );
- f.CreateWrite ( Formula );
- f.CreateWrite ( Name );
- f.CreateWrite ( Synonym );
- f.CreateWrite ( Charge );
- f.WriteFile ( &xyz_source,sizeof(xyz_source) );
-
- f.WriteInt ( &nLeavingAtoms );
- for (i=0;i<nLeavingAtoms;i++) {
- f.WriteInt ( &(leavingAtom[i]) );
- f.WriteInt ( &(bondedAtom [i]) );
- }
-
- f.WriteInt ( &nAtoms );
- for (i=0;i<nAtoms;i++)
- StreamWrite ( f,Atom[i] );
-
- f.WriteInt ( &nBonds );
- for (i=0;i<nBonds;i++)
- StreamWrite ( f,Bond[i] );
-
- f.WriteInt ( &nAngles );
- for (i=0;i<nAngles;i++)
- StreamWrite ( f,Angle[i] );
-
- f.WriteInt ( &nTorsions );
- for (i=0;i<nTorsions;i++)
- StreamWrite ( f,Torsion[i] );
-
-}
-
-void CSBStructure::read ( RCFile f ) {
-int i,Version;
-
- FreeMemory();
-
- f.ReadInt ( &Version );
-
- f.ReadFile ( compoundID,sizeof(compoundID) );
- f.CreateRead ( Formula );
- f.CreateRead ( Name );
- f.CreateRead ( Synonym );
- f.CreateRead ( Charge );
- f.ReadFile ( &xyz_source,sizeof(xyz_source) );
-
- f.ReadInt ( &nLeavingAtoms );
- if (nLeavingAtoms>0) {
- GetVectorMemory ( leavingAtom,nLeavingAtoms,0 );
- GetVectorMemory ( bondedAtom ,nLeavingAtoms,0 );
- for (i=0;i<nLeavingAtoms;i++) {
- f.ReadInt ( &(leavingAtom[i]) );
- f.ReadInt ( &(bondedAtom [i]) );
- }
- }
-
- f.ReadInt ( &nAtoms );
- nAAlloc = nAtoms;
- if (nAtoms>0) {
- Atom = new PCSBAtom[nAtoms];
- for (i=0;i<nAtoms;i++) {
- Atom[i] = NULL;
- StreamRead ( f,Atom[i] );
- }
- }
-
- f.ReadInt ( &nBonds );
- nBAlloc = nBonds;
- if (nBonds>0) {
- Bond = new PCSBBond[nBonds];
- for (i=0;i<nBonds;i++) {
- Bond[i] = NULL;
- StreamRead ( f,Bond[i] );
- }
- }
-
- f.ReadInt ( &nAngles );
- nGAlloc = nAngles;
- if (nAngles>0) {
- Angle = new PCSBAngle[nAngles];
- for (i=0;i<nAngles;i++) {
- Angle[i] = NULL;
- StreamRead ( f,Angle[i] );
- }
- }
-
- f.ReadInt ( &nTorsions );
- nTAlloc = nTorsions;
- if (nTorsions>0) {
- Torsion = new PCSBTorsion[nTorsions];
- for (i=0;i<nTorsions;i++) {
- Torsion[i] = NULL;
- StreamRead ( f,Torsion[i] );
- }
- }
-
-}
-
-MakeStreamFunctions(CSBStructure)
-
-
-
-// ==================== Index Class ==============================
-
-CSBIndex::CSBIndex() : CStream() {
- SBIndexInit();
-}
-
-CSBIndex::CSBIndex ( RPCStream Object ) : CStream(Object) {
- SBIndexInit();
-}
-
-CSBIndex::~CSBIndex() {
- if (Comp1) delete[] Comp1;
- if (Comp2) delete[] Comp2;
-}
-
-void CSBIndex::SBIndexInit () {
- compoundID[0] = char(0);
- nAtoms = 0;
- nBonds = 0;
- fGraphPos = -1;
- fStructPos = -1;
- loadPos = -1; // -1 <=> not loaded
- nXTs = 0; // total number of "XT"-atoms
- Comp1 = NULL;
- Comp2 = NULL;
-}
-
-int CSBIndex::MakeCompositions ( PCSBStructure SBS ) {
-// MakeCompositions(..) makes the compositions strings for the
-// given structure.
-// A composition string consists of records E(N), where E stands
-// for chemical element name, and N - for the number of atoms of this
-// element in the structure. The records E(N) follow in alphabetical
-// order of E without spaces and contain no spaces, records with N=0
-// are excluded.
-// Comp2 differs of Comp1 only if there are leaving atoms and
-// represents the composition with leaving atoms taken into account.
-// If there is no leaving atoms, Comp2==Comp1.
-// The function returns the number of leaving atoms in the.
-// structure.
-char Cmp1[1000];
-char Cmp2[1000];
-char N[50];
-ivector elem;
-int i,k,x,l,nl;
-short n0,n;
-
- nAtoms = SBS->nAtoms;
- nBonds = SBS->nBonds;
-
- strcpy ( Cmp1,"" );
- strcpy ( Cmp2,"" );
-
- GetVectorMemory ( elem,nAtoms,0 );
- for (i=0;i<nAtoms;i++)
- elem[i] = getElementNo ( SBS->Atom[i]->element );
-
- n0 = -1;
- n = 0;
- nl = 0;
- for (i=0;(i<nAtoms) && (n<nElementNames);i++) {
- n = 10000;
- for (k=0;k<nAtoms;k++)
- if ((elem[k]>n0) && (elem[k]<n)) n = elem[k];
- if (n<nElementNames) {
- x = 0;
- l = 0;
- for (k=0;k<nAtoms;k++)
- if (elem[k]==n) {
- x++;
- if (SBS->Atom[k]->leaving=='Y') l++;
- }
- nl += l;
- sprintf ( N,"%s(%i)",ElementName[n-1],x );
- strcat ( Cmp1,N );
- sprintf ( N,"%s(%i)",ElementName[n-1],x-l );
- strcat ( Cmp2,N );
- n0 = n;
- }
- }
-
- FreeVectorMemory ( elem,0 );
-
- CreateCopy ( Comp1,Cmp1 );
- CreateCopy ( Comp2,Cmp2 );
-
- return nl;
-
-}
-
-
-void CSBIndex::write ( RCFile f ) {
-int Version=1;
- f.WriteInt ( &Version );
- f.WriteFile ( compoundID,sizeof(compoundID) );
- f.WriteInt ( &nAtoms );
- f.WriteInt ( &nBonds );
- f.WriteInt ( &fGraphPos );
- f.WriteInt ( &fStructPos );
- f.WriteInt ( &nXTs );
- f.CreateWrite ( Comp1 );
- f.CreateWrite ( Comp2 );
-}
-
-void CSBIndex::read ( RCFile f ) {
-int Version;
- f.ReadInt ( &Version );
- f.ReadFile ( compoundID,sizeof(compoundID) );
- f.ReadInt ( &nAtoms );
- f.ReadInt ( &nBonds );
- f.ReadInt ( &fGraphPos );
- f.ReadInt ( &fStructPos );
- f.ReadInt ( &nXTs );
- f.CreateRead ( Comp1 );
- f.CreateRead ( Comp2 );
-}
-
-MakeStreamFunctions(CSBIndex)
-
-
-
-// ========================= CSBase0 ============================
-
-CSBase0::CSBase0() {
- InitSBase0();
-}
-
-
-CSBase0::~CSBase0() {
- FreeMemory0();
-}
-
-void CSBase0::InitSBase0() {
- dirpath = NULL;
- Index = NULL;
- nStructures = 0;
- nIAlloc = 0;
- nLoad = 0;
- nLAlloc = 0;
- ldGraph = NULL;
- ldStructure = NULL;
-}
-
-void CSBase0::FreeMemory0() {
-int i;
- if (dirpath) delete[] dirpath;
- dirpath = NULL;
- if (Index) {
- for (i=0;i<nStructures;i++)
- delete Index[i];
- delete[] Index;
- }
- Index = NULL;
- nStructures = 0;
- nIAlloc = 0;
- for (i=0;i<nLAlloc;i++) {
- if (ldGraph[i]) delete ldGraph[i];
- if (ldStructure[i]) delete ldStructure[i];
- }
- if (ldGraph) delete[] ldGraph;
- if (ldStructure) delete[] ldStructure;
- nLoad = 0;
- nLAlloc = 0;
- ldGraph = NULL;
- ldStructure = NULL;
-}
-
-pstr CSBase0::GetPath ( pstr & S, cpstr FName ) {
- if (dirpath) {
- if (S) delete[] S;
- S = new char[strlen(dirpath)+strlen(FName)+10];
- strcpy ( S,dirpath );
- strcat ( S,FName );
- } else
- CreateCopy ( S,FName );
- return S;
-}
-
-int CSBase0::LoadIndex1 ( cpstr EnvVar ) {
- return LoadIndex ( getenv(EnvVar) );
-}
-
-int CSBase0::LoadIndex ( cpstr path ) {
-CFile f;
-pstr S;
-int i;
-PPCSBIndex Index1;
-
- FreeMemory0();
-
- if (path) {
- i = strlen(path);
- dirpath = new char[i+10];
- strcpy ( dirpath,path );
- if (i>0) {
- if (dirpath[i-1]!='/') strcat ( dirpath,"/" );
- }
- }
-
- S = NULL;
- f.assign ( GetPath(S,sbIndexFile),False,True );
- if (S) delete[] S;
-
- if (f.reset(True)) {
- while ((!f.FileEnd()) && f.Success()) {
- if (nStructures>=nIAlloc) {
- nIAlloc += 5000;
- Index1 = new PCSBIndex[nIAlloc];
- for (i=0;i<nStructures;i++)
- Index1[i] = Index[i];
- for (i=nStructures;i<nIAlloc;i++)
- Index1[i] = NULL;
- if (Index) delete[] Index;
- Index = Index1;
- }
- Index[nStructures] = new CSBIndex();
- StreamRead ( f,Index[nStructures] );
- if (!f.Success()) {
- delete Index[nStructures];
- Index[nStructures] = NULL;
- } else
- nStructures++;
- }
- f.shut();
- return SBASE_Ok;
- } else
- return SBASE_FileNotFound;
-
-}
-
-
-int CSBase0::LoadStructure ( cpstr compoundID ) {
-// LoadStructure(..) reads structure from *.sbase files and
-// stores it in RAM for faster access. There are no special
-// functions to access loaded structures, all requests to
-// *.sbase files and RAM-storage are dispatched automatically.
-PCFile structFile,graphFile;
-PCGraph G;
-PCSBStructure SBS;
-PPCGraph ldG;
-PPCSBStructure ldS;
-int structNo,i,k,RC;
-
- SBS = NULL;
- G = NULL;
- RC = SBASE_Ok;
- structNo = GetStructNo ( compoundID );
-
- if (structNo!=SBASE_StructNotFound) {
- if (Index[structNo]->loadPos>=0)
- RC = SBASE_AlreadyLoaded;
- else {
- structFile = GetStructFile();
- if (structFile) {
- structFile->seek ( Index[structNo]->fStructPos );
- StreamRead ( *structFile,SBS );
- structFile->shut ();
- delete structFile;
- if (!SBS) RC = SBASE_ReadError;
- } else
- RC = SBASE_FileNotFound;
- }
- if (RC==SBASE_Ok) {
- graphFile = GetGraphFile();
- if (graphFile) {
- graphFile->seek ( Index[structNo]->fGraphPos );
- StreamRead ( *graphFile,G );
- graphFile->shut ();
- if (!G) RC = SBASE_ReadError;
- delete graphFile;
- } else
- RC = SBASE_FileNotFound;
- }
- } else
- RC = SBASE_StructNotFound;
-
- if (RC==SBASE_Ok) {
- k = -1;
- for (i=0;(i<nLAlloc) && (k<0);i++)
- if (!ldStructure[i]) k = i;
- if (k<0) {
- nLAlloc += 100;
- ldS = new PCSBStructure[nLAlloc];
- ldG = new PCGraph [nLAlloc];
- for (i=0;i<nLoad;i++) {
- ldS[i] = ldStructure[i];
- ldG[i] = ldGraph [i];
- }
- for (i=nLoad;i<nLAlloc;i++) {
- ldS[i] = NULL;
- ldG[i] = NULL;
- }
- if (ldStructure) delete[] ldStructure;
- if (ldGraph) delete[] ldGraph;
- ldStructure = ldS;
- ldGraph = ldG;
- k = nLoad;
- }
- ldStructure[k] = SBS;
- ldGraph [k] = G;
- Index[structNo]->loadPos = k;
- } else {
- if (SBS) delete SBS;
- if (G) delete G;
- }
-
- return RC;
-
-}
-
-int CSBase0::UnloadStructure ( cpstr compoundID ) {
-// UnloadStructure(..) deletes strtucture from RAM and releases
-// its memory. The structure is then accessible through a normal
-// way from *.sbase files, which is slower.
-int structNo,ldPos;
- structNo = GetStructNo ( compoundID );
- if (structNo==SBASE_StructNotFound)
- return structNo;
- else {
- ldPos = Index[structNo]->loadPos;
- if (ldPos<0) return SBASE_AlreadyUnloaded;
- if (ldStructure[ldPos]) {
- delete ldStructure[ldPos];
- ldStructure[ldPos] = NULL;
- }
- if (ldGraph[ldPos]) {
- delete ldGraph[ldPos];
- ldGraph[ldPos] = NULL;
- }
- Index[structNo]->loadPos = -1;
- }
- return SBASE_Ok;
-}
-
-
-int MakeChirInd ( char chirality ) {
- if (chirality=='S') return -1;
- if (chirality=='R') return +1;
- return 0;
-}
-
-int MakeElementType ( int ElType, int Chirality, Boolean Cflag ) {
- if (Cflag) {
- if (Chirality<0) return ElType | CHIRAL_LEFT;
- if (Chirality>0) return ElType | CHIRAL_RIGHT;
- }
- return ElType;
-}
-
-int MakeElementType ( int ElType, char chirality, Boolean Cflag ) {
- if (Cflag) {
- if (chirality=='S') return ElType | CHIRAL_LEFT;
- if (chirality=='R') return ElType | CHIRAL_RIGHT;
- }
- return ElType;
-}
-
-int CSBase0::GetStructNo ( cpstr compoundID ) {
-int l1,l2,l,k;
-char id[20];
-
- strcpy_css ( id,compoundID );
-
- k = -1;
-
- if (nStructures<=3) {
- for (l=0;(l<nStructures) && (k<0);l++)
- if (!strcasecmp(Index[l]->compoundID,id))
- k = l;
- if (k>=0) return k;
- return SBASE_StructNotFound;
- }
-
- l = 0;
- l1 = 0;
- l2 = nStructures-1;
- while (l1<l2-1) {
- l = (l1+l2)/2;
- k = strcasecmp ( Index[l]->compoundID,id );
- if (k<0) l1 = l;
- else if (k>0) l2 = l;
- else {
- l1 = l;
- l2 = l;
- }
- }
-
- if (k==0) return l;
- else if (l==l1) {
- if (!strcasecmp(Index[l2]->compoundID,id)) return l2;
- } else if (l==l2) {
- if (!strcasecmp(Index[l1]->compoundID,id)) return l1;
- }
-
- return SBASE_StructNotFound;
-
-}
-
-PCFile CSBase0::GetStructFile() {
-PCFile structFile;
-pstr S;
- structFile = new CFile();
- S = NULL;
- structFile->assign ( GetPath(S,sbStructFile),False,True );
- if (S) delete[] S;
- if (!structFile->reset(True)) {
- delete structFile;
- structFile = NULL;
- }
- return structFile;
-}
-
-PCFile CSBase0::GetGraphFile() {
-PCFile graphFile;
-pstr S;
- graphFile = new CFile();
- S = NULL;
- graphFile->assign ( GetPath(S,sbGraphFile),False,True );
- if (S) delete[] S;
- if (!graphFile->reset(True)) {
- delete graphFile;
- graphFile = NULL;
- }
- return graphFile;
-}
-
-
-PCSBStructure CSBase0::GetStructure ( cpstr compoundID ) {
-// GetStructure returns pointer to the monomer structure
-// identified by 3-letter compoundID. If such structure is not
-// found, the function returns NULL.
-// The function returns a pointer to a private copy of the
-// structure. Modifying it will not change data in the structural
-// database. The application is responsible for deallocating
-// the structure after use (simply use delete).
-// See description of CSBStructure for the explanation of
-// its fields.
-PCFile structFile;
-PCSBStructure SBS;
-int structNo;
- SBS = NULL;
- structNo = GetStructNo ( compoundID );
- if (structNo!=SBASE_StructNotFound) {
- if (Index[structNo]->loadPos>=0) {
- SBS = new CSBStructure();
- SBS->Copy ( ldStructure[Index[structNo]->loadPos] );
- } else {
- structFile = GetStructFile();
- if (structFile) {
- structFile->seek ( Index[structNo]->fStructPos );
- StreamRead ( *structFile,SBS );
- structFile->shut ();
- delete structFile;
- }
- }
- }
- return SBS;
-}
-
-PCSBStructure CSBase0::GetStructure ( int structNo,
- PCFile structFile ) {
-PCFile sFile;
-PCSBStructure SBS;
- SBS = NULL;
- if ((0<=structNo) && (structNo<nStructures)) {
- if (Index[structNo]->loadPos>=0) {
- SBS = new CSBStructure();
- SBS->Copy ( ldStructure[Index[structNo]->loadPos] );
- } else {
- if (!structFile) sFile = GetStructFile();
- else sFile = structFile;
- if (sFile) {
- sFile->seek ( Index[structNo]->fStructPos );
- StreamRead ( *sFile,SBS );
- if (!structFile) delete sFile;
- }
- }
- }
- return SBS;
-}
-
-PCSBStructure CSBase0::GetStructure ( cpstr compoundID,
- PCFile structFile ) {
-// Another form of GetStructure(..) uses an open structure
-// file, which allows to save on opening/closing file if
-// multiple access to SBase structures is required.
-PCFile sFile;
-PCSBStructure SBS;
-int structNo;
- SBS = NULL;
- structNo = GetStructNo ( compoundID );
- if (structNo!=SBASE_StructNotFound) {
- if (Index[structNo]->loadPos>=0) {
- SBS = new CSBStructure();
- SBS->Copy ( ldStructure[Index[structNo]->loadPos] );
- } else {
- if (!structFile) sFile = GetStructFile();
- else sFile = structFile;
- if (sFile) {
- sFile->seek ( Index[structNo]->fStructPos );
- StreamRead ( *sFile,SBS );
- if (!structFile) delete sFile;
- }
- }
- }
- return SBS;
-}
-
-
-PCResidue CSBase0::makeCResidue ( cpstr compoundID,
- PCFile structFile,
- Boolean includeHydrogens,
- Boolean makeTer ) {
-PCSBStructure SBS;
-PCResidue Res;
- SBS = GetStructure ( compoundID,structFile );
- if (SBS) {
- Res = SBS->makeCResidue ( includeHydrogens,makeTer );
- delete SBS;
- return Res;
- } else
- return NULL;
-}
-
-PCResidue CSBase0::makeCResidue ( int structNo,
- PCFile structFile,
- Boolean includeHydrogens,
- Boolean makeTer ) {
-PCSBStructure SBS;
-PCResidue Res;
- SBS = GetStructure ( structNo,structFile );
- if (SBS) {
- Res = SBS->makeCResidue ( includeHydrogens,makeTer );
- delete SBS;
- return Res;
- } else
- return NULL;
-}
-
-
-int CSBase0::GetNofAtoms ( int structNo ) {
- if ((0<=structNo) && (structNo<nStructures))
- return Index[structNo]->nAtoms;
- else return SBASE_StructNotFound;
-}
-
-int CSBase0::GetNofAtoms ( cpstr compoundID ) {
-int structNo;
- structNo = GetStructNo ( compoundID );
- if (structNo!=SBASE_StructNotFound)
- return GetNofAtoms(structNo);
- else return SBASE_StructNotFound;
-}
-
-int CSBase0::GetGraph ( PCFile graphFile, int structNo, RPCGraph G,
- int Hflag ) {
-// GetGraph(..) retrieves data for chemical structure number structNo
-// (as described in Index) from graph file graphFile, then allocates
-// and builds the corresponding graph, which is returned in G.
-// If Hflag is set to 1, all hydrogens are removed from the graph.
-// If Hflag is set to 2, element types of atoms, to which hydrogens
-// are bonded, are modified with flag HYDROGEN_BOND and moved to
-// the end.
-// Returns 0 in case of success.
-int rc,htype;
-
- if ((structNo<0) || (structNo>=nStructures))
- return SBASE_WrongIndex;
-
- rc = SBASE_Ok;
-
- if (Index[structNo]->loadPos>=0) {
-
- if (!G) G = new CGraph();
- G->Copy ( ldGraph[Index[structNo]->loadPos] );
-
- } else {
-
- graphFile->seek ( Index[structNo]->fGraphPos );
- graphFile->SetSuccess();
- StreamRead ( *graphFile,G );
-
- if (!graphFile->Success()) {
- rc = SBASE_ReadError;
- if (G) delete G;
- G = NULL;
- }
-
- }
-
- if (G) {
- G->MakeVertexIDs();
- if (Hflag>=1) {
- htype = getElementNo(pstr("H"));
- if (Hflag==2) G->HideType ( htype );
- else G->ExcludeType ( htype );
- }
- G->Build ( False );
- }
-
- return rc;
-
-}
-
-int CSBase0::GetGraph ( PCFile graphFile, RPCGraph G, int Hflag ) {
-// GetGraph(..) retrieves data for chemical structure, which is
-// next in the graph file, then allocates and builds the corresponding
-// graph, which is returned in G.
-// If Hflag is set to 1, all hydrogens are removed from the graph.
-// If Hflag is set to 2, element types of atoms, to which hydrogens
-// are bonded, are modified with flag HYDROGEN_BOND and moved to
-// the end.
-// Returns 0 in case of success.
-int rc,htype;
-
- rc = 0;
-
- graphFile->SetSuccess();
- StreamRead ( *graphFile,G );
-
- if (!graphFile->Success()) {
- rc = SBASE_ReadError;
- if (G) delete G;
- G = NULL;
- }
-
- if (G) {
- G->MakeVertexIDs();
- if (Hflag>=1) {
- htype = getElementNo(pstr("H"));
- if (Hflag==2) G->HideType ( htype );
- else G->ExcludeType ( htype );
- }
- G->Build ( False );
- }
-
- return rc;
-
-}
-
-int CSBase0::GetGraph ( int structNo, RPCGraph G, int Hflag ) {
-PCFile graphFile;
-int htype;
-
- if ((0<=structNo) && (structNo<nStructures)) {
- if (Index[structNo]->loadPos>=0) {
- if (!G) G = new CGraph();
- G->Copy ( ldGraph[Index[structNo]->loadPos] );
- } else {
- graphFile = GetGraphFile();
- if (graphFile) {
- graphFile->seek ( Index[structNo]->fGraphPos );
- StreamRead ( *graphFile,G );
- graphFile->shut ();
- delete graphFile;
- } else {
- if (G) delete G;
- G = NULL;
- return SBASE_FileNotFound;
- }
- }
- } else {
- if (G) delete G;
- G = NULL;
- return SBASE_WrongIndex;
- }
-
- if (G) {
- G->MakeVertexIDs();
- if (Hflag>=1) {
- htype = getElementNo(pstr("H"));
- if (Hflag==2) G->HideType ( htype );
- else G->ExcludeType ( htype );
- }
- G->Build ( False );
- }
-
- return SBASE_Ok;
-
- /*
- graphFile = GetGraphFile();
- if (graphFile) {
- rc = GetGraph ( graphFile,G,Hflag );
- graphFile->shut();
- delete graphFile;
- return rc;
- } else {
- if (G) delete G;
- G = NULL;
- return SBASE_FileNotFound;
- }
- */
-
-}
-
-int CSBase0::GetGraph ( cpstr compoundID, RPCGraph G,
- int Hflag ) {
-PCFile graphFile;
-int structNo,htype;
-
- structNo = GetStructNo ( compoundID );
-
- if (structNo!=SBASE_StructNotFound) {
- if (Index[structNo]->loadPos>=0) {
- if (!G ) G = new CGraph();
- G->Copy ( ldGraph[Index[structNo]->loadPos] );
- } else {
- graphFile = GetGraphFile();
- if (graphFile) {
- graphFile->seek ( Index[structNo]->fGraphPos );
- StreamRead ( *graphFile,G );
- graphFile->shut ();
- delete graphFile;
- } else {
- if (G) delete G;
- G = NULL;
- return SBASE_FileNotFound;
- }
- }
- }
-
- if (G) {
- G->MakeVertexIDs();
- if (Hflag>=1) {
- htype = getElementNo(pstr("H"));
- if (Hflag==2) G->HideType ( htype );
- else G->ExcludeType ( htype );
- }
- G->Build ( False );
- }
-
- return structNo;
-
- /*
- if (structNo!=SBASE_StructNotFound) {
- return GetGraph ( structNo,G,Hflag );
- } else {
- if (G) delete G;
- G = NULL;
- return structNo;
- }
- */
-
-}
-
-int CSBase0::CheckGraph ( PCGraph G, int Hflag,
- Boolean Cflag,
- int & nInStructure,
- int & nMatched,
- ivector match,
- int minMatchSize ) {
-// CheckGraph(..) checks graph G against the same-name
-// structure in the database. The name must be passed in
-// G->name as a standard 3-letter code.
-// If Hflag is set >= 1, all hydrogens are removed from the graph.
-// If Hflag is set to 2, element types of atoms, to which hydrogens
-// are bonded, are modified with flag HYDROGEN_BOND.
-// If Cflag is set to True, then chirality information is
-// assumed in the input graph G and it is used for the
-// checking. If Cflag is set to False, then chirality
-// information is neither assumed nor used for the checking.
-// If a same-name structure is found in the database,
-// the function returns the number of matched vertices
-// (nMatched) from those found in the database (nInStructure).
-// The correspondence between the input and database graphs
-// is returned in array match (it should be of sufficient
-// length) such that ith vertex of input graph corresponds
-// to the match[i]th vertex of the database graph. The
-// function then returns SBASE_Ok if the number of matched
-// vertices coincides with nInStructure and nMatched, and
-// the return is SBASE_CheckFail otherwise.
-// If a same-name structure is not found, the function
-// returns SBASE_StructNotFound or SBASE_FileNotFound.
-PCFile graphFile;
-PCGraphMatch U;
-PCGraph G1;
-PAtomName atName;
-ivector F1,F2;
-realtype p1,p2;
-int structNo,rc,j,k, nAtoms,nH, minMatch;
-
- nMatched = 0;
- nInStructure = 0;
-
- structNo = GetStructNo ( G->GetName() );
- if (structNo==SBASE_StructNotFound)
- return SBASE_StructNotFound;
-
- if (Index[structNo]->loadPos<0) {
- graphFile = GetGraphFile();
- if (!graphFile) return SBASE_FileNotFound;
- } else
- graphFile = NULL;
-
- G1 = NULL;
- rc = GetGraph ( graphFile,structNo,G1,Hflag );
- if ((!G1) || (rc!=SBASE_Ok)) return rc;
-
- if (graphFile) {
- graphFile->shut();
- delete graphFile;
- }
-
- if (!Cflag) G1->RemoveChirality();
-
- nInStructure = G1->GetNofVertices();
-
- if (minMatchSize>0)
- minMatch = minMatchSize;
- else minMatch = nInStructure - Index[structNo]->nXTs;
-
- U = new CGraphMatch();
- U->MatchGraphs ( G,G1,minMatch );
- k = U->GetNofMatches();
- if (k>0) {
- U->GetMatch ( 0,F1,F2,nMatched,p1,p2 );
- for (j=1;j<=nMatched;j++)
- match[F1[j]-1] = F2[j]-1;
- }
-
- if ((nInStructure==G->GetNofVertices()) &&
- (nInStructure==nMatched)) {
- rc = SBASE_Ok;
- } else if (nMatched>0) {
- // check if atoms that were not matched are the
- // teminating ones ("-XT")
- atName = new AtomName[nInStructure*2+1];
- if (Hflag>=1) nH = -1; // remove hydrogens
- else nH = 0;
- k = 1;
- if (GetAtNames(structNo,atName,nAtoms,nH)==SBASE_Ok) {
- for (j=1;j<=nMatched;j++)
- atName[F2[j]-1][0] = char(0);
- k = 0;
- for (j=0;(j<nInStructure) && (!k);j++)
- if (atName[j][0] && (strcmp(&(atName[j][2]),"XT"))) k = 1;
- }
- if (!k) rc = SBASE_Ok;
- else rc = SBASE_CheckFail;
- delete[] atName;
- } else
- rc = SBASE_CheckFail;
-
- delete U;
- delete G1;
-
- return rc;
-
-}
-
-int CSBase0::CheckResidue ( PCResidue R,
- int Hflag, Boolean Cflag,
- int & nInResidue, int & nInStructure,
- int & nMatched, ivector match,
- cpstr altLoc, int minMatchSize ) {
-PCGraph G;
-int rc,htype;
-
- G = new CGraph ( R,altLoc );
-
- if (Hflag>=1) {
- htype = getElementNo(pstr("H"));
- if (Hflag==2) G->HideType ( htype );
- else G->ExcludeType ( htype );
- }
-
- G->Build ( False );
-
- nInResidue = G->GetNofVertices();
- if (nInResidue<=0) {
- rc = SBASE_NoAtomsFound;
- nInStructure = 0;
- nMatched = 0;
- } else
- rc = CheckGraph ( G,Hflag,Cflag,nInStructure,nMatched,match,
- minMatchSize );
- delete G;
-
- return rc;
-
-}
-
-
-void SDASelHandles::getNewHandles ( PCMMDBManager MMDB ) {
- selHndDonor = MMDB->NewSelection();
- selHndAcceptor = MMDB->NewSelection();
- selHndHydrogen = MMDB->NewSelection();
- selKey = SKEY_OR;
-}
-
-void SDASelHandles::makeSelIndexes ( PCMMDBManager MMDB ) {
- MMDB->MakeSelIndex ( selHndDonor );
- MMDB->MakeSelIndex ( selHndAcceptor );
- MMDB->MakeSelIndex ( selHndHydrogen );
-}
-
-void SDASelHandles::deleteSelections ( PCMMDBManager MMDB ) {
- MMDB->DeleteSelection ( selHndDonor );
- MMDB->DeleteSelection ( selHndAcceptor );
- MMDB->DeleteSelection ( selHndHydrogen );
-}
-
-
-int CSBase0::MakeBonds ( PCResidue R, pstr altLoc,
- PCFile structFile,
- PSDASelHandles selHandles,
- Boolean ignoreNegSigOcc ) {
-// MakeBonds(..) makes bonds between atoms in MMDB's residue R
-// from data found in SBase. Residue R must be associated with
-// coordinate hierarchy. Data is retrieved from SBase on the basis
-// of residue name only. In case of multiple conformations, if
-// altLoc:
-// NULL - the highest occupancy atom will be taken
-// if all occupancies are equal then atom with
-// first altLoc taken
-// other - atoms with given altLoc are taken. If such
-// altLoc is not found, the function does as if
-// NULL value for altLoc is given.
-// If selHandles is not NULL, the function also selects atoms
-// in the residue according to their hydrogen bond attributes.
-// This is a special option for hydrogen bond calculations.
-// If ignoreNegSigOcc is set True then the function will ignore
-// atoms with negative occupancy standard deviation. Such atoms
-// may be hydrogens added by CSBase0::AddHydrogens(..) function,
-// in general any atoms added by CSBAtom::MakeCAtom(..) function.
-// Added hydrogens may be ignored if MakeBonds is used in
-// CSbase::CalcHBonds(..) function.
-// Return:
-// SBASE_Ok success
-// SBASE_FileNotFound non-initiated SBase
-// SBASE_StructNotFound the residue's name is not found in SBase
-// SBASE_EmptyResidue residue R does not contain atoms
-// SBASE_NoAtomsFound SBase entry does not contain atoms
-// SBASE_BrokenBonds some bonds could not be set up because
-// of missing atoms in R. This could be
-// a result of residue R named wrongly.
-PCSBStructure SBS;
-PCMMDBManager MMDB;
-PPCAtom A;
-ivector anmatch;
-int natoms,i,i1,i2,rc;
-
- R->GetAtomTable ( A,natoms );
- if (!A) return SBASE_EmptyResidue;
-
- for (i=0;i<natoms;i++)
- if (A[i]) A[i]->FreeBonds();
-
- SBS = GetStructure ( R->GetResName(),structFile );
- if (!SBS) return SBASE_StructNotFound;
-
- if (SBS->nAtoms<=0) {
- delete SBS;
- return SBASE_NoAtomsFound;
- }
-
- GetVectorMemory ( anmatch,SBS->nAtoms,0 );
- SBS->GetAtomNameMatch ( A,natoms,altLoc,anmatch );
- if (ignoreNegSigOcc)
- for (i=0;i<SBS->nAtoms;i++) {
- i1 = anmatch[i];
- if (i1>=0) {
- if (A[i1]->sigOcc<0.0) anmatch[i] = -1;
- }
- }
-
- if (selHandles) {
- MMDB = PCMMDBManager(R->GetCoordHierarchy());
- if (MMDB) {
- i2 = selHandles->selKey;
- for (i=0;i<SBS->nAtoms;i++) {
- i1 = anmatch[i];
- if (i1>=0)
- switch (SBS->Atom[i]->hb_type) {
- case 'D' : MMDB->SelectAtom ( selHandles->selHndDonor,
- A[i1],i2,False );
- break;
- case 'A' : MMDB->SelectAtom ( selHandles->selHndAcceptor,
- A[i1],i2,False );
- break;
- case 'B' : MMDB->SelectAtom ( selHandles->selHndDonor,
- A[i1],i2,False );
- MMDB->SelectAtom ( selHandles->selHndAcceptor,
- A[i1],i2,False );
- break;
- case 'H' : MMDB->SelectAtom ( selHandles->selHndHydrogen,
- A[i1],i2,False );
- break;
- default :
- case 'N' : ;
- }
- }
- }
- }
-
- rc = SBASE_Ok;
- for (i=0;i<SBS->nBonds;i++) {
- i1 = anmatch[SBS->Bond[i]->atom1-1];
- i2 = anmatch[SBS->Bond[i]->atom2-1];
- if ((i1>=0) && (i2>=0)) {
- A[i1]->AddBond ( A[i2],SBS->Bond[i]->order,2 );
- A[i2]->AddBond ( A[i1],SBS->Bond[i]->order,2 );
- } else
- rc = SBASE_BrokenBonds;
- }
-
- FreeVectorMemory ( anmatch,0 );
- delete SBS;
-
- return rc;
-
-}
-
-
-int CSBase0::GetEnergyTypes ( PCResidue R, PCFile structFile ) {
-PCSBStructure SBS;
-PPCAtom A;
-int i,j,rc,natoms;
-
- R->GetAtomTable ( A,natoms );
- if (!A) return SBASE_EmptyResidue;
-
- for (i=0;i<natoms;i++)
- if (A[i]) A[i]->energyType[0] = char(0);
-
- SBS = GetStructure ( R->GetResName(),structFile );
- if (SBS) {
- if (SBS->nAtoms>0) {
- for (i=0;i<natoms;i++)
- if (A[i]) {
- for (j=0;j<SBS->nAtoms;j++)
- if (SBS->Atom[j]) {
- if (!strcmp(A[i]->name,SBS->Atom[j]->pdb_name)) {
- strcpy ( A[i]->energyType,SBS->Atom[j]->energyType );
- A[i]->charge = SBS->Atom[j]->ccp4_charge;
- }
- }
- }
- rc = SBASE_Ok;
- } else
- rc = SBASE_NoAtomsFound;
- delete SBS;
- } else
- rc = SBASE_StructNotFound;
-
- return rc;
-
-}
-
-
-int CSBase0::GetEnergyTypes ( PPCResidue R, int nRes,
- PCFile structFile ) {
-PCFile sFile;
-PCSBStructure SBS;
-PPCAtom A;
-bvector B;
-int i,j,k,n,natoms;
-
- GetVectorMemory ( B,nRes,0 );
- for (i=0;i<nRes;i++)
- B[i] = (!R[i]);
-
- if (structFile) sFile = structFile;
- else sFile = GetStructFile();
- if (!sFile) return SBASE_FileNotFound;
-
- i = 0;
- while (i<nRes) {
- while (i<nRes)
- if (B[i]) i++;
- else break;
- if (i<nRes) {
- SBS = GetStructure ( R[i]->GetResName(),sFile );
- j = i;
- while (j<nRes) {
- B[j] = True;
- R[j]->GetAtomTable ( A,natoms );
- if (A) {
- for (k=0;k<natoms;k++)
- if (A[k]) A[k]->energyType[0] = char(0);
- if (SBS) {
- if (SBS->nAtoms>0) {
- for (k=0;k<natoms;k++)
- if (A[k]) {
- for (n=0;n<SBS->nAtoms;n++)
- if (SBS->Atom[n]) {
- if (!strcmp(A[k]->name,SBS->Atom[n]->pdb_name)) {
- strcpy ( A[k]->energyType,
- SBS->Atom[n]->energyType );
- A[k]->charge = SBS->Atom[n]->ccp4_charge;
- }
- }
- }
- }
- }
- }
- j++;
- while (j<nRes)
- if (!B[j]) {
- if (!strcmp(R[i]->name,R[j]->name)) break;
- else j++;
- } else
- j++;
- }
- if (SBS) {
- delete SBS;
- SBS = NULL;
- }
- i++;
- }
- }
-
- if (!structFile) delete sFile;
- FreeVectorMemory ( B,0 );
-
- return SBASE_Ok;
-
-}
-
-
-int CSBase0::GetEnergyTypes ( PCChain chain, PCFile structFile ) {
-PPCResidue Res;
-int nRes;
- chain->GetResidueTable ( Res,nRes );
- if (nRes>0)
- return GetEnergyTypes ( Res,nRes,structFile );
- else return SBASE_EmptyResSet;
-}
-
-int CSBase0::GetEnergyTypes ( PCModel model, PCFile structFile ) {
-PPCResidue Res;
-PPCChain chain;
-PCMMDBManager MMDB;
-int rc,selHnd,i,nRes,nChains;
-
- rc = SBASE_Ok;
- MMDB = PCMMDBManager(model->GetCoordHierarchy());
-
- if (MMDB) {
-
- selHnd = MMDB->NewSelection();
- MMDB->Select ( selHnd,STYPE_RESIDUE,model->GetSerNum(),
- "*",ANY_RES,"*",ANY_RES,"*",
- "*","*","*","*",SKEY_NEW );
- MMDB->GetSelIndex ( selHnd,Res,nRes );
- if (nRes>0) rc = GetEnergyTypes ( Res,nRes,structFile );
- else rc = SBASE_EmptyResSet;
- MMDB->DeleteSelection ( selHnd );
-
- } else {
-
- model->GetChainTable ( chain,nChains );
- for (i=0;i<nChains;i++)
- if (chain[i]) {
- chain[i]->GetResidueTable ( Res,nRes );
- if (nRes>0) GetEnergyTypes ( Res,nRes,structFile );
- }
-
- }
-
- return rc;
-
-}
-
-int CSBase0::GetEnergyTypes ( PCMMDBManager MMDB, PCFile structFile ) {
-PPCResidue Res;
-int rc,selHnd,nRes;
-
- rc = SBASE_Ok;
-
- selHnd = MMDB->NewSelection();
- MMDB->Select ( selHnd,STYPE_RESIDUE,0,
- "*",ANY_RES,"*",ANY_RES,"*",
- "*","*","*","*",SKEY_NEW );
- MMDB->GetSelIndex ( selHnd,Res,nRes );
- if (nRes>0) rc = GetEnergyTypes ( Res,nRes,structFile );
- else rc = SBASE_EmptyResSet;
-
- MMDB->DeleteSelection ( selHnd );
-
- return rc;
-
-}
-
-int CSBase0::AddHydrogens ( PCResidue R, PCFile structFile ) {
-// Return:
-// SBASE_Ok success
-// SBASE_EmptyResidue residue R does not contain atoms
-// SBASE_NoAtomsFound SBStructure does not contain atoms
-// SBASE_NoBonds SBStructure does not contain bonds
-// SBASE_NoAtomsData SBStructure is not complete
-// SBASE_NoSimilarity too few coomon atom names in R and SBase
-// entry with the same structure name
-// SBASE_SuperpositionFailed failed residue superposition
-// NOTE: the function does not rearranges existing atoms in the
-// residue, but places the hydrogens on top of them (leaving the
-// Ter pseudoatom, if found, on top of the list)
-PCFile sFile;
-PCSBStructure SBS;
-int rc;
-
- if (structFile) sFile = structFile;
- else sFile = GetStructFile();
-
- if (!sFile) return SBASE_FileNotFound;
-
- SBS = GetStructure ( R->GetResName(),sFile );
- if (!structFile) delete sFile;
-
- if (!SBS) return SBASE_StructNotFound;
-
- rc = SBS->AddHydrogens ( R );
-
- delete SBS;
-
- return rc;
-
-}
-
-int CSBase0::AddHydrogens ( PCChain chain, PCFile structFile ) {
-PCFile sFile;
-PPCResidue Res;
-int i,k,nRes,rc;
-Boolean B;
-
- if (structFile) sFile = structFile;
- else sFile = GetStructFile();
-
- if (!sFile) return SBASE_FileNotFound;
-
- rc = SBASE_Ok;
- B = False;
- chain->GetResidueTable ( Res,nRes );
- for (i=0;i<nRes;i++)
- if (Res[i]) {
- k = AddHydrogens ( Res[i],sFile );
- if (k==SBASE_Ok) B = True;
- else rc = SBASE_Incomplete;
- }
- if (!B) rc = SBASE_Fail;
-
- if (!structFile) delete sFile;
-
- return rc;
-
-}
-
-
-int CSBase0::AddHydrogens ( PCModel model, PCFile structFile ) {
-PCFile sFile;
-PPCChain chain;
-PPCResidue Res;
-int i,j,k,nChains,nRes,rc;
-Boolean B;
-
- if (structFile) sFile = structFile;
- else sFile = GetStructFile();
-
- if (!sFile) return SBASE_FileNotFound;
-
- rc = SBASE_Ok;
- B = False;
- model->GetChainTable ( chain,nChains );
- for (i=0;i<nChains;i++)
- if (chain[i]) {
- chain[i]->GetResidueTable ( Res,nRes );
- for (j=0;j<nRes;j++)
- if (Res[j]) {
- k = AddHydrogens ( Res[j],sFile );
- if (k==SBASE_Ok) B = True;
- else rc = SBASE_Incomplete;
- }
- }
- if (!B) rc = SBASE_Fail;
-
- if (!structFile) delete sFile;
-
- return rc;
-
-}
-
-int CSBase0::AddHydrogens ( PCMMDBManager MMDB, PCFile structFile ) {
-PCFile sFile;
-PPCModel model;
-PPCChain chain;
-PPCResidue Res;
-int i,j,n,k,nModels,nChains,nRes,rc;
-Boolean B;
-
- if (structFile) sFile = structFile;
- else sFile = GetStructFile();
-
- if (!sFile) return SBASE_FileNotFound;
-
- rc = SBASE_Ok;
- B = False;
- MMDB->GetModelTable ( model,nModels );
- for (i=0;i<nModels;i++)
- if (model[i]) {
- model[i]->GetChainTable ( chain,nChains );
- for (j=0;j<nChains;j++)
- if (chain[j]) {
- chain[j]->GetResidueTable ( Res,nRes );
- for (n=0;n<nRes;n++)
- if (Res[n]) {
- k = AddHydrogens ( Res[n],sFile );
- if (k==SBASE_Ok) B = True;
- else rc = SBASE_Incomplete;
- }
- }
- }
- if (!B) rc = SBASE_Fail;
-
- if (!structFile) delete sFile;
-
- return rc;
-
-}
-
-
-
-int CSBase0::ComplementResidue ( PCResidue R, int complFlag,
- PCFile structFile ) {
-// ComplementResidue(..) extracts data from SBase by residue
-// name, then superposes atoms having identical names and
-// adds the residue with atoms that are found in SBase but are
-// absent in the residue. The added atoms are rotated and translated
-// such as to comply with the superposed parts.
-// complFlag:
-// CMPLF_Hydrogens complement residue with hydrogens
-// CMPLF_nonHs complement residue with non-hydrogens
-// CMPLF_XT complement with C-terminus
-// Return:
-// SBASE_Ok success
-// SBASE_FileNotFound non-initiated SBase
-// SBASE_StructNotFound the residue's name is not found in SBase
-// SBASE_EmptyResidue residue R does not contain atoms
-// SBASE_NoAtomsFound SBase entry does not contain atoms
-// SBASE_NoAtomsData SBase entry is not complete
-// SBASE_NoSimilarity too few coomon atom names in R and SBase
-// entry with the same structure name
-// SBASE_SuperpositionFailed failed residue superposition
-// NOTE: the function rearranges ALL atoms in the residue according
-// to PDB order as written in SBase.
-PCFile sFile;
-PCSBStructure SBS;
-PPCAtom A1,A2,A3;
-ivector c,x;
-mat44 T;
-Element Hydrogen;
-pstr aname;
-int i,j,k,natoms1,natoms2,rc;
-Boolean complH,complNH,complXT;
-
- if (structFile) sFile = structFile;
- else sFile = GetStructFile();
-
- if (!sFile) return SBASE_FileNotFound;
-
- SBS = GetStructure ( R->GetResName(),sFile );
- if (!structFile) delete sFile;
-
- if (!SBS) return SBASE_StructNotFound;
-
- /* --- temporary commented because of incompleteness of data
- in SBase files
- if (SBS->CheckAtoms()<0) {
- delete SBS;
- return SBASE_NoAtomData;
- }
- ---------- */
-
- rc = SBASE_Ok;
-
- SBS->GetAtomTable ( A1,natoms1 );
- if (!A1) {
- delete SBS;
- return SBASE_NoAtomsFound;
- }
-
- /* --- temporary fix, simply neglect atoms that do not have
- coordinates. This code should be removed and the
- code above uncommented ----------- */
- j = 0;
- for (i=0;i<natoms1;i++)
- if (A1[i]->x==-MaxReal) delete A1[i];
- else {
- if (j<i) A1[j] = A1[i];
- j++;
- }
- natoms1 = j;
- for (i=j;i<natoms1;i++)
- A1[i] = NULL;
-
- /* ---------------------------------------- */
-
- A2 = NULL;
- R->GetAtomTable ( A2,natoms2 );
- if (!A2) {
- delete SBS;
- return SBASE_EmptyResidue;
- }
-
- GetVectorMemory ( c,natoms1,0 );
- GetVectorMemory ( x,natoms2,0 );
- for (j=0;j<natoms2;j++)
- x[j] = -1;
-
- k = 0;
- for (i=0;i<natoms1;i++) {
- c[i] = -1;
- for (j=0;j<natoms2;j++)
- if (A2[j]) {
- if ((!A2[j]->isTer()) &&
- (!strcmp(A1[i]->GetAtomName(),A2[j]->GetAtomName()))) {
- if (c[i]<0) {
- c[i] = j;
- k++;
- }
- x[j] = i;
- }
- }
- }
-
- if (k>2) {
-
- // the rotational-translational matrix T such that |T*A1 - A2| is
- // as A1[i] <-> A2[C[i]] only for those i that C[i]>=0 .
- // The default
- k = SuperposeAtoms ( T,A1,natoms1,A2,c );
- if (k!=SPOSEAT_Ok) rc = SBASE_SuperpositionFailed;
- else {
- complH = ((complFlag & CMPLF_Hydrogens)!=0);
- complNH = ((complFlag & CMPLF_nonHs)!=0);
- complXT = ((complFlag & CMPLF_XT)!=0);
- strcpy ( Hydrogen,ElementName[0] );
- CutSpaces ( Hydrogen,SCUTKEY_BEGEND );
- A3 = new PCAtom[natoms1+natoms2+1];
- k = 0;
- for (i=0;i<natoms1;i++)
- if (c[i]>=0) {
- A3[k] = A1[i];
- A3[k]->Copy ( A2[c[i]] );
- A1[i] = NULL;
- k++;
- // check for altlocs
- for (j=c[i]+1;j<natoms2;j++)
- if (x[j]==i) {
- A3[k] = newCAtom();
- A3[k]->Copy ( A2[j] );
- k++;
- }
- } else {
- A3[k] = NULL;
- aname = A1[i]->GetAtomName();
- if (strcmp(A1[i]->GetElementName(),Hydrogen)) {
- // a non-hydrogen atom, check if it should be added
- if (complNH &&
- (complXT || (strcmp(aname," OXT"))))
- A3[k] = A1[i];
- } else if (complH) {
- // a hydrogen and hydrogens are to be added
- if (complXT)
- A3[k] = A1[i]; // add unconditionally
- else if (!strcmp(aname," HXT")) {
- // add HXT only if OXT is present in the residue
- for (j=0;(j<natoms2) && (!A3[k]);j++)
- if (A2[j]) {
- if ((!A2[j]->isTer()) &&
- (!strcmp(A2[j]->GetAtomName()," OXT")))
- A3[k] = A1[i];
- }
- } else // add non-HXT anyway
- A3[k] = A1[i];
- }
- if (A3[k]) {
- A3[k]->Transform ( T );
- A1[i] = NULL;
- k++;
- }
- }
- // add all atoms of original residue which were not superposed;
- // these include Ter, if any is present
- for (j=0;j<natoms2;j++)
- if (x[j]<0) {
- A3[k] = newCAtom();
- A3[k]->Copy ( A2[j] );
- k++;
- }
- R->DeleteAllAtoms();
- for (i=0;i<k;i++)
- R->AddAtom ( A3[i] );
- delete[] A3;
- }
-
- } else
- rc = SBASE_NoSimilarity;
-
- FreeVectorMemory ( x,0 );
- FreeVectorMemory ( c,0 );
- for (i=0;i<natoms1;i++)
- if (A1[i]) delete A1[i];
- delete[] A1;
- delete SBS;
-
- return rc;
-
-}
-
-int CSBase0::ComplementChain ( PCChain chain, int complFlag,
- PCFile structFile ) {
-PCFile sFile;
-PPCResidue Res;
-int i,k,nRes,rc;
-Boolean B;
-
- if (structFile) sFile = structFile;
- else sFile = GetStructFile();
-
- if (!sFile) return SBASE_FileNotFound;
-
- rc = SBASE_Ok;
- B = False;
- chain->GetResidueTable ( Res,nRes );
- for (i=0;i<nRes;i++)
- if (Res[i]) {
- k = ComplementResidue ( Res[i],complFlag,sFile );
- if (k==SBASE_Ok) B = True;
- else rc = SBASE_Incomplete;
- }
- if (!B) rc = SBASE_Fail;
-
- if (!structFile) delete sFile;
-
- return rc;
-
-}
-
-int CSBase0::ComplementModel ( PCModel model, int complFlag,
- PCFile structFile ) {
-PCFile sFile;
-PPCChain chain;
-PPCResidue Res;
-int i,j,k,nChains,nRes,rc;
-Boolean B;
-
- if (structFile) sFile = structFile;
- else sFile = GetStructFile();
-
- if (!sFile) return SBASE_FileNotFound;
-
- rc = SBASE_Ok;
- B = False;
- model->GetChainTable ( chain,nChains );
- for (i=0;i<nChains;i++)
- if (chain[i]) {
- chain[i]->GetResidueTable ( Res,nRes );
- for (j=0;j<nRes;j++)
- if (Res[j]) {
- k = ComplementResidue ( Res[j],complFlag,sFile );
- if (k==SBASE_Ok) B = True;
- else rc = SBASE_Incomplete;
- }
- }
- if (!B) rc = SBASE_Fail;
-
- if (!structFile) delete sFile;
-
- return rc;
-
-}
-
-int CSBase0::ComplementFile ( PCMMDBManager MMDB, int complFlag,
- PCFile structFile ) {
-PCFile sFile;
-PPCModel model;
-PPCChain chain;
-PPCResidue Res;
-int i,j,n,k,nModels,nChains,nRes,rc;
-Boolean B;
-
- if (structFile) sFile = structFile;
- else sFile = GetStructFile();
-
- if (!sFile) return SBASE_FileNotFound;
-
- rc = SBASE_Ok;
- B = False;
- MMDB->GetModelTable ( model,nModels );
- for (i=0;i<nModels;i++)
- if (model[i]) {
- model[i]->GetChainTable ( chain,nChains );
- for (j=0;j<nChains;j++)
- if (chain[j]) {
- chain[j]->GetResidueTable ( Res,nRes );
- for (n=0;n<nRes;n++)
- if (Res[n]) {
- k = ComplementResidue ( Res[n],complFlag,sFile );
- if (k==SBASE_Ok) B = True;
- else rc = SBASE_Incomplete;
- }
- }
- }
- if (!B) rc = SBASE_Fail;
-
- if (!structFile) delete sFile;
-
- return rc;
-
-}
-
-
-int CSBase0::GetAtNames ( int structNo, PAtomName AtName,
- int & nAtoms, int & nH ) {
-int rc;
-PCFile structFile;
- if ((structNo<0) || (structNo>=nStructures))
- return SBASE_WrongIndex;
- if (Index[structNo]->loadPos>=0) {
- rc = GetAtNames ( NULL,structNo,AtName,nAtoms,nH );
- } else {
- structFile = GetStructFile();
- if (structFile) {
- rc = GetAtNames ( structFile,structNo,AtName,nAtoms,nH );
- structFile->shut();
- delete structFile;
- } else
- return SBASE_FileNotFound;
- }
- return rc;
-}
-
-
-int CSBase0::GetAtNames ( PCFile structFile, int structNo,
- PAtomName AtName,
- int & nAtoms, int & nH ) {
-PCSBStructure SBS;
-PCSBAtom atom;
-int i,j;
-pstr p1,p2;
-Boolean removeHydrogens;
-
- if ((structNo<0) || (structNo>=nStructures))
- return SBASE_WrongIndex;
-
- removeHydrogens = (nH==-1);
-
- if (Index[structNo]->loadPos>=0) {
-
- SBS = ldStructure[Index[structNo]->loadPos];
-
- } else {
-
- structFile->seek ( Index[structNo]->fStructPos );
- SBS = NULL;
- StreamRead ( *structFile,SBS );
-
- if ((!SBS) || (!structFile->Success())) {
- if (SBS) delete SBS;
- return SBASE_ReadError;
- }
-
- }
-
- nAtoms = Index[structNo]->nAtoms;
- nH = 0;
- if (Index[structNo]->Comp1) {
- p1 = strstr ( Index[structNo]->Comp1,"H(" );
- if (p1) {
- p1 += 2;
- p2 = p1;
- while ((*p2) && (*p2!=')')) p2++;
- if (*p2==')') {
- *p2 = char(0);
- nH = mround(strtod(p1,NULL));
- *p2 = ')';
- }
- }
- }
-
- if (removeHydrogens) {
- j = 0;
- for (i=0;i<nAtoms;i++) {
- atom = SBS->Atom[i];
- if (atom) {
- if ((atom->element[0]!='H') || (atom->element[1]))
- strcpy ( AtName[j++],atom->pdb_name );
- }
- }
- } else {
- for (i=0;i<nAtoms;i++) {
- atom = SBS->Atom[i];
- if (atom)
- strcpy ( AtName[i],atom->pdb_name );
- }
- }
-
- if (Index[structNo]->loadPos<0) delete SBS;
-
- return SBASE_Ok;
-
-}
-
-int FindName ( PAtomName Nams, pstr N, int len ) {
-int i;
-AtomName Nam;
- i = 0;
- while (i<len) {
- strcpy ( Nam,Nams[i] );
- if (!strcmp(N,Nam)) break;
- i++;
- }
- if (i>=len) i = -1;
- return i;
-}
-
-int CSBase0::GetNofAtoms ( int structNo, int & nNonHAtoms,
- int & nHAtoms ) {
-pstr p1,p2;
-
- nNonHAtoms = 0;
- nHAtoms = 0;
-
- if ((structNo<0) || (structNo>=nStructures))
- return SBASE_WrongIndex;
-
- nNonHAtoms = Index[structNo]->nAtoms;
- nHAtoms = 0;
- if (Index[structNo]->Comp1) {
- p1 = strstr ( Index[structNo]->Comp1,"H(" );
- if (p1) {
- p1 += 2;
- p2 = p1;
- while ((*p2) && (*p2!=')')) p2++;
- if (*p2==')') {
- *p2 = char(0);
- nHAtoms = mround(strtod(p1,NULL));
- *p2 = ')';
- }
- }
- }
-
- nNonHAtoms -= nHAtoms;
-
- return SBASE_Ok;
-
-}
-
-int CSBase0::GetAtoms ( cpstr name,
- int & nNonHAtoms, PAtomName NonHAtName,
- int & nHAtoms, PAtomName HAtName,
- ivector Hconnect, ivector Elem,
- ivector Chiral ) {
-PCSBStructure SBS;
-PCSBAtom atom,atom2;
-PCSBBond bond;
-int i,j,structNo,rc;
-PCFile structFile;
-
- nNonHAtoms = 0;
- nHAtoms = 0;
-
- structNo = GetStructNo ( name );
- if (structNo<0) return SBASE_StructNotFound;
-
- if (Index[structNo]->loadPos>=0) {
-
- SBS = ldStructure[Index[structNo]->loadPos];
-
- } else {
-
- structFile = GetStructFile();
- if (!structFile) return SBASE_FileNotFound;
-
- SBS = NULL;
- structFile->seek ( Index[structNo]->fStructPos );
- StreamRead ( *structFile,SBS );
- structFile->shut ();
-
- if ((!SBS) || (!structFile->Success())) {
- if (SBS) delete SBS;
- delete structFile;
- return SBASE_ReadError;
- }
- delete structFile;
-
- }
-
- rc = SBASE_Ok;
-
- for (i=0;i<Index[structNo]->nAtoms;i++) {
- atom = SBS->Atom[i];
- if (atom) {
- Elem[i] = getElementNo ( atom->element );
- if ((atom->element[0]==' ') && (atom->element[1]=='H') &&
- (!atom->element[2])) {
- strcpy ( HAtName[nHAtoms],atom->pdb_name );
- nHAtoms++;
- } else {
- strcpy ( NonHAtName[nNonHAtoms],atom->pdb_name );
- nNonHAtoms++;
- }
- Chiral[i] = MakeChirInd ( atom->chirality );
- }
- }
-
- if (nHAtoms>0) {
- for (j=0;j<nHAtoms;j++)
- Hconnect[j] = -1;
- for (i=0;i<Index[structNo]->nBonds;i++) {
- bond = SBS->Bond[i];
- if (bond) {
- atom = SBS->Atom[bond->atom1-1];
- atom2 = SBS->Atom[bond->atom2-1];
- if (atom && atom2) {
- j = FindName ( HAtName,atom->pdb_name,nHAtoms );
- if (j>=0)
- Hconnect[j] = FindName ( NonHAtName,atom2->pdb_name,
- nNonHAtoms );
- else {
- j = FindName ( HAtName,atom2->pdb_name,nHAtoms );
- if (j>=0)
- Hconnect[j] = FindName ( NonHAtName,atom->pdb_name,
- nNonHAtoms );
- }
- }
- }
- }
- j = 0;
- while ((j<nHAtoms) && (Hconnect[j]>=0)) j++;
- if (j<nHAtoms)
- rc = SBASE_ConnectivityError;
- }
-
- if (Index[structNo]->loadPos<0) delete SBS;
-
- return rc;
-
-}
-
-
-int CSBase0::GetBonds ( cpstr name,
- ivector nBonds, imatrix bondPair,
- int & nAtoms, int maxNAtoms,
- int maxNBonds ) {
-PCGraph G;
-PCEdge edge;
-PCFile graphFile;
-int structNo,i, a1,a2;
-
- for (i=0;i<maxNAtoms;i++)
- nBonds[i] = 0;
-
- nAtoms = 0;
-
- structNo = GetStructNo ( name );
- if (structNo<0) return SBASE_StructNotFound;
-
- nAtoms = Index[structNo]->nAtoms;
- if (nAtoms<=0) return SBASE_Ok;
-
- if (Index[structNo]->loadPos>=0) {
-
- G = ldGraph[Index[structNo]->loadPos];
-
- } else {
-
- graphFile = GetGraphFile();
- if (!graphFile) return SBASE_FileNotFound;
-
- G = NULL;
- graphFile->seek ( Index[structNo]->fGraphPos );
- StreamRead ( *graphFile,G );
- graphFile->shut ();
-
- if ((!G) || (!graphFile->Success())) {
- if (G) delete G;
- delete graphFile;
- return SBASE_ReadError;
- }
- delete graphFile;
-
- }
-
- for (i=0;i<G->nEdges;i++) {
- edge = G->Edge[i];
- if (edge) {
- if (edge->v1<edge->v2) {
- a1 = edge->v1; a2 = edge->v2;
- } else {
- a1 = edge->v2; a2 = edge->v1;
- }
- a1--; a2--;
- if (nBonds[a1]<maxNBonds) {
- bondPair[a1][nBonds[a1]] = a2;
- nBonds[a1]++;
- }
- }
- }
-
- if (Index[structNo]->loadPos<0) delete G;
-
- return SBASE_Ok;
-
-}
-
-
-int CSBase0::GetHetInfo ( cpstr name,
- pstr Formula,
- pstr Hname,
- pstr Hsynonym,
- pstr Hcharge,
- PAtomName & ClinkAtom,
- PElement & ClinkEle,
- PAtomName & SlinkAtom,
- PElement & SlinkEle,
- int & nLeavingAtoms ) {
-PCSBStructure SBS;
-PCFile structFile;
-int i,structNo;
-
- Formula [0] = char(0);
- Hname [0] = char(0);
- Hsynonym[0] = char(0);
- Hcharge [0] = char(0);
- ClinkAtom = NULL;
- ClinkEle = NULL;
- SlinkAtom = NULL;
- SlinkEle = NULL;
- nLeavingAtoms = 0;
-
- structNo = GetStructNo ( name );
- if (structNo<0) return SBASE_StructNotFound;
-
- structFile = GetStructFile();
- if (!structFile) return SBASE_FileNotFound;
-
- SBS = NULL;
- structFile->seek ( Index[structNo]->fStructPos );
- StreamRead ( *structFile,SBS );
- structFile->shut ();
-
- if ((!SBS) || (!structFile->Success())) {
- if (SBS) delete SBS;
- delete structFile;
- return SBASE_ReadError;
- }
- delete structFile;
-
- if (SBS->Formula) strcpy ( Formula ,SBS->Formula );
- if (SBS->Synonym) strcpy ( Hsynonym,SBS->Synonym );
- if (SBS->Name) strcpy ( Hname ,SBS->Name );
- if (SBS->Charge) strcpy ( Hcharge ,SBS->Charge );
-
- nLeavingAtoms = SBS->nLeavingAtoms;
- if (nLeavingAtoms>0) {
- SlinkAtom = new AtomName[nLeavingAtoms];
- SlinkEle = new Element [nLeavingAtoms];
- ClinkAtom = new AtomName[nLeavingAtoms];
- ClinkEle = new Element [nLeavingAtoms];
- for (i=0;i<nLeavingAtoms;i++) {
- strcpy (SlinkAtom[i],SBS->Atom[SBS->leavingAtom[i]-1]->pdb_name);
- strcpy (SlinkEle [i],SBS->Atom[SBS->leavingAtom[i]-1]->element );
- if (SBS->bondedAtom[i]>0) {
- strcpy(ClinkAtom[i],SBS->Atom[SBS->bondedAtom[i]-1]->pdb_name);
- strcpy(ClinkEle [i],SBS->Atom[SBS->bondedAtom[i]-1]->element );
- } else {
- ClinkAtom[i][0] = char(0);
- ClinkEle [i][0] = char(0);
- }
- }
- }
-
- delete SBS;
-
- return SBASE_Ok;
-
-}
-
diff --git a/mmdb/mmdb_sbase0.h b/mmdb/mmdb_sbase0.h
deleted file mode 100755
index 00e108d..0000000
--- a/mmdb/mmdb_sbase0.h
+++ /dev/null
@@ -1,746 +0,0 @@
-// $Id: mmdb_sbase0.h,v 1.17 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 08.07.08 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : mmdb_sbase0 <implementation>
-// ~~~~~~~~~
-// **** Classes : CSBase0 ( structure base manager 0 )
-// ~~~~~~~~~ CSBAtom ( SB atom class )
-// CSBBond ( SB bond class )
-// CSBStructure ( SB structure (monomer) class )
-// CSBIndex ( SB index class )
-//
-// (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-#ifndef __MMDB_SBase0__
-#define __MMDB_SBase0__
-
-#ifndef __MMDB_Manager__
-#include "mmdb_manager.h"
-#endif
-
-#ifndef __MMDB_Graph__
-#include "mmdb_graph.h"
-#endif
-
-
-// =================================================================
-
-// -- oracle data field lengths
-#define compoundID_len 10
-#define formula_len 1000
-#define charge_len 5000
-#define name_len 1000
-#define synonym_len 1000
-#define sca_name_len 20
-#define pdb_name_len 20
-#define element_len 5
-#define sca_leaving_atom_len 3
-#define chirality_len 1
-#define scb_bond_order_len 10
-#define energy_type_len 8
-
-
-typedef char CompoundID [compoundID_len+1];
-typedef char SBPDBName [pdb_name_len+1];
-typedef char SBElementName[element_len+1];
-
-// -- names for graph files
-#define sbIndexFile cpstr("index.sbase")
-#define sbGraphFile cpstr("graph.sbase")
-#define sbStructFile cpstr("struct.sbase")
-
-
-// ====================== SB Atom Class =========================
-
-DefineClass(CSBAtom);
-
-class CSBAtom : public CStream {
-
- public :
- char sca_name [sca_name_len+1]; // SCA atom name
- char pdb_name [pdb_name_len+1]; // PDB atom name (aligned)
- char old_pdb_name[pdb_name_len+1]; // old PDB atom name (aligned)
- char element [element_len+1]; // chemical element (aligned)
- char energyType[energy_type_len+1]; // energy type; set to empty
- // string "" if not provided
- realtype x,y,z; // cartesian coordinates; set
- // to -MaxReal if not provided
- realtype x_esd,y_esd,z_esd; // ESDs for cartesian coordi-
- // nates; set to 0.0 if not
- // provided
- realtype ccp4_charge; // atom charge from ccp4 libs
- realtype sca_charge; // formal atom charge (MSD)
- realtype partial_charge; // partial atom charge (MSD)
- realtype vdw_radius; // Van-der-Waals radius
- realtype vdwh_radius; // Van-der-Waals radius with
- // hydrogen
- realtype ion_radius; // ion radius
- int valency; // valency
- char chirality; // chirality: 'R', 'S' or 'N'
- char leaving; // leaving atom: 'Y' or 'N'
- char hb_type; // hydrogen bond type:
- // 'D' donor
- // 'A' acceptor
- // 'B' both
- // 'H' hydrogen candidate
- // 'N' neither
-
- CSBAtom ();
- CSBAtom ( RPCStream Object );
- ~CSBAtom();
-
- void makeCAtom ( RPCAtom a );
- PCAtom makeCAtom ();
-
- virtual void Copy ( PCSBAtom A );
-
- void read ( RCFile f );
- void write ( RCFile f );
-
- protected :
- void SBAtomInit();
-
-};
-
-DefineStreamFunctions(CSBAtom);
-
-
-
-// ======================= SB Bond Class ========================
-
-DefineClass(CSBBond);
-
-class CSBBond : public CStream {
-
- public :
- int atom1,atom2,order; // bonded atoms ordinal numbers in
- // reference to the atom array in
- // CSBStructure; atom1 and atom2
- // number atoms like 1,2 on; these
- // fields are always provided
- realtype length,length_esd; // bond length in A and its esd;
- // set to 0.0 if not provided by
- // data base
-
- CSBBond ();
- CSBBond ( RPCStream Object );
- ~CSBBond();
-
- void SetBond ( int at1, int at2, int ord );
-
- virtual void Copy ( PCSBBond B );
-
- void read ( RCFile f );
- void write ( RCFile f );
-
- protected :
- void SBBondInit();
-
-};
-
-DefineStreamFunctions(CSBBond);
-
-
-
-// ======================= SB Angle Class =======================
-
-DefineClass(CSBAngle);
-
-class CSBAngle : public CStream {
-
- public :
- int atom1,atom2,atom3; // number atoms like 1,2 on; always
- // provided
- realtype angle,angle_esd; // angle is always provided; esd
- // is set to 0.0 if not provided
-
- CSBAngle ();
- CSBAngle ( RPCStream Object );
- ~CSBAngle();
-
- virtual void Copy ( PCSBAngle G );
-
- void read ( RCFile f );
- void write ( RCFile f );
-
- protected :
- void SBAngleInit();
-
-};
-
-DefineStreamFunctions(CSBAngle);
-
-
-// ====================== SB Torsion Class ======================
-
-DefineClass(CSBTorsion);
-
-class CSBTorsion : public CStream {
-
- public :
- int atom1,atom2,atom3,atom4; // number atoms like 1,2 on;
- // always provided
- realtype torsion,torsion_esd; // torsion is always provided;
- // esd is set to 0.0 if not provided
-
- CSBTorsion ();
- CSBTorsion ( RPCStream Object );
- ~CSBTorsion();
-
- virtual void Copy ( PCSBTorsion T );
-
- void read ( RCFile f );
- void write ( RCFile f );
-
- protected :
- void SBTorsionInit();
-
-};
-
-DefineStreamFunctions(CSBTorsion);
-
-
-// ==================== Structure Class =========================
-
-DefineClass(CSBStructure);
-
-class CSBStructure : public CStream {
-
- public :
- CompoundID compoundID; // CIF ID -- always provided
- pstr Formula; // NULL if not provided
- pstr Name; // NULL if not provided
- pstr Synonym; // NULL if not provided
- pstr Charge; // NULL if not provided
-
- // Atom, Bond, Angle and Torsion point on the vectors of
- // PCSBAtom[nAtoms], PCSBBond[nBonds], PCSBAngle[nAngles] and
- // PCSBTorsion[nTorsions], respectively. Not all of them may be
- // provided by the data base. If not provided, NULL is assigned.
- int nAtoms,nBonds,nAngles,nTorsions;
- PPCSBAtom Atom; // always provided
- PPCSBBond Bond; // report if not provided
- PPCSBAngle Angle; // NULL if not provided
- PPCSBTorsion Torsion; // NULL if not provided
-
- int nLeavingAtoms;
- ivector leavingAtom;
- ivector bondedAtom;
-
- char xyz_source; // 'A' for ACD coordinates,
- // 'R' for RCSB coordinates
- // 'P' for PDB coordinates
- // 'N' if xyz are not provided
-
- CSBStructure ();
- CSBStructure ( RPCStream Object );
- ~CSBStructure();
-
- void Reset ();
-
- void PutFormula ( cpstr F );
- void PutName ( cpstr N );
- void PutSynonym ( cpstr S );
- void PutCharge ( cpstr G );
-
- void AddAtom ( PCSBAtom atom );
- void AddBond ( PCSBBond bond );
- void MakeLeavingAtoms();
- void AddAngle ( PCSBAngle angle );
- void AddTorsion ( PCSBTorsion torsion );
-
- void RemoveEnergyTypes();
- int SetEnergyType ( cpstr sca_name, cpstr energyType,
- realtype partial_charge );
-
- int GetAtomNo ( cpstr sca_name ); // returns 0 if atom not
- // found, >0 gives the atom ordinal number
- int GetAtomNo_nss ( cpstr sca_name ); // same but disregards
- // leading and trailing spaces
-
- PCSBAtom GetAtom ( cpstr sca_name );
-
- // GetAtomTable(..) does not deallocate atomTable!
- void GetAtomTable ( PPCAtom & atomTable, int & nOfAtoms );
-
- // CheckAtoms() returns -1 if there is no atoms
- // -2 if not all atoms are annotated
- // -3 if not all coordinates are set
- // 0 otherwise
- int CheckAtoms();
-
- // GetAtomNameMatch(..) returns anmatch[i], i=0..nAtoms-1, equal
- // to j such that name(Atom[i])==name(A[j]). Note that atom names
- // are similarly aligned and space-padded in both MMDB and SBase.
- // If ith atom in the structue is not found in A, anmatch[i] is
- // set -1.
- // If array A contains atoms in different alternative
- // conformations, the the value of altLoc is interpreted as
- // follows:
- // NULL - the highest occupancy atom will be taken
- // if all occupancies are equal then atom with
- // first altLoc taken
- // other - atoms with given altLoc are taken. If such
- // altLoc is not found, the function does as if
- // NULL value for altLoc is given.
- // A clean PDB file is anticipated, so that atoms with
- // alternative conformations are grouped together.
- // It is Ok to have NULL pointers in A.
- void GetAtomNameMatch ( PPCAtom A, int nat, pstr altLoc,
- ivector anmatch );
-
- PCResidue makeCResidue ( Boolean includeHydrogens=False,
- Boolean makeTer=False );
-
- int AddHydrogens ( PCResidue R );
-
- virtual void Copy ( PCSBStructure S );
-
- void read ( RCFile f );
- void write ( RCFile f );
-
- protected :
- int nAAlloc,nBAlloc,nGAlloc,nTAlloc;
- void SBStructureInit();
- void FreeMemory ();
-
-};
-
-DefineStreamFunctions(CSBStructure);
-
-
-
-// ==================== Index Class ==============================
-
-DefineClass(CSBIndex);
-
-class CSBIndex : public CStream {
-
- public :
- CompoundID compoundID; // CIF ID of the compound
- int nAtoms; // number of atoms in the compound
- int nBonds; // number of bonds in the compound
- int fGraphPos; // offset for CGraph
- int fStructPos; // offset for CSBStructure
- int loadPos; // load ordinal number, not in the file
- int nXTs; // total number of "XT"-atoms
- pstr Comp1; // composition string
- pstr Comp2; // composition string with leaving atom
-
- CSBIndex ();
- CSBIndex ( RPCStream Object );
- ~CSBIndex();
-
- int MakeCompositions ( PCSBStructure SBS );
-
- void read ( RCFile f );
- void write ( RCFile f );
-
- protected :
- void SBIndexInit();
-
-};
-
-DefineStreamFunctions(CSBIndex);
-
-
-
-// ========================== CSBase0 ============================
-
-extern int MakeChirInd ( char chirality );
-extern int MakeElementType ( int ElType, int Chirality,
- Boolean Cflag );
-extern int MakeElementType ( int ElType, char chirality,
- Boolean Cflag );
-
-
-#define SBASE_noHBonds 6
-#define SBASE_noDonors 5
-#define SBASE_noAcceptors 4
-#define SBASE_Incomplete 3
-#define SBASE_AlreadyUnloaded 2
-#define SBASE_AlreadyLoaded 1
-#define SBASE_Ok 0
-#define SBASE_FileNotFound -1
-#define SBASE_StructNotFound -2
-#define SBASE_WrongIndex -3
-#define SBASE_ReadError -4
-#define SBASE_ConnectivityError -5
-#define SBASE_CheckFail -6
-#define SBASE_NoAtomsFound -7
-#define SBASE_NoBonds -8
-#define SBASE_NoAtomData -9
-#define SBASE_EmptyResidue -10
-#define SBASE_NoSimilarity -11
-#define SBASE_SuperpositionFailed -12
-#define SBASE_Fail -13
-#define SBASE_BrokenBonds -14
-#define SBASE_EmptyResSet -15
-#define SBASE_noCoordHierarchy -16
-
-#define CMPLF_Hydrogens 0x00000001
-#define CMPLF_nonHs 0x00000002
-#define CMPLF_XT 0x00000004
-#define CMPLF_All 0x00000007
-
-
-// SDASelHandles is optionally used in MakeBonds(..), when
-// the latter works for hydrogen bond calculations.
-DefineStructure(SDASelHandles);
-struct SDASelHandles {
- int selHndDonor;
- int selHndAcceptor;
- int selHndHydrogen;
- int selKey;
- void getNewHandles ( PCMMDBManager MMDB );
- void makeSelIndexes ( PCMMDBManager MMDB );
- void deleteSelections ( PCMMDBManager MMDB );
-};
-
-
-DefineClass(CSBase0);
-
-class CSBase0 {
-
- public :
-
- CSBase0 ();
- ~CSBase0();
-
- // LoadIndex() loads index of the structural database. 'path'
- // must point on the directory containing the database files.
- // The index must be loaded once before retrieving any
- // information from the database.
- // LoadIndex() may return either SBASE_Ok or SBASE_FileNotFound.
- int LoadIndex ( cpstr path );
- int LoadIndex1 ( cpstr EnvVar );
-
- // LoadStructure(..) reads structure from *.sbase files and
- // stores it in RAM for faster access. There is no special
- // functions to access loaded structures, all requests to
- // *.sbase files and RAM-storage are dispatched automatically.
- int LoadStructure ( cpstr compoundID );
- // UnloadStructure(..) deletes strtucture from RAM and releases
- // its memory. The structure is then accessible in the normal
- // way from *.sbase files, which is slower.
- int UnloadStructure ( cpstr compoundID );
-
- // GetPath() returns full path to a file with file name FName
- // in the database directory. Length of S should suffice for
- // accomodating the path. The function returns S.
- // GetPath() will work only after loading the database index.
- pstr GetPath ( pstr & S, cpstr FName );
-
- // GetStructFile() creates and opens the database structure
- // file and returns its pointer. In the case of errors returns
- // NULL. Application is responsible for deleting this file.
- PCFile GetStructFile();
-
- // GetGraphFile() creates and opens the database graph
- // file and returns its pointer. In the case of errors returns
- // NULL. Application is responsible for deleting this file.
- PCFile GetGraphFile();
-
- // GetStructure(..) returns pointer to the monomer structure
- // identified by 3-letter compoundID. If such structure is not
- // found, the function returns NULL.
- // The function returns a pointer to a private copy of the
- // structure. Modifying it will not change data in the structural
- // database. The application is responsible for deallocating
- // the structure after use (simply use delete).
- // See description of CSBStructure for the explanation of
- // its fields.
- PCSBStructure GetStructure ( cpstr compoundID );
- PCSBStructure GetStructure ( int structNo, PCFile structFile );
- // 0...nStructures-1
-
- // Another form of GetStructure(..) uses an open structure
- // file, which allows to save on opening/closing file if
- // multiple access to SBase structures is required. The file
- // is neither open nor closed by the function
- PCSBStructure GetStructure ( cpstr compoundID,
- PCFile structFile );
-
- PCResidue makeCResidue ( cpstr compoundID,
- PCFile structFile,
- Boolean includeHydrogens=False,
- Boolean makeTer=False );
- PCResidue makeCResidue ( int structNo,
- PCFile structFile,
- Boolean includeHydrogens=False,
- Boolean makeTer=False );
-
-
- // GetGraph(..) retrieves data for chemical structure number
- // structNo (as described in Index) from graph file graphFile,
- // then allocates and builds the corresponding graph, which is
- // returned in G.
- // If Hflag is set >= 1, all hydrogens are removed from
- // the graph. If Hflag is set to 2, element types of atoms,
- // to which hydrogens are bonded, are modified with flag
- // HYDROGEN_BOND.
- // Returns SBASE_Ok in case of success. Other return code are
- // SBASE_WrongIndex and SBASE_ReadError.
- int GetGraph ( PCFile graphFile, int structNo, RPCGraph G,
- int Hflag );
- int GetGraph ( PCFile graphFile, RPCGraph G, int Hflag );
- int GetGraph ( int structNo , RPCGraph G, int Hflag );
- int GetGraph ( cpstr compoundID, RPCGraph G, int Hflag );
-
- // GetStructNo() returns position of the structure with
- // (3-letter) name 'name' as found in the database index.
- // Non-negative return means success, otherwise
- // SBASE_StructNotFound indicates that the requested structure
- // was not found in the database index.
- int GetStructNo ( cpstr compoundID );
-
- int GetNofAtoms ( cpstr compoundID );
- int GetNofAtoms ( int structNo );
-
- // GetNofStructures() returns number of structures in the
- // database index.
- int GetNofStructures() { return nStructures; }
-
- // CheckGraph(..) checks graph G against a same-name
- // structure in the database. The name must be passed in
- // G->name as a standard 3-letter code.
- // If Hflag is set >= 1, all hydrogens are removed from
- // the graph. If Hflag is set to 2, element types of atoms,
- // to which hydrogens are bonded, are modified with flag
- // HYDROGEN_BOND.
- // If Cflag is set to True, then chirality information is
- // assumed in the input graph G and it is used for the
- // checking. If Cflag is set to False, then chirality
- // information is neither assumed nor used for the checking.
- // If chirality is there, all element IDs in the graph are
- // assigned flag CHIRAL_RIGHT for 'R'-chirtality, CHIRAL_LEFT
- // for 'S'-chirality and no flag if the atom is not a chiral
- // center.
- // If a same-name structure is found in the database,
- // the function returns the number of matched vertices
- // (nMatched) from those found in the database (nInStructure).
- // The correspondence between the input and database graphs
- // is returned in array match (it should be of sufficient
- // length) such that ith vertex of input graph corresponds
- // to the match[i]th vertex of the database graph. The
- // function then returns SBASE_Ok if the number of matched
- // vertices coincides with nInStructure and nMatched, and
- // the return is SBASE_CheckFail otherwise.
- // If a same-name structure is not found, the function
- // returns SBASE_StructNotFound or SBASE_FileNotFound.
- int CheckGraph ( PCGraph G, int Hflag, Boolean Cflag,
- int & nInStructure, int & nMatched,
- ivector match, int minMatchSize=0 );
-
- // In the current implementation of CheckResidue, Cflag
- // must be always set False, as the chirality information
- // cannot be calculated (in this version) from 3D coordinates.
- // See the meaning of altLoc in mmdb_graph.h, other parameters
- // are the same as in CheckGraph(..) above.
- int CheckResidue ( PCResidue R, int Hflag, Boolean Cflag,
- int & nInResidue, int & nInStructure,
- int & nMatched, ivector match,
- cpstr altLoc=pstr(""),
- int minMatchSize=0 );
-
-
-
- // MakeBonds(..) makes bonds between atoms in MMDB's residue R
- // from data found in SBase. Residue R must be associated with
- // coordinate hierarchy. Data is retrieved from SBase on the basis
- // of residue name only. In case of multiple conformations, if
- // altLoc:
- // NULL - the highest occupancy atom will be taken
- // if all occupancies are equal then atom with
- // first altLoc taken
- // other - atoms with given altLoc are taken. If such
- // altLoc is not found, the function does as if
- // NULL value for altLoc is given.
- // If selHandles is not NULL, the function also selects atoms
- // in the residue according to their hydrogen bond attributes.
- // This is a special option for hydrogen bond calculations
- // If ignoreNegSigOcc is set True then the function will ignore
- // atoms with negative occupancy standard deviation. Such atoms
- // may be hydrogens added by CSBase0::AddHydrogen(..) function,
- // in general any atoms added by CSBAtom::MakeCAtom(..) function.
- // Added hydrogens may be ignored if MakeBonds is used in
- // CSbase::CalcHBonds(..) function.
- // Return:
- // SBASE_Ok success
- // SBASE_FileNotFound non-initiated SBase
- // SBASE_StructNotFound the residue's name is not found
- // in SBase
- // SBASE_EmptyResidue residue R does not contain atoms
- // SBASE_NoAtomsFound SBase entry does not contain atoms
- // SBASE_BrokenBonds some bonds could not be set up because
- // of missing atoms in R. This could be
- // a result of residue R named wrongly.
- int MakeBonds ( PCResidue R,
- pstr altLoc,
- PCFile structFile,
- PSDASelHandles selHandles,
- Boolean ignoreNegSigOcc );
-
- int GetEnergyTypes ( PCResidue R, PCFile structFile );
- int GetEnergyTypes ( PPCResidue R, int nRes, PCFile structFile );
- int GetEnergyTypes ( PCChain chain, PCFile structFile );
- int GetEnergyTypes ( PCModel model, PCFile structFile );
- int GetEnergyTypes ( PCMMDBManager MMDB, PCFile structFile );
-
-
- int AddHydrogens ( PCResidue R, PCFile structFile );
- int AddHydrogens ( PCChain chain, PCFile structFile );
- int AddHydrogens ( PCModel model, PCFile structFile );
- int AddHydrogens ( PCMMDBManager MMDB, PCFile structFile );
-
-
- // ComplementResidue(..) extracts data from SBase by residue
- // name, then superposes atoms having identical names and
- // adds the residue with atoms that are found in SBase but are
- // absent in the residue. The added atoms are rotated and
- // translated such as to comply with the superposed parts.
- // complFlag:
- // CMPLF_Hydrogens complement residue with hydrogens
- // CMPLF_nonHs complement residue with non-hydrogens
- // CMPLF_XT complement with C-terminus
- // Return:
- // SBASE_Ok success
- // SBASE_FileNotFound SBase is not initialized
- // SBASE_StructNotFound the residue's name is not found
- // in SBase
- // SBASE_EmptyResidue residue R does not contain atoms
- // SBASE_NoAtomsFound SBase entry does not contain atoms
- // SBASE_NoAtomsData SBase entry is not complete
- // SBASE_NoSimilarity too few coomon atom names in R
- // and SBase entry with the same
- // structure name
- // SBASE_SuperpositionFailed failed residue superposition
- // NOTE: the function rearranges ALL atoms in the residue according
- // to PDB order as written in SBase.
- int ComplementResidue ( PCResidue R, int complFlag,
- PCFile structFile=NULL );
-
- // The following will return
- // SBASE_Ok success
- // SBASE_FileNotFound SBase is not initialized
- // SBASE_Incomplete some residues were not fully completed
- // (warning)
- // SBASE_Fail no residues were completed
- int ComplementChain ( PCChain chain, int complFlag,
- PCFile structFile=NULL );
- int ComplementModel ( PCModel model, int complFlag,
- PCFile structFile=NULL );
- int ComplementFile ( PCMMDBManager MMDB, int complFlag,
- PCFile structFile=NULL );
-
- // GetAtomNames(...) returns atom names (AtName[i]), total
- // number of atoms (nAtoms) and number of hydrogens (nH) for
- // structure number structNo, as found in the database index.
- // Length of AtName should allow for accomodating all atom
- // names.
- // The function may return SBASE_Ok, SBASE_FileNotFound,
- // SBASE_WrongIndex and SBASE_ReadError.
- int GetAtNames ( int structNo, PAtomName AtName,
- int & nAtoms, int & nH );
-
- // GetAtomNames(RCFile..) works exactly like its overload
- // version above, however it allows to save time on reopening
- // the database's description file (structFile). The file
- // reference, passed to the function, should be associated with
- // opened description file. The function does not close the file.
- // The function may return SBASE_Ok, SBASE_WrongIndex and
- // SBASE_ReadError.
- int GetAtNames ( PCFile structFile, int structNo,
- PAtomName AtName, int & nAtoms, int & nH );
-
- // GetNofAtoms(..) returns number of non-hydrogen atoms
- // (nNonHAtoms) and number of hydrogens (nHAtoms) for structure
- // number structNo, as found in the database index.
- // The function may return SBASE_Ok or SBASE_WrongIndex.
- int GetNofAtoms ( int structNo, int & nNonHAtoms, int & nHAtoms );
-
- // GetAtoms(...) retrieves the number of non-hydrogen atoms
- // (nNonHAtoms), their names (NonHAtName), number of hydrogens
- // (nHAtoms) and their names (HAtName), hydrogens' connectivity
- // to non-hydrogen atoms (Hconnect), element IDs (Elem) and
- // chiralities (Chiral) for structure named 'name'.
- // Hydrogen HAtName[i] is connected to non-hydrogen atom
- // NonHAtom[Hconnect[i]], if Hconnect[i]>=0.
- // The function may return SBASE_Ok, SNASE_StructNotFound,
- // SBASE_FileNotFound, SBASE_ReadError, SBASE_ConnectivityError.
- int GetAtoms ( cpstr compoundID,
- int & nNonHAtoms, PAtomName NonHAtName,
- int & nHAtoms, PAtomName HAtName,
- ivector Hconnect, ivector Elem,
- ivector Chiral );
-
- // GetAtoms(...) retrieves the number of atoms (nAtoms) and
- // number of bonds (nBonds[i]) and connectivity (bondPair[i][j])
- // for all atoms in the structure named 'name'. bondPair[i][j],
- // 0<=i<nAtoms, 0<=j<nBonds[i], gives the number of atom connected
- // to i-th atom. Only pairs i<j are returned.
- // maxNAtoms is the length of nBonds[] and bondPairs[],
- // maxNBonds is the length of bondPairs[][].
- // The function may return SBASE_Ok, SBASE_StructNotFound,
- // SBASE_FileNotFound, SBASE_ReadError.
- int GetBonds ( cpstr compoundID,
- ivector nBonds, imatrix bondPair,
- int & nAtoms, int maxNAtoms,
- int maxNBonds );
-
-
- int GetHetInfo ( cpstr name,
- pstr Formula,
- pstr Hname,
- pstr Hsynonym,
- pstr Hcharge,
- PAtomName & ClinkAtom, // will
- PElement & ClinkEle, // be
- PAtomName & SlinkAtom, // allocated
- PElement & SlinkEle, // or NULL
- int & nLeavingAtoms );
-
- protected :
- pstr dirpath;
- PPCSBIndex Index;
- int nStructures;
-
- void InitSBase0 ();
- void FreeMemory0();
-
- private :
- int nIAlloc,nLoad,nLAlloc;
- PPCGraph ldGraph;
- PPCSBStructure ldStructure;
-
-};
-
-#endif
diff --git a/mmdb/mmdb_selmngr.cpp b/mmdb/mmdb_selmngr.cpp
deleted file mode 100755
index fca71c1..0000000
--- a/mmdb/mmdb_selmngr.cpp
+++ /dev/null
@@ -1,3393 +0,0 @@
-// $Id: mmdb_selmngr.cpp,v 1.28 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 29.01.10 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : mmdb_selmngr <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CMMDBSelManager ( MMDB atom selection manager )
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2010
-//
-// =================================================================
-//
-
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifndef __MATH_H
-#include <math.h>
-#endif
-
-#ifndef __MMDB_SelMngr__
-#include "mmdb_selmngr.h"
-#endif
-
-
-
-// ==================== CMMDBSelManager =====================
-
-CMMDBSelManager::CMMDBSelManager() : CMMDBCoorManager() {
- InitMMDBSelManager();
-}
-
-CMMDBSelManager::CMMDBSelManager ( RPCStream Object )
- : CMMDBCoorManager(Object) {
- InitMMDBSelManager();
-}
-
-CMMDBSelManager::~CMMDBSelManager() {
- DeleteAllSelections();
-}
-
-void CMMDBSelManager::ResetManager() {
- CMMDBCoorManager::ResetManager();
- DeleteAllSelections();
- InitMMDBSelManager ();
-}
-
-void CMMDBSelManager::InitMMDBSelManager() {
- nSelections = 0; // number of selections
- Mask = NULL; // vector of selections
- SelType = NULL; // vector of selection types
- nSelItems = NULL; // numbers of selected items
- Selection = NULL; // vector of selected items
-}
-
-
-// ------------------------ Selection -----------------------------
-
-int CMMDBSelManager::NewSelection() {
-int i,l;
-PCMask M;
-PPCMask Mask1;
-PPCMask * Selection1;
-ivector nSelItems1;
-ivector SelType1;
-
- M = new CMask();
- M->NewMask ( Mask,nSelections );
-
- i = 0;
- while (i<nSelections)
- if (!Mask[i]) break;
- else i++;
-
- if (i>=nSelections) {
- l = nSelections+10;
- Mask1 = new PCMask [l];
- Selection1 = new PPCMask[l];
- nSelItems1 = new int[l];
- SelType1 = new int[l];
- for (i=0;i<nSelections;i++) {
- Mask1 [i] = Mask [i];
- Selection1[i] = Selection[i];
- nSelItems1[i] = nSelItems[i];
- SelType1 [i] = SelType [i];
- }
- for (i=nSelections;i<l;i++) {
- Mask1 [i] = NULL;
- Selection1[i] = NULL;
- nSelItems1[i] = 0;
- SelType1 [i] = STYPE_UNDEFINED;
- }
- if (Mask) delete[] Mask;
- if (Selection) delete[] Selection;
- if (nSelItems) delete[] nSelItems;
- if (SelType) delete[] SelType;
- Mask = Mask1;
- Selection = Selection1;
- nSelItems = nSelItems1;
- SelType = SelType1;
- i = nSelections;
- nSelections = l;
- }
-
- Mask[i] = M;
- if (Selection[i]) delete[] Selection[i];
- Selection[i] = NULL;
- nSelItems[i] = 0;
- SelType [i] = STYPE_UNDEFINED;
-
- return i+1;
-
-}
-
-int CMMDBSelManager::GetSelType ( int selHnd ) {
-int k;
- if ((selHnd>0) && (selHnd<=nSelections)) {
- k = selHnd-1;
- if (Mask[k]) return SelType[k];
- }
- return STYPE_INVALID;
-}
-
-void CMMDBSelManager::DeleteSelection ( int selHnd ) {
-int i,k;
- if ((selHnd>0) && (selHnd<=nSelections)) {
- k = selHnd-1;
- if (Mask[k]) {
- for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->RemoveMask ( Mask[k] );
-
- // for (i=0;i<nAtoms;i++)
- // if (Atom[i])
- // Atom[i]->RemoveMask ( Mask[k] );
-
- delete Mask[k];
- }
- Mask[k] = NULL;
- if (Selection[k]) delete[] Selection[k];
- Selection[k] = NULL;
- nSelItems[k] = 0;
- SelType [k] = STYPE_UNDEFINED;
- }
-}
-
-
-PCMask CMMDBSelManager::GetSelMask ( int selHnd ) {
- if ((selHnd>0) && (selHnd<=nSelections))
- return Mask[selHnd-1];
- else return NULL;
-}
-
-void CMMDBSelManager::DeleteAllSelections() {
-PCResidue res ,res1;
-PCChain chain,chain1;
-PCModel model,model1;
-int i;
-
- if (Mask) {
- res = NULL;
- chain = NULL;
- model = NULL;
- if (Atom)
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- Atom[i]->ClearMask();
- res1 = Atom[i]->GetResidue();
- if (res1!=res) {
- res = res1;
- res->ClearMask();
- chain1 = res->GetChain();
- if (chain1!=chain) {
- chain = chain1;
- chain->ClearMask();
- model1 = chain->GetModel();
- if (model1!=model) {
- model = model1;
- model->ClearMask();
- }
- }
- }
- }
- for (i=0;i<nSelections;i++) {
- if (Mask [i]) delete Mask[i];
- if (Selection[i]) delete[] Selection[i];
- }
- delete[] Mask;
- if (Selection) delete[] Selection;
- if (nSelItems) delete[] nSelItems;
- if (SelType) delete[] SelType;
- }
-
- nSelections = 0;
- Mask = NULL;
- Selection = NULL;
- nSelItems = NULL;
- SelType = NULL;
-
-}
-
-void CMMDBSelManager::SelectAtoms ( int selHnd, int iSer1, int iSer2,
- int selKey ) {
-// SelectAtoms(..) selects atoms in the serial number range
-// of iSer1 to iSer2 by adding them to the set of atoms
-// marked by the given mask. If iSer1=iSer2=0 then all atoms
-// are selected. Each atom may be selected by a number of masks
-// simultaneously
-int i,s1,s2,k, sk,nsel;
-
- if ((selHnd<=0) || (selHnd>nSelections) || (nAtoms<=0)) return;
-
- k = selHnd-1;
- sk = selKey;
-
- if ((SelType[k]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k] = STYPE_ATOM;
- else if (SelType[k]!=STYPE_ATOM) return;
-
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nAtoms;i++)
- if (Atom[i]) Atom[i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
- nsel = nSelItems[k];
- break;
- case SKEY_AND : nsel = 0; break;
- case SKEY_XOR : nsel = nSelItems[k]; break;
- case SKEY_CLR : nsel = nSelItems[k];
- if (nsel<=0) return;
- break;
- }
-
- if ((iSer1==0) && (iSer2==0)) {
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- if (!Atom[i]->Ter)
- SelectAtom ( Atom[i],k,sk,nsel );
- }
- } else {
- if (iSer1<=iSer2) {
- s1 = iSer1;
- s2 = iSer2;
- } else {
- s1 = iSer2;
- s2 = iSer1;
- }
- // for a very general use, we allow the serial number
- // to differ from the atom's index, although this is
- // against PDB format. Therefore we apply here the most
- // primitive and less efficient way of selection
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- if (!Atom[i]->Ter) {
- if ((s1<=Atom[i]->serNum) && (Atom[i]->serNum<=s2))
- SelectAtom ( Atom[i],k,sk,nsel );
- else if (sk==SKEY_AND)
- Atom[i]->RemoveMask ( Mask[k] );
- }
- }
- }
-
- MakeSelIndex ( selHnd,STYPE_ATOM,nsel );
-
-}
-
-
-void CMMDBSelManager::SelectAtoms ( int selHnd, ivector asn, int nsn,
- int selKey ) {
-// SelectAtoms(..) selects atoms with serial numbers given in
-// vector asn[0..nsn-1].
-CQuickSort QS;
-ivector asn1;
-int i,k,nsn1,j,j1,j2, sk,sn,nsel;
-
- if ((selHnd<=0) || (selHnd>nSelections) || (nAtoms<=0)) return;
-
- k = selHnd-1;
- sk = selKey;
-
- if ((SelType[k]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k] = STYPE_ATOM;
- else if (SelType[k]!=STYPE_ATOM) return;
-
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nAtoms;i++)
- if (Atom[i]) Atom[i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
- nsel = nSelItems[k];
- break;
- case SKEY_AND : nsel = 0; break;
- case SKEY_XOR : nsel = nSelItems[k]; break;
- case SKEY_CLR : nsel = nSelItems[k];
- if (nsel<=0) return;
- break;
- }
-
- GetVectorMemory ( asn1,nsn,0 );
- for (i=0;i<nsn;i++)
- asn1[i] = asn[i];
-
- QS.Sort ( asn1,nsn );
- nsn1 = nsn-1;
-
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- if (!Atom[i]->Ter) {
- sn = Atom[i]->serNum;
- if ((asn1[0]<=sn) && (sn<=asn1[nsn1])) {
- // binary search
- j1 = 0;
- j2 = nsn1;
- do {
- j = (j1+j2)/2;
- if (sn<asn1[j]) j2 = j;
- else if (sn>asn1[j]) j1 = j;
- else j1 = j2;
- } while (j1<j2-1);
- if ((sn==asn1[j]) || (sn==asn1[j1]) || (sn==asn1[j2]))
- SelectAtom ( Atom[i],k,sk,nsel );
- else if (sk==SKEY_AND)
- Atom[i]->RemoveMask ( Mask[k] );
- } else if (sk==SKEY_AND)
- Atom[i]->RemoveMask ( Mask[k] );
- }
- }
-
- FreeVectorMemory ( asn1,0 );
-
- MakeSelIndex ( selHnd,STYPE_ATOM,nsel );
-
-}
-
-
-void CMMDBSelManager::UnselectAtoms ( int selHnd, int iSer1, int iSer2 ) {
-// UnselectAtoms(..) clears the specified mask for atoms in
-// the serial number range of iSer1 to iSer2. If iSer1=iSer2=0
-// then all atoms are cleared of the specified mask. If selHnd
-// is set to 0, then the atoms are cleared of any mask.
-int i,s1,s2,k;
-
- if ((selHnd<=nSelections) && (nAtoms>0)) {
-
- k = selHnd-1;
-
- if (SelType[k]==STYPE_UNDEFINED) SelType[k] = STYPE_ATOM;
- else if (SelType[k]!=STYPE_ATOM) return;
-
- if ((iSer1==0) && (iSer2==0)) {
- if (k<0) {
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) Atom[i]->ClearMask();
- } else {
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) Atom[i]->RemoveMask ( Mask[k] );
- }
- } else {
- if (iSer1<=iSer2) {
- s1 = iSer1;
- s2 = iSer2;
- } else {
- s1 = iSer2;
- s2 = iSer1;
- }
- // for a very general use, we allow the serial number
- // to differ from the atom's index, although this is
- // against PDB format. Therefore we apply here the most
- // primitive and less efficient way of selection
- if (k<0) {
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- if ((s1<=Atom[i]->serNum) && (Atom[i]->serNum<=s2))
- Atom[i]->ClearMask();
- }
- } else {
- for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- if ((s1<=Atom[i]->serNum) && (Atom[i]->serNum<=s2))
- Atom[i]->RemoveMask ( Mask[k] );
- }
- }
- }
-
- MakeSelIndex ( selHnd,STYPE_ATOM,-1 );
-
- }
-
-}
-
-
-pstr MakeList ( cpstr S ) {
-// makes the list of selecting items:
-// 1st character - special use,
-// then each item from S embraced by commas
-pstr L;
-int i,j;
- i = 0;
- while (S[i]==' ') i++;
- if (S[i]!='*') {
- // compile a searchable list
- L = new char[strlen(S)+5];
- if (S[i]=='!') {
- L[0] = '!';
- i++;
- } else
- L[0] = ' ';
- if (strchr(S,'[')) L[1] = '"';
- else L[1] = ' ';
- L[2] = ',';
- j = 3;
- while (S[i]) {
- while (S[i]==' ') i++;
- if (S[i]=='[') {
- while (S[i] && (S[i]!=']'))
- L[j++] = S[i++];
- L[j++] = ']';
- if (S[i]==']') i++;
- } else
- while (S[i] && (S[i]!=' ') && (S[i]!=','))
- L[j++] = S[i++];
- while (S[i]==' ') i++;
- L[j++] = ',';
- if (S[i]==',') {
- i++;
- if (!S[i]) L[j++] = ','; // blank chain ID at the end assumed
- }
- }
- if (j==3) L[j++] = ',';
- L[j] = char(0);
- } else
- L = NULL;
- return L;
-}
-
-Boolean MatchName ( pstr L, pstr N ) {
-char M[MaxMMDBNameLength+5];
-int i,j;
- if (L) {
- i = 0;
- M[0] = ',';
- j = 1;
- while (N[i])
- if (N[i]==' ') i++;
- else M[j++] = N[i++];
- M[j++] = ',';
- M[j] = char(0);
- if (strstr(&(L[2]),M)) return (L[0]!='!');
- else if (L[1]!='"') return (L[0]=='!');
- else {
- strcpy ( M,",[" );
- strcat ( M,N );
- strcat ( M,"]," );
- if (strstr(&(L[2]),M)) return (L[0]!='!');
- else return (L[0]=='!');
- }
- } else
- return True;
-}
-
-Boolean MatchCharge ( pstr L, PCAtom atom ) {
-char N[100];
- if (L) {
- if (atom->WhatIsSet & ASET_Charge) {
- sprintf ( N,"%+2i",mround(atom->charge) );
- return MatchName ( L,N );
- } else
- return False;
- } else
- return True;
-}
-
-
-void CMMDBSelManager::SelectAtom ( int selHnd, PCAtom A, int selKey,
- Boolean makeIndex ) {
-int i, k, sk, nsel;
-
- if ((selHnd<=0) || (selHnd>nSelections)) return;
-
- k = selHnd-1;
- sk = selKey;
-
- if ((SelType[k]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k] = STYPE_ATOM;
- else if (SelType[k]!=STYPE_ATOM) return;
-
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
- nsel = nSelItems[k];
- break;
- case SKEY_AND : if (nSelItems[k]==0) return;
- nsel = 0;
- break;
- case SKEY_XOR : nsel = nSelItems[k];
- break;
- case SKEY_CLR : nsel = nSelItems[k];
- if (nsel<=0) return;
- break;
- }
-
- SelectAtom ( A,k,sk,nsel);
- if (makeIndex) MakeSelIndex ( selHnd,STYPE_ATOM,nsel );
-
-}
-
-
-void CMMDBSelManager::SelectResidue ( int selHnd, PCResidue Res,
- int selType, int selKey,
- Boolean makeIndex ) {
-// Selects residue Res or all its atoms depending on selType
-PPCAtom A;
-int i, k, sk, nsel, nat;
-
- if ((selHnd<=0) || (selHnd>nSelections)) return;
-
- k = selHnd-1;
- sk = selKey;
-
- if ((SelType[k]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k] = selType;
- else if (SelType[k]!=selType) return;
-
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
- nsel = nSelItems[k];
- break;
- case SKEY_AND : if (nSelItems[k]==0) return;
- nsel = 0;
- break;
- case SKEY_XOR : nsel = nSelItems[k];
- break;
- case SKEY_CLR : nsel = nSelItems[k];
- if (nsel<=0) return;
- break;
- }
-
- switch (selType) {
- case STYPE_ATOM : Res->GetAtomTable ( A,nat );
- for (i=0;i<nat;i++)
- if (A[i]) {
- if (!A[i]->Ter)
- SelectAtom ( A[i],k,sk,nsel);
- }
- break ;
- case STYPE_RESIDUE : SelectObject ( Res,k,sk,nsel );
- break ;
- default : ;
- }
-
- if (makeIndex) MakeSelIndex ( selHnd,selType,nsel );
-
-}
-
-
-void CMMDBSelManager::SelectChain ( int selHnd, PCChain Chain,
- int selType, int selKey,
- Boolean makeIndex ) {
-// Selects chain Chain or all its residues or atoms depending on selType
-PPCAtom A;
-PPCResidue Res;
-int i,j, k, sk, nsel, nat,nres;
-
- if ((selHnd<=0) || (selHnd>nSelections)) return;
-
- k = selHnd-1;
- sk = selKey;
-
- if ((SelType[k]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k] = selType;
- else if (SelType[k]!=selType) return;
-
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
- nsel = nSelItems[k];
- break;
- case SKEY_AND : if (nSelItems[k]==0) return;
- nsel = 0;
- break;
- case SKEY_XOR : nsel = nSelItems[k];
- break;
- case SKEY_CLR : nsel = nSelItems[k];
- if (nsel<=0) return;
- break;
- }
-
- switch (selType) {
- case STYPE_ATOM : Chain->GetResidueTable ( Res,nres );
- for (i=0;i<nres;i++)
- if (Res[i]) {
- Res[i]->GetAtomTable ( A,nat );
- for (j=0;j<nat;j++)
- if (A[j]) {
- if (!A[j]->Ter)
- SelectAtom ( A[j],k,sk,nsel);
- }
- }
- break ;
- case STYPE_RESIDUE : Chain->GetResidueTable ( Res,nres );
- for (i=0;i<nres;i++)
- if (Res[i])
- SelectObject ( Res[i],k,sk,nsel );
- break ;
- case STYPE_CHAIN : SelectObject ( Chain,k,sk,nsel );
- break ;
- default : ;
- }
-
- if (makeIndex) MakeSelIndex ( selHnd,selType,nsel );
-
-}
-
-
-void CMMDBSelManager::SelectModel ( int selHnd, PCModel model,
- int selType, int selKey,
- Boolean makeIndex ) {
-// Selects model or all its chains or residues or atoms depending
-// on selType
-PPCAtom A;
-PPCResidue Res;
-PPCChain Chain;
-int i,j,n, k, sk, nsel, nat,nres,nch;
-
- if ((selHnd<=0) || (selHnd>nSelections)) return;
-
- k = selHnd-1;
- sk = selKey;
-
- if ((SelType[k]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k] = selType;
- else if (SelType[k]!=selType) return;
-
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
- nsel = nSelItems[k];
- break;
- case SKEY_AND : if (nSelItems[k]==0) return;
- nsel = 0;
- break;
- case SKEY_XOR : nsel = nSelItems[k];
- break;
- case SKEY_CLR : nsel = nSelItems[k];
- if (nsel<=0) return;
- break;
- }
-
- switch (selType) {
- case STYPE_ATOM : model->GetChainTable ( Chain,nch );
- for (i=0;i<nch;i++)
- if (Chain[i]) {
- Chain[i]->GetResidueTable ( Res,nres );
- for (j=0;j<nres;j++)
- if (Res[j]) {
- Res[j]->GetAtomTable ( A,nat );
- for (n=0;n<nat;n++)
- if (A[n]) {
- if (!A[n]->Ter)
- SelectAtom ( A[n],k,sk,nsel);
- }
- }
- }
- break ;
- case STYPE_RESIDUE : model->GetChainTable ( Chain,nch );
- for (i=0;i<nch;i++)
- if (Chain[i]) {
- Chain[i]->GetResidueTable ( Res,nres );
- for (j=0;j<nres;j++)
- if (Res[j])
- SelectObject ( Res[j],k,sk,nsel );
- }
- break ;
- case STYPE_CHAIN : model->GetChainTable ( Chain,nch );
- for (i=0;i<nch;i++)
- if (Chain[i])
- SelectObject ( Chain[i],k,sk,nsel );
- break ;
- case STYPE_MODEL : SelectObject ( model,k,sk,nsel );
- break ;
- default : ;
- }
-
- if (makeIndex) MakeSelIndex ( selHnd,selType,nsel );
-
-}
-
-
-int CMMDBSelManager::MakeSelIndex ( int selHnd ) {
-int k;
- if ((selHnd<=0) || (selHnd>nSelections)) return 0;
- k = selHnd-1;
- if (SelType[k]==STYPE_UNDEFINED) return 0;
- MakeSelIndex ( selHnd,SelType[k],-1 );
- return nSelItems[k];
-}
-
-void CMMDBSelManager::MakeAllSelIndexes() {
-int k;
- for (k=0;k<nSelections;k++)
- if (SelType[k]!=STYPE_UNDEFINED)
- MakeSelIndex ( k+1,SelType[k],-1 );
-}
-
-void CMMDBSelManager::SelectAtoms (
- int selHnd, // must be obtained from NewSelection()
- int iModel, // model number; iModel=0 means
- // 'any models'
- cpstr Chains, // may be several chains "A,B,W";
- // "*" means 'any chain' (in model)
- int ResNo1, // starting residue number
- cpstr Ins1, // starting residue insertion code;
- // "*" means 'any code'
- int ResNo2, // ending residue number.
- // ResNo1=ResNo2=ANY_RES
- // means 'any residue number'
- // (in chain)
- cpstr Ins2, // ending residue insertion code
- // "*" means 'any code'
- cpstr RNames, // may be several residue names
- // "ALA,GLU,CIS"; "*" means
- // 'any residue name'
- cpstr ANames, // may be several names "CA,CB";
- // "*" means 'any atom' (in residue)
- cpstr Elements, // may be several element types like
- // "H,C,O,CU"; "*" means 'any element'
- cpstr altLocs, // may be several alternative
- // locations 'A,B'; "*" means 'any
- // alternative location'
- cpstr Segments, // may be several segment IDs like
- // "S1,S2,A234"; "*" means 'any
- // segment'
- cpstr Charges, // may be several charges like
- // "+1,-2, "; "*" means 'any charge'
- realtype occ1, // lowest occupancy
- realtype occ2, // highest occupancy;
- // occ1=occ2<0.0 means
- // "any occupancy"
- realtype x0, // reference x-point
- realtype y0, // reference y-point
- realtype z0, // reference z-point
- realtype d0, // selection distance from the reference
- // reference point; d0<=0.0 means
- // 'any distance" and values of
- // x0, y0 and z0 are ignored
- int selKey // selection key
- ) {
-
- Select ( selHnd,STYPE_ATOM,iModel,Chains,ResNo1,Ins1,ResNo2,Ins2,
- RNames,ANames,Elements,altLocs,Segments,Charges,
- occ1,occ2,x0,y0,z0,d0,selKey );
-
-}
-
-
-#define hetIndicator '@'
-
-void CMMDBSelManager::Select (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- int iModel, // model number; iModel=0 means
- // 'any models'
- cpstr Chains, // may be several chains "A,B,W";
- // "*" means 'any chain' (in model)
- int ResNo1, // starting residue number
- cpstr Ins1, // starting residue insertion code;
- // "*" means 'any code'
- int ResNo2, // ending residue number.
- // ResNo1=ResNo2=ANY_RES means 'any
- // residue number' (in chain)
- cpstr Ins2, // ending residue insertion code
- // "*" means 'any code'
- cpstr RNames, // may be several residue names
- // "ALA,GLU,CIS"; "*" means 'any
- // residue name'
- cpstr ANames, // may be several names "CA,CB";"*"
- // means 'any atom' (in residue)
- cpstr Elements, // may be several element types like
- // "H,C,O,CU"; "*" means 'any element'
- cpstr altLocs, // may be several alternative
- // locations 'A,B'; "*" means 'any
- // alternative location'
- cpstr Segments, // may be several segment IDs like
- // "S1,S2,A234"; "*" means 'any
- // segment'
- cpstr Charges, // may be several charges like
- // "+1,-2, "; "*" means 'any charge'
- realtype occ1, // lowest occupancy
- realtype occ2, // highest occupancy;
- // occ1=occ2<0.0 means
- // "any occupancy"
- realtype x0, // reference x-point
- realtype y0, // reference y-point
- realtype z0, // reference z-point
- realtype d0, // selection distance from the reference
- // reference point; d0<=0.0 means
- // 'any distance" and values of
- // x0, y0 and z0 are ignored
- int selKey // selection key
- ) {
-int i,j,k,n,m1,m2,c, sk,nsel;
-realtype dx,dy,dz,d02;
-Boolean noRes,Occ,Dist,Sel,selAND;
-Boolean modelSel,chainSel,resSel;
-PCModel model;
-PCChain chain;
-PCResidue res;
-PCAtom atom;
-pstr chain_l;
-pstr res_l;
-pstr atom_l;
-pstr elem_l;
-pstr altLocs1;
-pstr aloc_l;
-pstr segm_l;
-pstr charge_l;
-
- if ((selHnd<=0) || (selHnd>nSelections) || (nAtoms<=0)) return;
-
- modelSel = False;
-
- k = selHnd-1;
- sk = selKey;
-
- if ((SelType[k]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k] = selType;
- else if (SelType[k]!=selType) return;
-
- // if something goes wrong, sk should be assigned SKEY_OR if
- // selKey is set to SKEY_NEW or SKEY_OR below
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
- nsel = nSelItems[k];
- break;
- case SKEY_AND : nsel = 0; break;
- case SKEY_XOR : nsel = nSelItems[k]; break;
- case SKEY_CLR : nsel = nSelItems[k];
- if (nsel<=0) return;
- break;
- default : return;
- }
-
- selAND = (selKey==SKEY_AND);
-
- altLocs1 = NULL;
- if (altLocs) {
- if (strchr(altLocs,hetIndicator)) {
- CreateCopy ( altLocs1,altLocs );
- DelSpaces ( altLocs1 );
- aloc_l = strchr ( altLocs1,hetIndicator );
- aloc_l[0] = ' ';
- if (aloc_l[1]) aloc_l[1] = ' '; // instead of comma
- else if (aloc_l!=altLocs1) {
- aloc_l--;
- aloc_l[0] = ' ';
- }
- DelSpaces ( altLocs1 );
- aloc_l = MakeList ( altLocs1 );
- } else
- aloc_l = MakeList ( altLocs );
- } else
- aloc_l = MakeList ( altLocs );
-
- chain_l = MakeList ( Chains );
- res_l = MakeList ( RNames );
- atom_l = MakeList ( ANames );
- elem_l = MakeList ( Elements );
- segm_l = MakeList ( Segments );
- charge_l = MakeList ( Charges );
-
- // noRes==True means no residue restrictions
- noRes = (ResNo1==ResNo2) && (ResNo1==ANY_RES) &&
- (Ins1[0]==Ins2[0]) && (Ins1[0]=='*');
-
- Occ = (occ1>=0.0) || (occ2>=0.0);
- Dist = (d0>0.0);
- d02 = d0*d0;
-
- m1 = iModel-1;
-
- if (m1>=0)
- m2 = m1+1; // will take only this model
- else {
- m1 = 0; // will take
- m2 = nModels; // all models
- }
-
- if (m1>=nModels) return;
-
- for (n=0;n<nModels;n++) {
- model = Model[n];
- if (model) { // check for safety
- if ((m1<=n) && (n<m2)) {
- modelSel = False; // will be True on any selection in the model
- for (c=0;c<model->nChains;c++) {
- chain = model->Chain[c];
- if (chain) { // again check for safety
- if (MatchName(chain_l,chain->chainID)) {
- // the chain has to be taken
- i = 0;
- if (!noRes)
- while (i<chain->nResidues) {
- res = chain->Residue[i];
- if (res) {
- if ((res->seqNum==ResNo1) &&
- MatchName(res_l,res->name) &&
- ((Ins1[0]=='*') ||
- (!strcmp(res->insCode,Ins1))))
- break;
- else if (selAND) {
- if (selType==STYPE_ATOM)
- res->UnmaskAtoms ( Mask[k] );
- else if (selType==STYPE_RESIDUE)
- res->RemoveMask ( Mask[k] );
- }
- }
- i++;
- }
- while (i<chain->nResidues) {
- res = chain->Residue[i];
- if (res) {
- resSel = False; // will be True on 1st sel-n in the res-e
- if (MatchName(res_l,res->name)) {
- for (j=0;j<res->nAtoms;j++) {
- atom = res->atom[j];
- if (atom) {
- if ((!atom->Ter) &&
- MatchName(atom_l ,atom->name ) &&
- MatchName(elem_l ,atom->element) &&
- MatchName(aloc_l ,atom->altLoc ) &&
- MatchName(segm_l ,atom->segID ) &&
- MatchCharge(charge_l,atom ) &&
- ((!altLocs1) || atom->Het)) {
- Sel = True;
- if (Occ)
- Sel = ((occ1<=atom->occupancy) &&
- (atom->occupancy<=occ2));
- if (Dist) {
- dx = atom->x - x0;
- dy = atom->y - y0;
- dz = atom->z - z0;
- Sel = Sel && ((dx*dx+dy*dy+dz*dz)<=d02);
- }
- } else
- Sel = False;
- if (Sel) {
- SelectObject ( selType,atom,k,sk,nsel );
- resSel = True;
- chainSel = True;
- modelSel = True;
- } else if (selAND && (selType==STYPE_ATOM))
- atom->RemoveMask ( Mask[k] );
- }
- if (resSel && (selType!=STYPE_ATOM)) break;
- }
- } else if (selAND && (selType==STYPE_ATOM))
- res->UnmaskAtoms ( Mask[k] );
- if ((!resSel) && selAND && (selType==STYPE_RESIDUE))
- res->RemoveMask ( Mask[k] );
- if (chainSel && (selType>STYPE_RESIDUE)) break;
- if (!noRes) {
- if ((res->seqNum==ResNo2) &&
- ((Ins2[0]=='*') || (!strcmp(res->insCode,Ins2)))
- ) break;
- }
- }
- i++;
- }
- if (selAND) {
- if (selType==STYPE_ATOM)
- while (i<chain->nResidues) {
- res = chain->Residue[i];
- if (res) res->UnmaskAtoms ( Mask[k] );
- i++;
- }
- if (selType==STYPE_RESIDUE)
- while (i<chain->nResidues) {
- res = chain->Residue[i];
- if (res) res->RemoveMask ( Mask[k] );
- i++;
- }
- }
- } else if (selAND)
- switch (selType) {
- case STYPE_ATOM : chain->UnmaskAtoms ( Mask[k] ); break;
- case STYPE_RESIDUE : chain->UnmaskResidues ( Mask[k] ); break;
- case STYPE_CHAIN : chain->RemoveMask ( Mask[k] ); break;
- default : ;
- }
- if ((!chainSel) && selAND && (selType==STYPE_CHAIN))
- chain->RemoveMask ( Mask[k] );
- if (modelSel && (selType>STYPE_CHAIN)) break;
- }
- }
- } else if (selAND)
- switch (selType) {
- case STYPE_ATOM : model->UnmaskAtoms ( Mask[k] ); break;
- case STYPE_RESIDUE : model->UnmaskResidues ( Mask[k] ); break;
- case STYPE_CHAIN : model->UnmaskChains ( Mask[k] ); break;
- default : ;
- }
- if ((!modelSel) && selAND && (selType==STYPE_MODEL))
- model->RemoveMask ( Mask[k] );
- }
- }
-
- // release dynamic memory
- if (chain_l) delete[] chain_l;
- if (res_l) delete[] res_l;
- if (atom_l) delete[] atom_l;
- if (elem_l) delete[] elem_l;
- if (altLocs1) delete[] altLocs1;
- if (aloc_l) delete[] aloc_l;
- if (segm_l) delete[] segm_l;
- if (charge_l) delete[] charge_l;
-
- MakeSelIndex ( selHnd,STYPE_ATOM,nsel );
-
-}
-
-
-void CMMDBSelManager::SelectAtoms (
- int selHnd, // must be obtained from NewSelection()
- int iModel, // model number; iModel=0 means
- // 'any models'
- cpstr Chains, // may be several chains "A,B,W";
- // "*" means 'any chain' (in model)
- int ResNo1, // starting residue number
- cpstr Ins1, // starting residue insertion code;
- // "*" means 'any code'
- int ResNo2, // ending residue number.
- // ResNo1=ResNo2=ANY_RES means 'any
- // residue number' (in chain)
- cpstr Ins2, // ending residue insertion code
- // "*" means 'any code'
- cpstr RNames, // may be several residue names
- // "ALA,GLU,CIS"; "*" means 'any
- // residue name'
- cpstr ANames, // may be several names "CA,CB"; "*"
- // means 'any atom' (in residue)
- cpstr Elements, // may be several element types like
- // "H,C,O,CU"; "*" means 'any
- // element'
- cpstr altLocs, // may be several alternative
- // locations 'A,B'; "*" means 'any
- // alternative location'
- int selKey // selection key
- ) {
- Select ( selHnd,STYPE_ATOM,iModel,Chains,ResNo1,Ins1,ResNo2,Ins2,
- RNames,ANames,Elements,altLocs,selKey );
-}
-
-
-int CMMDBSelManager::Select (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- cpstr CID, // coordinate ID
- int selKey // selection key
- ) {
-int iModel,l,RC;
-pstr Chains;
-int seqNum1 ,seqNum2;
-InsCode insCode1,insCode2;
-pstr RNames;
-pstr ANames;
-pstr Elements;
-pstr altLocs;
-
- l = IMax(10,strlen(CID))+1;
- Chains = new char[l];
- RNames = new char[l];
- ANames = new char[l];
- Elements = new char[l];
- altLocs = new char[l];
-
- if (strcmp(CID,"-all")) {
- RC = ParseSelectionPath ( CID,iModel,Chains,seqNum1,insCode1,
- seqNum2,insCode2,RNames,ANames,
- Elements,altLocs );
- } else {
- iModel = 0;
- strcpy ( Chains,"*" );
- seqNum1 = ANY_RES;
- seqNum2 = ANY_RES;
- strcpy ( insCode1,"*" );
- strcpy ( insCode2,"*" );
- strcpy ( RNames ,"*" );
- strcpy ( ANames ,"*" );
- strcpy ( Elements,"*" );
- strcpy ( altLocs ,"" ); // only main conformation by default
- RC = 0;
- }
-
- if (!RC) {
- Select ( selHnd,selType,iModel,Chains,seqNum1,insCode1,
- seqNum2,insCode2,RNames,ANames,Elements,altLocs,selKey );
- RC = 0;
- }
-
- delete[] Chains;
- delete[] RNames;
- delete[] ANames;
- delete[] Elements;
- delete[] altLocs;
-
- return RC;
-
-}
-
-void CMMDBSelManager::Select (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- int iModel, // model number; iModel=0 means
- // 'any model'
- cpstr Chains, // may be several chains "A,B,W";
- // "*" means 'any chain' (in model)
- int ResNo1, // starting residue number
- cpstr Ins1, // starting residue insertion code;
- // "*" means 'any code'
- int ResNo2, // ending residue number.
- // ResNo1=ResNo2=ANY_RES means 'any
- // residue number' (in chain)
- cpstr Ins2, // ending residue insertion code
- // "*" means 'any code'
- cpstr RNames, // may be several residue names
- // "ALA,GLU,CIS"; "*" means 'any
- // residue name'
- cpstr ANames, // may be several names "CA,CB"; "*"
- // means 'any atom' (in residue)
- cpstr Elements, // may be several element types like
- // "H,C,O,CU"; "*" means 'any element'
- cpstr altLocs, // may be several alternative
- // locations 'A,B'; "*" means 'any
- // alternative location'
- int selKey // selection key
- ) {
-int i,j,k,n,m1,m2,c, sk,nsel;
-Boolean noRes,modelSel,chainSel,resSel,selAND;
-PCModel model;
-PCChain chain;
-PCResidue res;
-PCAtom atom;
-pstr chain_l;
-pstr res_l;
-pstr atom_l;
-pstr elem_l;
-pstr altLocs1;
-pstr aloc_l;
-
- if ((selHnd<=0) || (selHnd>nSelections) || (nAtoms<=0)) return;
-
- modelSel = False;
-
- k = selHnd-1;
- sk = selKey;
-
- if ((SelType[k]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k] = selType;
- else if (SelType[k]!=selType) return;
-
- // if something goes wrong, sk should be assigned SKEY_OR if
- // selKey is set to SKEY_NEW or SKEY_OR below
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
- nsel = nSelItems[k];
- break;
- case SKEY_AND : nsel = 0; break;
- case SKEY_XOR : nsel = nSelItems[k]; break;
- case SKEY_CLR : nsel = nSelItems[k];
- if (nsel<=0) return;
- break;
- default : return;
- }
-
- selAND = (selKey==SKEY_AND);
-
- altLocs1 = NULL;
- if (altLocs) {
- if (strchr(altLocs,hetIndicator)) {
- CreateCopy ( altLocs1,altLocs );
- DelSpaces ( altLocs1 );
- aloc_l = strchr ( altLocs1,hetIndicator );
- aloc_l[0] = ' ';
- if (aloc_l[1]) aloc_l[1] = ' '; // instead of comma
- else if (aloc_l!=altLocs1) {
- aloc_l--;
- aloc_l[0] = ' ';
- }
- DelSpaces ( altLocs1 );
- aloc_l = MakeList ( altLocs1 );
- } else
- aloc_l = MakeList ( altLocs );
- } else
- aloc_l = MakeList ( altLocs );
-
- chain_l = MakeList ( Chains );
- res_l = MakeList ( RNames );
- atom_l = MakeList ( ANames );
- elem_l = MakeList ( Elements );
-
- // noRes==True means no residue restrictions
- noRes = (ResNo1==ResNo2) && (ResNo1==ANY_RES) &&
- (Ins1[0]=='*') && (Ins2[0]=='*');
-
- m1 = iModel-1;
- if (m1>=0)
- m2 = m1+1; // will take only this model
- else {
- m1 = 0; // will take
- m2 = nModels; // all models
- }
-
- if (m1>=nModels) return;
-
- for (n=0;n<nModels;n++) {
- model = Model[n];
- if (model) { // check for safety
- if ((m1<=n) && (n<m2)) {
- modelSel = False; // will be True on any selection in the model
- for (c=0;c<model->nChains;c++) {
- chain = model->Chain[c];
- if (chain) { // again check for safety
- chainSel = False; // will be True on 1st sel-n in the chain
- if (MatchName(chain_l,chain->chainID)) {
- // the chain is to be taken
- i = 0;
- if (!noRes) // skip "leading" residues
- while (i<chain->nResidues) {
- res = chain->Residue[i];
- if (res) {
- if ((res->seqNum==ResNo1) &&
- MatchName(res_l,res->name) &&
- ((Ins1[0]=='*') ||
- (!strcmp(res->insCode,Ins1))))
- break;
- else if (selAND) {
- if (selType==STYPE_ATOM)
- res->UnmaskAtoms ( Mask[k] );
- else if (selType==STYPE_RESIDUE)
- res->RemoveMask ( Mask[k] );
- }
- }
- i++;
- }
- while (i<chain->nResidues) {
- res = chain->Residue[i];
- i++;
- if (res) {
- resSel = False; // will be True on 1st selection
- // in the residue
- if (MatchName(res_l,res->name)) {
- for (j=0;j<res->nAtoms;j++) {
- atom = res->atom[j];
- if (atom) {
- if ((!atom->Ter) &&
- MatchName(atom_l,atom->name ) &&
- MatchName(elem_l,atom->element) &&
- MatchName(aloc_l,atom->altLoc ) &&
- ((!altLocs1) || atom->Het)) {
- SelectObject ( selType,atom,k,sk,nsel );
- resSel = True;
- chainSel = True;
- modelSel = True;
- } else if (selAND && (selType==STYPE_ATOM))
- atom->RemoveMask ( Mask[k] );
- }
- if (resSel && (selType!=STYPE_ATOM)) break;
- }
- } else if (selAND && (selType==STYPE_ATOM))
- res->UnmaskAtoms ( Mask[k] );
- if ((!resSel) && selAND && (selType==STYPE_RESIDUE))
- res->RemoveMask ( Mask[k] );
- if (chainSel && (selType>STYPE_RESIDUE)) break;
- if (!noRes) {
- if ((res->seqNum==ResNo2) &&
- ((Ins2[0]=='*') || (!strcmp(res->insCode,Ins2)))
- ) break;
- }
- }
- }
- if (selAND) {
- if (selType==STYPE_ATOM)
- while (i<chain->nResidues) {
- res = chain->Residue[i];
- if (res) res->UnmaskAtoms ( Mask[k] );
- i++;
- }
- if (selType==STYPE_RESIDUE)
- while (i<chain->nResidues) {
- res = chain->Residue[i];
- if (res) res->RemoveMask ( Mask[k] );
- i++;
- }
- }
- } else if (selAND)
- switch (selType) {
- case STYPE_ATOM : chain->UnmaskAtoms ( Mask[k] ); break;
- case STYPE_RESIDUE : chain->UnmaskResidues ( Mask[k] ); break;
- default : ;
- }
- if ((!chainSel) && selAND && (selType==STYPE_CHAIN))
- chain->RemoveMask ( Mask[k] );
- if (modelSel && (selType>STYPE_CHAIN)) break;
- }
- }
- } else if (selAND)
- switch (selType) {
- case STYPE_ATOM : model->UnmaskAtoms ( Mask[k] ); break;
- case STYPE_RESIDUE : model->UnmaskResidues ( Mask[k] ); break;
- case STYPE_CHAIN : model->UnmaskChains ( Mask[k] ); break;
- default : ;
- }
- if ((!modelSel) && selAND && (selType==STYPE_MODEL))
- model->RemoveMask ( Mask[k] );
- }
- }
-
- // release dynamic memory
- if (chain_l) delete[] chain_l;
- if (res_l) delete[] res_l;
- if (atom_l) delete[] atom_l;
- if (elem_l) delete[] elem_l;
- if (altLocs1) delete[] altLocs1;
- if (aloc_l) delete[] aloc_l;
-
- MakeSelIndex ( selHnd,selType,nsel );
-
-}
-
-
-#define SKEY_XAND 100
-
-void CMMDBSelManager::Select (
- int selHnd1, // destination, must be obtained from
- // NewSelection()
- int selType, // selection type STYPE_XXXXX
- int selHnd2, // source, must be obtained from
- // NewSelection() and have been used
- // for selection
- int selKey // selection key
- ) {
-// SKEY_XOR works only downward the hierarchy!
-int k1,k2,sk,i,j,l,n,nsel;
-PCAtom atom;
-PCResidue res;
-PCChain chain;
-PCModel model;
-
- if ((selHnd1<=0) || (selHnd1>nSelections) ||
- (selHnd2<=0) || (selHnd2>nSelections) || (nAtoms<=0)) return;
-
- k1 = selHnd1-1;
- k2 = selHnd2-1;
- sk = selKey;
-
- if ((SelType[k1]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k1] = selType;
- else if (SelType[k1]!=selType) return;
-
- if (SelType[k2]==STYPE_UNDEFINED) return;
-
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nSelItems[k1];i++)
- if (Selection[k1][i])
- Selection[k1][i]->RemoveMask ( Mask[k1] );
- nSelItems[k1] = 0;
- sk = SKEY_OR;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k1]==0) sk = SKEY_NEW;
- nsel = nSelItems[k1];
- break;
- case SKEY_AND : if (nSelItems[k1]==0) return;
- sk = SKEY_XAND;
- nsel = 0;
- break;
- case SKEY_XOR : nsel = nSelItems[k1]; break;
- case SKEY_CLR : nsel = nSelItems[k1];
- if (nsel<=0) return;
- break;
- default : return;
- }
-
-
- switch (SelType[k2]) {
-
- case STYPE_ATOM :
- for (i=0;i<nSelItems[k2];i++) {
- atom = (PCAtom)Selection[k2][i];
- if (atom) {
- if (!atom->Ter)
- SelectObject ( selType,atom,k1,sk,nsel );
- }
- }
- break;
-
- case STYPE_RESIDUE :
- for (i=0;i<nSelItems[k2];i++) {
- res = (PCResidue)Selection[k2][i];
- if (res)
- switch (selType) {
- case STYPE_ATOM : for (j=0;j<res->nAtoms;j++) {
- atom = res->atom[j];
- if (atom) {
- if (!atom->Ter)
- SelectObject (atom,k1,sk,nsel);
- }
- }
- break;
- case STYPE_RESIDUE : //if (res->chain)
- SelectObject ( res,k1,sk,nsel );
- break;
- case STYPE_CHAIN : if (res->chain)
- SelectObject ( res->chain,k1,
- sk,nsel );
- break;
- case STYPE_MODEL : if (res->chain) {
- if (res->chain->model)
- SelectObject ( res->chain->model,
- k1,sk,nsel );
- }
- default : ;
- }
- }
- break;
-
- case STYPE_CHAIN :
- for (i=0;i<nSelItems[k2];i++) {
- chain = (PCChain)Selection[k2][i];
- if (chain)
- switch (selType) {
- case STYPE_ATOM : for (j=0;j<chain->nResidues;j++) {
- res = chain->Residue[j];
- if (res)
- for (l=0;l<res->nAtoms;l++) {
- atom = res->atom[l];
- if (atom) {
- if (!atom->Ter)
- SelectObject ( atom,k1,
- sk,nsel );
- }
- }
- }
- break;
- case STYPE_RESIDUE : for (j=0;j<chain->nResidues;j++) {
- res = chain->Residue[j];
- if (res)
- SelectObject ( res,k1,sk,nsel );
- }
- break;
- case STYPE_CHAIN : //if (chain->model)
- SelectObject ( chain,k1,sk,nsel );
- break;
- case STYPE_MODEL : if (chain->model)
- SelectObject ( chain->model,k1,
- sk,nsel );
- default : ;
- }
- }
- break;
-
- case STYPE_MODEL :
- for (i=0;i<nSelItems[k2];i++) {
- model = (PCModel)Selection[k2][i];
- if (model)
- switch (selType) {
- case STYPE_ATOM :
- for (j=0;j<model->nChains;j++) {
- chain = model->Chain[j];
- if (chain)
- for (l=0;l<chain->nResidues;l++) {
- res = chain->Residue[l];
- if (res)
- for (n=0;n<res->nAtoms;n++) {
- atom = res->atom[n];
- if (atom) {
- if (!atom->Ter)
- SelectObject ( atom,k1,sk,nsel );
- }
- }
- }
- }
- break;
- case STYPE_RESIDUE :
- for (j=0;j<model->nChains;j++) {
- chain = model->Chain[j];
- if (chain)
- for (l=0;l<chain->nResidues;l++) {
- res = chain->Residue[j];
- if (res)
- SelectObject ( res,k1,sk,nsel );
- }
- }
- break;
- case STYPE_CHAIN : for (j=0;j<model->nChains;j++) {
- chain = model->Chain[j];
- if (chain)
- SelectObject (chain,k1,sk,nsel);
- }
- break;
- case STYPE_MODEL : SelectObject ( model,k1,sk,nsel );
- default : ;
- }
- }
- break;
-
- default : ;
-
- }
-
- if (selKey==SKEY_AND)
- for (i=0;i<nSelItems[k1];i++)
- if (Selection[k1][i])
- Selection[k1][i]->XadMask ( Mask[k1] );
-
- MakeSelIndex ( selHnd1,selType,nsel );
-
-}
-
-void CMMDBSelManager::SelectProperty (
- int selHnd, // must be obtained from NewSelection()
- int propKey, // property key: 0 Solvent 1 Aminoacid
- int selType, // selection type STYPE_XXXXX
- int selKey // selection key
- ) {
-PCModel model;
-PCChain chain;
-PCResidue res;
-int i,k,selHnd1,sk,nsel, m,c,r;
-Boolean doSelect;
-
- if ((selHnd<=0) || (selHnd>nSelections) || (nAtoms<=0)) return;
-
- k = selHnd-1;
- if ((SelType[k]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k] = selType;
- else if (SelType[k]!=selType) return;
-
- if (selType!=STYPE_RESIDUE) {
- selHnd1 = NewSelection();
- if ((selKey==SKEY_AND) || (selKey==SKEY_CLR))
- Select ( selHnd1,STYPE_RESIDUE,selHnd,SKEY_NEW );
- } else
- selHnd1 = selHnd;
-
- k = selHnd1-1;
- SelType[k] = STYPE_RESIDUE;
- sk = selKey;
-
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- sk = SKEY_OR;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
- nsel = nSelItems[k];
- break;
- case SKEY_AND : if (nSelItems[k]==0) return;
- sk = SKEY_XAND;
- nsel = 0;
- break;
- case SKEY_XOR : nsel = nSelItems[k]; break;
- case SKEY_CLR : nsel = nSelItems[k];
- if (nsel<=0) return;
- break;
- default : return;
- }
-
- if ((selKey==SKEY_AND) || (selKey==SKEY_CLR)) {
-
- for (i=0;i<nSelItems[k];i++) {
- res = (PCResidue)Selection[k][i];
- if (res) {
- switch (propKey) {
- case SELPROP_Solvent : doSelect = res->isSolvent();
- break;
- case SELPROP_Aminoacid : doSelect = res->isAminoacid();
- break;
- case SELPROP_Nucleotide : doSelect = res->isNucleotide();
- break;
- case SELPROP_Sugar : doSelect = res->isSugar();
- break;
- case SELPROP_ModRes : doSelect = res->isModRes();
- break;
- default : doSelect = False;
- }
- if (doSelect) SelectObject ( res,k,sk,nsel );
- }
- }
-
- if (selKey==SKEY_AND)
- for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->XadMask ( Mask[k] );
-
- } else {
-
- for (m=0;m<nModels;m++) {
- model = Model[m];
- if (model) {
- for (c=0;c<model->nChains;c++) {
- chain = model->Chain[c];
- if (chain) {
- for (r=0;r<chain->nResidues;r++) {
- res = chain->Residue[r];
- if (res) {
- switch (propKey) {
- case SELPROP_Solvent : doSelect = res->isSolvent();
- break;
- case SELPROP_Aminoacid : doSelect = res->isAminoacid();
- break;
- case SELPROP_Nucleotide : doSelect = res->isNucleotide();
- break;
- case SELPROP_Sugar : doSelect = res->isSugar();
- break;
- case SELPROP_ModRes : doSelect = res->isModRes();
- break;
- default : doSelect = False;
- }
- if (doSelect) SelectObject ( res,k,sk,nsel );
- }
- }
- }
- }
- }
- }
-
- }
-
-
- MakeSelIndex ( selHnd1,STYPE_RESIDUE,nsel );
-
- if (selType!=STYPE_RESIDUE) {
- Select ( selHnd,selType,selHnd1,SKEY_NEW );
- DeleteSelection ( selHnd1 );
- }
-
-}
-
-
-void CMMDBSelManager::SelectUDD (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- int UDDhandle, // UDD handle
- int selMin, // lower selection boundary
- int selMax, // upper selection boundary
- int selKey // selection key
- ) {
-PCModel model;
-PCChain chain;
-PCResidue res;
-PCAtom atom;
-int i,k,sk,nsel,iudd, n,c,r,a;
-Boolean selAND;
-
- k = selHnd-1;
- sk = selKey;
-
- if ((SelType[k]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k] = selType;
- else if (SelType[k]!=selType) return;
-
-
- if ((selHnd<=0) || (selHnd>nSelections)) return;
-
- switch (selType) {
- case STYPE_ATOM : if ((UDDhandle & UDRF_ATOM)==0) return;
- break;
- case STYPE_RESIDUE : if ((UDDhandle & UDRF_RESIDUE)==0) return;
- break;
- case STYPE_CHAIN : if ((UDDhandle & UDRF_CHAIN)==0) return;
- break;
- case STYPE_MODEL : if ((UDDhandle & UDRF_MODEL)==0) return;
- break;
- default : return;
- }
-
-
- // if something goes wrong, sk should be assigned SKEY_OR if
- // selKey is set to SKEY_NEW or SKEY_OR below
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
- nsel = nSelItems[k];
- break;
- case SKEY_AND : if (nSelItems[k]==0) return;
- nsel = 0;
- break;
- case SKEY_XOR : nsel = nSelItems[k]; break;
- case SKEY_CLR : nsel = nSelItems[k];
- if (nsel<=0) return;
- break;
- default : return;
- }
-
- selAND = (selKey==SKEY_AND);
-
-
- for (n=0;n<nModels;n++) {
-
- model = Model[n];
- if (model) { // check for safety
-
- if (selType==STYPE_MODEL) {
-
- model->getUDData ( UDDhandle,iudd );
- if ((selMin<=iudd) && (iudd<=selMax))
- SelectObject ( model,k,sk,nsel );
- else if (selAND)
- model->RemoveMask ( Mask[k] );
-
- } else {
-
- for (c=0;c<model->nChains;c++) {
-
- chain = model->Chain[c];
- if (chain) { // again check for safety
-
- if (selType==STYPE_CHAIN) {
- chain->getUDData ( UDDhandle,iudd );
- if ((selMin<=iudd) && (iudd<=selMax))
- SelectObject ( chain,k,sk,nsel );
- else if (selAND)
- chain->RemoveMask ( Mask[k] );
-
- } else {
-
- for (r=0;r<chain->nResidues;r++) {
-
- res = chain->Residue[r];
- if (res) {
-
- if (selType==STYPE_RESIDUE) {
- res->getUDData ( UDDhandle,iudd );
- if ((selMin<=iudd) && (iudd<=selMax))
- SelectObject ( res,k,sk,nsel );
- else if (selAND)
- res->RemoveMask ( Mask[k] );
-
- } else {
-
- for (a=0;a<res->nAtoms;a++) {
- atom = res->atom[a];
- if (atom) {
- if (!atom->Ter) {
- atom->getUDData ( UDDhandle,iudd );
- if ((selMin<=iudd) && (iudd<=selMax))
- SelectObject ( atom,k,sk,nsel );
- else if (selAND)
- atom->RemoveMask ( Mask[k] );
- }
- }
-
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- MakeSelIndex ( selHnd,selType,nsel );
-
-}
-
-
-void CMMDBSelManager::SelectUDD (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- int UDDhandle, // UDD handle
- realtype selMin, // lower selection boundary
- realtype selMax, // upper selection boundary
- int selKey // selection key
- ) {
-PCModel model;
-PCChain chain;
-PCResidue res;
-PCAtom atom;
-realtype rudd;
-int i,k,sk,nsel, n,c,r,a;
-Boolean selAND;
-
- k = selHnd-1;
- sk = selKey;
-
- if ((SelType[k]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k] = selType;
- else if (SelType[k]!=selType) return;
-
-
- if ((selHnd<=0) || (selHnd>nSelections)) return;
-
- switch (selType) {
- case STYPE_ATOM : if ((UDDhandle & UDRF_ATOM)==0) return;
- break;
- case STYPE_RESIDUE : if ((UDDhandle & UDRF_RESIDUE)==0) return;
- break;
- case STYPE_CHAIN : if ((UDDhandle & UDRF_CHAIN)==0) return;
- break;
- case STYPE_MODEL : if ((UDDhandle & UDRF_MODEL)==0) return;
- break;
- default : return;
- }
-
-
- // if something goes wrong, sk should be assigned SKEY_OR if
- // selKey is set to SKEY_NEW or SKEY_OR below
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
- nsel = nSelItems[k];
- break;
- case SKEY_AND : if (nSelItems[k]==0) return;
- nsel = 0;
- break;
- case SKEY_XOR : nsel = nSelItems[k]; break;
- case SKEY_CLR : nsel = nSelItems[k];
- if (nsel<=0) return;
- break;
- default : return;
- }
-
- selAND = (selKey==SKEY_AND);
-
-
- for (n=0;n<nModels;n++) {
-
- model = Model[n];
- if (model) { // check for safety
-
- if (selType==STYPE_MODEL) {
-
- model->getUDData ( UDDhandle,rudd );
- if ((selMin<=rudd) && (rudd<=selMax))
- SelectObject ( model,k,sk,nsel );
- else if (selAND)
- model->RemoveMask ( Mask[k] );
-
- } else {
-
- for (c=0;c<model->nChains;c++) {
-
- chain = model->Chain[c];
- if (chain) { // again check for safety
-
- if (selType==STYPE_CHAIN) {
- chain->getUDData ( UDDhandle,rudd );
- if ((selMin<=rudd) && (rudd<=selMax))
- SelectObject ( chain,k,sk,nsel );
- else if (selAND)
- chain->RemoveMask ( Mask[k] );
-
- } else {
-
- for (r=0;r<chain->nResidues;r++) {
-
- res = chain->Residue[r];
- if (res) {
-
- if (selType==STYPE_RESIDUE) {
- res->getUDData ( UDDhandle,rudd );
- if ((selMin<=rudd) && (rudd<=selMax))
- SelectObject ( res,k,sk,nsel );
- else if (selAND)
- res->RemoveMask ( Mask[k] );
-
- } else {
-
- for (a=0;a<res->nAtoms;a++) {
- atom = res->atom[a];
- if (atom) {
- if (!atom->Ter) {
- atom->getUDData ( UDDhandle,rudd );
- if ((selMin<=rudd) && (rudd<=selMax))
- SelectObject ( atom,k,sk,nsel );
- else if (selAND)
- atom->RemoveMask ( Mask[k] );
- }
- }
-
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- MakeSelIndex ( selHnd,selType,nsel );
-
-}
-
-
-Boolean selSUDD ( cpstr sudd, cpstr selStr, int cmpRule, int ssLen ) {
- if (!sudd) return False;
- switch (cmpRule) {
- case UDSCR_LT : return (strcmp(sudd,selStr)<0);
- case UDSCR_LE : return (strcmp(sudd,selStr)<=0);
- case UDSCR_EQ : return (strcmp(sudd,selStr)==0);
- case UDSCR_NE : return (strcmp(sudd,selStr)!=0);
- case UDSCR_GE : return (strcmp(sudd,selStr)>=0);
- case UDSCR_GT : return (strcmp(sudd,selStr)>=0);
- case UDSCR_LTcase : return (strcasecmp(sudd,selStr)<0);
- case UDSCR_LEcase : return (strcasecmp(sudd,selStr)<=0);
- case UDSCR_EQcase : return (strcasecmp(sudd,selStr)==0);
- case UDSCR_NEcase : return (strcasecmp(sudd,selStr)!=0);
- case UDSCR_GEcase : return (strcasecmp(sudd,selStr)>=0);
- case UDSCR_GTcase : return (strcasecmp(sudd,selStr)>=0);
- case UDSCR_LTn : return (strncmp(sudd,selStr,ssLen)<0);
- case UDSCR_LEn : return (strncmp(sudd,selStr,ssLen)<=0);
- case UDSCR_EQn : return (strncmp(sudd,selStr,ssLen)==0);
- case UDSCR_NEn : return (strncmp(sudd,selStr,ssLen)!=0);
- case UDSCR_GEn : return (strncmp(sudd,selStr,ssLen)>=0);
- case UDSCR_GTn : return (strncmp(sudd,selStr,ssLen)>=0);
- case UDSCR_LTncase : return (strncasecmp(sudd,selStr,ssLen)<0);
- case UDSCR_LEncase : return (strncasecmp(sudd,selStr,ssLen)<=0);
- case UDSCR_EQncase : return (strncasecmp(sudd,selStr,ssLen)==0);
- case UDSCR_NEncase : return (strncasecmp(sudd,selStr,ssLen)!=0);
- case UDSCR_GEncase : return (strncasecmp(sudd,selStr,ssLen)>=0);
- case UDSCR_GTncase : return (strncasecmp(sudd,selStr,ssLen)>=0);
- case UDSCR_Substr : return (strstr(sudd,selStr)!=NULL);
- case UDSCR_NoSubstr : return (strstr(sudd,selStr)==NULL);
- case UDSCR_Substr1 : return (strstr(selStr,sudd)!=NULL);
- case UDSCR_NoSubstr1 : return (strstr(selStr,sudd)==NULL);
- default : return False;
- }
-}
-
-
-void CMMDBSelManager::SelectUDD (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- int UDDhandle, // UDD handle
- cpstr selStr, // selection string
- int cmpRule, // comparison rule
- int selKey // selection key
- ) {
-PCModel model;
-PCChain chain;
-PCResidue res;
-PCAtom atom;
-int i,k,sk,nsel,ssLen, n,c,r,a;
-Boolean selAND;
-
- k = selHnd-1;
- sk = selKey;
-
- if ((SelType[k]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k] = selType;
- else if (SelType[k]!=selType) return;
-
-
- if ((selHnd<=0) || (selHnd>nSelections)) return;
-
- switch (selType) {
- case STYPE_ATOM : if ((UDDhandle & UDRF_ATOM)==0) return;
- break;
- case STYPE_RESIDUE : if ((UDDhandle & UDRF_RESIDUE)==0) return;
- break;
- case STYPE_CHAIN : if ((UDDhandle & UDRF_CHAIN)==0) return;
- break;
- case STYPE_MODEL : if ((UDDhandle & UDRF_MODEL)==0) return;
- break;
- default : return;
- }
-
-
- // if something goes wrong, sk should be assigned SKEY_OR if
- // selKey is set to SKEY_NEW or SKEY_OR below
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
- nsel = nSelItems[k];
- break;
- case SKEY_AND : if (nSelItems[k]==0) return;
- nsel = 0;
- break;
- case SKEY_XOR : nsel = nSelItems[k]; break;
- case SKEY_CLR : nsel = nSelItems[k];
- if (nsel<=0) return;
- break;
- default : return;
- }
-
- selAND = (selKey==SKEY_AND);
- ssLen = strlen ( selStr );
-
- for (n=0;n<nModels;n++) {
-
- model = Model[n];
- if (model) { // check for safety
-
- if (selType==STYPE_MODEL) {
-
- if (selSUDD(model->getUDData(UDDhandle),selStr,
- cmpRule,ssLen))
- SelectObject ( model,k,sk,nsel );
- else if (selAND)
- model->RemoveMask ( Mask[k] );
-
- } else {
-
- for (c=0;c<model->nChains;c++) {
-
- chain = model->Chain[c];
- if (chain) { // again check for safety
-
- if (selType==STYPE_CHAIN) {
- if (selSUDD(chain->getUDData(UDDhandle),selStr,
- cmpRule,ssLen))
- SelectObject ( chain,k,sk,nsel );
- else if (selAND)
- chain->RemoveMask ( Mask[k] );
-
- } else {
-
- for (r=0;r<chain->nResidues;r++) {
-
- res = chain->Residue[r];
- if (res) {
-
- if (selType==STYPE_RESIDUE) {
- if (selSUDD(res->getUDData(UDDhandle),selStr,
- cmpRule,ssLen))
- SelectObject ( res,k,sk,nsel );
- else if (selAND)
- res->RemoveMask ( Mask[k] );
-
- } else {
-
- for (a=0;a<res->nAtoms;a++) {
- atom = res->atom[a];
- if (atom) {
- if (!atom->Ter) {
- if (selSUDD(atom->getUDData(UDDhandle),selStr,
- cmpRule,ssLen))
- SelectObject ( atom,k,sk,nsel );
- else if (selAND)
- atom->RemoveMask ( Mask[k] );
- }
- }
-
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- MakeSelIndex ( selHnd,selType,nsel );
-
-}
-
-
-void CMMDBSelManager::SelectSphere (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- realtype x, // x-coordinate of the sphere's center
- realtype y, // y-coordinate of the sphere's center
- realtype z, // z-coordinate of the sphere's center
- realtype r, // radius of the sphere
- int selKey // selection key
- ) {
-// Selecting a sphere
-int i,k, nat,sk,nsel, im,ic,ir;
-realtype dx,dy,dz, r2;
-Boolean ASel, resSel,chainSel,modelSel,selAND;
-PPCAtom A;
-PCAtom atom;
-PCResidue res;
-PCChain chain;
-PCModel model;
-
- if ((selHnd<=0) || (selHnd>nSelections) || (r<=0.0)) return;
-
- k = selHnd-1;
- sk = selKey;
- A = Atom;
- nat = nAtoms;
-
- if ((SelType[k]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k] = selType;
- else if (SelType[k]!=selType) return;
-
- // if something goes wrong, sk should be assigned SKEY_OR if
- // selKey is set to SKEY_NEW or SKEY_OR below
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
- nsel = nSelItems[k];
- break;
- case SKEY_AND : nsel = 0;
- nat = nSelItems[k];
- A = (PPCAtom)Selection[k];
- break;
- case SKEY_XOR : nsel = nSelItems[k];
- break;
- case SKEY_CLR : nsel = nSelItems[k];
- nat = nSelItems[k];
- A = (PPCAtom)Selection[k];
- break;
- default : return;
- }
-
- selAND = selType==SKEY_AND;
-
- if ((nat<=0) || (!A)) return;
-
- r2 = r*r;
-
- if (selType==STYPE_ATOM) {
-
- for (i=0;i<nat;i++)
- if (A[i]) {
- ASel = sk!=SKEY_AND;
- if ((!A[i]->Ter) && (A[i]->WhatIsSet & ASET_Coordinates)) {
- dx = fabs(A[i]->x-x);
- if (dx<=r) {
- dy = fabs(A[i]->y-y);
- if (dy<=r) {
- dz = fabs(A[i]->z-z);
- if (dz<=r) {
- if (dx*dx+dy*dy+dz*dz<=r2) {
- ASel = True;
- SelectAtom ( A[i],k,sk,nsel );
- }
- }
- }
- }
- }
- if (!ASel) A[i]->RemoveMask ( Mask[k] );
- }
-
- } else {
-
- for (im=0;im<nModels;im++) {
- model = Model[im];
- if (model) {
- modelSel = False;
- for (ic=0;ic<model->nChains;ic++) {
- chain = model->Chain[ic];
- if (chain) {
- chainSel = False;
- for (ir=0;ir<chain->nResidues;ir++) {
- res = chain->Residue[ir];
- if (res) {
- resSel = False;
- for (i=0;i<res->nAtoms;i++) {
- atom = res->atom[i];
- if (atom) {
- ASel = False;
- if ((!atom->Ter) &&
- (atom->WhatIsSet & ASET_Coordinates)) {
- dx = fabs(atom->x-x);
- if (dx<=r) {
- dy = fabs(atom->y-y);
- if (dy<=r) {
- dz = fabs(atom->z-z);
- if (dz<=r) {
- if (dx*dx+dy*dy+dz*dz<=r2) {
- SelectObject ( selType,atom,k,sk,nsel );
- ASel = True;
- resSel = True;
- chainSel = True;
- modelSel = True;
- }
- }
- }
- }
- }
- if (ASel) break; // selType>=STYPE_RESIDUE
- }
- }
- if ((!resSel) && selAND && (selType==STYPE_RESIDUE))
- res->RemoveMask ( Mask[k] );
- if (chainSel && (selType>STYPE_RESIDUE)) break;
- }
- }
- if ((!chainSel) && selAND && (selType==STYPE_CHAIN))
- chain->RemoveMask ( Mask[k] );
- if (modelSel && (selType>STYPE_CHAIN)) break;
- }
- }
- if ((!modelSel) && selAND && (selType==STYPE_MODEL))
- model->RemoveMask ( Mask[k] );
- }
- }
-
- }
-
- MakeSelIndex ( selHnd,selType,nsel );
-
-}
-
-
-void CMMDBSelManager::SelectCylinder (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- realtype x1, // x-coordinate of the cylinder axis' 1st end
- realtype y1, // y-coordinate of the cylinder axis' 1st end
- realtype z1, // z-coordinate of the cylinder axis' 1st end
- realtype x2, // x-coordinate of the cylinder axis' 2nd end
- realtype y2, // y-coordinate of the cylinder axis' 2nd end
- realtype z2, // z-coordinate of the cylinder axis' 2nd end
- realtype r, // radius of the cylinder
- int selKey // selection key
- ) {
-//
-// Selecting a cylinder
-//
-// Method : given a line running through (x1,y1,z1) to (x2,y2,z2) on,
-// a point (x,y,z) is then projected on it at distance
-//
-// c1 = (c^2-a^2+b^2)/(2c),
-//
-// from (x1,y1,z1), where
-// 'a' is the distance between (x,y,z) and (x2,y2,z2)
-// 'b' is the distance between (x,y,z) and (x1,y1,z1)
-// 'c' is the distance between (x1,y1,z1) and (x2,y2,z2).
-// The distance between point (x,y,z) and line is determined as
-//
-// h^2 = b^2 - c1^2
-//
-// If c1>=0 and c1<=c and h^2<=r^2 then point (x,y,z) is inside
-// a cylinder of radius 'r' with axis running from point
-// (x1,y1,z1) to (x2,y2,z2).
-//
-int i,k, nat,sk,nsel, im,ic,ir;
-realtype dx,dy,dz, c,dc,c1,c2, a2,b2, r2;
-Boolean resSel,chainSel,modelSel,selAND;
-PPCAtom A;
-PCAtom atom;
-PCResidue res;
-PCChain chain;
-PCModel model;
-
- if ((selHnd<=0) || (selHnd>nSelections) || (r<=0.0)) return;
-
- dx = x1-x2;
- dy = y1-y2;
- dz = z1-z2;
- c2 = dx*dx + dy*dy + dz*dz;
- if (c2<=0.0) return;
- c = sqrt(c2);
- dc = 2.0*c;
- r2 = r*r;
-
- k = selHnd-1;
- sk = selKey;
- A = Atom;
- nat = nAtoms;
-
- if ((SelType[k]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k] = selType;
- else if (SelType[k]!=selType) return;
-
- // if something goes wrong, sk should be assigned SKEY_OR if
- // selKey is set to SKEY_NEW or SKEY_OR below
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
- nsel = nSelItems[k];
- break;
- case SKEY_AND : nsel = 0;
- nat = nSelItems[k];
- A = (PPCAtom)Selection[k];
- break;
- case SKEY_XOR : nsel = nSelItems[k];
- break;
- case SKEY_CLR : nsel = nSelItems[k];
- nat = nSelItems[k];
- A = (PPCAtom)Selection[k];
- break;
- default : return;
- }
-
- selAND = selType==SKEY_AND;
-
- if ((nat<=0) || (!A)) return;
-
- if (selType==STYPE_ATOM) {
-
- for (i=0;i<nat;i++)
- if (A[i]) {
- if ((!A[i]->Ter) && (A[i]->WhatIsSet & ASET_Coordinates)) {
- dx = fabs(A[i]->x-x1);
- dy = fabs(A[i]->y-y1);
- dz = fabs(A[i]->z-z1);
- a2 = dx*dx + dy*dy + dz*dz;
- dx = fabs(A[i]->x-x2);
- dy = fabs(A[i]->y-y2);
- dz = fabs(A[i]->z-z2);
- b2 = dx*dx + dy*dy + dz*dz;
- c1 = (c2-a2+b2)/dc;
- if ((0.0<=c1) && (c1<=c) && (b2-c1*c1<=r2))
- SelectAtom ( A[i],k,sk,nsel );
- else if (sk==SKEY_AND)
- A[i]->RemoveMask ( Mask[k] );
- }
- }
-
- } else {
-
- for (im=0;im<nModels;im++) {
- model = Model[im];
- if (model) {
- modelSel = False;
- for (ic=0;ic<model->nChains;ic++) {
- chain = model->Chain[ic];
- if (chain) {
- chainSel = False;
- for (ir=0;ir<chain->nResidues;ir++) {
- res = chain->Residue[ir];
- if (res) {
- resSel = False;
- for (i=0;i<res->nAtoms;i++) {
- atom = res->atom[i];
- if (atom) {
- if ((!atom->Ter) &&
- (atom->WhatIsSet & ASET_Coordinates)) {
- dx = fabs(atom->x-x1);
- dy = fabs(atom->y-y1);
- dz = fabs(atom->z-z1);
- a2 = dx*dx + dy*dy + dz*dz;
- dx = fabs(atom->x-x2);
- dy = fabs(atom->y-y2);
- dz = fabs(atom->z-z2);
- b2 = dx*dx + dy*dy + dz*dz;
- c1 = (c2-a2+b2)/dc;
- if ((0.0<=c1) && (c1<=c) && (b2-c1*c1<=r2)) {
- SelectObject ( selType,atom,k,sk,nsel );
- resSel = True;
- chainSel = True;
- modelSel = True;
- break; // selType>=STYPE_RESIDUE
- }
- }
- }
- }
- if ((!resSel) && selAND && (selType==STYPE_RESIDUE))
- res->RemoveMask ( Mask[k] );
- if (chainSel && (selType>STYPE_RESIDUE)) break;
- }
- }
- if ((!chainSel) && selAND && (selType==STYPE_CHAIN))
- chain->RemoveMask ( Mask[k] );
- if (modelSel && (selType>STYPE_CHAIN)) break;
- }
- }
- if ((!modelSel) && selAND && (selType==STYPE_MODEL))
- model->RemoveMask ( Mask[k] );
- }
- }
-
- }
-
- MakeSelIndex ( selHnd,selType,nsel );
-
-}
-
-
-void CMMDBSelManager::SelectSlab (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- realtype a, // a-parameter of the plane ax+by+cz=d
- realtype b, // b-parameter of the plane ax+by+cz=d
- realtype c, // c-parameter of the plane ax+by+cz=d
- realtype d, // d-parameter of the plane ax+by+cz=d
- realtype r, // distance to the plane
- int selKey // selection key
- ) {
-//
-// Selecting all atoms on a given distance from a plane
-//
-// Method : the distance between a point (x0,y0,z0) and a plane
-// defined by equation
-//
-// a*x + b*y + c*z = d
-//
-// is found as
-//
-// h = (d-a*x0-b*y0-c*z0)/sqrt(a^2+b^2+c^2)
-//
-// If |h|<d then point (x0,y0,z0) belongs to the slab.
-//
-int i,k, nat,sk,nsel, im,ic,ir;
-realtype v,h;
-Boolean resSel,chainSel,modelSel,selAND;
-PPCAtom A;
-PCAtom atom;
-PCResidue res;
-PCChain chain;
-PCModel model;
-
- if ((selHnd<=0) || (selHnd>nSelections) || (r<=0.0)) return;
-
- v = sqrt(a*a + b*b + c*c);
- if (v<=0.0) return;
-
- k = selHnd-1;
- sk = selKey;
- A = Atom;
- nat = nAtoms;
-
- if ((SelType[k]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k] = selType;
- else if (SelType[k]!=selType) return;
-
- // if something goes wrong, sk should be assigned SKEY_OR if
- // selKey is set to SKEY_NEW or SKEY_OR below
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
- nsel = nSelItems[k];
- break;
- case SKEY_AND : nsel = 0;
- nat = nSelItems[k];
- A = (PPCAtom)Selection[k];
- break;
- case SKEY_XOR : nsel = nSelItems[k];
- break;
- case SKEY_CLR : nsel = nSelItems[k];
- nat = nSelItems[k];
- A = (PPCAtom)Selection[k];
- break;
- default : return;
- }
-
- selAND = selType==SKEY_AND;
-
- if ((nat<=0) || (!A)) return;
-
- if (selType==STYPE_ATOM) {
-
- for (i=0;i<nat;i++)
- if (A[i]) {
- if ((!A[i]->Ter) && (A[i]->WhatIsSet & ASET_Coordinates)) {
- h = fabs(d-a*A[i]->x-b*A[i]->y-c*A[i]->z)/v;
- if (h<=r)
- SelectAtom ( A[i],k,sk,nsel );
- else if (sk==SKEY_AND)
- A[i]->RemoveMask ( Mask[k] );
- }
- }
-
- } else {
-
- for (im=0;im<nModels;im++) {
- model = Model[im];
- if (model) {
- modelSel = False;
- for (ic=0;ic<model->nChains;ic++) {
- chain = model->Chain[ic];
- if (chain) {
- chainSel = False;
- for (ir=0;ir<chain->nResidues;ir++) {
- res = chain->Residue[ir];
- if (res) {
- resSel = False;
- for (i=0;i<res->nAtoms;i++) {
- atom = res->atom[i];
- if (atom) {
- if ((!atom->Ter) &&
- (atom->WhatIsSet & ASET_Coordinates)) {
- h = fabs(d-a*A[i]->x-b*A[i]->y-c*A[i]->z)/v;
- if (h<=r) {
- SelectObject ( selType,atom,k,sk,nsel );
- resSel = True;
- chainSel = True;
- modelSel = True;
- break; // selType>=STYPE_RESIDUE
- }
- }
- }
- }
- if ((!resSel) && selAND && (selType==STYPE_RESIDUE))
- res->RemoveMask ( Mask[k] );
- if (chainSel && (selType>STYPE_RESIDUE)) break;
- }
- }
- if ((!chainSel) && selAND && (selType==STYPE_CHAIN))
- chain->RemoveMask ( Mask[k] );
- if (modelSel && (selType>STYPE_CHAIN)) break;
- }
- }
- if ((!modelSel) && selAND && (selType==STYPE_MODEL))
- model->RemoveMask ( Mask[k] );
- }
- }
-
- }
-
- MakeSelIndex ( selHnd,selType,nsel );
-
-}
-
-
-void CMMDBSelManager::SelectNeighbours (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- PPCAtom sA, // array of already selected atoms
- int alen, // length of A
- realtype d1, // minimal distance to already selected atoms
- realtype d2, // maximal distance to already selected atoms
- int selKey // selection key
- ) {
-// Selecting all atoms on a given distance from already selected
-int i,j,k, dn, nx,ny,nz, nat,sk,nsel, im,ic,ir;
-int ix1,ix2,ix, iy1,iy2,iy, iz1,iz2,iz;
-realtype x,y,z, dx,dy,dz, dst, d12,d22;
-PPCAtom A;
-PCBrick B;
-PCAtom atom;
-PCResidue res;
-PCChain chain;
-PCModel model;
-Boolean ASel,resSel,chainSel,modelSel,selAND;
-
- if ((selHnd<=0) || (selHnd>nSelections) ||
- (d2<=0.0) || (d2<d1)) return;
-
- k = selHnd-1;
- sk = selKey;
- A = Atom;
- nat = nAtoms;
- d12 = d1*d1;
- d22 = d2*d2;
-
- if ((SelType[k]==STYPE_UNDEFINED) ||
- (selKey==SKEY_NEW)) SelType[k] = selType;
- else if (SelType[k]!=selType) return;
-
- if ((alen<1) || (!sA)) {
- if ((selKey==SKEY_NEW) || (selKey==SKEY_AND)) {
- for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- }
- return;
- }
-
- // if something goes wrong, sk should be assigned SKEY_OR if
- // selKey is set to SKEY_NEW or SKEY_OR below
- switch (selKey) {
- case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
- if (Selection[k][i])
- Selection[k][i]->RemoveMask ( Mask[k] );
- nSelItems[k] = 0;
- nsel = 0;
- break;
- case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
- nsel = nSelItems[k];
- break;
- case SKEY_AND : nsel = 0;
- nat = nSelItems[k];
- A = (PPCAtom)Selection[k];
- break;
- case SKEY_XOR : nsel = nSelItems[k];
- break;
- case SKEY_CLR : nsel = nSelItems[k];
- nat = nSelItems[k];
- A = (PPCAtom)Selection[k];
- break;
- default : return;
- }
-
- selAND = (sk==SKEY_AND);
-
- if ((nat<=0) || (!A)) return;
-
- MakeBricks ( sA,alen,d2*1.5 );
- dn = mround(d2/brick_size)+1;
-
- if (Brick && (selType==STYPE_ATOM)) {
-
- for (i=0;i<nat;i++)
- if (A[i]) {
- if (!A[i]->Ter) {
- ASel = False;
- GetBrickCoor ( A[i],nx,ny,nz );
- if (nx<0) nx++;
- ix1 = IMax ( 0,nx-dn );
- iy1 = IMax ( 0,ny-dn );
- iz1 = IMax ( 0,nz-dn );
- ix2 = IMin ( nbrick_x,nx+dn+1 );
- iy2 = IMin ( nbrick_y,ny+dn+1 );
- iz2 = IMin ( nbrick_z,nz+dn+1 );
- x = A[i]->x;
- y = A[i]->y;
- z = A[i]->z;
- for (ix=ix1;(ix<ix2) && (!ASel);ix++)
- if (Brick[ix])
- for (iy=iy1;(iy<iy2) && (!ASel);iy++)
- if (Brick[ix][iy])
- for (iz=iz1;(iz<iz2) && (!ASel);iz++) {
- B = Brick[ix][iy][iz];
- if (B)
- for (j=0;(j<B->nAtoms) && (!ASel);j++)
- if (B->Atom[j]!=A[i]) {
- dx = fabs(x-B->Atom[j]->x);
- if (dx<=d2) {
- dy = fabs(y-B->Atom[j]->y);
- if (dy<=d2) {
- dz = fabs(z-B->Atom[j]->z);
- if (dz<=d2) {
- dst = dx*dx+dy*dy+dz*dz;
- if ((dst>=d12) && (dst<=d22)) {
- ASel = True;
- SelectAtom ( A[i],k,sk,nsel );
- }
- }
- }
- }
- }
- }
- if ((!ASel) && selAND) A[i]->RemoveMask ( Mask[k] );
- }
- }
-
- } else if (Brick) {
-
- for (im=0;im<nModels;im++) {
- model = Model[im];
- if (model) {
- modelSel = False;
- for (ic=0;ic<model->nChains;ic++) {
- chain = model->Chain[ic];
- if (chain) {
- chainSel = False;
- for (ir=0;ir<chain->nResidues;ir++) {
- res = chain->Residue[ir];
- if (res) {
- resSel = False;
- for (i=0;(i<res->nAtoms) && (!resSel);i++) {
- atom = res->atom[i];
- if (atom) {
- if ((!atom->Ter) &&
- (atom->WhatIsSet & ASET_Coordinates)) {
- GetBrickCoor ( atom,nx,ny,nz );
- if (nx<0) nx++;
- ix1 = IMax ( 0,nx-dn );
- iy1 = IMax ( 0,ny-dn );
- iz1 = IMax ( 0,nz-dn );
- ix2 = IMin ( nbrick_x,nx+dn+1 );
- iy2 = IMin ( nbrick_y,ny+dn+1 );
- iz2 = IMin ( nbrick_z,nz+dn+1 );
- x = atom->x;
- y = atom->y;
- z = atom->z;
- for (ix=ix1;(ix<ix2) && (!resSel);ix++)
- if (Brick[ix])
- for (iy=iy1;(iy<iy2) && (!resSel);iy++)
- if (Brick[ix][iy])
- for (iz=iz1;(iz<iz2) && (!resSel);iz++) {
- B = Brick[ix][iy][iz];
- if (B)
- for (j=0;(j<B->nAtoms) &&
- (!resSel);j++)
- if (B->Atom[j]!=atom) {
- dx = fabs(x-B->Atom[j]->x);
- if (dx<=d2) {
- dy = fabs(y-B->Atom[j]->y);
- if (dy<=d2) {
- dz = fabs(z-B->Atom[j]->z);
- if (dz<=d2) {
- dst = dx*dx+dy*dy+dz*dz;
- if ((dst>=d12) &&
- (dst<=d22)) {
- SelectObject ( selType,
- atom,k,sk,nsel );
- resSel = True;
- chainSel = True;
- modelSel = True;
- }
- }
- }
- }
- }
- }
-
- }
- }
- }
- if ((!resSel) && selAND && (selType==STYPE_RESIDUE))
- res->RemoveMask ( Mask[k] );
- if (chainSel && (selType>STYPE_RESIDUE)) break;
- }
- }
- if ((!chainSel) && selAND && (selType==STYPE_CHAIN))
- chain->RemoveMask ( Mask[k] );
- if (modelSel && (selType>STYPE_CHAIN)) break;
- }
- }
- if ((!modelSel) && selAND && (selType==STYPE_MODEL))
- model->RemoveMask ( Mask[k] );
- }
- }
-
- }
-
- MakeSelIndex ( selHnd,selType,nsel );
-
-}
-
-
-
-int TakeChainID ( pstr & p, pstr chainID ) {
-int RC,k;
- chainID[0] = char(0);
- if (*p) {
- RC = 0;
- if (*p==':') {
- // starts with colon <=> empty chain ID
- chainID[0] = char(0);
- p++; // advance to residue number
- } else if (p[1]==':') {
- // second symbol is colon <=> regular chain ID
- chainID[0] = *p;
- chainID[1] = char(0);
- p++;
- p++; // advance to residue number
- } else if (*p=='\'') {
- // starts with a strip <=> assume empty chain ID
- chainID[0] = char(0);
- p++;
- if (*p=='\'') {
- // closing strip must be followed by colon
- p++;
- if (*p!=':') RC = -1;
- } else {
- // no concluding strip <=> could be a strip chain ID,
- // although this must be captured by 2nd "if"
- chainID[0] = '\'';
- chainID[1] = char(0);
- // assume that residue number is following the strip
- }
- } else if ((int(*p)>=int('0')) && (int(*p)<=int('9'))) {
- // a digit without following semicolon looks very much
- // like residue number with unspecified empty chain ID
- chainID[0] = char(0);
- // assume that p already points on residue number
- } else {
- // assume a long chain ID
- k = 0;
- while (*p && (*p!=':') && (k<(int)sizeof(ChainID)-1)) {
- chainID[k++] = *p;
- p++;
- }
- if (*p==':') {
- chainID[k] = char(0);
- } else {
- // a mistake
- chainID[0] = char(0);
- RC = -1;
- }
- }
- while (*p==' ') p++;
- } else
- RC = 1;
- return RC;
-}
-
-int TakeResID( pstr & p, int & seqNum, pstr inscode ) {
-char N[100];
-int i,RC;
-pstr endptr;
- RC = 1;
- inscode[0] = '*';
- inscode[1] = char(0);
- seqNum = ANY_RES;
- if (((*p) &&
- (int(*p)>=int('0')) && (int(*p)<=int('9'))) || (*p=='-')) {
- N[0] = *p;
- p++;
- i = 1;
- while ((*p) && (int(*p)>=int('0')) && (int(*p)<=int('9'))) {
- N[i++] = *p;
- p++;
- }
- N[i] = char(0);
- seqNum = mround(strtod(N,&endptr));
- if ((seqNum==0) && (endptr==N))
- RC = -1;
- else {
- RC = 0;
- if ((*p) && (*p!='-') && (*p!=',') && (*p!=' ')) {
- inscode[0] = *p;
- inscode[1] = char(0);
- p++;
- } else
- inscode[0] = char(0);
- if ((*p=='-') || (*p==',')) p++;
- }
- while (*p==' ') p++;
- }
- return RC;
-}
-
-
-int CMMDBSelManager::SelectDomain ( int selHnd , cpstr domainRange,
- int selType, int selKey,
- int modelNo ) {
-// domainRange is of the following format:
-// "*", "(all)" - take all file
-// "-" - take chain without chain ID
-// "a:Ni-Mj,b:Kp-Lq,..." - take chain a residue number N
-// insertion code i to residue number M
-// insertion code j plus chain b
-// residue number K insertion code p to
-// residue number L insertion code q and
-// so on.
-// "a:,b:..." - take whole chains a and b and so on
-// "a:,b:Kp-Lq,..." - any combination of the above.
-ChainID chainID;
-InsCode insCode1,insCode2;
-pstr S,p;
-int seqNum1,seqNum2,rc,selKey1;
-
- if ((selHnd<=0) || (selHnd>nSelections)) return 1;
-
- // leave only required residues
-
- rc = 1;
- if (!domainRange) rc = 0;
- else if ((!domainRange[0]) || (domainRange[0]=='*')) rc = 0;
- else if (!strcasecmp(domainRange,"(all)")) rc = 0;
- if (!rc) {
- // select all
- Select ( selHnd,selType,modelNo,"*",ANY_RES,"*",ANY_RES,"*",
- "*","*","*","*",selKey );
- return 0;
- }
- if (!strcasecmp(domainRange,"-")) {
- // select chain without chain ID
- Select ( selHnd,selType,modelNo,"",ANY_RES,"*",ANY_RES,"*",
- "*","*","*","*",selKey );
- return 0;
- }
-
- S = new char[strlen(domainRange)+10];
- strcpy ( S,domainRange );
- DelSpaces ( S );
-// UpperCase ( S );
-
- p = S;
- rc = 0;
-
- selKey1 = selKey;
-
- while ((*p) && (!rc)) {
-
- if (TakeChainID(p,chainID)<0) rc = -1;
- else if (TakeResID(p,seqNum1,insCode1)<0) rc = -2;
- else if (TakeResID(p,seqNum2,insCode2)<0) rc = -3;
- else {
- Select ( selHnd,selType,modelNo,chainID,
- seqNum1,insCode1,seqNum2,insCode2,
- "*","*","*","*",selKey1 );
- if (*p==',') p++;
- if (selKey1==SKEY_NEW) selKey1 = SKEY_OR;
- }
-
- }
-
- delete[] S;
-
- return rc;
-
-}
-
-
-int CMMDBSelManager::GetSelLength ( int selHnd ) {
- if ((selHnd>0) && (selHnd<=nSelections))
- return nSelItems[selHnd-1];
- else return 0;
-}
-
-
-void CMMDBSelManager::GetSelIndex ( int selHnd,
- PPCAtom & SelAtom,
- int & nSelAtoms ) {
- if ((selHnd>0) && (selHnd<=nSelections)) {
- if (SelType[selHnd-1]!=STYPE_ATOM) {
- SelAtom = NULL;
- nSelAtoms = 0;
- } else {
- SelAtom = (PPCAtom)Selection[selHnd-1];
- nSelAtoms = nSelItems[selHnd-1];
- }
- } else {
- SelAtom = NULL;
- nSelAtoms = 0;
- }
-}
-
-void CMMDBSelManager::GetSelIndex ( int selHnd,
- PPCResidue & SelResidue,
- int & nSelResidues ) {
- if ((selHnd>0) && (selHnd<=nSelections)) {
- if (SelType[selHnd-1]!=STYPE_RESIDUE) {
- SelResidue = NULL;
- nSelResidues = 0;
- } else {
- SelResidue = (PPCResidue)Selection[selHnd-1];
- nSelResidues = nSelItems[selHnd-1];
- }
- } else {
- SelResidue = NULL;
- nSelResidues = 0;
- }
-}
-
-void CMMDBSelManager::GetSelIndex ( int selHnd,
- PPCChain & SelChain,
- int & nSelChains ) {
- if ((selHnd>0) && (selHnd<=nSelections)) {
- if (SelType[selHnd-1]!=STYPE_CHAIN) {
- SelChain = NULL;
- nSelChains = 0;
- } else {
- SelChain = (PPCChain)Selection[selHnd-1];
- nSelChains = nSelItems[selHnd-1];
- }
- } else {
- SelChain = NULL;
- nSelChains = 0;
- }
-}
-
-void CMMDBSelManager::GetSelIndex ( int selHnd,
- PPCModel & SelModel,
- int & nSelModels ) {
- if ((selHnd>0) && (selHnd<=nSelections)) {
- if (SelType[selHnd-1]!=STYPE_MODEL) {
- SelModel = NULL;
- nSelModels = 0;
- } else {
- SelModel = (PPCModel)Selection[selHnd-1];
- nSelModels = nSelItems[selHnd-1];
- }
- } else {
- SelModel = NULL;
- nSelModels = 0;
- }
-}
-
-
-void CMMDBSelManager::GetAtomStatistics ( int selHnd, RSAtomStat AS ) {
-int i,k;
- AS.Init();
- if ((selHnd>0) && (selHnd<=nSelections)) {
- k = selHnd-1;
- switch (SelType[k]) {
- case STYPE_MODEL : if (Selection[k])
- for (i=0;i<nSelItems[k];i++)
- ((PCModel)Selection[k][i])->
- CalcAtomStatistics ( AS );
- break;
- case STYPE_CHAIN : if (Selection[k])
- for (i=0;i<nSelItems[k];i++)
- ((PCChain)Selection[k][i])->
- CalcAtomStatistics ( AS );
- break;
- case STYPE_RESIDUE : if (Selection[k])
- for (i=0;i<nSelItems[k];i++)
- ((PCResidue)Selection[k][i])->
- CalcAtomStatistics ( AS );
- break;
- case STYPE_ATOM : if (Selection[k])
- for (i=0;i<nSelItems[k];i++)
- ((PCAtom)Selection[k][i])->
- CalcAtomStatistics ( AS );
- break;
- default : break;
- }
- }
- AS.Finish();
-}
-
-
-void CMMDBSelManager::SelectAtom ( PCAtom atom, int maskNo,
- int selKey, int & nsel ) {
-Boolean ASel;
- ASel = atom->CheckMask ( Mask[maskNo] );
- switch (selKey) {
- default :
- case SKEY_NEW :
- case SKEY_OR : if (!ASel) {
- atom->SetMask ( Mask[maskNo] );
- nsel++;
- }
- break;
- case SKEY_AND : if (ASel) nsel++;
- break;
- case SKEY_XOR : if (ASel) {
- atom->RemoveMask ( Mask[maskNo] );
- nsel--;
- } else {
- atom->SetMask ( Mask[maskNo] );
- nsel++;
- }
- break;
- case SKEY_CLR : if (ASel) {
- atom->RemoveMask ( Mask[maskNo] );
- nsel--;
- }
- }
-}
-
-
-void CMMDBSelManager::SelectObject ( int selType, PCAtom atom,
- int maskNo, int selKey,
- int & nsel ) {
-PCMask object;
- switch (selType) {
- default :
- case STYPE_UNDEFINED : return;
- case STYPE_ATOM : object = atom; break;
- case STYPE_RESIDUE : object = atom->GetResidue(); break;
- case STYPE_CHAIN : object = atom->GetChain (); break;
- case STYPE_MODEL : object = atom->GetModel (); break;
- }
- if (!object) return;
- SelectObject ( object,maskNo,selKey,nsel );
-}
-
-
-void CMMDBSelManager::SelectObject ( PCMask object, int maskNo,
- int selKey, int & nsel ) {
-Boolean ASel;
- ASel = object->CheckMask ( Mask[maskNo] );
- switch (selKey) {
- default :
- case SKEY_NEW :
- case SKEY_OR : if (!ASel) {
- object->SetMask ( Mask[maskNo] );
- nsel++;
- }
- break;
- case SKEY_AND : if (ASel) nsel++;
- break;
- case SKEY_XOR : if (ASel) {
- object->RemoveMask ( Mask[maskNo] );
- nsel--;
- } else {
- object->SetMask ( Mask[maskNo] );
- nsel++;
- }
- break;
- case SKEY_CLR : if (ASel) {
- object->RemoveMask ( Mask[maskNo] );
- nsel--;
- }
- break;
- case SKEY_XAND : if (ASel) {
- object->RemoveMask ( Mask[maskNo] );
- nsel++;
- }
- }
-}
-
-
-void CMMDBSelManager::DeleteSelObjects ( int selHnd ) {
-PPCModel model;
-PPCChain chain;
-PPCResidue res;
-PPCAtom atom;
-int i,k,nSel;
-
- if ((selHnd>0) && (selHnd<=nSelections)) {
-
- k = selHnd-1;
- nSel = nSelItems[k];
- switch (SelType[k]) {
-
- case STYPE_MODEL : model = (PPCModel)Selection[k];
- for (i=0;i<nSel;i++)
- delete model[i];
- break;
-
- case STYPE_CHAIN : chain = (PPCChain)Selection[k];
- for (i=0;i<nSel;i++)
- delete chain[i];
- break;
-
- case STYPE_RESIDUE : res = (PPCResidue)Selection[k];
- for (i=0;i<nSel;i++)
- delete res[i];
- break;
-
- case STYPE_ATOM : atom = (PPCAtom)Selection[k];
- for (i=0;i<nSel;i++)
- delete atom[i];
- break;
-
- default : ;
-
- }
-
- if (Selection[k]) delete[] Selection[k];
- Selection[k] = NULL;
- nSelItems[k] = 0;
-
- }
-
-}
-
-// ------------------------------------------------------------------------
-
-void CMMDBSelManager::MakeSelIndex ( int selHnd, int selType, int nsel ) {
-// if nsel is less than 0, the number of selected atoms will
-// be calculated.
-int k,i,j,n,ns,k1,k2, nns;
-PCModel model;
-PCChain chain;
-PCResidue res;
-
- if ((selHnd>0) && (selHnd<=nSelections)) {
- k1 = selHnd-1;
- k2 = k1+1;
- } else {
- k1 = 0;
- k2 = nSelections;
- }
-
- for (k=k1;k<k2;k++) {
- if (nsel<0) {
- ns = 0;
- switch (selType) {
- case STYPE_ATOM : for (i=0;i<nAtoms;i++)
- if (Atom[i])
- if (Atom[i]->CheckMask(Mask[k])) ns++;
- break;
- case STYPE_RESIDUE : for (n=0;n<nModels;n++) {
- model = Model[n];
- if (model)
- for (i=0;i<model->nChains;i++) {
- chain = model->Chain[i];
- if (chain)
- for (j=0;j<chain->nResidues;j++) {
- res = chain->Residue[j];
- if (res)
- if (res->CheckMask(Mask[k])) ns++;
- }
- }
- }
- break;
- case STYPE_CHAIN : for (i=0;i<nModels;i++) {
- model = Model[i];
- if (model)
- for (j=0;j<model->nChains;j++) {
- chain = model->Chain[j];
- if (chain)
- if (chain->CheckMask(Mask[k])) ns++;
- }
- }
- break;
- case STYPE_MODEL : for (i=0;i<nModels;i++)
- if (Model[i])
- if (Model[i]->CheckMask(Mask[k])) ns++;
- break;
- default : ;
- }
- } else
- ns = nsel;
- if (Selection[k]) delete[] Selection[k];
- if (ns>0) {
- Selection[k] = new PCMask[ns];
- nns = 0;
- switch (selType) {
- case STYPE_ATOM : for (i=0;i<nAtoms;i++)
- if (Atom[i]) {
- if (Atom[i]->CheckMask(Mask[k])) {
- Selection[k][nns++] = Atom[i];
- if (nns>=ns) nns = ns-1;
- }
- }
- break;
- case STYPE_RESIDUE : for (n=0;n<nModels;n++) {
- model = Model[n];
- if (model)
- for (i=0;i<model->nChains;i++) {
- chain = model->Chain[i];
- if (chain)
- for (j=0;j<chain->nResidues;j++) {
- res = chain->Residue[j];
- if (res)
- if (res->CheckMask(Mask[k])) {
- Selection[k][nns++] = res;
- if (nns>=ns) nns = ns-1;
- }
- }
- }
- }
- break;
- case STYPE_CHAIN : for (i=0;i<nModels;i++) {
- model = Model[i];
- if (model)
- for (j=0;j<model->nChains;j++) {
- chain = model->Chain[j];
- if (chain)
- if (chain->CheckMask(Mask[k])) {
- Selection[k][nns++] = chain;
- if (nns>=ns) nns = ns-1;
- }
- }
- }
- break;
- case STYPE_MODEL : for (i=0;i<nModels;i++)
- if (Model[i])
- if (Model[i]->CheckMask(Mask[k])) {
- Selection[k][nns++] = Model[i];
- if (nns>=ns) nns = ns-1;
- }
- break;
- default : ;
- }
-
- } else
- Selection[k] = NULL;
-
- nSelItems[k] = ns;
- }
-
-}
-
-
-// ------------------- Stream functions ----------------------
-
-
-void CMMDBSelManager::write ( RCFile f ) {
-int i;
-byte Version=1;
-
- f.WriteByte ( &Version );
-
- CMMDBCoorManager::write ( f );
-
- f.WriteInt ( &nSelections );
- for (i=0;i<nSelections;i++) {
- StreamWrite ( f,Mask[i] );
- f.WriteInt ( &(nSelItems[i]) );
- f.WriteInt ( &(SelType[i]) );
- }
-
-}
-
-void CMMDBSelManager::read ( RCFile f ) {
-int i;
-byte Version;
-
- f.ReadByte ( &Version );
-
- DeleteAllSelections();
-
- CMMDBCoorManager::read ( f );
-
- f.ReadInt ( &nSelections );
- if (nSelections>0) {
- Mask = new PCMask [nSelections];
- Selection = new PPCMask[nSelections];
- nSelItems = new int [nSelections];
- SelType = new int [nSelections];
- for (i=0;i<nSelections;i++) {
- Mask[i] = NULL;
- StreamRead ( f,Mask[i] );
- f.ReadInt ( &(nSelItems[i]) );
- f.ReadInt ( &(SelType[i]) );
- Selection[i] = NULL;
- if (Mask[i])
- MakeSelIndex ( i+1,SelType[i],-1 );
- else nSelItems[i] = 0;
- }
- }
-
-}
-
-
-MakeStreamFunctions(CMMDBSelManager)
diff --git a/mmdb/mmdb_selmngr.h b/mmdb/mmdb_selmngr.h
deleted file mode 100755
index 9843bb0..0000000
--- a/mmdb/mmdb_selmngr.h
+++ /dev/null
@@ -1,624 +0,0 @@
-// $Id: mmdb_selmngr.h,v 1.22 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 08.07.08 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : mmdb_selmngr <interface>
-// ~~~~~~~~~
-// Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CMMDBSelManager ( MMDB atom selection manager )
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-#ifndef __MMDB_SelMngr__
-#define __MMDB_SelMngr__
-
-#ifndef __MMDB_CoorMngr__
-#include "mmdb_coormngr.h"
-#endif
-
-#ifndef __MMDB_Mask__
-#include "mmdb_mask.h"
-#endif
-
-
-
-// ====================== CMMDBSelManager =========================
-
-// Selection keys. These specify how the requested selection
-// operation applies to the existing selection for the given mask:
-// SKEY_NEW previous selection is wiped out
-// SKEY_OR new selection is added to the already selected set;
-// if no selection preexists, SKEY_NEW and SKEY_OR
-// are equivalent. This key is the default one in
-// all selection functions.
-// SKEY_AND new selection is made on the already selected set;
-// this corresponds to logical 'and' of former and
-// current selections. If no selection preexists,
-// no selection will be made.
-// SKEY_XOR only those atoms will be left which are found
-// in either former or newly selected sets, but not
-// in both of them; this corresponds to logical
-// 'exclusive or' of previous and current selections.
-// If no selection preexists, it is equivalent to
-// SKEY_OR.
-#define SKEY_NEW 0
-#define SKEY_OR 1
-#define SKEY_AND 2
-#define SKEY_XOR 3
-#define SKEY_CLR 4
-
-
-// Selection types
-#define STYPE_INVALID (-1)
-#define STYPE_UNDEFINED 0
-#define STYPE_ATOM 1
-#define STYPE_RESIDUE 2
-#define STYPE_CHAIN 3
-#define STYPE_MODEL 4
-
-// Residue properties for SelectProperties()
-#define SELPROP_Solvent 0
-#define SELPROP_Aminoacid 1
-#define SELPROP_Nucleotide 2
-#define SELPROP_Sugar 3
-#define SELPROP_ModRes 4
-
-// comparison rules for SelectUDD function
-#define UDSCR_LT 1
-#define UDSCR_LE 2
-#define UDSCR_EQ 3
-#define UDSCR_NE 4
-#define UDSCR_GE 5
-#define UDSCR_GT 6
-#define UDSCR_LTcase 7
-#define UDSCR_LEcase 8
-#define UDSCR_EQcase 9
-#define UDSCR_NEcase 10
-#define UDSCR_GEcase 11
-#define UDSCR_GTcase 12
-#define UDSCR_LTn 13
-#define UDSCR_LEn 14
-#define UDSCR_EQn 15
-#define UDSCR_NEn 16
-#define UDSCR_GEn 17
-#define UDSCR_GTn 18
-#define UDSCR_LTncase 19
-#define UDSCR_LEncase 20
-#define UDSCR_EQncase 21
-#define UDSCR_NEncase 22
-#define UDSCR_GEncase 23
-#define UDSCR_GTncase 24
-#define UDSCR_Substr 25
-#define UDSCR_NoSubstr 26
-#define UDSCR_Substr1 27
-#define UDSCR_NoSubstr1 28
-
-
-
-DefineClass(CMMDBSelManager);
-DefineStreamFunctions(CMMDBSelManager);
-
-class CMMDBSelManager : public CMMDBCoorManager {
-
- public :
-
- CMMDBSelManager ();
- CMMDBSelManager ( RPCStream Object );
- ~CMMDBSelManager();
-
-
- // ==================== Selecting atoms =======================
-
- // NewSelection() creates a new selection mask and returns its
- // handle. A handle is always a positive (non-zero) integer.
- // Calling NewSelection() is the only way to create a new
- // selection mask. Notice however that masks will be automatically
- // copied from another MMDB (see Copy(..) in CMMDBManager) if
- // coordinates are copied; if this is the case, the mask handles
- // will be inherited from the source MMDB as well. The masks will
- // also be automatically deleted (see Delete(..) in CMMDBManager())
- // if coordinates are deleted.
- int NewSelection ();
-
- int GetSelType ( int selHnd ); // returns STYPE_XXXX
-
- // DeleteSelection(..) deletes the specified selection mask
- // and removes the corresponding selection attributes from
- // all atoms, which were selected with this mask. If an atom
- // was selected also with other mask(s), the other selection(s)
- // will remain, provided that the corresponding masks are valid.
- // After DeleteSelection() returns, the corresponding mask
- // becomes invalid.
- void DeleteSelection ( int selHnd );
-
- // DeleteAllSelections() deletes all selection masks and
- // unselects all atoms in the file. All mask handles become
- // invalid.
- void DeleteAllSelections();
-
- // SelectAtoms(..) selects atoms in the serial number range
- // of iSer1 to iSer2 by adding them to the set of atoms
- // marked by the given mask. If iSer1=iSer2=0 then all atoms
- // are selected. Each atom may be selected by a number of masks
- // simultaneously.
- void SelectAtoms ( int selHnd, int iSer1, int iSer2,
- int selKey=SKEY_OR // selection key
- );
-
- // SelectAtoms(..) selects atoms with serial numbers given in
- // vector asn[0..nsn-1].
- void SelectAtoms ( int selHnd, ivector asn, int nsn,
- int selKey=SKEY_OR // selection key
- );
-
- // UnselectAtoms(..) clears the specified mask for atoms in
- // the serial number range of iSer1 to iSer2. If iSer1=iSer2=0
- // then all atoms are cleared of the specified mask. If selHnd
- // is set to 0, then the atoms are cleared of any mask.
- void UnselectAtoms ( int selHnd, int iSer1, int iSer2 );
-
- // SelectAtom(..) selects a single atom according to the value
- // of selection key. If makeIndex is False, then the routine
- // does not update the selection index. This saves time, but
- // prevents GetSelIndex(..) from accessing all selected atoms.
- // In order to update the index after all single-atom selections
- // are done, use MakeSelIndex(selHnd) found next.
- void SelectAtom ( int selHnd, PCAtom A, int selKey=SKEY_OR,
- Boolean makeIndex=True );
-
- // SelectResidue(..), SelectChain(..) and SelectModel(..)
- // select a single residue, chain or model, or all their
- // hierarchical descendants depending on the value of selType
- // (i.e. atoms, residues (in chain and model) and chains
- // (in model only). Ascending hierarchical objects should be
- // selected explicitely, e.g. atom->GetResidue()->SelectResidue(..)
- void SelectResidue ( int selHnd, PCResidue Res,
- int selType, int selKey,
- Boolean makeIndex );
- void SelectChain ( int selHnd, PCChain Chain,
- int selType, int selKey,
- Boolean makeIndex );
- void SelectModel ( int selHnd, PCModel model,
- int selType, int selKey,
- Boolean makeIndex );
-
-
- // MakeSelIndex(.) calculates selection index for selection
- // adressed by selHnd. All selection functions except the
- // SelectAtom(..) above, update selection index automatically.
- // This function is for use after a series of calls to
- // SelectAtom(..) with makeIndex parameter set False. This
- // combination of SelectAtom - MakeSelIndex considerably saves CPU
- // at extensive selections.
- // MakeSelIndex(.) returns the number of selected objects.
- int MakeSelIndex ( int selHnd );
- void MakeAllSelIndexes();
-
- // Selecting by atom ID, space condition (a sphere) and some
- // other bits.
- void SelectAtoms (
- int selHnd, // must be obtained from NewSelection()
- int iModel, // model number; iModel=0 means
- // 'any model'
- cpstr Chains, // may be several chains "A,B,W"; "*"
- // means 'any chain' (in selected
- // model(s))
- int ResNo1, // starting residue sequence number
- cpstr Ins1, // starting residue insertion code; "*"
- // means 'any code'
- int ResNo2, // ending residue sequence number.
- cpstr Ins2, // ending residue insertion code; "*"
- // means 'any code'. Combination of
- // ResNo1=ResNo2=ANY_RES and
- // Ins1=Ins2="*" means 'any residue'
- // (in selected chain(s))
- cpstr RNames, // may be several residue names
- // "ALA,GLU,CIS"; "*" means 'any
- // residue name'
- cpstr ANames, // may be several names "CA,CB"; "*"
- // means 'any atom' (in selected
- // residue(s))
- cpstr Elements, // may be several element types
- // 'H,C,O,CU'; "*" means 'any element'
- cpstr altLocs, // may be several alternative
- // locations 'A,B'; "*" means
- // 'any alternative location'
- cpstr Segments, // may be several segment IDs
- // like "S1,S2,A234"; "*" means
- // 'any segment'
- cpstr Charges, // may be several charges like
- // "+1,-2, "; "*" means 'any charge'
- realtype occ1, // lowest occupancy
- realtype occ2, // highest occupancy; occ1=occ2<0.0
- // means "any occupancy"
- realtype x0, // reference x-point
- realtype y0, // reference y-point
- realtype z0, // reference z-point
- realtype d0, // selection distance from the
- // reference point; d0<=0.0
- // means "any distance" and values
- // of x0, y0 and z0 are ignored
- int selKey=SKEY_OR // selection key
- );
-
- // Selecting by just atom ID, no other conditions
- void SelectAtoms (
- int selHnd, // must be obtained from NewSelection()
- int iModel, // model number; iModel=0 means
- // 'any model'
- cpstr Chains, // may be several chains "A,B,W"; "*"
- // means 'any chain' (in selected
- // model(s))
- int ResNo1, // starting residue sequence number
- cpstr Ins1, // starting residue insertion code; "*"
- // means 'any code'
- int ResNo2, // ending residue sequence number.
- cpstr Ins2, // ending residue insertion code; "*"
- // means 'any code'. Combination of
- // ResNo1=ResNo2=ANY_RES and
- // Ins1=Ins2="*" means 'any residue
- // number' (in selected chain(s))
- cpstr RNames, // may be several residue names
- // "ALA,GLU,CIS"; "*" means 'any
- // residue name'
- cpstr ANames, // may be several names "CA,CB"; "*"
- // means 'any atom' (in selected
- // residue(s))
- cpstr Elements, // may be several element types
- // "H,C,O,CU"; "*" means 'any element'
- cpstr altLocs, // may be several alternative
- // locations 'A,B'; "*" means
- // 'any alternative location'
- int selKey=SKEY_OR // selection key
- );
-
-
- // Selecting by integer User-Defined Data
- void SelectUDD (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- int UDDhandle, // UDD handle
- int selMin, // lower selection boundary
- int selMax, // upper selection boundary
- int selKey // selection key
- );
- void SelectUDD (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- int UDDhandle, // UDD handle
- realtype selMin, // lower selection boundary
- realtype selMax, // upper selection boundary
- int selKey // selection key
- );
- void SelectUDD (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- int UDDhandle, // UDD handle
- cpstr selStr, // selection string
- int cmpRule, // comparison rule
- int selKey // selection key
- );
-
-
- // Selecting a sphere
- void SelectSphere (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- realtype x, // x-coordinate of the sphere's center
- realtype y, // y-coordinate of the sphere's center
- realtype z, // z-coordinate of the sphere's center
- realtype r, // radius of the sphere
- int selKey=SKEY_OR // selection key
- );
-
- // Selecting a cylinder
- void SelectCylinder (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- realtype x1, // x-coordinate of the cylinder axis' 1st end
- realtype y1, // y-coordinate of the cylinder axis' 1st end
- realtype z1, // z-coordinate of the cylinder axis' 1st end
- realtype x2, // x-coordinate of the cylinder axis' 2nd end
- realtype y2, // y-coordinate of the cylinder axis' 2nd end
- realtype z2, // z-coordinate of the cylinder axis' 2nd end
- realtype r, // radius of the cylinder
- int selKey=SKEY_OR // selection key
- );
-
- // Selecting all atoms on a given distance from a plane
- void SelectSlab (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- realtype a, // a-parameter of the plane ax+by+cz=d
- realtype b, // b-parameter of the plane ax+by+cz=d
- realtype c, // c-parameter of the plane ax+by+cz=d
- realtype d, // d-parameter of the plane ax+by+cz=d
- realtype r, // distance to the plane
- int selKey=SKEY_OR // selection key
- );
-
- // Selecting all atoms on a given distance from already selected
- void SelectNeighbours (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- PPCAtom sA, // array of already selected atoms
- int alen, // length of A
- realtype d1, // minimal distance to already selected atoms
- realtype d2, // maximal distance to already selected atoms
- int selKey=SKEY_OR // selection key
- );
-
-
- int GetSelLength ( int selHnd );
-
- // Getting an array of atoms selected for a certain mask
- void GetSelIndex (
- int selHnd, // selection mask
- PPCAtom & SelAtom, // continuous index of selected
- // atoms; application must not
- // dispose either index or atoms
- int & nSelAtoms // length of index
- // [0..nSelectedAtoms-1]
- );
-
- // Getting an array of residues selected for a certain mask
- void GetSelIndex (
- int selHnd, // selection mask
- PPCResidue & SelResidues, // continuous index of selected
- // residues; application must
- // not dispose either index or
- // residues
- int & nSelResidues // length of index
- // [0..nSelResidues-1]
- );
-
- // Getting an array of chains selected for a certain mask
- void GetSelIndex (
- int selHnd, // selection mask
- PPCChain & SelChains, // continuous index of selected
- // chains; application must not
- // dispose either index or chains
- int & nSelChains // length of index
- // [0..nSelChains-1]
- );
-
- // Getting an array of models selected for a certain mask
- void GetSelIndex (
- int selHnd, // selection mask
- PPCModel & SelModels, // continuous index of selected
- // models; application must not
- // dispose either index or models
- int & nSelModels // length of index
- // [0..nSelModels-1]
- );
-
- void GetAtomStatistics ( int selHnd, RSAtomStat AS );
-
-
- // =============== General selection functions ================
-
- // Selecting by atom ID, space condition (a sphere) and some
- // other bits.
- void Select (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- int iModel, // model number; iModel=0 means
- // 'any model'
- cpstr Chains, // may be several chains "A,B,W"; "*"
- // means 'any chain' (in selected
- // model(s))
- int ResNo1, // starting residue sequence number
- cpstr Ins1, // starting residue insertion code; "*"
- // means 'any code'
- int ResNo2, // ending residue sequence number.
- cpstr Ins2, // ending residue insertion code; "*"
- // means 'any code'. Combination of
- // ResNo1=ResNo2=ANY_RES and
- // Ins1=Ins2="*" means 'any residue'
- // (in selected chain(s))
- cpstr RNames, // may be several residue names
- // "ALA,GLU,CIS"; "*" means
- // 'any residue name'
- cpstr ANames, // may be several names "CA,CB"; "*"
- // means 'any atom' (in selected
- // residue(s))
- cpstr Elements, // may be several element types
- // 'H,C,O,CU'; "*" means 'any element'
- cpstr altLocs, // may be several alternative
- // locations 'A,B'; "*" means
- // 'any alternative location'
- cpstr Segments, // may be several segment IDs like
- // "S1,S2,A234"; "*" means
- // 'any segment'
- cpstr Charges, // may be several charges like
- // "+1,-2, "; "*" means 'any charge'
- realtype occ1, // lowest occupancy
- realtype occ2, // highest occupancy; occ1=occ2<0.0
- // means "any occupancy"
- realtype x0, // reference x-point
- realtype y0, // reference y-point
- realtype z0, // reference z-point
- realtype d0, // selection distance from the
- // reference point; d0<=0.0
- // means "any distance" and values
- // of x0, y0 and z0 are ignored
- int selKey=SKEY_OR // selection key
- );
-
-
- // Selecting by just atom ID, no other conditions
- void Select (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- int iModel, // model number; iModel=0 means
- // 'any model'
- cpstr Chains, // may be several chains "A,B,W"; "*"
- // means 'any chain' (in selected
- // model(s))
- int ResNo1, // starting residue sequence number
- cpstr Ins1, // starting residue insertion code; "*"
- // means 'any code'
- int ResNo2, // ending residue sequence number.
- cpstr Ins2, // ending residue insertion code; "*"
- // means 'any code'. Combination of
- // ResNo1=ResNo2=ANY_RES and
- // Ins1=Ins2="*" means 'any residue
- // number' (in selected chain(s))
- cpstr RNames, // may be several residue names
- // "ALA,GLU,CIS"; "*" means
- // 'any residue name'
- cpstr ANames, // may be several names "CA,CB"; "*"
- // means 'any atom' (in selected
- // residue(s))
- cpstr Elements, // may be several element types
- // "H,C,O,CU"; "*" means 'any element'
- cpstr altLocs, // may be several alternative
- // locations 'A,B'; "*" means
- // 'any alternative location'
- int selKey=SKEY_OR // selection key
- );
-
-
- // Selecting by coordinate ID.
- // Examples:
- //
- // 1. /mdl/chn/s1.i1-s2.i2/at[el]:aloc
- // 2. /mdl/chn/*(res).ic /at[el]:aloc
- // 3. chn/*(res).ic /at[el]:aloc
- // 4. s1.i1-s2.i2/at[el]:aloc
- // 5. s1.i1 /at[el]:aloc
- // 6. /mdl
- // 7. chn
- // 8. s1.i1-s2.i2
- // 9. (res)
- // 10. at[el]:aloc
- // 11. chn//[el]
- //
- // mdl - the model's serial number or 0 or '*' for any model
- // (default).
- // chn - the chain ID or list of chains 'A,B,C' or '*' for
- // any chain (default).
- // s1,s2 - the starting and ending residue sequence numbers
- // or '*' for any sequence number (default).
- // i1,i2 - the residues insertion codes or '*' for any
- // insertion code. If the sequence number other than
- // '*' is specified, then insertion code defaults to ""
- // (no insertion code), otherwise the default is '*'.
- // at - atom name or list of atom names 'CA,N1,O' or '*'
- // for any atom name (default)
- // el - chemical element name or list of chemical element
- // names 'C,N,O' or '*' for any chemical element name
- // (default)
- // aloc - the alternative location indicator or '*' for any
- // alternate location. If the atom name and chemical
- // element name is specified (both may be '*'), then
- // the alternative location indicator defaults to ""
- // (no alternate location), otherwise the default is
- // '*'.
- //
- // All spaces are ignored.
- //
- // Returns -1 if numerical format of model is wrong, -2 if
- // numerical format for sequence number is wrong, and 0
- // otherwise.
-
- int Select (
- int selHnd, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- cpstr CID, // coordinate ID
- int selKey // selection key
- );
-
- // Propagating the selection up and down coordinate hierarchy
- void Select (
- int selHnd1, // must be obtained from NewSelection()
- int selType, // selection type STYPE_XXXXX
- int selHnd2, // must be obtained from NewSelection()
- // and have been used for selection
- int selKey=SKEY_OR // selection key
- );
-
- void SelectProperty (
- int selHnd, // must be obtained from NewSelection()
- int propKey, // property key SELPROP_XXXXXXX
- int selType, // selection type STYPE_XXXXX
- int selKey // selection key
- );
-
- // In SelectDomain, domainRange is of the following format:
- // "*", "(all)" - take all file
- // "-" - take chain without chain ID
- // "a:Ni-Mj,b:Kp-Lq,..." - take chain a residue number N
- // insertion code i to residue numberM
- // insertion code j plus chain b
- // residue number K insertion code p to
- // residue number L insertion code q
- // and so on.
- // "a:,b:..." - take whole chains a and b and so on
- // "a:,b:Kp-Lq,..." - any combination of the above.
- int SelectDomain ( int selHnd , cpstr domainRange,
- int selType, int selKey, int modelNo=1 );
-
- void DeleteSelObjects ( int selHnd );
-
-
- protected :
-
- // --- SELECTION DATA NOT FOR PUBLIC ACCESS
- int nSelections; // number of selections
- PPCMask Mask; // vector of selections
- ivector SelType; // vector of selection types
- ivector nSelItems; // numbers of selected items
- PPCMask * Selection; // vector of selected items
-
- // --------------- Stream I/O -----------------------------
- void write ( RCFile f );
- void read ( RCFile f );
-
- void InitMMDBSelManager();
- void SelectAtom ( PCAtom atom, int maskNo,
- int selKey, int & nsel );
- void SelectObject ( int selType, PCAtom atom, int maskNo,
- int selKey, int & nsel );
- void SelectObject ( PCMask object, int maskNo,
- int selKey, int & nsel );
- void MakeSelIndex ( int selHnd, int selType,
- int nsel );
-
- void ResetManager();
-
- PCMask GetSelMask ( int selHnd );
-
-};
-
-#endif
-
diff --git a/mmdb/mmdb_symop.cpp b/mmdb/mmdb_symop.cpp
deleted file mode 100755
index fa869e3..0000000
--- a/mmdb/mmdb_symop.cpp
+++ /dev/null
@@ -1,1009 +0,0 @@
-// $Id: mmdb_symop.cpp,v 1.24 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 29.01.10 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_SymOp <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-//
-// **** Classes : CSymOp ( symmetry operator )
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2010
-//
-// =================================================================
-//
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifndef __MATH_H
-#include <math.h>
-#endif
-
-#ifndef __MMDB_SymOp__
-#include "mmdb_symop.h"
-#endif
-
-
-
-// ==================== CSymOp ========================
-
-CSymOp::CSymOp() : CStream() {
- InitSymOp();
-}
-
-CSymOp::CSymOp ( RPCStream Object ) : CStream(Object) {
- InitSymOp();
-}
-
-CSymOp::~CSymOp() {
- FreeMemory();
-}
-
-void CSymOp::InitSymOp() {
-int i,j;
- XYZOp = NULL;
- for (i=0;i<4;i++) {
- for (j=0;j<4;j++)
- T[i][j] = 0.0;
- T[i][i] = 1.0;
- }
-}
-
-void CSymOp::FreeMemory() {
- if (XYZOp) delete[] XYZOp;
- XYZOp = NULL;
-}
-
-int CSymOp::SetSymOp ( cpstr XYZOperation ) {
-int i,j;
-
- CreateCopy ( XYZOp,XYZOperation );
- DelSpaces ( XYZOp );
-
- for (i=0;i<4;i++)
- for (j=0;j<4;j++)
- T[i][j] = 0.0;
-
- i = GetOperation ( 0 );
- if (!i) i = GetOperation ( 1 );
- if (!i) i = GetOperation ( 2 );
- T[3][3] = 1.0;
-
- return i;
-
-}
-
-pstr CSymOp::GetSymOp() {
- if (XYZOp) return XYZOp;
- else return pstr("");
-}
-
-
-int CSymOp::GetOperation ( int n ) {
-char L[100];
-pstr p1,p2;
-int len;
-realtype V;
-
- p1 = XYZOp;
- p2 = strchr ( p1,',' );
- if (!p2) return SYMOP_WrongSyntax;
- if (n>0) {
- p1 = p2+1;
- p2 = strchr ( p1,',' );
- if (!p2) return SYMOP_WrongSyntax;
- }
- if (n>1) {
- p1 = p2+1;
- p2 = NULL;
- }
-
- if (p2) *p2 = char(0);
- strcpy ( L,p1 );
- if (p2) *p2 = ',';
-
- DelSpaces ( L );
- if (!L[0]) return SYMOP_WrongSyntax;
- UpperCase ( L );
-
- len = strlen ( L );
- T[n][0] = 0.0;
- if (L[0]=='X') {
- T[n][0] += 1.0;
- L[0] = ' ';
- }
- do {
- p1 = strstr ( L,"+X" );
- if (p1) {
- T[n][0] += 1.0;
- strncpy ( p1," ",2 );
- }
- } while (p1);
- do {
- p1 = strstr ( L,"-X" );
- if (p1) {
- T[n][0] -= 1.0;
- strncpy ( p1," ",2 );
- }
- } while (p1);
-
- T[n][1] = 0.0;
- if (L[0]=='Y') {
- T[n][1] += 1.0;
- L[0] = ' ';
- }
- do {
- p1 = strstr ( L,"+Y" );
- if (p1) {
- T[n][1] += 1.0;
- strncpy ( p1," ",2 );
- }
- } while (p1);
- do {
- p1 = strstr ( L,"-Y" );
- if (p1) {
- T[n][1] -= 1.0;
- strncpy ( p1," ",2 );
- }
- } while (p1);
-
- T[n][2] = 0.0;
- if (L[0]=='Z') {
- T[n][2] += 1.0;
- L[0] = ' ';
- }
- do {
- p1 = strstr ( L,"+Z" );
- if (p1) {
- T[n][2] += 1.0;
- strncpy ( p1," ",2 );
- }
- } while (p1);
- do {
- p1 = strstr ( L,"-Z" );
- if (p1) {
- T[n][2] -= 1.0;
- strncpy ( p1," ",2 );
- }
- } while (p1);
-
- DelSpaces ( L );
- if ((int)strlen(L)>=len) return SYMOP_NotAnOperation;
-
- // translational part
- p1 = L;
- T[n][3] = strtod ( p1,&p2 );
- if (*p2=='/') {
- p1 = p2+1;
- V = strtod ( p1,&p2 );
- if (V==0.0) return SYMOP_ZeroDenominator;
- T[n][3] /= V;
- }
-
- return SYMOP_Ok;
-
-}
-
-void MakeSign ( pstr S, realtype V, realtype & AV ) {
-int l;
- if (V>0.0) {
- l = strlen ( S );
- if (l>0) {
- if (S[l-1]!=',') {
- strcat ( S,"+" );
- }
- }
- AV = V;
- } else if (V<0.0) {
- strcat ( S,"-" );
- AV = -V;
- } else {
- AV = V;
- return;
- }
-}
-
-
-#define __eps 1.0e-5
-
-void GenTranslation ( pstr S, realtype V ) {
-realtype AV,nAV;
-char N[50];
-int n,d;
-
- if (fabs(V)<=__eps) return;
- MakeSign ( S,V,AV );
-
- d = 0;
- n = -1;
- while ((d<=20) && (n<0)) {
- d++;
- nAV = AV*d;
- n = mround(nAV);
- if (fabs(nAV-n)>__eps) n = -1;
- }
-
- if (d<=1) sprintf ( N,"%i" ,n );
- else if (n>=0) sprintf ( N,"%i/%i" ,n,d );
- else sprintf ( N,"%-.10g",AV );
- strcat ( S,N );
-
-}
-
-void GenTransformation ( pstr S, realtype V, pstr Axis ) {
-realtype AV,nAV;
-char N[50];
-int n,d;
-
- if (fabs(V)<=__eps) return;
- MakeSign ( S,V,AV );
-
- if (fabs(AV-1.0)>__eps) {
-
- d = 0;
- n = -1;
- while ((d<=20) && (n<0)) {
- d++;
- nAV = AV*d;
- n = mround(nAV);
- if (fabs(nAV-n)>__eps) n = -1;
- }
-
- if (n>=0) sprintf ( N,"%i/%i*",n,d );
- else sprintf ( N,"%-.10g*",AV );
- strcat ( S,N );
-
- }
-
- strcat ( S,Axis );
-
-}
-
-
-/*
-void GenTranslation ( pstr S, realtype V ) {
-realtype AV,fAV;
-int n,d;
-char N[50];
-
- if (V==0.0) return;
- MakeSign ( S,V,AV );
-
- n = mround(floor(AV+0.00000001));
- fAV = AV-n;
-
- if (fabs(fAV-0.5)<=__eps) { n += 1; d = 2; }
- else if (fabs(fAV-0.25)<=__eps) { n += 1; d = 4; }
- else if (fabs(fAV-0.75)<=__eps) { n += 3; d = 4; }
- else if (fabs(fAV-0.33333333333)<=__eps) { n += 1; d = 3; }
- else if (fabs(fAV-0.66666666666)<=__eps) { n += 2; d = 3; }
- else if (fabs(fAV-0.16666666666)<=__eps) { n += 1; d = 6; }
- else if (fabs(fAV-0.83333333333)<=__eps) { n += 5; d = 6; }
- else d = 1;
-
- N[0] = char(0);
- if (d>1) sprintf ( N,"%i/%i",n,d );
- else if (n>0) sprintf ( N,"%i",n );
- else ParamStr ( N,pstr(""),AV );
- strcat ( S,N );
-
-}
-
-void GenTransformation ( pstr S, realtype V, pstr Axis ) {
-realtype AV;
-
- if (V==0.0) return;
- MakeSign ( S,V,AV );
-
- if (fabs(AV-0.5)<=__eps) strcat ( S,"1/2*" );
- else if (fabs(AV-0.25)<=__eps) strcat ( S,"1/4*" );
- else if (fabs(AV-0.75)<=__eps) strcat ( S,"3/4*" );
- else if (fabs(AV-0.33333333333)<=__eps) strcat ( S,"1/3*" );
- else if (fabs(AV-0.66666666666)<=__eps) strcat ( S,"2/3*" );
- else if (fabs(AV-0.16666666666)<=__eps) strcat ( S,"1/6*" );
- else if (fabs(AV-0.83333333333)<=__eps) strcat ( S,"5/6*" );
- else if (fabs(AV-1.0)>__eps) ParamStr ( S,pstr(""),AV,
- 10,pstr("*") );
-
- strcat ( S,Axis );
-
-}
-
-*/
-
-Boolean CSymOp::CompileOpTitle ( pstr S ) {
- return CompileOpTitle ( S,T,True );
-}
-
-Boolean CSymOp::CompileOpTitle ( pstr S, mat44 symMat,
- Boolean compare ) {
- S[0] = char(0);
- GenTransformation ( S,symMat[0][0],pstr("X") );
- GenTransformation ( S,symMat[0][1],pstr("Y") );
- GenTransformation ( S,symMat[0][2],pstr("Z") );
- GenTranslation ( S,symMat[0][3] );
- strcat ( S,"," );
- GenTransformation ( S,symMat[1][0],pstr("X") );
- GenTransformation ( S,symMat[1][1],pstr("Y") );
- GenTransformation ( S,symMat[1][2],pstr("Z") );
- GenTranslation ( S,symMat[1][3] );
- strcat ( S,"," );
- GenTransformation ( S,symMat[2][0],pstr("X") );
- GenTransformation ( S,symMat[2][1],pstr("Y") );
- GenTransformation ( S,symMat[2][2],pstr("Z") );
- GenTranslation ( S,symMat[2][3] );
- DelSpaces ( S );
- if ((!compare) || (!strcmp(S,XYZOp))) return True;
- else {
- S[0] = char(0);
- GenTranslation ( S,symMat[0][3] );
- GenTransformation ( S,symMat[0][0],pstr("X") );
- GenTransformation ( S,symMat[0][1],pstr("Y") );
- GenTransformation ( S,symMat[0][2],pstr("Z") );
- strcat ( S,"," );
- GenTranslation ( S,symMat[1][3] );
- GenTransformation ( S,symMat[1][0],pstr("X") );
- GenTransformation ( S,symMat[1][1],pstr("Y") );
- GenTransformation ( S,symMat[1][2],pstr("Z") );
- strcat ( S,"," );
- GenTranslation ( S,symMat[2][3] );
- GenTransformation ( S,symMat[2][0],pstr("X") );
- GenTransformation ( S,symMat[2][1],pstr("Y") );
- GenTransformation ( S,symMat[2][2],pstr("Z") );
- DelSpaces ( S );
- if (!strcmp(S,XYZOp)) return True;
- }
- return False;
-}
-
-void CSymOp::Transform ( realtype & x, realtype & y, realtype & z ) {
-realtype x1,y1,z1;
- x1 = T[0][0]*x + T[0][1]*y + T[0][2]*z + T[0][3];
- y1 = T[1][0]*x + T[1][1]*y + T[1][2]*z + T[1][3];
- z1 = T[2][0]*x + T[2][1]*y + T[2][2]*z + T[2][3];
- x = x1;
- y = y1;
- z = z1;
-}
-
-void CSymOp::GetTMatrix ( mat44 & TMatrix ) {
-// copies T to TMatrix
-int i,j;
- for (i=0;i<4;i++)
- for (j=0;j<4;j++)
- TMatrix[i][j] = T[i][j];
-}
-
-void CSymOp::SetTMatrix ( mat44 & TMatrix ) {
-// copies TMatrix to T
-int i,j;
- for (i=0;i<4;i++)
- for (j=0;j<4;j++)
- T[i][j] = TMatrix[i][j];
-}
-
-
-void CSymOp::Print() {
-int i;
- printf ( " operation '%s'\n",XYZOp );
- for (i=0;i<4;i++)
- printf ( " %10.3g %10.3g %10.3g %10.3g\n",
- T[i][0],T[i][1],T[i][2],T[i][3] );
-}
-
-void CSymOp::Copy ( PCSymOp SymOp ) {
-int i,j;
- CreateCopy ( XYZOp,SymOp->XYZOp );
- for (i=0;i<4;i++)
- for (j=0;j<4;j++)
- T[i][j] = SymOp->T[i][j];
-}
-
-void CSymOp::write ( RCFile f ) {
-int i,j;
-byte Version=1;
- f.WriteByte ( &Version );
- f.CreateWrite ( XYZOp );
- for (i=0;i<4;i++)
- for (j=0;j<4;j++)
- f.WriteReal ( &(T[i][j]) );
-}
-
-void CSymOp::read ( RCFile f ) {
-int i,j;
-byte Version;
- f.ReadByte ( &Version );
- f.CreateRead ( XYZOp );
- for (i=0;i<4;i++)
- for (j=0;j<4;j++)
- f.ReadReal ( &(T[i][j]) );
-}
-
-MakeStreamFunctions(CSymOp);
-
-
-
-// ==================== CSymOps ========================
-
-CSymOps::CSymOps() : CStream() {
- InitSymOps();
-}
-
-CSymOps::CSymOps ( RPCStream Object ) : CStream(Object) {
- InitSymOps();
-}
-
-CSymOps::~CSymOps() {
- FreeMemory();
-}
-
-void CSymOps::InitSymOps() {
- SpGroup = NULL;
- Nops = 0;
- SymOp = NULL;
-}
-
-void CSymOps::FreeMemory() {
-int i;
- if (SpGroup) delete[] SpGroup;
- SpGroup = NULL;
- if (SymOp) {
- for (i=0;i<Nops;i++)
- if (SymOp[i]) delete SymOp[i];
- delete[] SymOp;
- SymOp = NULL;
- }
- Nops = 0;
-}
-
-#define symop_file cpstr("symop.lib")
-
-int CSymOps::SetGroupSymopLib ( cpstr SpaceGroup,
- cpstr symop_lib ) {
-char S[500];
-char G[100];
-pstr p;
-CFile f;
-int i,RC;
-
- FreeMemory();
-
- CreateCopy ( SpGroup,SpaceGroup );
-
- if (!symop_lib) p = pstr(symop_file);
- else if (!symop_lib[0]) p = pstr(symop_file);
- else p = pstr(symop_lib);
- f.assign ( p,True );
- if (!f.reset(True)) {
- p = getenv ( "SYMOP" );
- if (p)
- strcpy ( S,p );
- else {
- p = getenv ( "CLIBD" );
- if (p) {
- strcpy ( S,p );
- if (S[strlen(S)-1]!='/') strcat ( S,"/" );
- strcat ( S,"symop.lib" );
- } else
- strcpy ( S,"symop.lib" );
- }
- f.assign ( S,True );
- if (!f.reset(True)) return SYMOP_NoLibFile;
- }
-
- strcpy ( G," '" );
- strcat ( G,SpGroup );
- strcat ( G,"'" );
- S[0] = char(0);
- while (!f.FileEnd() && (!strstr(S,G)))
- f.ReadLine ( S,sizeof(S) );
- if (f.FileEnd()) {
- f.shut();
- return SYMOP_UnknownSpaceGroup;
- }
-
- p = S;
- while (*p==' ') p++;
- p = strchr ( p,' ' );
- if (p) Nops = mround(strtod(p,NULL));
- if (Nops<=0) return SYMOP_NoSymOps;
-
- SymOp = new PCSymOp[Nops];
- RC = SYMOP_Ok;
- for (i=0;(i<Nops) && (!RC);i++) {
- f.ReadLine ( S,sizeof(S) );
- SymOp[i] = new CSymOp();
- RC = SymOp[i]->SetSymOp ( S );
- }
-
- f.shut();
-
- return RC;
-
-}
-
-
-#define syminfo_file cpstr("syminfo.lib")
-
-int CSymOps::SetGroup ( cpstr SpaceGroup,
- cpstr syminfo_lib ) {
-CFile f;
-pstr p;
-psvector lines,lines1;
-char S[500];
-char G[100];
-char O[100];
-mat44 T1,T2,T3;
-int i,j,k,l,m,n,RC;
-int nlines,npops,ncops;
-
- FreeMemory();
-
- npops = 0;
- ncops = 0;
-
- CreateCopy ( SpGroup,SpaceGroup );
-
- if (!syminfo_lib) p = pstr(syminfo_file);
- else if (!syminfo_lib[0]) p = pstr(syminfo_file);
- else p = pstr(syminfo_lib);
- f.assign ( p,True );
- if (!f.reset(True)) {
- p = getenv ( "SYMINFO" );
- if (p)
- strcpy ( S,p );
- else {
- p = getenv ( "CLIBD" );
- if (p) {
- strcpy ( S,p );
- if (S[strlen(S)-1]!='/') strcat ( S,"/" );
- strcat ( S,"syminfo.lib" );
- } else
- strcpy ( S,"syminfo.lib" );
- }
- f.assign ( S,True );
- if (!f.reset(True)) return SYMOP_NoLibFile;
- }
-
-
- if (strncasecmp(SpGroup,"Hall:",5)) {
- // normal space group symbol on input
- strcpy ( G," '" );
- strcat ( G,SpGroup );
- strcat ( G,"'" );
- S[0] = char(0);
- while (!f.FileEnd() && !(strstr(S,G) && (strstr(S,"symbol xHM") ||
- strstr(S,"symbol old"))))
- f.ReadLine ( S,sizeof(S) );
- } else {
- // hall descriptor on input
- strcpy ( G," ' " );
- p = &(SpGroup[5]);
- while (*p==' ') p++;
- strcat ( G,p );
- strcat ( G,"'" );
- S[0] = char(0);
- while (!f.FileEnd() && !(strstr(S,G) && strstr(S,"symbol Hall")))
- f.ReadLine ( S,sizeof(S) );
- }
- if (f.FileEnd()) {
- f.shut();
- return SYMOP_UnknownSpaceGroup;
- }
-
- // found spacegroup, move to symop lines
- while (!f.FileEnd() && (!strstr(S,"symop")))
- f.ReadLine ( S,sizeof(S) );
-
- nlines = 256;
- GetVectorMemory ( lines,nlines,0 );
- for (i=0;i<nlines;i++)
- lines[i] = NULL;
- n = 0;
- CreateCopy ( lines[n++],S );
-
- // count primitive operators
- while (!f.FileEnd() && (strstr(S,"symop"))) {
- npops++;
- f.ReadLine ( S,sizeof(S) );
- if (n>=nlines) {
- nlines += + 256;
- GetVectorMemory ( lines1,nlines,0 );
- for (i=0;i<n;i++)
- lines1[i] = lines[i];
- for (i=n;i<nlines;i++)
- lines1[i] = NULL;
- FreeVectorMemory ( lines,0 );
- lines = lines1;
- }
- CreateCopy ( lines[n++],S );
- }
-
- // count centering operators
- while (!f.FileEnd() && (strstr(S,"cenop"))) {
- ncops++;
- f.ReadLine ( S,sizeof(S) );
- if (n>=nlines) {
- nlines += + 256;
- GetVectorMemory ( lines1,nlines,0 );
- for (i=0;i<n;i++)
- lines1[i] = lines[i];
- for (i=n;i<nlines;i++)
- lines1[i] = NULL;
- FreeVectorMemory ( lines,0 );
- lines = lines1;
- }
- CreateCopy ( lines[n++],S );
- }
-
- Nops = npops*ncops;
- SymOp = new PCSymOp[Nops];
- RC = SYMOP_Ok;
-
- n = 0; // start second pass here
-
- // read primitive operators
- for (i=0;(i<npops) && (!RC);i++) {
- SymOp[i] = new CSymOp();
- RC = SymOp[i]->SetSymOp ( lines[n++]+6 );
- }
-
- // loop over non-trivial centering operators, and for each loop
- // over primtive operators
- for (i=1;(i<ncops) && (!RC);i++) {
- n++; // this also skips the identity operator
- for (j=0;(j<npops) && (!RC);j++) {
- SymOp[i*npops+j] = new CSymOp();
- RC = SymOp[i*npops+j]->SetSymOp ( lines[n]+6 );
- SymOp[i*npops+j]->GetTMatrix(T1);
- SymOp[j]->GetTMatrix(T2);
- for (k=0;k<4;k++)
- for (l=0;l<4;l++) {
- T3[k][l] = 0.0;
- for (m=0;m<4;m++)
- T3[k][l] += T1[k][m]*T2[m][l];
- }
- for (k=0;k<3;k++) // kdc fix
- T3[k][3] -= floor ( T3[k][3] ); // kdc fix
- SymOp[i*npops+j]->CompileOpTitle ( O,T3,False );
- SymOp[i*npops+j]->SetSymOp ( O );
- }
- }
-
- f.shut();
-
- for (i=0;i<nlines;i++)
- if (lines[i]) delete[] lines[i];
- FreeVectorMemory ( lines,0 );
-
- return RC;
-
-}
-
-/*
-int CSymOps::SetGroup ( cpstr SpaceGroup,
- cpstr syminfo_lib ) {
-CFile f;
-pstr p;
-char S[500];
-char G[100];
-char O[100];
-mat44 T1,T2,T3;
-int i,j,k,l,m,RC;
-int npops,ncops;
-long symop_start;
-//fpos_t symop_start;
-
- FreeMemory();
-
- npops = 0;
- ncops = 0;
-
- CreateCopy ( SpGroup,SpaceGroup );
-
- if (!syminfo_lib) p = pstr(syminfo_file);
- else if (!syminfo_lib[0]) p = pstr(syminfo_file);
- else p = pstr(syminfo_lib);
- f.assign ( p,True );
- if (!f.reset(True)) {
- p = getenv ( "SYMINFO" );
- if (p)
- strcpy ( S,p );
- else {
- p = getenv ( "CLIBD" );
- if (p) {
- strcpy ( S,p );
- if (S[strlen(S)-1]!='/') strcat ( S,"/" );
- strcat ( S,"syminfo.lib" );
- } else
- strcpy ( S,"syminfo.lib" );
- }
- f.assign ( S,True );
- if (!f.reset(True)) return SYMOP_NoLibFile;
- }
-
- if (strncasecmp(SpGroup,"Hall:",5)) {
- // normal space group symbol on input
- strcpy ( G," '" );
- strcat ( G,SpGroup );
- strcat ( G,"'" );
- S[0] = char(0);
- while (!f.FileEnd() && !(strstr(S,G) && (strstr(S,"symbol xHM") ||
- strstr(S,"symbol old"))))
- f.ReadLine ( S,sizeof(S) );
- } else {
- // hall descriptor on input
- strcpy ( G," ' " );
- p = &(SpGroup[5]);
- while (*p==' ') p++;
- strcat ( G,p );
- strcat ( G,"'" );
- S[0] = char(0);
- while (!f.FileEnd() && !(strstr(S,G) && strstr(S,"symbol Hall")))
- f.ReadLine ( S,sizeof(S) );
- }
- if (f.FileEnd()) {
- f.shut();
- return SYMOP_UnknownSpaceGroup;
- }
-
- // found spacegroup, move to symop lines
- while (!f.FileEnd() && (!strstr(S,"symop"))) {
- symop_start = f.Position();
-//# fgetpos ( f.GetHandle(),&symop_start );
- f.ReadLine ( S,sizeof(S) );
- }
- // count primitive operators
- while (!f.FileEnd() && (strstr(S,"symop"))) {
- npops++;
- f.ReadLine ( S,sizeof(S) );
- }
- // count centering operators
- while (!f.FileEnd() && (strstr(S,"cenop"))) {
- ncops++;
- f.ReadLine ( S,sizeof(S) );
- }
- Nops = npops*ncops;
- f.seek(symop_start);
-//# fsetpos ( f.GetHandle(),&symop_start );
- SymOp = new PCSymOp[Nops];
- RC = SYMOP_Ok;
-
- // read primitive operators
- for (i=0;(i<npops) && (!RC);i++) {
- f.ReadLine ( S,sizeof(S) );
- SymOp[i] = new CSymOp();
- RC = SymOp[i]->SetSymOp ( S+6 );
- }
-
- // skip identity centering operator
- f.ReadLine ( S,sizeof(S) );
- // loop over non-trivial centering operators, and for each loop
- // over primtive operators
- for (i=1;(i<ncops) && (!RC);i++) {
- f.ReadLine ( S,sizeof(S) );
- for (j=0;(j<npops) && (!RC);j++) {
- SymOp[i*npops+j] = new CSymOp();
- RC = SymOp[i*npops+j]->SetSymOp ( S+6 );
-
- SymOp[i*npops+j]->GetTMatrix(T1);
- SymOp[j]->GetTMatrix(T2);
- for (k=0;k<4;k++)
- for (l=0;l<4;l++) {
- T3[k][l] = 0.0;
- for (m=0;m<4;m++)
- T3[k][l] += T1[k][m]*T2[m][l];
- }
- for (k=0;k<3;k++) // kdc fix
- T3[k][3] -= floor ( T3[k][3] ); // kdc fix
- SymOp[i*npops+j]->CompileOpTitle(O,T3,False);
- SymOp[i*npops+j]->SetSymOp (O);
- }
- }
-
- f.shut();
-
- return RC;
-
-}
-*/
-
-void CSymOps::Reset() {
-// removes all symmetry operations
- FreeMemory();
-}
-
-int CSymOps::AddSymOp ( cpstr XYZOperation ) {
-// adds a symmetry operation
-PPCSymOp SymOp1;
-int i;
- SymOp1 = new PCSymOp[Nops+1];
- for (i=0;i<Nops;i++)
- SymOp1[i] = SymOp[i];
- if (SymOp) delete[] SymOp;
- SymOp = SymOp1;
- i = Nops;
- SymOp[i] = new CSymOp();
- Nops++;
- return SymOp[i]->SetSymOp ( XYZOperation );
-}
-
-void CSymOps::PutGroupName ( cpstr SpGroupName ) {
- CreateCopy ( SpGroup,SpGroupName );
-}
-
-
-int CSymOps::GetNofSymOps() {
-// GetNofSymOps() returns Nops -- the number of symmetry operations
- return Nops;
-}
-
-pstr CSymOps::GetSymOp ( int Nop ) {
- if ((0<=Nop) && (Nop<Nops)) return SymOp[Nop]->GetSymOp();
- else return pstr("");
-}
-
-int CSymOps::Transform ( realtype & x, realtype & y, realtype & z,
- int Nop ) {
-// Transform(..) transforms the coordinates according to the
-// symmetry operation Nop. The return code is non-zero if
-// Nop is a wrong operation number (must range from 0 to Nops-1).
- if ((Nop<0) || (Nop>=Nops)) return 1;
- if (SymOp[Nop]) {
- SymOp[Nop]->Transform ( x,y,z );
- return 0;
- } else
- return 2;
-}
-
-int CSymOps::GetTMatrix ( mat44 & TMatrix, int Nop ) {
-// GetTMatrix(..) returns the coordinate transformation matrix
-// for the symmetry operation Nop. The return code is non-zero if
-// Nop is a wrong operation number (must range from 0 to Nops-1).
- if ((Nop<0) || (Nop>=Nops)) return 1;
- if (SymOp[Nop]) {
- SymOp[Nop]->GetTMatrix ( TMatrix );
- return 0;
- } else
- return 2;
-}
-
-void CSymOps::Print() {
-int i;
-char S[200];
- printf ( " SPACE GROUP '%s'\n",SpGroup );
- for (i=0;i<Nops;i++) {
- SymOp[i]->Print();
- if (SymOp[i]->CompileOpTitle(S))
- printf ( " CHECK STATUS: Ok\n" );
- else printf ( " CHECK STATUS: Generated '%s'\n",S );
- }
-}
-
-
-void CSymOps::Copy ( PCSymOps SymOps ) {
-int i;
- FreeMemory();
- CreateCopy ( SpGroup,SymOps->SpGroup );
- Nops = SymOps->Nops;
- if (Nops>0) {
- SymOp = new PCSymOp[Nops];
- for (i=0;i<Nops;i++) {
- SymOp[i] = new CSymOp();
- SymOp[i]->Copy ( SymOps->SymOp[i] );
- }
- }
-}
-
-
-void CSymOps::write ( RCFile f ) {
-int i;
-byte Version=1;
- f.WriteByte ( &Version );
- f.CreateWrite ( SpGroup );
- f.WriteInt ( &Nops );
- for (i=0;i<Nops;i++)
- StreamWrite ( f,SymOp[i] );
-}
-
-void CSymOps::read ( RCFile f ) {
-int i;
-byte Version;
- FreeMemory();
- f.ReadByte ( &Version );
- f.CreateRead ( SpGroup );
- f.ReadInt ( &Nops );
- if (Nops>0) {
- SymOp = new PCSymOp[Nops];
- for (i=0;i<Nops;i++) {
- SymOp[i] = NULL;
- StreamRead ( f,SymOp[i] );
- }
- }
-}
-
-
-MakeStreamFunctions(CSymOps)
-
-
-/*
-
-void TestSymOps() {
-pstr p,p1;
-int RC;
-char S[500];
-CSymOps SymOps;
-CFile f;
-
- p = getenv ( "PDB_ROOT" );
- if (p) {
- strcpy ( S,p );
- strcat ( S,"/lib/" );
- } else
- S[0] = char(0);
- strcat ( S,"symop.lib" );
- f.assign ( S,True );
- if (!f.reset()) {
- printf ( " +++++ No symop.lib file found.\n" );
- return;
- }
-
- while (!f.FileEnd()) {
- f.ReadLine ( S,sizeof(S) );
- if (S[0] && (S[0]!=' ')) {
- p = strchr ( S,'\'' );
- if (p) {
- p++;
- p1 = strchr ( p,'\'' );
- if (!p1) p = NULL;
- }
- if (!p) {
- printf ( " +++++ Strange line in symop.lib:\n"
- "%s\n",S );
- return;
- }
- *p1 = char(0);
- RC = SymOps.SetGroup ( p );
- printf ( " =========================================================\n"
- " RC=%i\n",RC );
- SymOps.Print();
- }
- }
-
- return;
-
-}
-
-*/
diff --git a/mmdb/mmdb_symop.h b/mmdb/mmdb_symop.h
deleted file mode 100755
index 21aa34c..0000000
--- a/mmdb/mmdb_symop.h
+++ /dev/null
@@ -1,173 +0,0 @@
-// $Id: mmdb_symop.h,v 1.21 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 08.07.08 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_SymOp <interface>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-//
-// **** Classes : CSymOp ( symmetry operators )
-// ~~~~~~~~~ CSymOps ( container of symmetry operators )
-//
-// (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-#ifndef __MMDB_SymOp__
-#define __MMDB_SymOp__
-
-
-#ifndef __Stream__
-#include "stream_.h"
-#endif
-
-#ifndef __MMDB_Defs__
-#include "mmdb_defs.h"
-#endif
-
-
-
-// ==================== CSymOp ========================
-
-DefineClass(CSymOp);
-DefineStreamFunctions(CSymOp);
-
-class CSymOp : public CStream {
-
- public :
-
- CSymOp ();
- CSymOp ( RPCStream Object );
- ~CSymOp();
-
- int SetSymOp ( cpstr XYZOperation );
- pstr GetSymOp ();
-
- void Transform ( realtype & x, realtype & y, realtype & z );
-
- void GetTMatrix ( mat44 & TMatrix ); // copies T to TMatrix
- void SetTMatrix ( mat44 & TMatrix ); // copies TMatrix to T
-
- Boolean CompileOpTitle ( pstr S ); // makes XYZOp from matrix T
- Boolean CompileOpTitle ( pstr S, mat44 symMat, Boolean compare );
- void Print (); // prints operation and matrix
-
- void Copy ( PCSymOp SymOp );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- pstr XYZOp;
- mat44 T;
-
- void InitSymOp ();
- void FreeMemory ();
- int GetOperation ( int n );
-
-};
-
-
-// ==================== CSymOps ========================
-
-#define SYMOP_Ok 0
-#define SYMOP_NoLibFile -1
-#define SYMOP_UnknownSpaceGroup -2
-#define SYMOP_NoSymOps -3
-#define SYMOP_WrongSyntax -4
-#define SYMOP_NotAnOperation -5
-#define SYMOP_ZeroDenominator -6
-
-
-DefineClass(CSymOps);
-DefineStreamFunctions(CSymOps);
-
-class CSymOps : public CStream {
-
- public :
-
- CSymOps ();
- CSymOps ( RPCStream Object );
- ~CSymOps();
-
- virtual void FreeMemory();
-
- int SetGroupSymopLib ( cpstr SpaceGroup,
- cpstr symop_lib=NULL );
- // Space Group is taken from symop.lib. Return Code:
- // SYMOP_Ok <=> success
-
- int SetGroup ( cpstr SpaceGroup,
- cpstr syminfo_lib=NULL );
- // Space Group is taken from syminfo.lib. Return Code:
- // SYMOP_Ok <=> success
-
- void Reset (); // removes all symmetry operations
- virtual int AddSymOp ( cpstr XYZOperation ); // adds a sym.
- // operation
- void PutGroupName ( cpstr SpGroupName );
-
- // GetNofSymOps() returns Nops -- the number of sym. operations
- int GetNofSymOps ();
- pstr GetSymOp ( int Nop );
-
- // Transform(..) transforms the coordinates according to the
- // symmetry operation Nop. The return code is non-zero if
- // Nop is a wrong operation number (must range from 0 to Nops-1).
- int Transform ( realtype & x, realtype & y, realtype & z,
- int Nop );
-
- // GetTMatrix(..) returns the coordinate transformation matrix
- // for the symmetry operation Nop. The return code is non-zero if
- // Nop is a wrong operation number (must range from 0 to Nops-1).
- int GetTMatrix ( mat44 & TMatrix, int Nop );
-
- void Print ();
-
- virtual void Copy ( PCSymOps SymOps );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- pstr SpGroup;
- int Nops;
- PPCSymOp SymOp;
-
- void InitSymOps();
-
-};
-
-
-// extern void TestSymOps();
-
-#endif
-
diff --git a/mmdb/mmdb_tables.cpp b/mmdb/mmdb_tables.cpp
deleted file mode 100755
index 18a178f..0000000
--- a/mmdb/mmdb_tables.cpp
+++ /dev/null
@@ -1,750 +0,0 @@
-// $Id: mmdb_tables.cpp,v 1.26 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 29.01.10 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDBF_Tables <interface>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-//
-// **** Functions :
-// ~~~~~~~~~~~
-//
-// **** Constants : AName ( array of 2-character atom names )
-// ~~~~~~~~~~~ HAName ( array of 2=character heteroatom names )
-// RName ( 3-characters amino acid names )
-// RName1 ( 1-characters amino acid names )
-//
-//
-// (C) E. Krissinel 2000-2010
-//
-// =================================================================
-//
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __MMDB_Tables__
-#include "mmdb_tables.h"
-#endif
-
-#ifndef __MMDB_Defs__
-#include "mmdb_defs.h"
-#endif
-
-
-// =================================================================
-
-cpstr const ElementName[nElementNames] = {
- " H", "HE",
- "LI", "BE", " B", " C", " N", " O", " F", "NE",
- "NA", "MG", "AL", "SI", " P", " S", "CL", "AR",
- " K", "CA",
- "SC", "TI", " V", "CR", "MN", "FE",
- "CO", "NI", "CU", "ZN",
- "GA", "GE", "AS", "SE", "BR", "KR",
- "RB", "SR",
- " Y", "ZR", "NB", "MO", "TC", "RU",
- "RH", "PD", "AG", "CD",
- "IN", "SN", "SB", "TE", " I", "XE",
- "CS", "BA",
- "LA", "CE", "PR", "ND", "PM", "SM", "EU",
- "GD", "TB", "DY", "HO", "ER", "TM", "YB",
- "LU", "HF", "TA", " W", "RE", "OS",
- "IR", "PT", "AU", "HG",
- "TL", "PB", "BI", "PO", "AT", "RN",
- "FR", "RA",
- "AC", "TH", "PA", " U", "NP", "PU", "AM",
- "CM", "BK", "CF", "ES", "FM", "MD", "NO",
- "LR", "RF", "DB", "SG", "BH", "HS",
- "MT", "UN", "UU", "UB",
- "UQ", "UH", "UO",
- " D", "AN"
-};
-
-realtype const MolecWeight[nElementNames] = {
- 1.0079, 4.0026,
- 6.9410, 9.0122, 10.811, 12.011, 14.007, 15.999, 18.998, 20.180,
- 22.990, 24.305, 26.982, 28.086, 30.974, 32.066, 35.453, 39.948,
- 39.098, 40.078,
- 44.956, 47.867, 50.942, 51.996, 54.938, 55.845,
- 58.993, 58.693, 63.546, 65.390,
- 69.723, 72.610, 74.922, 78.960, 79.904, 83.800,
- 85.468, 87.620,
- 88.906, 91.224, 92.906, 95.940, 97.907, 101.07,
- 102.91, 106.42, 107.87, 112.41,
- 114.82, 118.71, 121.76, 127.60, 126.90, 131.29,
- 132.91, 137.33,
- 138.91, 140.12, 140.91, 144.24, 144.91, 150.36, 151.96,
- 157.25, 158.93, 162.50, 164.93, 167.26, 168.93, 173.04,
- 174.97, 178.49, 180.95, 183.84, 186.21, 190.23,
- 192.22, 195.08, 196.97, 200.59,
- 204.38, 207.20, 208.98, 208.98, 209.99, 222.02,
- 232.02, 226.03,
- 227.03, 232.04, 231.04, 238.03, 237.05, 244.06, 243.06,
- 247.07, 247.07, 251.08, 252.08, 257.10, 258.10, 259.10,
- 262.11, 263.11, 262.11, 266.12, 264.12, 269.13,
- 268.14, 272.15, 272.15, 277.00,
- 289.00, 289.00, 293.00,
- 2.0200, 3.0300
-};
-
-
-realtype const CovalentRadius[nElementNames] = {
- 0.32, 0.93,
- 1.23, 0.90, 0.82, 0.77, 0.75, 0.73, 0.72, 0.71,
- 1.54, 1.36, 1.18, 1.11, 1.06, 1.02, 0.99, 0.98,
- 2.03, 1.91,
- 1.62, 1.45, 1.34, 1.18, 1.17, 1.17,
- 1.16, 1.15, 1.17, 1.25,
- 1.26, 1.22, 1.20, 1.16, 1.14, 1.12,
- 2.16, 1.91,
- 1.62, 1.45, 1.34, 1.30, 1.27, 1.25,
- 1.25, 1.28, 1.34, 1.48,
- 1.44, 1.41, 1.40, 1.36, 1.33, 1.31,
- 2.35, 1.98,
- 1.69, 1.44, 1.34, 1.30, 1.28, 1.26, 1.27,
- 1.30, 1.34, 1.49, 1.48, 1.47, 1.46, 1.46,
- 1.45, 1.43, 2.50, 2.40, 2.20, 1.65,
- 1.65, 1.64, 1.63, 1.62,
- 1.85, 1.61, 1.59, 1.59, 1.58, 1.57,
- 1.56, 1.74,
- 1.56, 1.65, 1.65, 1.42, 1.65, 1.65, 1.65,
- 1.65, 1.65, 1.65, 1.65, 1.65, 1.65, 1.65,
- 1.65, 0.32, 0.10, /**/
- 0.20, 0.20, 0.20,
- 0.20, 0.20, 0.20, 0.20,
- 0.20, 0.20, 0.20,
- 0.32, 0.32
-};
-
-
-realtype const VdWaalsRadius[nElementNames] = {
- 1.20, 1.40,
- 1.82, 1.78, 1.74, 1.70, 1.55, 1.52, 1.47, 1.54,
-// ^^^^ ^^^^ <- only a guess
- 2.27, 1.73, 1.80, 2.10, 1.80, 1.80, 1.75, 1.88,
-// ^^^^
- 2.75, 2.65,
-// ^^^^
- 2.55, 2.45, 2.35, 2.20, 1.73, 1.90,
-// ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
- 1.75, 1.63, 1.40, 1.39,
-// ^^^^
- 1.87, 1.86, 1.85, 1.90, 1.85, 2.02,
-// ^^^^
- 2.75, 2.65,
-//^^^^ ^^^^
- 2.55, 2.45, 2.35, 2.20, 2.05, 1.90,
-// ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
- 1.75, 1.63, 1.72, 1.58,
-// ^^^^
- 1.93, 2.17, 2.10, 2.06, 1.98, 2.16,
-// ^^^^
- 2.75, 2.75,
-//^^^^ ^^^^
- 2.75, 2.75, 2.75, 2.75, 2.75, 2.75, 2.75,
-// ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
- 2.75, 2.75, 2.75, 2.75, 2.75, 2.65, 2.55,
-// ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
- 2.45, 2.35, 2.25, 2.15, 2.05, 1.95,
-// ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
- 1.85, 1.75, 1.66, 1.55,
-// ^^^^
- 1.96, 2.02, 2.00, 2.00, 2.00, 2.00,
-// ^^^^ ^^^^ ^^^^ ^^^^
- 2.75, 2.75,
-//^^^^ ^^^^
- 2.50, 2.25, 1.95, 1.86, 1.80, 1.80, 1.80,
-// ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
- 1.80, 1.80, 1.80, 1.80, 1.80, 1.80, 1.80,
-// ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
- 1.80, 1.80, 1.80, 1.80, 1.80, 1.80,
-// ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
- 1.80, 1.80, 1.80, 1.80,
-// ^^^^ ^^^^ ^^^^ ^^^^
- 1.80, 1.80, 1.80,
-// ^^^^ ^^^^ ^^^^
- 1.30, 1.50
-//^^^^ ^^^^
-};
-
-realtype const IonicRadius[nElementNames] = {
- 0.79, 0.49, 2.05, 1.40, 1.17, 0.91, 0.75, 0.65, 0.57, 0.51,
- 2.23, 1.72, 1.82, 1.46, 1.23, 1.09, 0.97, 0.88, 2.77, 2.23,
- 2.09, 2.00, 1.92, 1.85, 1.79, 1.72, 1.67, 1.62, 1.57, 1.53,
- 1.81, 1.52, 1.33, 1.22, 1.12, 1.03, 2.98, 2.45, 2.27, 2.16,
- 2.09, 2.01, 1.95, 1.89, 1.83, 1.79, 1.75, 1.71, 2.00, 1.72,
- 1.53, 1.42, 1.32, 1.24, 3.34, 2.78, 2.74, 2.16, 2.09, 2.02,
- 1.97, 1.92, 1.87, 1.83, 1.79, 1.76, 2.08, 1.81, 1.63, 1.53,
- 1.43, 1.34, 3.50, 3.00, 3.20, 2.70, 2.67, 2.64, 2.62, 2.59,
- 2.56, 2.54, 2.51, 2.49, 2.47, 2.45, 2.42, 2.40, 2.25, 3.16,
- 3.14, 3.11, 3.08, 3.05, 3.02, 2.99, 2.97, 2.95, 2.92, 2.90,
- 2.87, 2.85
-};
-
-cpstr const ElementMetal[nElementMetals] = {
- "LI", "BE", "NA", "MG", "AL", " K", "CA", "SC", "TI", " V",
- "MN", "FE", "CO", "NI", "CU", "ZN", "GA", "RB", "SR", " Y",
- "ZR", "NB", "MO", "TC", "RU", "RH", "PD", "AG", "CD", "IN",
- "SN", "SB", "CS", "BA", "LA", "CE", "PR", "ND", "PM", "SM",
- "EU", "GD", "TB", "DY", "HO", "ER", "TM", "YB", "LU", "HF",
- "TA", " W", "RE", "OS", "IR", "PT", "AU", "HG", "TL", "PB",
- "BI", "PO", "FR", "RA", "AC", "TH", "PA", " U", "NP", "PU",
- "AM", "CM", "BK", "CF", "ES", "FM", "MD", "NO", "LR", "RF",
- "DB", "SG", "BH", "HS", "MT", "UN", "UU", "UB", "UQ", "UH",
- "UO"
-};
-
-
-cpstr const HydAtomName[nHydAtomNames] = {
- "0H", "1H", "2H", "3H", "4H", "5H", "6H", "7H", "8H", "9H",
- "HH", "*H", "'H", """H"
-};
-
-
-
-Boolean isMetal ( cpstr element ) {
-char name[3];
-Boolean isThere;
-int i;
- if (!element[1]) {
- name[0] = ' ';
- name[1] = element[0];
- } else
- strncpy ( name,element,2 );
- name[2] = char(0);
- isThere = False;
- for (i=0;(i<nElementMetals) && (!isThere);i++)
- isThere = (!strcmp(ElementMetal[i],name));
- return isThere;
-}
-
-int getElementNo ( cpstr element ) {
-int type=0;
-char El[3];
- if ((!element[1]) || (element[1]==' ')) {
- El[0] = ' ';
- El[1] = element[0];
- } else {
- El[0] = element[0];
- El[1] = element[1];
- }
- El[2] = char(0);
- UpperCase ( El );
- while (type<nElementNames)
- if (!strcmp(El,ElementName[type])) break;
- else type++;
- if (type>=nElementNames) return ELEMENT_UNKNOWN;
- return type+1; // so that hydrogen is 1
-}
-
-realtype getMolecWeight ( cpstr element ) {
-int type=0;
-char El[3];
- if ((!element[1]) || (element[1]==' ')) {
- El[0] = ' ';
- El[1] = element[0];
- } else {
- El[0] = element[0];
- El[1] = element[1];
- }
- El[2] = char(0);
- UpperCase ( El );
- while (type<nElementNames)
- if (!strcmp(El,ElementName[type])) break;
- else type++;
- if (type>=nElementNames) return 1.0;
- return MolecWeight[type];
-}
-
-realtype getCovalentRadius ( cpstr element ) {
-int type=0;
-char El[3];
- if ((!element[1]) || (element[1]==' ')) {
- El[0] = ' ';
- El[1] = element[0];
- } else {
- El[0] = element[0];
- El[1] = element[1];
- }
- El[2] = char(0);
- UpperCase ( El );
- while (type<nElementNames)
- if (!strcmp(El,ElementName[type])) break;
- else type++;
- if (type>=nElementNames) return 2.2*CovalentRadius[0];
- return CovalentRadius[type];
-}
-
-realtype getVdWaalsRadius ( cpstr element ) {
-int type=0;
-char El[3];
- if ((!element[1]) || (element[1]==' ')) {
- El[0] = ' ';
- El[1] = element[0];
- } else {
- El[0] = element[0];
- El[1] = element[1];
- }
- El[2] = char(0);
- UpperCase ( El );
- while (type<nElementNames)
- if (!strcmp(El,ElementName[type])) break;
- else type++;
- if (type>=nElementNames) return 1.8;
- return VdWaalsRadius[type];
-}
-
-cpstr const ResidueName[nResNames] = {
- "ALA", "ARG", "ASN", "ASP", "CYS", "CYH", "GLN",
- "GLU", "GLY", "HIS", "ILE", "LEU", "LYS", "MET",
- "PHE", "PRO", "SER", "THR", "TRP", "TYR", "VAL",
- "HEM", "WAT", "SUL", "END", "DUM"
-};
-
-int getResidueNo ( cpstr resName ) {
-int i,m;
- m = -1;
- for (i=0;(i<nResNames) && (m<0);i++)
- if (!strcmp(resName,ResidueName[i]))
- m = i;
- return m;
-}
-
-char const ResidueName1[nResNames] = {
- 'A', 'R', 'N', 'D', 'C', 'C', 'Q',
- 'E', 'G', 'H', 'I', 'L', 'K', 'M',
- 'F', 'P', 'S', 'T', 'W', 'Y', 'V',
- 'X', 'O', 'U', 'Z', 'Z'
-};
-
-
-cpstr const StdSolventName[nSolventNames] = {
- "ADE", "CYT", "GUA", "INO", "THY", "URA",
- "WAT", "HOH", "TIP", "H2O", "DOD", "MOH"
-};
-
-
-SAAProperty const AAProperty[nAminoacidNames] = {
- { "ALA", 1.8, 0.0, 0.42 },
- { "ARG", -4.5, 1.0, -1.37 },
- { "ASN", -3.5, 0.0, -0.82 },
- { "ASP", -3.5, -1.0, -1.05 },
- { "ASX", -3.5, -0.5, -1.05 }, // by analogy
- { "CYS", 2.5, 0.0, 1.34 },
- { "CYH", 2.5, 0.0, 1.34 }, // by analogy
- { "GLN", -3.5, 0.0, -0.30 },
- { "GLU", -3.5, -1.0, -0.87 },
- { "GLX", -3.5, -0.5, 0.0 }, // by analogy
- { "GLY", -0.4, 0.0, 0.0 },
- { "HIS", -3.2, 0.0, 0.18 },
- { "ILE", 4.5, 0.0, 2.46 },
- { "LEU", 3.8, 0.0, 2.32 },
- { "LYS", -3.9, 1.0, -1.35 },
- { "MET", 1.9, 0.0, 1.68 },
- { "PHE", 2.8, 0.0, 2.44 },
- { "PRO", -1.6, 0.0, 0.98 },
- { "SER", -0.8, 0.0, -0.05 },
- { "THR", -0.7, 0.0, 0.35 },
- { "TRP", -0.9, 0.0, 3.07 },
- { "TYR", -1.3, 0.0, 1.31 },
- { "VAL", 4.2, 0.0, 1.66 }
-};
-
-realtype GetAAHydropathy ( cpstr resName ) {
-int i1,j;
- i1 = -1;
- j = 0;
- while (j<nAminoacidNames)
- if (!strcasecmp(resName,AAProperty[j].name)) {
- i1 = j;
- break;
- } else
- j++;
- if (i1<0) return -MaxReal;
- return AAProperty[i1].hydropathy;
-}
-
-realtype GetAACharge ( cpstr resName ) {
-int i1,j;
- i1 = -1;
- j = 0;
- while (j<nAminoacidNames)
- if (!strcasecmp(resName,AAProperty[j].name)) {
- i1 = j;
- break;
- } else
- j++;
- if (i1<0) return 0.0;
- return AAProperty[i1].charge;
-}
-
-realtype GetAASolvationEnergy ( cpstr resName ) {
-int i1,j;
- i1 = -1;
- j = 0;
- while (j<nAminoacidNames)
- if (!strcasecmp(resName,AAProperty[j].name)) {
- i1 = j;
- break;
- } else
- j++;
- if (i1<0) return 0.0;
- return AAProperty[i1].relSolvEnergy;
-}
-
-
-int const AASimilarity[nAminoacidNames][nAminoacidNames] = {
-/* A A A A A C C G G G G H I L L M P P S T T T V */
-/* L R S S S Y Y L L L L I L E Y E H R E H R Y A */
-/* A G N P X S H N U X Y S E U S T E O R R P R L */
- { 5,0,0,0,0,0,0,0,0,2,2,0,2,2,0,2,2,2,1,1,2,2,2 }, /* ALA */
- { 0,5,2,2,2,0,0,2,2,0,0,2,0,0,4,0,0,0,0,0,0,0,0 }, /* ARG */
- { 0,2,5,3,5,0,0,3,3,0,0,0,0,0,2,0,0,0,0,0,0,0,0 }, /* ASN */
- { 0,2,3,5,5,0,0,3,3,0,0,0,0,0,2,0,0,0,0,0,0,0,0 }, /* ASP */
- { 0,2,5,5,5,0,0,3,3,0,0,0,0,0,2,0,0,0,0,0,0,0,0 }, /* ASX */
- { 0,0,0,0,0,5,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* CYS */
- { 0,0,0,0,0,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* CYH */
- { 0,2,3,3,3,0,0,5,3,0,0,0,0,0,2,0,0,0,0,0,0,0,0 }, /* GLN */
- { 0,2,3,3,3,0,0,3,5,0,0,0,0,0,2,0,0,0,0,0,0,0,0 }, /* GLU */
- { 2,0,0,0,0,0,0,0,0,5,5,0,1,1,0,1,1,2,0,0,1,1,1 }, /* GLX */
- { 2,0,0,0,0,0,0,0,0,5,5,0,1,1,0,1,1,2,0,0,1,1,1 }, /* GLY */
- { 0,2,0,0,0,0,0,0,0,0,0,5,1,1,2,2,2,0,1,1,2,2,1 }, /* HIS */
- { 2,0,0,0,0,0,0,0,0,1,1,1,5,4,0,4,4,0,0,0,4,4,4 }, /* ILE */
- { 2,0,0,0,0,0,0,0,0,1,1,1,4,5,0,4,4,0,0,0,4,4,4 }, /* LEU */
- { 0,4,2,2,2,0,0,2,2,0,0,2,0,0,5,0,0,0,0,0,0,0,0 }, /* LYS */
- { 2,0,0,0,0,0,0,0,0,1,1,2,4,4,0,5,4,0,0,0,4,4,4 }, /* MET */
- { 2,0,0,0,0,0,0,0,0,1,1,2,4,4,0,4,5,0,0,0,5,5,4 }, /* PHE */
- { 2,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,5,0,0,0,0,0 }, /* PRO */
- { 1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,5,3,0,0,0 }, /* SER */
- { 1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,3,5,0,0,0 }, /* THR */
- { 2,0,0,0,0,0,0,0,0,1,1,2,4,4,0,4,5,0,0,0,5,5,4 }, /* TRP */
- { 2,0,0,0,0,0,0,0,0,1,1,2,4,4,0,4,5,0,0,0,5,5,4 }, /* TYR */
- { 2,0,0,0,0,0,0,0,0,1,1,1,4,4,0,4,4,0,0,0,4,4,5 }, /* VAL */
-};
-
-int GetAAPIndex ( cpstr resName ) {
-// 0..nAminoacidNames-1
-int i,k;
- k = -1;
- for (i=0;(i<nAminoacidNames) && (k<0);i++)
- if (!strcasecmp(resName,AAProperty[i].name))
- k = i;
- return k;
-}
-
-
-int GetAASimilarity ( cpstr resName1, cpstr resName2 ) {
-int i1,i2,j;
-
- i1 = -1;
- j = 0;
- while (j<nAminoacidNames)
- if (!strcasecmp(resName1,AAProperty[j].name)) {
- i1 = j;
- break;
- } else
- j++;
- if (i1<0) return -1;
-
- i2 = -1;
- j = 0;
- while (j<nAminoacidNames)
- if (!strcasecmp(resName2,AAProperty[j].name)) {
- i2 = j;
- break;
- } else
- j++;
- if (i2<0) return -2;
-
- return AASimilarity[i1][i2];
-
-}
-
-
-
-
-
-/*
-
-
-pstr const AminoacidName[nAminoacidNames] = {
- "ALA", "ARG", "ASN", "ASP", "ASX", "CYS", "CYH", "GLN",
- "GLU", "GLX", "GLY", "HIS", "ILE", "LEU", "LYS", "MET",
- "PHE", "PRO", "SER", "THR", "TRP", "TYR", "VAL"
-};
-
-
-// The higher is the hydropathy scale value, the more
-// hydrophobic the residue is.
-// Some sources suggest that sure hydrophilic residues
-// are those with hydropathy scale value less than -1.5,
-// while sure hydropoobic residues have hydropathy scale
-// value greater than 0.0.
-// The scale is after J. Kyte and R. F. Doolittle,
-// A simple method for displaying the hydropathic character
-// of a protein, J. Mol. Biol. (1982) 157, 105-132
-realtype const AAHydropathyScale[nAminoacidNames] = {
- 1.8, -4.5, -3.5, -3.5, -3.5, 2.5, 2.5, -3.5,
- -3.5, -3.5, -0.4, -3.2, 4.5, 3.8, -3.9, 1.9,
- 2.8, -1.6, -0.8, -0.7, -0.9, -1.3, 4.2
-};
-
-realtype GetAAHydropathy ( cpstr resName ) {
-int i1,j;
- i1 = -1;
- j = 0;
- while (j<nAminoacidNames)
- if (!strcasecmp(resName,AminoacidName[j])) {
- i1 = j;
- break;
- } else
- j++;
- if (i1<0) return -MaxReal;
- return AAHydropathyScale[i1];
-}
-
-// Acid residues are those with negative charge
-// Base residues are those with positive charge
-realtype const AACharge[nAminoacidNames] = {
- 0.0, 1.0, 0.0, -1.0, -0.5, 0.0, 0.0, 0.0,
- -1.0, -0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
- 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
-};
-
-int GetAASimilarity ( cpstr resName1, cpstr resName2 ) {
-int i1,i2,j;
-
- i1 = -1;
- j = 0;
- while (j<nAminoacidNames)
- if (!strcasecmp(resName1,AminoacidName[j])) {
- i1 = j;
- break;
- } else
- j++;
- if (i1<0) return -1;
-
- i2 = -1;
- j = 0;
- while (j<nAminoacidNames)
- if (!strcasecmp(resName2,AminoacidName[j])) {
- i2 = j;
- break;
- } else
- j++;
- if (i2<0) return -2;
-
- return AASimilarity[i1][i2];
-
-}
-
-Boolean isAminoacid ( cpstr resName ) {
-Boolean isThere;
-int i;
- isThere = False;
- for (i=0;(i<nAminoacidNames) && (!isThere);i++)
- isThere = (!strcmp(AminoacidName[i],resName));
- return isThere;
-}
-
-*/
-
-
-cpstr const NucleotideName[nNucleotideNames] = {
- "A", "C", "G", "I", "T", "U",
- "+A", "+C", "+G", "+I", "+T", "+U",
- "DA", "DC", "DG", "DI", "DT", "DU",
- "RA", "RC", "RG", "RU", "5NC", "TYD"
-};
-
-
-Boolean isSolvent ( cpstr resName ) {
-Boolean isThere;
-int i;
- isThere = False;
- for (i=0;(i<nSolventNames) && (!isThere);i++)
- isThere = (!strcmp(StdSolventName[i],resName));
- return isThere;
-}
-
-Boolean isAminoacid ( cpstr resName ) {
-Boolean isThere;
-int i;
- isThere = False;
- for (i=0;(i<nAminoacidNames) && (!isThere);i++)
- isThere = (!strcmp(AAProperty[i].name,resName));
- return isThere;
-}
-
-Boolean isNucleotide ( cpstr resName ) {
-Boolean isThere;
-int i;
- isThere = False;
- for (i=0;(i<nNucleotideNames) && (!isThere);i++)
- isThere = (!strcmp(NucleotideName[i],resName));
- return isThere;
-}
-
-int isDNARNA ( cpstr resName ) {
-Boolean isThere;
-int i;
- isThere = False;
- for (i=0;(i<nNucleotideNames) && (!isThere);i++)
- isThere = (!strcmp(NucleotideName[i],resName));
- if (!isThere) return 0; // neither
- if (resName[0]=='D') return 1; // DNA
- return 2; // RNA
-}
-
-Boolean isSugar ( cpstr resName ) {
-UNUSED_ARGUMENT(resName);
- return False;
-}
-
-
-cpstr const Res1Code[] = {
-
- // standard aminoacids
-
- "ALA A", // Alanine
- "ARG R", // Arginine
- "ASN N", // Asparagine
- "ASP D", // Aspartic acid (Aspartate)
- "CYS C", // Cysteine
- "GLN Q", // Glutamine
- "GLU E", // Glutamic acid (Glutamate)
- "GLY G", // Glycine
- "HIS H", // Histidine
- "ILE I", // Isoleucine
- "LEU L", // Leucine
- "LYS K", // Lysine
- "MET M", // Methionine
- "PHE F", // Phenylalanine
- "PRO P", // Proline
- "SER S", // Serine
- "THR T", // Threonine
- "TRP W", // Tryptophan
- "TYR Y", // Tyrosine
- "VAL V", // Valine
- "ASX B", // Aspartic acid or Asparagine
- "GLX Z", // Glutamine or Glutamic acid.
- // ??? X Any amino acid.
-
- // other
-
- "1PA A", "1PI A", "2AS D", "2ML L", "2MR R", "3GA A",
- "5HP E", "ACB D", "ACL R", "AGM R", "AHB D", "ALM A",
- "ALN A", "ALO T", "ALT A", "ALY K", "APH A", "APM A",
- "AR2 R", "ARM R", "ARO R", "ASA D", "ASB D", "ASI D",
- "ASK D", "ASL D", "ASQ D", "AYA A", "B1F A", "B2A A",
- "B2F A", "B2I I", "B2V V", "BAL A", "BCS C", "BFD D",
- "BHD D", "BLE L", "BLY K", "BNN F", "BNO L", "BTA L",
- "BTC C", "BTR W", "BUC C", "BUG L", "C5C C", "C6C C",
- "CAF C", "CAS C", "CAY C", "CCS C", "CEA C", "CGU E",
- "CHG G", "CHP G", "CLB A", "CLD A", "CLE L", "CME C",
- "CMT C", "CSB C", "CSD A", "CSE C", "CSO C", "CSP C",
- "CSR C", "CSS C", "CSW C", "CSX C", "CSY C", "CSZ C",
- "CTH T", "CXM M", "CY1 C", "CYM C", "CZZ C", "DAH F",
- "DAL A", "DAM A", "DAR R", "DAS D", "DBY Y", "DCY C",
- "DGL E", "DGN Q", "DHI H", "DHN V", "DIL I", "DIV V",
- "DLE L", "DLY K", "DNP A", "DOH D", "DPH F", "DPN F",
- "DPR P", "DSE S", "DSN S", "DSP D", "DTH T", "DTR W",
- "DTY Y", "DVA V", "EFC C", "EHP F", "EYS C", "FLA A",
- "FLE L", "FME M", "FTY Y", "GGL E", "GHP G", "GSC G",
- "GT9 C", "H5M P", "HAC A", "HAR R", "HIC H", "HIP H",
- "HMR R", "HPH F", "HPQ F", "HTR W", "HV5 A", "HYP P",
- "IAS N", "IIL I", "ILG Q", "IML I", "IN2 K", "ISO A",
- "IVA V", "IYR Y", "KCX K", "KPH K", "LLY K", "LOL L",
- "LPL L", "LTR W", "LYM K", "LYZ K", "M3L K", "MAA A",
- "MAI R", "MEN N", "MGN Q", "MGY G", "MHL L", "MHO M",
- "MHS H", "MIS S", "MLE L", "MLY K", "MLZ K", "MME M",
- "MNL L", "MNV V", "MPQ G", "MSE M", "MSO M", "MTY Y",
- "MVA V", "NAL A", "NAM A", "NCY C", "NEM H", "NEP H",
- "NFA F", "NIT A", "NLE L", "NLN L", "NNH R", "NPH C",
- "NVA V", "OAS S", "OCS C", "OCY C", "OMT M", "OPR R",
- "PAQ F", "PBB C", "PCA E", "PEC C", "PGY G", "PHA F",
- "PHD N", "PHI F", "PHL F", "PHM F", "PLE L", "POM P",
- "PPH F", "PPN F", "PR3 C", "PRR A", "PRS P", "PTH Y",
- "PTR Y", "PYA A", "RON V", "S1H S", "SAC S", "SAH C",
- "SAM M", "SBD A", "SBL A", "SCH C", "SCS C", "SCY C",
- "SEB S", "SEG A", "SEP S", "SET S", "SHC C", "SHP G",
- "SLZ K", "SMC C", "SME M", "SNC C", "SOC C", "STY Y",
- "SVA S", "TBG G", "TCR W", "THC T", "THO T", "TIH A",
- "TNB C", "TPL W", "TPO T", "TPQ F", "TRF W", "TRG K",
- "TRN W", "TRO W", "TYB Y", "TYI Y", "TYN Y", "TYQ Y",
- "TYS Y", "TYY A", "VAD V", "VAF V", "YOF Y", ""
-
-};
-
-
-void Get1LetterCode ( cpstr res3name, pstr res1code ) {
-char r[4];
-int i;
-
- strncpy ( r,res3name,3 );
- r[3] = char(0);
- UpperCase ( r );
- i = 0;
- res1code[0] = char(1);
- while (Res1Code[i][0]) {
- if (Res1Code[i][0]==r[0]) {
- if (Res1Code[i][1]==r[1]) {
- if (Res1Code[i][2]==r[2]) {
- res1code[0] = Res1Code[i][4];
- break;
- }
- }
- }
- i++;
- }
-
- if (res1code[0]!=char(1)) res1code[1] = char(0);
- else if (isNucleotide(r)) strcpy ( res1code,r );
- else strcpy ( res1code,"X" );
-
-}
-
-
-void Get3LetterCode ( cpstr res1name, pstr res3code ) {
-int i;
-
- strcpy ( res3code,"XXX" );
- i = 0;
- while (Res1Code[i][0]) {
- if (Res1Code[i][4]==res1name[0]) {
- res3code[0] = Res1Code[i][0];
- res3code[1] = Res1Code[i][1];
- res3code[2] = Res1Code[i][2];
- break;
- }
- i++;
- }
-
-}
diff --git a/mmdb/mmdb_tables.h b/mmdb/mmdb_tables.h
deleted file mode 100755
index dbc59ab..0000000
--- a/mmdb/mmdb_tables.h
+++ /dev/null
@@ -1,129 +0,0 @@
-// $Id: mmdb_tables.h,v 1.26 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 04.02.09 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDBF_Tables <interface>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-//
-// **** Functions :
-// ~~~~~~~~~~~
-//
-// **** Constants : AName ( array of 2-character atom names )
-// ~~~~~~~~~~~ HAName ( array of 2=character heteroatom names )
-// RName ( 3-characters amino acid names )
-// RName1 ( 1-characters amino acid names )
-//
-//
-// (C) E. Krissinel 2000-2009
-//
-// =================================================================
-//
-
-
-#ifndef __MMDB_Tables__
-#define __MMDB_Tables__
-
-
-#ifndef __MatType__
-#include "mattype_.h"
-#endif
-
-
-
-// =================================================================
-
-
-#define nElementNames 117
-#define nElementMetals 91
-#define nHydAtomNames 14
-
-extern cpstr const ElementName [nElementNames];
-extern cpstr const ElementMetal [nElementMetals];
-extern cpstr const HydAtomName [nHydAtomNames];
-extern realtype const MolecWeight [nElementNames];
-extern realtype const CovalentRadius[nElementNames];
-extern realtype const VdWaalsRadius [nElementNames];
-extern realtype const IonicRadius [nElementNames];
-
-extern Boolean isMetal ( cpstr element );
-
-#define ELEMENT_UNKNOWN -1
-
-extern int getElementNo ( cpstr element );
-extern realtype getMolecWeight ( cpstr element );
-extern realtype getCovalentRadius ( cpstr element );
-extern realtype getVdWaalsRadius ( cpstr element );
-
-#define nResNames 26
-
-extern cpstr const ResidueName [nResNames];
-extern char const ResidueName1[nResNames];
-
-extern int getResidueNo ( cpstr resName );
-
-#define nSolventNames 12
-#define nAminoacidNames 23
-#define nNucleotideNames 24
-
-
-DefineStructure(SAAProperty)
-
-struct SAAProperty {
- char name[4];
- realtype hydropathy;
- realtype charge;
- realtype relSolvEnergy;
-};
-
-extern SAAProperty const AAProperty[nAminoacidNames];
-extern int const AASimilarity[nAminoacidNames][nAminoacidNames];
-
-extern int GetAAPIndex ( cpstr resName ); // 0..nAminoacidNames-1
-extern realtype GetAAHydropathy ( cpstr resName ); // -4.5...+4.5
-extern realtype GetAACharge ( cpstr resName );
-extern realtype GetAASolvationEnergy ( cpstr resName );
-extern int GetAASimilarity ( cpstr resName1,
- cpstr resName2 ); // 0..5
-
-extern cpstr const StdSolventName[nSolventNames];
-//extern pstr const AminoacidName [nAminoacidNames];
-extern cpstr const NucleotideName[nNucleotideNames];
-
-extern Boolean isSolvent ( cpstr resName );
-extern Boolean isAminoacid ( cpstr resName );
-extern Boolean isNucleotide ( cpstr resName );
-extern int isDNARNA ( cpstr resName ); // 0,1(DNA),2(RNA)
-extern Boolean isSugar ( cpstr resName );
-
-extern void Get1LetterCode ( cpstr res3name, pstr res1code );
-extern void Get3LetterCode ( cpstr res1name, pstr res3code );
-
-
-#endif
-
diff --git a/mmdb/mmdb_title.cpp b/mmdb/mmdb_title.cpp
deleted file mode 100755
index 1d83f80..0000000
--- a/mmdb/mmdb_title.cpp
+++ /dev/null
@@ -1,2653 +0,0 @@
-// $Id: mmdb_title.cpp,v 1.26 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 23.06.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_Title <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CTitleContainer (container for title classes)
-// ~~~~~~~~~ CObsLine
-// CTitleLine
-// CCaveat
-// CCompound
-// CSource
-// CKeyWords
-// CExpData
-// CMdlType
-// CAuthor
-// CRevData
-// CSupersede
-// CJournal
-// CRemark
-// CBiomolecule
-// CMMDBTitle ( MMDB title section )
-//
-// (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifndef __MMDB_Title__
-#include "mmdb_title.h"
-#endif
-
-#ifndef __MMDB_CIFDefs__
-#include "mmdb_cifdefs.h"
-#endif
-
-
-// ============== CTitleContainer ====================
-
-PCContainerClass CTitleContainer::MakeContainerClass ( int ClassID ) {
- switch (ClassID) {
- default :
- case ClassID_Template : return
- CClassContainer::MakeContainerClass(ClassID);
- case ClassID_ObsLine : return new CObsLine ();
- case ClassID_CAVEAT : return new CCaveat ();
- case ClassID_TitleLine : return new CTitleLine();
- case ClassID_Compound : return new CCompound ();
- case ClassID_Source : return new CSource ();
- case ClassID_ExpData : return new CExpData ();
- case ClassID_Author : return new CAuthor ();
- case ClassID_RevData : return new CRevData ();
- case ClassID_Supersede : return new CSupersede();
- case ClassID_Journal : return new CJournal ();
- case ClassID_Remark : return new CRemark ();
- }
-}
-
-MakeStreamFunctions(CTitleContainer)
-
-
-// ================ CObsLine ===================
-
-CObsLine::CObsLine() : CContainerClass() {
- InitObsLine();
-}
-
-CObsLine::CObsLine ( cpstr S ) : CContainerClass() {
- InitObsLine();
- ConvertPDBASCII ( S );
-}
-
-CObsLine::CObsLine ( RPCStream Object ) : CContainerClass(Object) {
- InitObsLine();
-}
-
-CObsLine::~CObsLine() {}
-
-void CObsLine::InitObsLine() {
-int i;
- strcpy ( repDate,"DD-MMM-YYYY" );
- strcpy ( idCode, "----" );
- for (i=0;i<8;i++)
- strcpy ( rIdCode[i]," " );
-}
-
-void CObsLine::PDBASCIIDump ( pstr S, int N ) {
-// makes the ASCII PDB OBSLTE line number N
-// from the class' data
-int i;
- if (N==0) strcpy ( S,"OBSLTE " );
- else sprintf ( S,"OBSLTE %2i",N+1 );
- PadSpaces ( S,80 );
- Date11to9 ( repDate,&(S[11]) );
- strncpy ( &(S[21]),idCode,4 );
- for (i=0;i<8;i++)
- strncpy ( &(S[31+5*i]),rIdCode[i],4 );
-}
-
-void CObsLine::MakeCIF ( PCMMCIFData CIF, int ) {
-PCMMCIFLoop Loop;
-int RC,i,j;
-char DateCIF[20];
- RC = CIF->AddLoop ( CIFCAT_OBSLTE,Loop );
- if (RC!=CIFRC_Ok) {
- // the category was (re)created, provide tags
- Loop->AddLoopTag ( CIFTAG_ID );
- Loop->AddLoopTag ( CIFTAG_DATE );
- Loop->AddLoopTag ( CIFTAG_REPLACE_PDB_ID );
- Loop->AddLoopTag ( CIFTAG_PDB_ID );
- }
- Date11toCIF ( repDate,DateCIF );
- for (i=0;i<8;i++) {
- j = 0;
- while (rIdCode[i][j] && (rIdCode[i][j]==' ')) j++;
- if (rIdCode[i][j]) {
- Loop->AddString ( pstr("OBSLTE") );
- Loop->AddString ( DateCIF );
- Loop->AddString ( idCode );
- Loop->AddString ( rIdCode[i] );
- }
- }
-}
-
-int CObsLine::ConvertPDBASCII ( cpstr S ) {
-int i;
- Date9to11 ( &(S[11]),repDate );
- strncpy ( idCode,&(S[21]),4 );
- idCode[4] = char(0);
- for (i=0;i<8;i++) {
- strncpy ( rIdCode[i],&(S[31+i*5]),4 );
- rIdCode[i][4] = char(0);
- }
- return 0;
-}
-
-void CObsLine::GetCIF ( PCMMCIFData CIF, int & Signal ) {
-PCMMCIFLoop Loop;
-int i,RC;
-pstr F,FDate,FID;
-char DateCIF [20];
-char DateCIF0[20];
-IDCode idCode1;
- Loop = CIF->GetLoop ( CIFCAT_OBSLTE );
- if (!Loop) {
- Signal = -1; // signal to finish processing of this structure
- return;
- }
- i = 0;
- do {
- F = Loop->GetString ( CIFTAG_ID,Signal,RC );
- if (RC) {
- if (i==0) Signal = -1;
- return;
- }
- if (F) {
- if (!strcmp(F,"OBSLTE")) {
- FDate = Loop->GetString ( CIFTAG_DATE,Signal,RC );
- if ((!RC) && FDate)
- strncpy ( DateCIF,FDate,15 );
- else strcpy ( DateCIF,"YYYY-MMM-DD" );
- FID = Loop->GetString ( CIFTAG_REPLACE_PDB_ID,Signal,RC );
- if ((!RC) && FID)
- strncpy ( idCode1,FID,sizeof(IDCode)-1 );
- else idCode1[0] = char(0);
- if (i==0) {
- DateCIFto11 ( DateCIF,repDate );
- DateCIF[11] = char(0);
- strcpy ( idCode ,idCode1 );
- strcpy ( DateCIF0,DateCIF );
- } else if ((strcmp(DateCIF0,DateCIF)) ||
- (strcmp(idCode,idCode1)))
- return;
- FID = Loop->GetString ( CIFTAG_PDB_ID,Signal,RC );
- if ((!RC) && FID)
- strncpy ( rIdCode[i],FID,sizeof(IDCode)-1 );
- else rIdCode[i][0] = char(0);
- Loop->DeleteField ( CIFTAG_ID ,Signal );
- Loop->DeleteField ( CIFTAG_DATE ,Signal );
- Loop->DeleteField ( CIFTAG_REPLACE_PDB_ID,Signal );
- Loop->DeleteField ( CIFTAG_PDB_ID ,Signal );
- i++;
- }
- }
- Signal++;
- } while (i<8);
-}
-
-void CObsLine::Copy ( PCContainerClass ObsLine ) {
-int i;
- strcpy ( repDate,PCObsLine(ObsLine)->repDate );
- strcpy ( idCode ,PCObsLine(ObsLine)->idCode );
- for (i=0;i<8;i++)
- strcpy ( rIdCode[i],PCObsLine(ObsLine)->rIdCode[i] );
-}
-
-void CObsLine::write ( RCFile f ) {
-int i;
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteTerLine ( repDate,False );
- f.WriteTerLine ( idCode ,False );
- for (i=0;i<8;i++)
- f.WriteTerLine ( rIdCode[i],False );
-}
-
-void CObsLine::read ( RCFile f ) {
-int i;
-byte Version;
- f.ReadByte ( &Version );
- f.ReadTerLine ( repDate,False );
- f.ReadTerLine ( idCode ,False );
- for (i=0;i<8;i++)
- f.ReadTerLine ( rIdCode[i],False );
-}
-
-MakeStreamFunctions(CObsLine)
-
-
-// =================== CTitleLine ======================
-
-CTitleLine::CTitleLine() : CContString() {
- InitTitleLine();
-}
-
-CTitleLine::CTitleLine ( cpstr S ) : CContString() {
- InitTitleLine();
- ConvertPDBASCII ( S );
-}
-
-CTitleLine::CTitleLine ( RPCStream Object ) : CContString(Object) {
- InitTitleLine();
-}
-
-CTitleLine::~CTitleLine() {
-}
-
-void CTitleLine::InitTitleLine() {
- CreateCopy ( CIFCategory,CIFCAT_STRUCT );
- CreateCopy ( CIFTag, CIFTAG_TITLE );
-}
-
-int CTitleLine::ConvertPDBASCII ( cpstr S ) {
- if (strlen(S)>10)
- CreateCopy ( Line,&(S[10]) );
- else CreateCopy ( Line,pstr(" ") );
- return 0;
-}
-
-void CTitleLine::PDBASCIIDump ( pstr S, int N ) {
- if (N==0) strcpy ( S,"TITLE " );
- else sprintf ( S,"TITLE %2i",N+1 );
- strcat ( S,Line );
-}
-
-void CTitleLine::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- CContString::write ( f );
-}
-
-void CTitleLine::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- CContString::read ( f );
-}
-
-MakeStreamFunctions(CTitleLine)
-
-
-
-// =================== CCaveat ======================
-
-CCaveat::CCaveat() : CContString() {
- InitCaveat();
-}
-
-CCaveat::CCaveat ( cpstr S ) : CContString() {
- InitCaveat();
- ConvertPDBASCII ( S );
-}
-
-CCaveat::CCaveat ( RPCStream Object ) : CContString(Object) {
- InitCaveat();
-}
-
-CCaveat::~CCaveat() {}
-
-void CCaveat::InitCaveat() {
- strcpy ( idCode,"----" );
- CreateCopy ( CIFCategory,CIFCAT_DATABASE_PDB_CAVEAT );
- CreateCopy ( CIFTag ,CIFTAG_TEXT );
-}
-
-int CCaveat::ConvertPDBASCII ( cpstr S ) {
- if (strlen(S)>12) {
- strncpy ( idCode,&(S[11]),4 );
- idCode[4] = char(0);
- if (strlen(S)>19)
- CreateCopy ( Line,&(S[19]) );
- else CreateCopy ( Line,pstr(" ") );
- } else
- CreateCopy ( Line,pstr(" ") );
- return 0;
-}
-
-void CCaveat::PDBASCIIDump ( pstr S, int N ) {
- if (N==0) strcpy ( S,"CAVEAT " );
- else sprintf ( S,"CAVEAT %2i ",N+1 );
- strcat ( S,idCode );
- strcat ( S," " );
- strcat ( S,Line );
-}
-
-void CCaveat::MakeCIF ( PCMMCIFData CIF, int N ) {
-char S[500];
- CIF->PutString ( idCode,CIFCAT_DATABASE_PDB_CAVEAT,CIFTAG_ID,False );
- strcpy ( S,"\n" );
- strncat ( S,Line,sizeof(S)-2 );
- S[sizeof(S)-1] = char(0);
- CIF->PutString ( S,CIFCAT_DATABASE_PDB_CAVEAT,CIFTAG_TEXT,(N!=0) );
-}
-
-void CCaveat::GetCIF ( PCMMCIFData CIF, int & Signal ) {
-pstr F;
-int RC;
- F = CIF->GetString ( CIFCAT_DATABASE_PDB_CAVEAT,CIFTAG_ID,RC );
- if ((!RC) && F) {
- strncpy ( idCode,F,sizeof(IDCode) );
- idCode[sizeof(IDCode)-1] = char(0);
- }
- CContString::GetCIF ( CIF,Signal );
- if (Signal<0)
- CIF->DeleteField ( CIFCAT_DATABASE_PDB_CAVEAT,CIFTAG_ID );
-}
-
-void CCaveat::Copy ( PCContainerClass Caveat ) {
- strcpy ( idCode,PCCaveat(Caveat)->idCode );
- CContString::Copy ( Caveat );
-}
-
-void CCaveat::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteTerLine ( idCode,False );
- CContString::write ( f );
-}
-
-void CCaveat::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- f.ReadTerLine ( idCode,False );
- CContString::read ( f );
-}
-
-MakeStreamFunctions(CCaveat)
-
-
-
-// =================== CCompound ======================
-
-CCompound::CCompound() : CContString() {
- InitCompound();
-}
-
-CCompound::CCompound ( cpstr S ) : CContString() {
- InitCompound();
- ConvertPDBASCII ( S );
-}
-
-CCompound::CCompound ( RPCStream Object ) : CContString(Object) {
- InitCompound();
-}
-
-CCompound::~CCompound() {}
-
-void CCompound::InitCompound() {
- CreateCopy ( CIFCategory,CIFCAT_STRUCT );
- CreateCopy ( CIFTag ,CIFTAG_NDB_DESCRIPTOR );
-}
-
-int CCompound::ConvertPDBASCII ( cpstr S ) {
- if (strlen(S)>10)
- CreateCopy ( Line,&(S[10]) );
- else CreateCopy ( Line,pstr(" ") );
- return 0;
-}
-
-void CCompound::PDBASCIIDump ( pstr S, int N ) {
- if (N==0) strcpy ( S,"COMPND " );
- else sprintf ( S,"COMPND %2i",N+1 );
- strcat ( S,Line );
-}
-
-void CCompound::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- CContString::write ( f );
-}
-
-void CCompound::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- CContString::read ( f );
-}
-
-MakeStreamFunctions(CCompound)
-
-
-
-// =================== CSource ======================
-
-CSource::CSource() : CContString() {
- InitSource();
-}
-
-CSource::CSource ( cpstr S ) : CContString() {
- InitSource();
- ConvertPDBASCII ( S );
-}
-
-CSource::CSource ( RPCStream Object ) : CContString(Object) {
- InitSource();
-}
-
-CSource::~CSource() {}
-
-void CSource::InitSource() {
- CreateCopy ( CIFCategory,CIFCAT_STRUCT );
- CreateCopy ( CIFTag ,CIFTAG_SOURCE );
-}
-
-int CSource::ConvertPDBASCII ( cpstr S ) {
- if (strlen(S)>10)
- CreateCopy ( Line,&(S[10]) );
- else CreateCopy ( Line,pstr(" ") );
- return 0;
-}
-
-void CSource::PDBASCIIDump ( pstr S, int N ) {
- if (N==0) strcpy ( S,"SOURCE " );
- else sprintf ( S,"SOURCE %2i",N+1 );
- strcat ( S,Line );
-}
-
-void CSource::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- CContString::write ( f );
-}
-
-void CSource::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- CContString::read ( f );
-}
-
-MakeStreamFunctions(CSource)
-
-
-// =================== CKeyWords ======================
-
-CKeyWords::CKeyWords() : CStream() {
- Init();
-}
-
-CKeyWords::CKeyWords ( cpstr S ) : CStream() {
- Init();
- ConvertPDBASCII ( S );
-}
-
-CKeyWords::CKeyWords ( RPCStream Object ) : CStream(Object) {
- Init();
-}
-
-CKeyWords::~CKeyWords() {
- Delete();
-}
-
-void CKeyWords::Init() {
- nKeyWords = 0;
- KeyWord = NULL;
- Cont = False;
-}
-
-void CKeyWords::Delete() {
-int i;
- if (KeyWord) {
- for (i=0;i<nKeyWords;i++)
- if (KeyWord[i])
- delete[] KeyWord[i];
- delete[] KeyWord;
- }
- nKeyWords = 0;
- KeyWord = NULL;
- Cont = False;
-}
-
-int CKeyWords::ConvertPDBASCII ( cpstr S ) {
-// we anticipate that length of S is 80 characters
-// -- pad with spaces if necessary
-char L[85];
-int i,k,m;
-pstr * KW;
-
- i = 10; // scan PDB line from ith character
-
- k = nKeyWords;
- if (!Cont) k++; // 1st keyword does not continue from previous line
- m = 0;
- while (S[i] && (i<70)) {
- if (S[i]==',') k++; // count keywords
- if (S[i]!=' ') m++; // count non-spaces to see if the line is empty
- i++;
- }
-
- if (m==0) return 0; // empty line
-
- KW = new pstr[k];
- if (KeyWord) {
- for (i=0;i<nKeyWords;i++)
- KW[i] = KeyWord[i];
- delete[] KeyWord;
- }
- for (i=nKeyWords;i<k;i++)
- KW[i] = NULL; // null new pointers
- KeyWord = KW;
-
- i = 10;
- if (Cont) nKeyWords--;
- while (S[i] && (i<70)) {
- while ((S[i]==' ') && (i<70)) i++; // skip leading spaces
- if (Cont) {
- strcpy ( L," " );
- m = 1;
- } else
- m = 0;
- while (S[i] && (S[i]!=',') && (i<70))
- L[m++] = S[i++];
- m--;
- while ((m>0) && (L[m]==' ')) m--; // remove padding spaces
- m++;
- L[m] = char(0);
- if (Cont) CreateConcat ( KeyWord[nKeyWords],L );
- else CreateCopy ( KeyWord[nKeyWords],L );
- if (S[i]==',') {
- i++;
- Cont = False;
- } else
- Cont = True;
- nKeyWords++;
- }
-
- return 0;
-
-}
-
-void CKeyWords::PDBASCIIDump ( RCFile f ) {
-int N,i,k,m1,m2,ms;
-char S[85];
-char c;
- if (KeyWord) {
- N = 0;
- i = 0;
- while (i<nKeyWords) {
- if (N==0) strcpy ( S,"KEYWDS " );
- else sprintf ( S,"KEYWDS %2i ",N+1 );
- do {
- while ((i<nKeyWords) && (!KeyWord[i])) i++;
- if (i<nKeyWords) {
- m1 = 0;
- while (KeyWord[i][m1]) {
- while (KeyWord[i][m1]==' ') m1++;
- m2 = m1;
- ms = -1;
- while ((KeyWord[i][m2]) && ((m2-m1)<58)) {
- if (KeyWord[i][m2]==' ') ms = m2;
- m2++;
- }
- if ((ms<0) || ((m2-m1)<58)) ms = m2;
- c = KeyWord[i][ms];
- KeyWord[i][ms] = char(0);
- strcat ( S,&(KeyWord[i][m1]) );
- KeyWord[i][ms] = c;
- m1 = ms;
- if (c) {
- PadSpaces ( S,80 );
- f.WriteLine ( S );
- N++;
- sprintf ( S,"KEYWDS %2i ",N+1 );
- }
- }
- i++;
- if (i<nKeyWords) {
- k = strlen(S) + strlen(KeyWord[i]) + 2;
- if (i<nKeyWords)
- strcat ( S,", " );
- } else
- k = 80;
- } else
- k = 80;
- } while (k<70);
- PadSpaces ( S,80 );
- f.WriteLine ( S );
- N++;
- }
- }
-}
-
-void CKeyWords::MakeCIF ( PCMMCIFData CIF ) {
-int i,k;
-char S[500];
- strcpy ( S,"\n" );
- for (i=0;i<nKeyWords;i++)
- if (KeyWord[i]) {
- k = strlen(KeyWord[i]);
- if (strlen(S)+k>70) {
- CIF->PutString ( S,CIFCAT_STRUCT_KEYWORDS,CIFTAG_TEXT,True );
- if (k>(int)sizeof(S)) {
- CIF->PutString ( KeyWord[i],CIFCAT_STRUCT_KEYWORDS,
- CIFTAG_TEXT,True );
- k = 0;
- }
- strcpy ( S,"\n" );
- }
- if (k>0) {
- strcat ( S,KeyWord[i] );
- if (i<nKeyWords-1) strcat ( S,", " );
- }
- }
- if (strlen(S)>1)
- CIF->PutString ( S,CIFCAT_STRUCT_KEYWORDS,CIFTAG_TEXT,True );
-}
-
-void CKeyWords::GetCIF ( PCMMCIFData CIF ) {
-pstr F;
-int i,j,k;
-Boolean NB;
-char c;
- Delete();
- F = CIF->GetString ( CIFCAT_STRUCT_KEYWORDS,CIFTAG_TEXT,i );
- k = 0;
- if ((!i) && F) {
- i = 0;
- NB = False;
- while (F[i]) {
- if (F[i]==',') {
- nKeyWords++;
- NB = False;
- } else if (F[i]!=' ')
- NB = True;
- i++;
- }
- if (NB) nKeyWords++;
- KeyWord = new pstr[nKeyWords];
- i = 0;
- while (F[i] && (k<nKeyWords)) {
- while ((F[i]==' ') || (F[i]=='\n') || (F[i]=='\r')) i++;
- j = i;
- while (F[i] && (F[i]!=',')) i++;
- c = F[i];
- F[i] = char(0);
- KeyWord[k] = NULL;
- CreateCopy ( KeyWord[k],&(F[j]) );
- j = 0;
- while (KeyWord[k][j]) {
- if ((KeyWord[k][j]=='\n') || (KeyWord[k][j]=='\r'))
- KeyWord[k][j] = ' ';
- j++;
- }
- F[i] = c;
- k++;
- if (F[i]) i++;
- }
- }
- while (k<nKeyWords) KeyWord[k++] = NULL;
- CIF->DeleteField ( CIFCAT_STRUCT_KEYWORDS,CIFTAG_TEXT );
-}
-
-
-void CKeyWords::Copy ( PCKeyWords KeyWords ) {
-int i;
- Delete();
- nKeyWords = KeyWords->nKeyWords;
- if (nKeyWords>0) {
- KeyWord = new pstr[nKeyWords];
- for (i=0;i<nKeyWords;i++) {
- KeyWord[i] = NULL;
- CreateCopy ( KeyWord[i],KeyWords->KeyWord[i] );
- }
- }
-}
-
-void CKeyWords::write ( RCFile f ) {
-int i;
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &nKeyWords );
- for (i=0;i<nKeyWords;i++)
- f.CreateWrite ( KeyWord[i] );
-}
-
-void CKeyWords::read ( RCFile f ) {
-int i;
-byte Version;
- Delete();
- f.ReadByte ( &Version );
- f.ReadInt ( &nKeyWords );
- if (nKeyWords>0) {
- KeyWord = new pstr[nKeyWords];
- for (i=0;i<nKeyWords;i++) {
- KeyWord[i] = NULL;
- f.CreateRead ( KeyWord[i] );
- }
- }
-}
-
-MakeStreamFunctions(CKeyWords)
-
-
-// =================== CExpData ======================
-
-CExpData::CExpData() : CContString() {
- InitExpData();
-}
-
-CExpData::CExpData ( cpstr S ) : CContString() {
- InitExpData();
- ConvertPDBASCII ( S );
-}
-
-CExpData::CExpData ( RPCStream Object ) : CContString(Object) {
- InitExpData();
-}
-
-CExpData::~CExpData() {}
-
-void CExpData::InitExpData() {
- CreateCopy ( CIFCategory,CIFCAT_EXPTL );
- CreateCopy ( CIFTag ,CIFTAG_METHOD );
-}
-
-int CExpData::ConvertPDBASCII ( cpstr S ) {
- if (strlen(S)>10)
- CreateCopy ( Line,&(S[10]) );
- else CreateCopy ( Line,pstr(" ") );
- return 0;
-}
-
-void CExpData::PDBASCIIDump ( pstr S, int N ) {
- if (N==0) strcpy ( S,"EXPDTA " );
- else sprintf ( S,"EXPDTA %2i",N+1 );
- strcat ( S,Line );
-}
-
-void CExpData::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- CContString::write ( f );
-}
-
-void CExpData::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- CContString::read ( f );
-}
-
-MakeStreamFunctions(CExpData)
-
-
-
-
-// =================== CMdlType ======================
-
-CMdlType::CMdlType() : CContString() {
- InitMdlType();
-}
-
-CMdlType::CMdlType ( cpstr S ) : CContString() {
- InitMdlType();
- ConvertPDBASCII ( S );
-}
-
-CMdlType::CMdlType ( RPCStream Object ) : CContString(Object) {
- InitMdlType();
-}
-
-CMdlType::~CMdlType() {}
-
-void CMdlType::InitMdlType() {
- CreateCopy ( CIFCategory,CIFCAT_EXPTL );
- CreateCopy ( CIFTag ,CIFTAG_METHOD );
-}
-
-int CMdlType::ConvertPDBASCII ( cpstr S ) {
- if (strlen(S)>10)
- CreateCopy ( Line,&(S[10]) );
- else CreateCopy ( Line,pstr(" ") );
- return 0;
-}
-
-void CMdlType::PDBASCIIDump ( pstr S, int N ) {
- if (N==0) strcpy ( S,"MDLTYP " );
- else sprintf ( S,"MDLTYP %2i",N+1 );
- strcat ( S,Line );
-}
-
-void CMdlType::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- CContString::write ( f );
-}
-
-void CMdlType::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- CContString::read ( f );
-}
-
-MakeStreamFunctions(CMdlType)
-
-
-// =================== CAuthor ======================
-
-CAuthor::CAuthor() : CContString() {
- InitAuthor();
-}
-
-CAuthor::CAuthor ( cpstr S ) : CContString() {
- InitAuthor();
- ConvertPDBASCII ( S );
-}
-
-CAuthor::CAuthor ( RPCStream Object ) : CContString(Object) {
- InitAuthor();
-}
-
-CAuthor::~CAuthor() {}
-
-void CAuthor::InitAuthor() {
- CreateCopy ( CIFCategory,CIFCAT_AUDIT_AUTHOR );
- CreateCopy ( CIFTag ,CIFTAG_NAME );
-}
-
-int CAuthor::ConvertPDBASCII ( cpstr S ) {
- if (strlen(S)>10)
- CreateCopy ( Line,&(S[10]) );
- else CreateCopy ( Line,pstr(" ") );
- return 0;
-}
-
-void CAuthor::PDBASCIIDump ( pstr S, int N ) {
- if (N==0) strcpy ( S,"AUTHOR " );
- else sprintf ( S,"AUTHOR %2i",N+1 );
- strcat ( S,Line );
-}
-
-void CAuthor::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- CContString::write ( f );
-}
-
-void CAuthor::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- CContString::read ( f );
-}
-
-MakeStreamFunctions(CAuthor)
-
-
-
-// ================ CRevData ===================
-
-CRevData::CRevData() : CContainerClass() {
- InitRevData();
-}
-
-CRevData::CRevData ( cpstr S ) : CContainerClass() {
- InitRevData();
- ConvertPDBASCII ( S );
-}
-
-CRevData::CRevData ( RPCStream Object ) : CContainerClass(Object) {
- InitRevData();
-}
-
-CRevData::~CRevData() {}
-
-void CRevData::InitRevData() {
-int i;
- modNum = 0;
- strcpy ( modDate,"DD-MMM-YYYY" );
- strcpy ( modId , "----" );
- modType = -1;
- for (i=0;i<4;i++)
- strcpy ( record[i]," " );
- Warning = 0;
-}
-
-void CRevData::PDBASCIIDump ( pstr S, int N ) {
-// makes the ASCII PDB REVDATA line number N
-// from the class' data
-int i;
- if (N==0) sprintf ( S,"REVDAT %3i " ,modNum );
- else sprintf ( S,"REVDAT %3i%2i",modNum,N+1 );
- i = strlen(S);
- while (i<80)
- S[i++] = ' ';
- S[i] = char(0);
- Date11to9 ( modDate,&(S[13]) );
- strncpy ( &(S[23]),modId,5 );
- S[31] = char(modType+int('0'));
- for (i=0;i<4;i++)
- strncpy ( &(S[39+i*7]),record[i],6 );
-}
-
-void CRevData::MakeCIF ( PCMMCIFData CIF, int N ) {
-PCMMCIFLoop Loop;
-int RC,i,j;
-char DateCIF[20];
- RC = CIF->AddLoop ( CIFCAT_DATABASE_PDB_REV,Loop );
- if ((RC!=CIFRC_Ok) || (N==0)) {
- // the category was (re)created, privide tags
- Loop->AddLoopTag ( CIFTAG_NUM );
- Loop->AddLoopTag ( CIFTAG_DATE );
- Loop->AddLoopTag ( CIFTAG_REPLACES );
- Loop->AddLoopTag ( CIFTAG_MOD_TYPE );
- Loop->AddLoopTag ( CIFTAG_RCSB_RECORD_REVISED_1 );
- Loop->AddLoopTag ( CIFTAG_RCSB_RECORD_REVISED_2 );
- Loop->AddLoopTag ( CIFTAG_RCSB_RECORD_REVISED_3 );
- Loop->AddLoopTag ( CIFTAG_RCSB_RECORD_REVISED_4 );
- }
- Date11toCIF ( modDate,DateCIF );
- Loop->AddInteger ( modNum );
- Loop->AddString ( DateCIF );
- Loop->AddString ( modId );
- Loop->AddInteger ( modType );
- for (i=0;i<4;i++) {
- j = 0;
- while (record[i][j] && (record[i][j]==' ')) j++;
- if (record[i][j]) Loop->AddString ( record[i] );
- else Loop->AddString ( NULL );
- }
-
-}
-
-void CRevData::GetCIF ( PCMMCIFData CIF, int & Signal ) {
-PCMMCIFLoop Loop;
-int RC;
-pstr F;
-
- Loop = CIF->GetLoop ( CIFCAT_DATABASE_PDB_REV );
- if (!Loop) {
- Signal = -1;
- return;
- }
-
- RC = Loop->GetInteger ( modNum,CIFTAG_NUM,Signal,True );
- if (RC==CIFRC_WrongIndex) {
- Signal = -1;
- return;
- }
- if (RC==CIFRC_WrongFormat) {
- sprintf ( CIFErrorLocation,"loop %s.%s row %i",
- CIFCAT_DATABASE_PDB_REV,CIFTAG_NUM,Signal );
- Signal = -Error_UnrecognizedInteger-1;
- return;
- }
-
- F = Loop->GetString ( CIFTAG_DATE,Signal,RC );
- if ((!RC) && F) DateCIFto11 ( F,modDate );
- F = Loop->GetString ( CIFTAG_REPLACES,Signal,RC );
- if ((!RC) && F) strcpy ( modId,F );
- RC = Loop->GetInteger ( modType,CIFTAG_MOD_TYPE,Signal,True );
- if (RC==CIFRC_WrongFormat) {
- sprintf ( CIFErrorLocation,"loop %s.%s row %i",
- CIFCAT_DATABASE_PDB_REV,CIFTAG_MOD_TYPE,Signal );
- Signal = -Error_UnrecognizedInteger-1;
- return;
- }
-
- F = Loop->GetString ( CIFTAG_RCSB_RECORD_REVISED_1,Signal,RC );
- if ((!RC) && F) strcpy ( record[0],F );
- F = Loop->GetString ( CIFTAG_RCSB_RECORD_REVISED_2,Signal,RC );
- if ((!RC) && F) strcpy ( record[1],F );
- F = Loop->GetString ( CIFTAG_RCSB_RECORD_REVISED_3,Signal,RC );
- if ((!RC) && F) strcpy ( record[2],F );
- F = Loop->GetString ( CIFTAG_RCSB_RECORD_REVISED_4,Signal,RC );
- if ((!RC) && F) strcpy ( record[3],F );
-
- Loop->DeleteField ( CIFTAG_DATE ,Signal );
- Loop->DeleteField ( CIFTAG_REPLACES ,Signal );
- Loop->DeleteField ( CIFTAG_RCSB_RECORD_REVISED_1,Signal );
- Loop->DeleteField ( CIFTAG_RCSB_RECORD_REVISED_2,Signal );
- Loop->DeleteField ( CIFTAG_RCSB_RECORD_REVISED_3,Signal );
- Loop->DeleteField ( CIFTAG_RCSB_RECORD_REVISED_4,Signal );
-
- Signal++;
-
-}
-
-int CRevData::ConvertPDBASCII ( cpstr S ) {
-int i;
-pstr endptr;
-char N[20];
- Warning = 0;
- strncpy ( N,&(S[7]),3 );
- N[3] = char(0);
- modNum = mround(strtod(N,&endptr));
- if (endptr==N) Warning |= REVDAT_WARN_MODNUM;
- Date9to11 ( &(S[13]),modDate );
- strncpy ( modId,&(S[23]),5 );
- modId[5] = char(0);
- modType = int(S[31]) - int('0');
- if (modType>9) Warning |= REVDAT_WARN_MODTYPE;
- for (i=0;i<4;i++) {
- strncpy ( record[i],&(S[39+i*7]),6 );
- record[i][6] = char(0);
- }
- return 0;
-}
-
-void CRevData::Copy ( PCContainerClass RevData ) {
-int i;
- modNum = PCRevData(RevData)->modNum;
- modType = PCRevData(RevData)->modType;
- strcpy ( modDate,PCRevData(RevData)->modDate );
- strcpy ( modId ,PCRevData(RevData)->modId );
- for (i=0;i<4;i++)
- strcpy ( record[i],PCRevData(RevData)->record[i] );
-}
-
-void CRevData::write ( RCFile f ) {
-int i;
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &modNum );
- f.WriteInt ( &modType );
- f.WriteWord ( &Warning );
- f.WriteTerLine ( modDate,False );
- f.WriteTerLine ( modId ,False );
- for (i=0;i<4;i++)
- f.WriteTerLine ( record[i],False );
-}
-
-void CRevData::read ( RCFile f ) {
-int i;
-byte Version;
- f.ReadByte ( &Version );
- f.ReadInt ( &modNum );
- f.ReadInt ( &modType );
- f.ReadWord ( &Warning );
- f.ReadTerLine ( modDate,False );
- f.ReadTerLine ( modId ,False );
- for (i=0;i<4;i++)
- f.ReadTerLine ( record[i],False );
-}
-
-MakeStreamFunctions(CRevData)
-
-
-
-// ================ CSupersede ===================
-
-CSupersede::CSupersede() : CContainerClass() {
- InitSupersede();
-}
-
-CSupersede::CSupersede ( cpstr S ) : CContainerClass() {
- InitSupersede();
- ConvertPDBASCII ( S );
-}
-
-CSupersede::CSupersede ( RPCStream Object ) : CContainerClass(Object) {
- InitSupersede();
-}
-
-CSupersede::~CSupersede() {}
-
-void CSupersede::InitSupersede() {
-int i;
- strcpy ( sprsdeDate,"DD-MMM-YYYY" );
- strcpy ( idCode, "----" );
- for (i=0;i<8;i++)
- strcpy ( sIdCode[i]," " );
-}
-
-void CSupersede::PDBASCIIDump ( pstr S, int N ) {
-// makes the ASCII PDB OBSLTE line number N
-// from the class' data
-int i;
- if (N==0) strcpy ( S,"SPRSDE " );
- else sprintf ( S,"SPRSDE %2i",N+1 );
- i = strlen(S);
- while (i<80)
- S[i++] = ' ';
- S[i] = char(0);
- if (N==0) {
- Date11to9 ( sprsdeDate,&(S[11]) );
- strncpy ( &(S[21]),idCode,4 );
- }
- for (i=0;i<8;i++)
- strncpy ( &(S[31+5*i]),sIdCode[i],4 );
-}
-
-void CSupersede::MakeCIF ( PCMMCIFData CIF, int ) {
-PCMMCIFLoop Loop;
-int RC,i,j;
-char DateCIF[20];
- RC = CIF->AddLoop ( CIFCAT_SPRSDE,Loop );
- if (RC!=CIFRC_Ok) {
- // the category was (re)created, privide tags
- Loop->AddLoopTag ( CIFTAG_ID );
- Loop->AddLoopTag ( CIFTAG_DATE );
- Loop->AddLoopTag ( CIFTAG_REPLACE_PDB_ID );
- Loop->AddLoopTag ( CIFTAG_PDB_ID );
- }
- Date11toCIF ( sprsdeDate,DateCIF );
- for (i=0;i<8;i++) {
- j = 0;
- while (sIdCode[i][j] && (sIdCode[i][j]==' ')) j++;
- if (sIdCode[i][j]) {
- Loop->AddString ( pstr("SPRSDE") );
- Loop->AddString ( DateCIF );
- Loop->AddString ( idCode );
- Loop->AddString ( sIdCode[i] );
- }
- }
-}
-
-int CSupersede::ConvertPDBASCII ( cpstr S ) {
-int i;
- if (S[9]==' ') {
- Date9to11 ( &(S[11]),sprsdeDate );
- strncpy ( idCode,&(S[21]),4 );
- idCode[4] = char(0);
- }
- for (i=0;i<8;i++) {
- strncpy ( sIdCode[i],&(S[31+i*5]),4 );
- sIdCode[i][4] = char(0);
- }
- return 0;
-}
-
-void CSupersede::GetCIF ( PCMMCIFData CIF, int & Signal ) {
-PCMMCIFLoop Loop;
-int i,RC;
-pstr F,FDate,FID;
-char DateCIF [20];
-char DateCIF0[20];
-IDCode idCode1;
- Loop = CIF->GetLoop ( CIFCAT_SPRSDE );
- if (!Loop) {
- Signal = -1; // signal to finish processing of this structure
- return;
- }
- i = 0;
- do {
- F = Loop->GetString ( CIFTAG_ID,Signal,RC );
- if (RC) {
- if (i==0)
- Signal = -1;
- return;
- }
- if (F) {
- if (!strcmp(F,"SPRSDE")) {
- FDate = Loop->GetString ( CIFTAG_DATE,Signal,RC );
- if ((!RC) && FDate)
- strncpy ( DateCIF,FDate,15 );
- else strcpy ( DateCIF,"YYYY-MMM-DD" );
- FID = Loop->GetString ( CIFTAG_REPLACE_PDB_ID,Signal,RC );
- if ((!RC) && FID)
- strncpy ( idCode1,FID,sizeof(IDCode)-1 );
- else idCode1[0] = char(0);
- if (i==0) {
- DateCIFto11 ( DateCIF,sprsdeDate );
- DateCIF[11] = char(0);
- strcpy ( idCode ,idCode1 );
- strcpy ( DateCIF0,DateCIF );
- } else if ((strcmp(DateCIF0,DateCIF)) ||
- (strcmp(idCode,idCode1)))
- return;
- FID = Loop->GetString ( CIFTAG_PDB_ID,Signal,RC );
- if ((!RC) && FID)
- strncpy ( sIdCode[i],FID,sizeof(IDCode)-1 );
- else sIdCode[i][0] = char(0);
- Loop->DeleteField ( CIFTAG_ID ,Signal );
- Loop->DeleteField ( CIFTAG_DATE ,Signal );
- Loop->DeleteField ( CIFTAG_REPLACE_PDB_ID,Signal );
- Loop->DeleteField ( CIFTAG_PDB_ID ,Signal );
- i++;
- }
- }
- Signal++;
- } while (i<8);
-}
-
-void CSupersede::Copy ( PCContainerClass Supersede ) {
-int i;
- strcpy ( sprsdeDate,PCSupersede(Supersede)->sprsdeDate );
- strcpy ( idCode ,PCSupersede(Supersede)->idCode );
- for (i=0;i<8;i++)
- strcpy ( sIdCode[i],PCSupersede(Supersede)->sIdCode[i] );
-}
-
-void CSupersede::write ( RCFile f ) {
-int i;
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteTerLine ( sprsdeDate,False );
- f.WriteTerLine ( idCode ,False );
- for (i=0;i<8;i++)
- f.WriteTerLine ( sIdCode[i],False );
-}
-
-void CSupersede::read ( RCFile f ) {
-int i;
-byte Version;
- f.ReadByte ( &Version );
- f.ReadTerLine ( sprsdeDate,False );
- f.ReadTerLine ( idCode ,False );
- for (i=0;i<8;i++)
- f.ReadTerLine ( sIdCode[i],False );
-}
-
-MakeStreamFunctions(CSupersede)
-
-
-// =================== CJournal ======================
-
-CJournal::CJournal() : CContString() {
- InitJournal();
-}
-
-CJournal::CJournal ( cpstr S ) : CContString() {
- InitJournal();
- ConvertPDBASCII ( S );
-}
-
-CJournal::CJournal ( RPCStream Object ) : CContString(Object) {
- InitJournal();
-}
-
-CJournal::~CJournal() {}
-
-void CJournal::InitJournal() {
- CreateCopy ( CIFCategory,CIFCAT_CITATION );
- CreateCopy ( CIFTag ,CIFTAG_TEXT );
-}
-
-int CJournal::ConvertPDBASCII ( cpstr S ) {
- if (strlen(S)>10)
- CreateCopy ( Line,&(S[10]) );
- else CreateCopy ( Line,pstr(" ") );
- return 0;
-}
-
-void CJournal::PDBASCIIDump ( pstr S, int ) {
- strcpy ( S,"JRNL " );
- strcat ( S,Line );
-}
-
-void CJournal::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- CContString::write ( f );
-}
-
-void CJournal::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- CContString::read ( f );
-}
-
-MakeStreamFunctions(CJournal)
-
-
-
-// =================== CRemark ======================
-
-CRemark::CRemark() : CContainerClass() {
- InitRemark();
-}
-
-CRemark::CRemark ( cpstr S ) : CContainerClass() {
- InitRemark();
- ConvertPDBASCII ( S );
-}
-
-CRemark::CRemark ( RPCStream Object ) : CContainerClass(Object) {
- InitRemark();
-}
-
-CRemark::~CRemark() {
- if (Remark) delete[] Remark;
-}
-
-void CRemark::InitRemark() {
- remarkNum = 0;
- Remark = NULL;
-}
-
-int CRemark::ConvertPDBASCII ( cpstr S ) {
-int i;
- GetInteger ( remarkNum,&(S[7]),3 );
- if (remarkNum==MinInt4) CreateCopy ( Remark,S );
- else if (strlen(S)>11) CreateCopy ( Remark,&(S[11]) );
- else CreateCopy ( Remark,pstr(" ") );
- i = strlen(Remark)-1;
- while ((i>0) && (Remark[i]==' ')) i--;
- Remark[i+1] = char(0);
- return 0;
-}
-
-void CRemark::PDBASCIIDump ( pstr S, int ) {
- if (remarkNum==MinInt4)
- strcpy ( S,Remark );
- else {
- strcpy ( S,"REMARK" );
- PadSpaces ( S,80 );
- PutInteger ( &(S[7]) ,remarkNum,3 );
- strncpy ( &(S[11]),Remark,IMin(68,strlen(Remark)) );
- }
-}
-
-void CRemark::MakeCIF ( PCMMCIFData CIF, int N ) {
-PCMMCIFLoop Loop;
-int RC;
- RC = CIF->AddLoop ( CIFCAT_NDB_DATABASE_REMARK,Loop );
- if ((RC!=CIFRC_Ok) || (N==0)) {
- // the category was (re)created, privide tags
- Loop->AddLoopTag ( CIFTAG_ID );
- Loop->AddLoopTag ( CIFTAG_TEXT );
- }
- if (remarkNum==MinInt4) Loop->AddString ( NULL );
- else Loop->AddInteger ( remarkNum );
- Loop->AddString ( Remark );
-}
-
-void CRemark::GetCIF ( PCMMCIFData CIF, int & Signal ) {
-PCMMCIFLoop Loop;
-int RC;
-
- Loop = CIF->GetLoop ( CIFCAT_NDB_DATABASE_REMARK );
- if (!Loop) {
- Signal = -1;
- return;
- }
- if (Signal>=Loop->GetLoopLength() ) {
- Signal = -1;
- return;
- }
-
- RC = Loop->GetInteger ( remarkNum,CIFTAG_ID,Signal,True );
- if (RC==CIFRC_WrongFormat) {
- sprintf ( CIFErrorLocation,"loop %s.%s row %i",
- CIFCAT_NDB_DATABASE_REMARK,CIFTAG_ID,Signal );
- Signal = -Error_UnrecognizedInteger-1;
- return;
- } else if (RC)
- remarkNum = MinInt4;
- Loop->GetString ( Remark,CIFTAG_TEXT,Signal,True );
-
- Signal++;
-
-}
-
-void CRemark::Copy ( PCContainerClass RemarkClass ) {
- remarkNum = PCRemark(RemarkClass)->remarkNum;
- CreateCopy ( Remark,PCRemark(RemarkClass)->Remark );
-}
-
-void CRemark::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &remarkNum );
- f.CreateWrite ( Remark );
-}
-
-void CRemark::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- f.ReadInt ( &remarkNum );
- f.CreateRead ( Remark );
-}
-
-MakeStreamFunctions(CRemark)
-
-
-// ================= CBiomolecule =====================
-
-#define R350_ERRBIOMT (-3)
-#define R350_ERROR (-2)
-#define R350_END (-1)
-#define R350_NONE 0
-#define R350_BIOMOLECULE 1
-#define R350_CHAINS 2
-#define R350_BIOMT 3
-
-void getRemarkKey ( RPCRemark rem, int & lkey ) {
- if (rem) {
- if (rem->remarkNum!=350) lkey = R350_END;
- else if (rem->Remark) {
- if (strcasestr(rem->Remark,"BIOMOLECULE:"))
- lkey = R350_BIOMOLECULE;
- else if (strcasestr(rem->Remark,"CHAINS:"))
- lkey = R350_CHAINS;
- else if (strcasestr(rem->Remark,"BIOMT1") ||
- strcasestr(rem->Remark,"BIOMT2") ||
- strcasestr(rem->Remark,"BIOMT3"))
- lkey = R350_BIOMT;
- else
- lkey = R350_NONE;
- }
- }
-}
-
-int lookupRemarks ( int & i, RPCRemark rem,
- RCTitleContainer Remark ) {
-int l,lkey;
-
- l = Remark.Length();
- lkey = R350_NONE;
- while ((i<l) && (lkey==R350_NONE)) {
- getRemarkKey ( rem,lkey );
- if (lkey==R350_NONE) {
- i++;
- rem = (PCRemark)Remark.GetContainerClass ( i );
- }
- }
-
- return lkey;
-
-}
-
-
-
-CBMApply::CBMApply() : CStream() {
- InitBMApply();
-}
-
-CBMApply::CBMApply ( RPCStream Object ) : CStream ( Object ) {
- InitBMApply();
-}
-
-CBMApply::~CBMApply() {
- FreeMemory();
-}
-
-void CBMApply::InitBMApply() {
- chain = NULL;
- nChains = 0;
- tm = NULL;
- nMatrices = 0;
-}
-
-void CBMApply::FreeMemory() {
- if (chain) delete[] chain;
- if (tm) delete[] tm;
- chain = NULL;
- nChains = 0;
- tm = NULL;
- nMatrices = 0;
-}
-
-int CBMApply::addChains ( int & i, RPCRemark rem,
- RCTitleContainer Remark ) {
-PChainID ch1;
-pstr p;
-int l,lkey,nAdd,j;
-
- l = Remark.Length();
- lkey = R350_NONE;
-
- while ((i<l) && (lkey==R350_NONE)) {
-
- p = strcasestr ( rem->Remark,"CHAINS:" );
- if (p) p += 7;
- else {
- p = rem->Remark;
- while (*p==' ') p++;
- if ((p[1]!=',') && (p[1]!=' ')) p = NULL;
- }
-
- if (p) {
- nAdd = strlen(p)/2 + 3;
- ch1 = chain;
- chain = new ChainID[nChains+nAdd];
- for (j=0;j<nChains;j++)
- strcpy ( chain[j],ch1[j] );
- if (ch1) delete[] ch1;
-
- while (*p) {
- while ((*p==' ') || (*p==',')) p++;
- if (*p) {
- if ((p[1]==',') || (p[1]==' ') || (p[1]==char(0))) {
- chain[nChains][0] = *p;
- chain[nChains][1] = char(0);
- nChains++;
- p++;
- } else
- break;
- }
- }
- }
-
- do {
- i++;
- if (i<l) {
- rem = (PCRemark)Remark.GetContainerClass ( i );
- if (rem) {
- if (rem->remarkNum!=350) lkey = R350_END;
- else getRemarkKey ( rem,lkey );
- }
- } else
- lkey = R350_END;
- } while ((!rem) && (lkey==R350_NONE));
-
- }
-
- return lkey;
-
-}
-
-int getBIOMT ( RPCRemark rem, int biomtNo, mat44 & t,
- RCTitleContainer Remark, int & i ) {
-char PN[20];
-pstr p1,p2;
-int l,j,lkey;
-
- sprintf ( PN,"BIOMT%1i",biomtNo );
- p1 = strcasestr ( rem->Remark,PN );
- if (!p1) return R350_ERRBIOMT;
-
- p1 += 6;
- while (*p1==' ') p1++;
- while (*p1 && (*p1!=' ')) p1++;
-
- l = biomtNo - 1;
- t[l][0] = strtod ( p1,&p2 );
- if (p1==p2) return R350_ERRBIOMT;
- t[l][1] = strtod ( p2,&p1 );
- if (p1==p2) return R350_ERRBIOMT;
- t[l][2] = strtod ( p1,&p2 );
- if (p1==p2) return R350_ERRBIOMT;
- t[l][3] = strtod ( p2,&p1 );
- if (p1==p2) return R350_ERRBIOMT;
-
- if (biomtNo==3) {
- for (j=0;j<3;j++)
- t[3][j] = 0.0;
- t[3][3] = 1.0;
- }
-
- l = Remark.Length();
- lkey = R350_BIOMT;
- do {
- i++;
- if (i<l) {
- rem = (PCRemark)Remark.GetContainerClass ( i );
- if (rem) {
- if (rem->remarkNum!=350) lkey = R350_END;
- else getRemarkKey ( rem,lkey );
- }
- } else
- lkey = R350_END;
- } while ((lkey==R350_NONE) || ((!rem) && (lkey==R350_BIOMT)));
-
- return lkey;
-
-}
-
-int CBMApply::addMatrices ( int & i, RPCRemark rem,
- RCTitleContainer Remark ) {
-pmat44 tm1;
-int l,lkey,j,k1,k2,nAlloc;
-
- l = Remark.Length();
- lkey = R350_BIOMT;
- nAlloc = nMatrices;
-
- while ((i<l) && (lkey==R350_BIOMT)) {
-
- if (nMatrices>=nAlloc) {
- nAlloc = nMatrices + 10;
- tm1 = tm;
- tm = new mat44[nAlloc];
- for (j=0;j<nMatrices;j++)
- for (k1=0;k1<4;k1++)
- for (k2=0;k2<4;k2++)
- tm[j][k1][k2] = tm1[j][k1][k2];
- if (tm1) delete[] tm1;
- }
-
- lkey = getBIOMT ( rem,1,tm[nMatrices],Remark,i );
- if (lkey==R350_BIOMT)
- lkey = getBIOMT ( rem,2,tm[nMatrices],Remark,i );
- if (lkey==R350_BIOMT)
- lkey = getBIOMT ( rem,3,tm[nMatrices],Remark,i );
- nMatrices++;
-
- }
-
- return lkey;
-
-}
-
-void CBMApply::Copy ( PCBMApply BMA ) {
-// if BMA is NULL, then empties the class
-int i,j,k;
-
- FreeMemory();
-
- if (BMA) {
-
- nChains = BMA->nChains;
- if (nChains>0) {
- chain = new ChainID[nChains];
- for (i=0;i<nChains;i++)
- strcpy ( chain[i],BMA->chain[i] );
- }
-
- nMatrices = BMA->nMatrices;
- if (nMatrices>0) {
- tm = new mat44[nMatrices];
- for (i=0;i<nMatrices;i++)
- for (j=0;j<4;j++)
- for (k=0;k<4;k++)
- tm[i][j][k] = BMA->tm[i][j][k];
- }
- }
-
-}
-
-void CBMApply::write ( RCFile f ) {
-int i,j,k;
- f.WriteInt ( &nChains );
- for (i=0;i<nChains;i++)
- f.WriteTerLine ( chain[i],False );
- f.WriteInt ( &nMatrices );
- for (i=0;i<nMatrices;i++)
- for (j=0;j<3;j++)
- for (k=0;k<4;k++)
- f.WriteReal ( &(tm[i][j][k]) );
-}
-
-void CBMApply::read ( RCFile f ) {
-int i,j,k;
- FreeMemory();
- f.ReadInt ( &nChains );
- if (nChains>0) {
- chain = new ChainID[nChains];
- for (i=0;i<nChains;i++)
- f.ReadTerLine ( chain[i],False );
- }
- f.ReadInt ( &nMatrices );
- if (nMatrices>0) {
- tm = new mat44[nMatrices];
- for (i=0;i<nMatrices;i++) {
- for (j=0;j<3;j++) {
- for (k=0;k<4;k++)
- f.ReadReal ( &(tm[i][j][k]) );
- tm[i][3][j] = 0.0;
- }
- tm[i][3][3] = 1.0;
- }
- }
-}
-
-MakeStreamFunctions(CBMApply)
-
-
-CBiomolecule::CBiomolecule() : CStream() {
- InitBiomolecule();
-}
-
-CBiomolecule::CBiomolecule ( RPCStream Object )
- : CStream ( Object ) {
- InitBiomolecule();
-}
-
-CBiomolecule::~CBiomolecule() {
- FreeMemory();
-}
-
-void CBiomolecule::InitBiomolecule() {
- BMApply = NULL;
- nBMAs = 0;
-}
-
-void CBiomolecule::FreeMemory() {
-int i;
- if (BMApply) {
- for (i=0;i<nBMAs;i++)
- if (BMApply[i]) delete BMApply[i];
- delete[] BMApply;
- BMApply = NULL;
- }
- nBMAs = 0;
-}
-
-
-PCBMApply CBiomolecule::addBMApply() {
-PPCBMApply BMA1;
-int i;
- BMA1 = BMApply;
- BMApply = new PCBMApply[nBMAs+1];
- for (i=0;i<nBMAs;i++)
- BMApply[i] = BMA1[i];
- if (BMA1) delete[] BMA1;
- BMApply[nBMAs] = new CBMApply();
- nBMAs++;
- return BMApply[nBMAs-1];
-}
-
-int CBiomolecule::Size() {
-int i,k;
- k = 0;
- for (i=0;i<nBMAs;i++)
- k += BMApply[i]->nChains*BMApply[i]->nMatrices;
- return k;
-}
-
-Boolean CBiomolecule::checkComposition ( PChainID chID, ivector occ,
- ivector wocc, int n ) {
-// chID[n] is list of chain IDs
-// occ[n] is list of chain occurencies
-// wocc[n] is working array
-int i,j,k,k1;
-Boolean cmp;
-
- for (i=0;i<n;i++)
- wocc[i] = 0;
-
- cmp = True;
-
- for (i=0;(i<nBMAs) && cmp;i++)
- for (j=0;(j<BMApply[i]->nChains) && cmp;j++) {
- k1 = -1;
- for (k=0;(k<n) && (k1<0);k++)
- if (!strcmp(chID[k],BMApply[i]->chain[j]))
- k1 = k;
- if (k1<0) cmp = False; // chain not found in the list
- else wocc[k1] += BMApply[i]->nMatrices;
- }
-
- for (i=0;(i<n) && cmp;i++)
- if (occ[i]!=wocc[i]) cmp = False;
-
- return cmp;
-
-}
-
-void CBiomolecule::Copy ( PCBiomolecule B ) {
-// if B is NULL, then empties the class
-int i;
-
- FreeMemory();
-
- if (B) {
-
- nBMAs = B->nBMAs;
- if (nBMAs>0) {
- BMApply = new PCBMApply[nBMAs];
- for (i=0;i<nBMAs;i++)
- if (B->BMApply[i]) {
- BMApply[i] = new CBMApply();
- BMApply[i]->Copy ( B->BMApply[i] );
- } else
- BMApply[i] = NULL;
- }
-
- }
-
-}
-
-void CBiomolecule::write ( RCFile f ) {
-int i;
- f.WriteInt ( &nBMAs );
- for (i=0;i<nBMAs;i++)
- StreamWrite ( f,BMApply[i] );
-}
-
-void CBiomolecule::read ( RCFile f ) {
-int i;
- FreeMemory();
- f.ReadInt ( &nBMAs );
- if (nBMAs>0) {
- BMApply = new PCBMApply[nBMAs];
- for (i=0;i<nBMAs;i++) {
- BMApply[i] = NULL;
- StreamRead ( f,BMApply[i] );
- }
- }
-}
-
-MakeStreamFunctions(CBiomolecule)
-
-
-// ===================== CMMDBFTitle =======================
-
-CMMDBTitle::CMMDBTitle() : CStream() {
- Init();
-}
-
-CMMDBTitle::CMMDBTitle ( RPCStream Object ) : CStream(Object) {
- Init();
-}
-
-void CMMDBTitle::Init() {
-
- // Header data
- classification = NULL;
- depDate[0] = char(0);
- idCode [0] = char(0);
- resolution = -2.0;
- col73 = False;
-
- Biomolecule = NULL;
- nBiomolecules = 0;
-
-}
-
-CMMDBTitle::~CMMDBTitle() {
- FreeMemory ( False );
-}
-
-void CMMDBTitle::FreeMemory ( Boolean keepBiomolecules ) {
-
- if (classification) delete[] classification;
- classification = NULL;
- resolution = -2.0;
-
- ObsData .FreeContainer();
- Title .FreeContainer();
- CAVEAT .FreeContainer();
- Compound .FreeContainer();
- Source .FreeContainer();
- KeyWords .Delete ();
- ExpData .FreeContainer();
- MdlType .FreeContainer();
- Author .FreeContainer();
- RevData .FreeContainer();
- Supersede.FreeContainer();
- Journal .FreeContainer();
- Remark .FreeContainer();
-
- col73 = False;
-
- if (!keepBiomolecules)
- FreeBiomolecules();
-
-}
-
-void CMMDBTitle::FreeBiomolecules() {
-int i;
- if (Biomolecule) {
- for (i=0;i<nBiomolecules;i++)
- if (Biomolecule[i]) delete Biomolecule[i];
- delete[] Biomolecule;
- Biomolecule = NULL;
- }
- nBiomolecules = 0;
-}
-
-
-void CMMDBTitle::SetHeader ( cpstr Classification,
- cpstr DepDate,
- cpstr IDCode ) {
-// fills the PDB file header
- CreateCopy ( classification ,Classification );
- strncpy ( depDate,DepDate,sizeof(depDate) );
- strncpy ( idCode ,IDCode ,sizeof(idCode) );
- depDate[sizeof(depDate)-1] = char(0);
- idCode [sizeof(idCode) -1] = char(0);
-}
-
-int CMMDBTitle::ConvertPDBString ( pstr PDBString ) {
-// Interprets the ASCII PDB line belonging to the title section
-// and fills the corresponding fields.
-// Returns zero if the line was converted, otherwise returns a
-// non-negative value of Error_XXXX.
-// PDBString must be not shorter than 81 characters.
-int i;
-char c;
-PCContainerClass ContainerClass;
-
- // pad input line with spaces, if necessary
- PadSpaces ( PDBString,80 );
-
- if (!strncmp(PDBString,"HEADER",6)) {
-
- i = 49;
- while ((i>=10) && (PDBString[i]==' ')) i--;
- i++;
- c = PDBString[i];
- PDBString[i] = char(0);
- CreateCopy ( classification,&(PDBString[10]) );
- PDBString[i] = c;
-
- Date9to11 ( &(PDBString[50]),depDate );
-
- strncpy ( idCode,&(PDBString[62]),4 );
- idCode[4] = char(0);
-
- } else if (!strncmp(PDBString,"OBSLTE",6)) {
-
- ContainerClass = new CObsLine(PDBString);
- ObsData.AddData ( ContainerClass );
-
- } else if (!strncmp(PDBString,"TITLE ",6)) {
-
- ContainerClass = new CTitleLine(PDBString);
- Title.AddData ( ContainerClass );
-
- } else if (!strncmp(PDBString,"CAVEAT",6)) {
-
- ContainerClass = new CCaveat(PDBString);
- CAVEAT.AddData ( ContainerClass );
-
- } else if (!strncmp(PDBString,"COMPND",6)) {
-
- ContainerClass = new CCompound(PDBString);
- Compound.AddData ( ContainerClass );
-
- } else if (!strncmp(PDBString,"SOURCE",6)) {
-
- ContainerClass = new CSource(PDBString);
- Source.AddData ( ContainerClass );
-
- } else if (!strncmp(PDBString,"KEYWDS",6)) {
-
- KeyWords.ConvertPDBASCII ( PDBString );
-
- } else if (!strncmp(PDBString,"EXPDTA",6)) {
-
- ContainerClass = new CExpData(PDBString);
- ExpData.AddData ( ContainerClass );
-
- } else if (!strncmp(PDBString,"MDLTYPE",6)) {
-
- ContainerClass = new CMdlType(PDBString);
- MdlType.AddData ( ContainerClass );
-
- } else if (!strncmp(PDBString,"AUTHOR",6)) {
-
- ContainerClass = new CAuthor(PDBString);
- Author.AddData ( ContainerClass );
-
- } else if (!strncmp(PDBString,"REVDAT",6)) {
-
- ContainerClass = new CRevData(PDBString);
- RevData.AddData ( ContainerClass );
-
- } else if (!strncmp(PDBString,"SPRSDE",6)) {
-
- ContainerClass = new CSupersede(PDBString);
- Supersede.AddData ( ContainerClass );
-
- } else if (!strncmp(PDBString,"JRNL ",6)) {
-
- ContainerClass = new CJournal(PDBString);
- Journal.AddData ( ContainerClass );
-
- } else if (!strncmp(PDBString,"REMARK",6)) {
-
- ContainerClass = new CRemark(PDBString);
- Remark.AddData ( ContainerClass );
-
- } else
- return Error_WrongSection;
-
- // check for ID code in columns 73-80
-
- if (!col73) {
- if (('0'<=idCode[0]) && (idCode[0]<='9')) {
- if (!strncasecmp(idCode,&(PDBString[72]),4))
- col73 = True;
- }
- }
-
- return 0;
-
-}
-
-PCTitleContainer CMMDBTitle::GetRemarks() {
- return &Remark;
-}
-
-PCTitleContainer CMMDBTitle::GetJournal() {
- return &Journal;
-}
-
-realtype CMMDBTitle::GetResolution() {
-// returns -1.0 if there is no resolution record in the file
-PCRemark rem;
-pstr p,eptr;
-int i,l;
- if (resolution>-1.5) return resolution;
- l = Remark.Length();
- for (i=0;(i<l) && (resolution<-1.5);i++) {
- rem = (PCRemark)Remark.GetContainerClass ( i );
- if (rem) {
- if (rem->remarkNum==2) {
- if (rem->Remark) {
- p = strcasestr ( rem->Remark,"RESOLUTION" );
- if (p) {
- while ((*p) && (*p!=' ')) p++;
- if (*p) {
- resolution = strtod ( p,&eptr );
- if ((resolution<0.0) || (eptr==p))
- resolution = -1.0;
- }
- }
- }
- } else if (rem->remarkNum>2)
- resolution = -1.0;
- }
- }
- return resolution;
-}
-
-PCBiomolecule CMMDBTitle::addBiomolecule() {
-PPCBiomolecule BM1;
-int i;
- BM1 = Biomolecule;
- Biomolecule = new PCBiomolecule[nBiomolecules+1];
- for (i=0;i<nBiomolecules;i++)
- Biomolecule[i] = BM1[i];
- if (BM1) delete[] BM1;
- Biomolecule[nBiomolecules] = new CBiomolecule();
- nBiomolecules++;
- return Biomolecule[nBiomolecules-1];
-}
-
-int CMMDBTitle::ParseBiomolecules() {
-PCRemark rem;
-PCBiomolecule BMol;
-PCBMApply BMA;
-int i,l, lkey;
-
- FreeBiomolecules();
-
- l = Remark.Length();
- i = 0;
- lkey = 0;
- while ((i<l) && (!lkey)) {
- rem = (PCRemark)Remark.GetContainerClass ( i );
- if (rem) {
- if (rem->remarkNum==350) lkey = 1;
- else if (rem->remarkNum>350) lkey = -1;
- }
- if (!lkey) i++;
- }
-
- BMol = NULL;
- BMA = NULL;
-
- while (lkey>0) {
-
- rem = (PCRemark)Remark.GetContainerClass ( i );
- lkey = lookupRemarks ( i,rem,Remark );
-
- switch (lkey) {
- case R350_BIOMOLECULE : BMol = addBiomolecule();
- i++;
- break;
- case R350_CHAINS : if (BMol) {
- BMA = BMol->addBMApply();
- while (lkey==R350_CHAINS)
- lkey = BMA->addChains(i,rem,Remark);
- } else
- lkey = R350_ERROR;
- break;
- case R350_BIOMT : if (BMA)
- lkey = BMA->addMatrices(i,rem,Remark);
- else
- lkey = R350_ERROR;
- break;
- default : i++;
- }
-
- }
-
- if (lkey<=R350_ERROR) {
- FreeBiomolecules();
- return lkey;
- }
-
- return nBiomolecules;
-
-}
-
-int CMMDBTitle::GetNofBiomolecules() {
- return nBiomolecules;
-}
-
-void CMMDBTitle::GetBiomolecules ( PPCBiomolecule & BM, int & nBMs ) {
- BM = Biomolecule;
- nBMs = nBiomolecules;
-}
-
-PCBiomolecule CMMDBTitle::GetBiomolecule ( int bmNo ) { // bmno=0,1,..
- if ((0<=bmNo) && (bmNo<nBiomolecules))
- return Biomolecule[bmNo];
- return NULL;
-}
-
-
-int CMMDBTitle::GetCIF ( PCMMCIFData CIF ) {
-pstr S;
-int RC;
-
- S = NULL;
- CIF->GetDataName ( S,True );
- if (!S) CIF->GetString ( S,CIFCAT_DATABASE,CIFTAG_ENTRY_ID,True );
- if (!S) CIF->GetString ( S,CIFCAT_DATABASE,CIFTAG_CODE_NDB,True );
- if (!S) CIF->GetString ( S,CIFCAT_DATABASE,CIFTAG_CODE_PDB,True );
- if (S) {
- strncpy ( idCode,S,sizeof(IDCode)-1 );
- idCode[sizeof(IDCode)-1] = char(0);
- delete[] S;
- S = NULL;
- CIF->DeleteField ( CIFCAT_DATABASE,CIFTAG_ENTRY_ID );
- CIF->DeleteField ( CIFCAT_DATABASE,CIFTAG_CODE_NDB );
- CIF->DeleteField ( CIFCAT_DATABASE,CIFTAG_CODE_PDB );
- } else
- idCode[0] = char(0);
- CIF->GetString ( classification,CIFCAT_STRUCT_KEYWORDS,
- CIFTAG_NDB_KEYWORDS,True );
- CIF->GetString ( S,CIFCAT_DATABASE,CIFTAG_DATE_ORIGINAL,True );
- if (S) {
- DateCIFto11 ( S,depDate );
- delete[] S;
- S = NULL;
- } else
- depDate[0] = char(0);
-
- ObsData .GetCIF ( CIF,ClassID_ObsLine );
- Title .GetCIF ( CIF,ClassID_TitleLine );
- CAVEAT .GetCIF ( CIF,ClassID_CAVEAT );
- Compound.GetCIF ( CIF,ClassID_Compound );
- Source .GetCIF ( CIF,ClassID_Source );
- KeyWords.GetCIF ( CIF );
- ExpData .GetCIF ( CIF,ClassID_ExpData );
- MdlType .GetCIF ( CIF,ClassID_MdlType );
- Author .GetCIF ( CIF,ClassID_Author );
- RC = RevData.GetCIF ( CIF,ClassID_RevData );
- if (!RC) {
- Supersede.GetCIF ( CIF,ClassID_Supersede );
- Journal .GetCIF ( CIF,ClassID_Journal );
- RC = Remark .GetCIF ( CIF,ClassID_Remark );
- }
- return RC;
-
-}
-
-void CMMDBTitle::MakePDBHeaderString ( pstr PDBString ) {
-// makes the ASCII PDB HEADER line from the class' data
-int i;
-
- if (classification) {
-
- strcpy ( PDBString,"HEADER " );
- strcat ( PDBString,classification );
- i = strlen(PDBString);
- while (i<80)
- PDBString[i++] = ' ';
- PDBString[IMin(i,80)] = char(0);
- Date11to9 ( depDate,&(PDBString[50]) );
- strncpy ( &(PDBString[62]),idCode,4 );
-
- } else
- strcpy ( PDBString,
- "HEADER XXXXXXXXXXXXXXXXXXXXXXXXXXXX XX-XXX-XX ----" );
-
-}
-
-pstr CMMDBTitle::GetStructureTitle ( pstr & S ) {
-// GetStructureTitle() returns the contents of TITLE record
-// unfolded into single line. If Title is missing, returns
-// contents of COMPND(:MOLECULE). If COMPND is missing, returns
-// HEADER. If Header is missing, returns PDB code. If no PDB
-// code is there, returns "Not available".
-PCTitleLine TLine;
-PCCompound CLine;
-pstr p;
-int i,cl,l;
-Boolean B;
-
- if (S) delete[] S;
- S = NULL;
-
- cl = Title.Length();
- if (cl>0) {
- l = 0;
- for (i=0;i<cl;i++) {
- TLine = PCTitleLine(Title.GetContainerClass(i));
- if (TLine) l += strlen_des(TLine->Line)+5;
- }
- S = new char[l];
- S[0] = char(0);
- for (i=0;i<cl;i++) {
- TLine = PCTitleLine(Title.GetContainerClass(i));
- if (TLine) {
- if (i>0) strcat ( S," " );
- strcat_des ( S,TLine->Line );
- }
- }
- } else {
- cl = Compound.Length();
- if (cl>0) {
- l = 0;
- p = NULL;
- B = True;
- for (i=0;(i<cl) && B;i++) {
- CLine = PCCompound(Compound.GetContainerClass(i));
- if (CLine) {
- if (!p) {
- p = strstr(CLine->Line,"MOLECULE:");
- if (p) l += strlen_des(&(p[9]))+5;
- } else {
- p = strstr(CLine->Line,"MOLECULE:");
- if (p)
- l += strlen_des(&(p[9]))+5;
- else {
- p = strchr(CLine->Line,':');
- if (!p) {
- l += strlen_des(CLine->Line)+5;
- p = CLine->Line;
- } else
- B = False;
- }
- }
- }
- }
- if (l>0) {
- S = new char[l];
- S[0] = char(0);
- p = NULL;
- B = True;
- for (i=0;(i<cl) && B;i++) {
- CLine = PCCompound(Compound.GetContainerClass(i));
- if (CLine) {
- if (!p) {
- p = strstr(CLine->Line,"MOLECULE:");
- if (p) strcat_des ( S,&(p[9]) );
- } else {
- p = strstr(CLine->Line,"MOLECULE:");
- if (p)
- strcat_des ( S,&(p[9]) );
- else {
- p = strchr(CLine->Line,':');
- if (!p) {
- strcat_des ( S,CLine->Line );
- p = CLine->Line;
- } else
- B = False;
- }
- }
- l = strlen(S)-1;
- if (S[l]==';') S[l] = char(0);
- }
- }
- } else {
- l = 0;
- for (i=0;i<cl;i++) {
- CLine = PCCompound(Compound.GetContainerClass(i));
- if (CLine) l += strlen_des(CLine->Line)+5;
- }
- S = new char[l];
- S[0] = char(0);
- for (i=0;i<cl;i++) {
- CLine = PCCompound(Compound.GetContainerClass(i));
- if (CLine) {
- if (i>0) strcat ( S," " );
- strcat_des ( S,CLine->Line );
- }
- }
- }
- } else if (classification)
- CreateCopy ( S,classification );
- else if (idCode[0])
- CreateCopy ( S,idCode );
- else
- CreateCopy ( S,pstr("Not available") );
- }
-
- if (!S[0]) CreateCopy ( S,pstr("Not available") );
-
- return S;
-
-}
-
-void CMMDBTitle::PDBASCIIDump ( RCFile f ) {
-char PDBString[100];
- if (classification) {
- MakePDBHeaderString ( PDBString );
- f.WriteLine ( PDBString );
- }
- ObsData .PDBASCIIDump ( f );
- Title .PDBASCIIDump ( f );
- CAVEAT .PDBASCIIDump ( f );
- Compound .PDBASCIIDump ( f );
- Source .PDBASCIIDump ( f );
- KeyWords .PDBASCIIDump ( f );
- ExpData .PDBASCIIDump ( f );
- MdlType .PDBASCIIDump ( f );
- Author .PDBASCIIDump ( f );
- RevData .PDBASCIIDump ( f );
- Supersede.PDBASCIIDump ( f );
- Journal .PDBASCIIDump ( f );
- Remark .PDBASCIIDump ( f );
-}
-
-
-void CMMDBTitle::MakeCIF ( PCMMCIFData CIF ) {
-char DateCIF[20];
-
- if (idCode[0]) {
- CIF->PutDataName ( idCode );
- CIF->PutString ( idCode, CIFCAT_DATABASE,CIFTAG_ENTRY_ID );
- CIF->PutString ( idCode, CIFCAT_DATABASE,CIFTAG_CODE_NDB );
- CIF->PutString ( idCode, CIFCAT_DATABASE,CIFTAG_CODE_PDB );
- } else {
- CIF->PutDataName ( pstr("") );
- CIF->PutString ( NULL, CIFCAT_DATABASE,CIFTAG_ENTRY_ID );
- CIF->PutString ( NULL, CIFCAT_DATABASE,CIFTAG_CODE_NDB );
- CIF->PutString ( NULL, CIFCAT_DATABASE,CIFTAG_CODE_PDB );
- }
- CIF->PutString ( classification, CIFCAT_STRUCT_KEYWORDS,
- CIFTAG_NDB_KEYWORDS );
- if (depDate[0]) {
- Date11toCIF ( depDate,DateCIF );
- CIF->PutString ( DateCIF,CIFCAT_DATABASE,CIFTAG_DATE_ORIGINAL );
- } else
- CIF->PutString ( NULL,CIFCAT_DATABASE,CIFTAG_DATE_ORIGINAL );
-
- ObsData .MakeCIF ( CIF );
- Title .MakeCIF ( CIF );
- CAVEAT .MakeCIF ( CIF );
- Compound .MakeCIF ( CIF );
- Source .MakeCIF ( CIF );
- KeyWords .MakeCIF ( CIF );
- ExpData .MakeCIF ( CIF );
- MdlType .MakeCIF ( CIF );
- Author .MakeCIF ( CIF );
- RevData .MakeCIF ( CIF );
- Supersede.MakeCIF ( CIF );
- Journal .MakeCIF ( CIF );
- Remark .MakeCIF ( CIF );
-
-}
-
-void CMMDBTitle::Copy ( PCMMDBTitle TS ) {
-int i;
-
- FreeBiomolecules();
-
- if (TS) {
-
- CreateCopy ( classification,TS->classification );
- strcpy ( depDate ,TS->depDate );
- strcpy ( idCode ,TS->idCode );
- resolution = TS->resolution;
-
- ObsData .Copy ( &(TS->ObsData) );
- Title .Copy ( &(TS->Title) );
- CAVEAT .Copy ( &(TS->CAVEAT) );
- Compound .Copy ( &(TS->Compound) );
- Source .Copy ( &(TS->Source) );
- KeyWords .Copy ( &(TS->KeyWords) );
- ExpData .Copy ( &(TS->ExpData) );
- MdlType .Copy ( &(TS->MdlType) );
- Author .Copy ( &(TS->Author) );
- RevData .Copy ( &(TS->RevData) );
- Supersede.Copy ( &(TS->Supersede) );
- Journal .Copy ( &(TS->Journal) );
- Remark .Copy ( &(TS->Remark) );
-
- nBiomolecules = TS->nBiomolecules;
- if (nBiomolecules>0) {
- Biomolecule = new PCBiomolecule[nBiomolecules];
- for (i=0;i<nBiomolecules;i++)
- if (TS->Biomolecule[i]) {
- Biomolecule[i] = new CBiomolecule();
- Biomolecule[i]->Copy ( TS->Biomolecule[i] );
- } else
- Biomolecule[i] = NULL;
- }
-
- } else {
-
- if (classification) delete[] classification;
- classification = NULL;
- resolution = -2.0;
- ObsData .FreeContainer();
- Title .FreeContainer();
- CAVEAT .FreeContainer();
- Compound .FreeContainer();
- Source .FreeContainer();
- KeyWords .Delete ();
- ExpData .FreeContainer();
- MdlType .FreeContainer();
- Author .FreeContainer();
- RevData .FreeContainer();
- Supersede.FreeContainer();
- Journal .FreeContainer();
- Remark .FreeContainer();
-
- }
-
-}
-
-void CMMDBTitle::TrimInput ( pstr PDBString ) {
- if (col73) {
- if (!strncasecmp(idCode,&(PDBString[72]),4))
- PDBString[72] = char(0);
- }
- PadSpaces ( PDBString,80 );
-}
-
-void CMMDBTitle::write ( RCFile f ) {
-// writes header to PDB binary file
-int i;
-byte Version=3;
-
- f.WriteByte ( &Version );
-
- // Header data
- f.CreateWrite ( classification );
- f.WriteTerLine ( depDate,False );
- f.WriteTerLine ( idCode ,False );
- f.WriteReal ( &resolution );
-
- ObsData .write ( f ); // Obsoletion data
- Title .write ( f ); // Title
- CAVEAT .write ( f ); // Error data
- Compound .write ( f ); // Compound
- Source .write ( f ); // Source
- KeyWords .write ( f ); // Key words
- ExpData .write ( f ); // Experimental data
- MdlType .write ( f ); // Model descriptions
- Author .write ( f ); // Author data
- RevData .write ( f ); // Revision data
- Supersede.write ( f ); // Supersede records
- Journal .write ( f ); // Journal records
- Remark .write ( f ); // Remarks
-
- f.WriteInt ( &nBiomolecules );
- for (i=0;i<nBiomolecules;i++)
- StreamWrite ( f,Biomolecule[i] );
-
-}
-
-void CMMDBTitle::read ( RCFile f ) {
-// reads header from PDB binary file
-int i;
-byte Version;
-
- f.ReadByte ( &Version );
-
- // Header data
- f.CreateRead ( classification );
- f.ReadTerLine ( depDate,False );
- f.ReadTerLine ( idCode ,False );
- if (Version>1)
- f.ReadReal ( &resolution );
- else
- resolution = -2.0;
-
- ObsData .read ( f ); // Obsoletion data
- Title .read ( f ); // Title
- CAVEAT .read ( f ); // Error data
- Compound .read ( f ); // Compound
- Source .read ( f ); // Source
- KeyWords .read ( f ); // Key words
- ExpData .read ( f ); // Experimental data
- if (Version>2)
- MdlType.read ( f ); // Model descriptions
- Author .read ( f ); // Author data
- RevData .read ( f ); // Revision data
- Supersede.read ( f ); // Supersede records
- Journal .read ( f ); // Journal records
- Remark .read ( f ); // Remarks
-
- FreeBiomolecules();
- if (Version>1) {
- f.ReadInt ( &nBiomolecules );
- if (nBiomolecules>0) {
- Biomolecule = new PCBiomolecule[nBiomolecules];
- for (i=0;i<nBiomolecules;i++) {
- Biomolecule[i] = NULL;
- StreamRead ( f,Biomolecule[i] );
- }
- }
- }
-
-}
-
-MakeStreamFunctions(CMMDBTitle)
-
-
-
-// ===================================================================
-
-/*
-void TestHeader() {
-PCMMDBTitle Hdr;
-char S[81],S1[81];
-
- Hdr = new CMMDBTitle();
-
- Hdr->SetHeader ( pstr("MUSCLE PROTEIN"),pstr("02-JUN-1993"),pstr("1MYS") );
- Hdr->MakePDBHeaderString ( S );
- printf ( "1234567890123456789012345678901234567890"
- "1234567890123456789012345678901234567890\n" );
- printf ( S );
- printf ( "\n" );
-
- strcpy ( S,
-// 1234567890123456789012345678901234567890123456789012345678901234567890
- "HEADER HYDROLASE (CARBOXYLIC ESTER) 07-APR-01 2PHI" );
-
- Hdr->ConvertPDBString ( S );
- Hdr->MakePDBHeaderString ( S1 );
- printf ( "1234567890123456789012345678901234567890"
- "1234567890123456789012345678901234567890\n" );
- printf ( S1 );
- printf ( "\n" );
-
- Hdr->SetHeader (
- pstr("MUSCLE PROTEIN;**A VERY LONG TITLE TEST;**ARBITRARY LENGTH"),
- pstr("02-JUN-1993"),pstr("1MYS") );
- Hdr->MakePDBHeaderString ( S );
- printf ( "1234567890123456789012345678901234567890"
- "1234567890123456789012345678901234567890\n" );
- printf ( S );
- printf ( "\n" );
-
- delete Hdr;
-
- printf ( " header deleted \n" );
-
-}
-
-void TestTitle() {
-// reads PDB title from file 'in.title'
-// and rewrites it into 'out.title' and 'abin.title'
-CFile f;
-char S[81];
-PCMMDBTitle Title;
-
- Title = new CMMDBTitle();
-
- f.assign ( pstr("in.title"),True );
- if (f.reset()) {
- while (!f.FileEnd()) {
- f.ReadLine ( S,sizeof(S) );
- Title->ConvertPDBString ( S );
- }
- f.shut();
- } else {
- printf ( " Can't open input file 'in.title' \n" );
- delete Title;
- return;
- }
-
- f.assign ( pstr("out.title"),True );
- if (f.rewrite()) {
- Title->PDBASCIIDump ( f );
- f.shut();
- } else {
- printf ( " Can't open output file 'out.title' \n" );
- delete Title;
- return;
- }
-
-
-
- f.assign ( pstr("mmdb.title.bin"),False );
- if (f.rewrite()) {
- Title->write ( f );
- f.shut();
- } else {
- printf ( " Can't open binary file for writing.\n" );
- delete Title;
- return;
- }
-
- delete Title;
- printf ( " Title deleted.\n" );
-
- Title = new CMMDBTitle();
- if (f.reset()) {
- Title->read ( f );
- f.shut();
- } else {
- printf ( " Can't open binary file for reading.\n" );
- delete Title;
- return;
- }
-
- f.assign ( pstr("abin.title"),True );
- if (f.rewrite()) {
- Title->PDBASCIIDump ( f );
- f.shut();
- } else {
- printf ( " Can't open output file 'abin.title' \n" );
- }
-
- delete Title;
-
-}
-
-
-*/
diff --git a/mmdb/mmdb_title.h b/mmdb/mmdb_title.h
deleted file mode 100755
index 17a3b78..0000000
--- a/mmdb/mmdb_title.h
+++ /dev/null
@@ -1,734 +0,0 @@
-// $Id: mmdb_title.h,v 1.22 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 23.06.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_Title <interface>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CTitleContainer (container of title classes)
-// ~~~~~~~~~ CObsLine
-// CTitleLine
-// CCaveat
-// CCompound
-// CSource
-// CKeyWords
-// CExpData
-// CMdlType
-// CAuthor
-// CRevData
-// CSupersede
-// CJournal
-// CRemark
-// CBiomolecule
-// CMMDBTitle ( MMDB title section )
-//
-// (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-#ifndef __MMDB_Title__
-#define __MMDB_Title__
-
-
-#ifndef __Stream__
-#include "stream_.h"
-#endif
-
-#ifndef __MMDB_Defs__
-#include "mmdb_defs.h"
-#endif
-
-#ifndef __MMDB_Utils__
-#include "mmdb_utils.h"
-#endif
-
-#ifndef __MMDB_MMCIF__
-#include "mmdb_mmcif.h"
-#endif
-
-
-// ==================== CTitleContainer ======================
-
-DefineClass(CTitleContainer);
-DefineStreamFunctions(CTitleContainer);
-
-class CTitleContainer : public CClassContainer {
-
- public :
-
- CTitleContainer () : CClassContainer() {}
- CTitleContainer ( RPCStream Object )
- : CClassContainer ( Object ) {}
- ~CTitleContainer () {}
-
- PCContainerClass MakeContainerClass ( int ClassID );
-
-};
-
-
-// ================== CObsLine ========================
-
-DefineClass(CObsLine);
-DefineStreamFunctions(CObsLine);
-
-class CObsLine : public CContainerClass {
-
- public :
-
- Date repDate; // date of replacement
- IDCode idCode; // ID code of replaced entry
- IDCode rIdCode[8]; // ID codes of entries that replaced this one
-
- CObsLine ();
- CObsLine ( cpstr S );
- CObsLine ( RPCStream Object );
- ~CObsLine();
-
- void PDBASCIIDump ( pstr S, int N );
- void MakeCIF ( PCMMCIFData CIF, int N );
- int ConvertPDBASCII ( cpstr S );
- void GetCIF ( PCMMCIFData CIF, int & Signal );
- int GetClassID () { return ClassID_ObsLine; }
-
- void Copy ( PCContainerClass ObsLine );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitObsLine();
-
-};
-
-
-// ==================== CTitleLine =====================
-
-DefineClass(CTitleLine);
-DefineStreamFunctions(CTitleLine);
-
-class CTitleLine : public CContString {
-
- public :
-
- CTitleLine ();
- CTitleLine ( cpstr S );
- CTitleLine ( RPCStream Object );
- ~CTitleLine();
-
- int ConvertPDBASCII ( cpstr S );
- void PDBASCIIDump ( pstr S, int N );
- Boolean PDBASCIIDump1 ( RCFile ) { return False; }
- int GetClassID () { return ClassID_TitleLine; }
-
-// void GetCIF ( PCMMCIFData CIF, int & Signal );
-// void MakeCIF ( PCMMCIFData CIF, int N );
-// void Copy ( PCContainerClass TitleLine );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitTitleLine();
-
-};
-
-
-// ==================== CCaveat =====================
-
-DefineClass(CCaveat);
-DefineStreamFunctions(CCaveat);
-
-class CCaveat : public CContString {
-
- public :
-
- IDCode idCode; // ID code of the entry
-
- CCaveat ();
- CCaveat ( cpstr S );
- CCaveat ( RPCStream Object );
- ~CCaveat();
-
- void PDBASCIIDump ( pstr S, int N );
- Boolean PDBASCIIDump1 ( RCFile ) { return False; }
- void MakeCIF ( PCMMCIFData CIF, int N );
- int ConvertPDBASCII ( cpstr S );
- void GetCIF ( PCMMCIFData CIF, int & Signal );
- int GetClassID () { return ClassID_CAVEAT; }
-
- void Copy ( PCContainerClass Caveat );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitCaveat();
-
-};
-
-
-// ==================== CCompound =====================
-
-DefineClass(CCompound);
-DefineStreamFunctions(CCompound);
-
-class CCompound : public CContString {
-
- public :
-
- CCompound ();
- CCompound ( cpstr S );
- CCompound ( RPCStream Object );
- ~CCompound();
-
- void PDBASCIIDump ( pstr S, int N );
- Boolean PDBASCIIDump1 ( RCFile ) { return False; }
- int ConvertPDBASCII ( cpstr S );
- int GetClassID () { return ClassID_Compound; }
-
-// void GetCIF ( PCMMCIFData CIF, int & Signal );
-// void MakeCIF ( PCMMCIFData CIF, int N );
-// void Copy ( PCContainerClass Compound );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitCompound();
-
-};
-
-
-// ==================== CSource =====================
-
-DefineClass(CSource);
-DefineStreamFunctions(CSource);
-
-class CSource : public CContString {
-
- public :
-
- CSource ();
- CSource ( cpstr S );
- CSource ( RPCStream Object );
- ~CSource();
-
- void PDBASCIIDump ( pstr S, int N );
- Boolean PDBASCIIDump1 ( RCFile ) { return False; }
- int ConvertPDBASCII ( cpstr S );
- int GetClassID () { return ClassID_Source; }
-
-// void GetCIF ( PCMMCIFData CIF, int & Signal );
-// void MakeCIF ( PCMMCIFData CIF, int N );
-// void Copy ( PCContainerClass Source );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitSource();
-
-};
-
-
-// ==================== CKeyWords =====================
-
-DefineClass(CKeyWords);
-DefineStreamFunctions(CKeyWords);
-
-class CKeyWords : public CStream {
-
- public :
-
- int nKeyWords; // number of key words
- psvector KeyWord; // key word array
-
- CKeyWords ();
- CKeyWords ( cpstr S );
- CKeyWords ( RPCStream Object );
- ~CKeyWords();
-
- void Delete ();
-
- void PDBASCIIDump ( RCFile f );
- void MakeCIF ( PCMMCIFData CIF );
-
- int ConvertPDBASCII ( cpstr S );
- void GetCIF ( PCMMCIFData CIF );
-
- void Copy ( PCKeyWords KeyWords );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- Boolean Cont;
-
- void Init();
-
-};
-
-
-// ==================== CExpData =====================
-
-DefineClass(CExpData);
-DefineStreamFunctions(CExpData);
-
-class CExpData : public CContString {
-
- public :
-
- CExpData ();
- CExpData ( cpstr S );
- CExpData ( RPCStream Object );
- ~CExpData();
-
- void PDBASCIIDump ( pstr S, int N );
- Boolean PDBASCIIDump1 ( RCFile ) { return False; }
-
- int ConvertPDBASCII ( cpstr S );
- int GetClassID () { return ClassID_ExpData; }
-
-// void GetCIF ( PCMMCIFData CIF, int & Signal );
-// void MakeCIF ( PCMMCIFData CIF, int N );
-// void Copy ( PCContainerClass ExpData );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitExpData();
-
-};
-
-
-// ==================== CMdlType =====================
-
-DefineClass(CMdlType);
-DefineStreamFunctions(CMdlType);
-
-class CMdlType : public CContString {
-
- public :
-
- CMdlType ();
- CMdlType ( cpstr S );
- CMdlType ( RPCStream Object );
- ~CMdlType();
-
- void PDBASCIIDump ( pstr S, int N );
- Boolean PDBASCIIDump1 ( RCFile ) { return False; }
-
- int ConvertPDBASCII ( cpstr S );
- int GetClassID () { return ClassID_MdlType; }
-
-// void GetCIF ( PCMMCIFData CIF, int & Signal );
-// void MakeCIF ( PCMMCIFData CIF, int N );
-// void Copy ( PCContainerClass ExpData );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitMdlType();
-
-};
-
-
-// ==================== CAuthor =====================
-
-DefineClass(CAuthor);
-DefineStreamFunctions(CAuthor);
-
-class CAuthor : public CContString {
-
- public :
-
- CAuthor ();
- CAuthor ( cpstr S );
- CAuthor ( RPCStream Object );
- ~CAuthor();
-
- void PDBASCIIDump ( pstr S, int N );
- Boolean PDBASCIIDump1 ( RCFile ) { return False; }
-
- int ConvertPDBASCII ( cpstr S );
- int GetClassID () { return ClassID_Author; }
-
-// void GetCIF ( PCMMCIFData CIF, int & Signal );
-// void MakeCIF ( PCMMCIFData CIF, int N );
-// void Copy ( PCContainerClass Author );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitAuthor();
-
-};
-
-
-// ==================== CRevData =====================
-
-DefineClass(CRevData);
-DefineStreamFunctions(CRevData);
-
-#define REVDAT_WARN_MODNUM 0x00000001
-#define REVDAT_WARN_MODTYPE 0x00000002
-
-class CRevData : public CContainerClass {
-
- public :
-
- int modNum;
- Date modDate;
- char modId[13];
- int modType;
- RecName record[4];
- word Warning;
-
- CRevData ();
- CRevData ( cpstr S );
- CRevData ( RPCStream Object );
- ~CRevData();
-
- void PDBASCIIDump ( pstr S, int N );
- void MakeCIF ( PCMMCIFData CIF, int N );
-
- int ConvertPDBASCII ( cpstr S );
- void GetCIF ( PCMMCIFData CIF, int & Signal );
-
- int GetClassID () { return ClassID_RevData; }
-
- void Copy ( PCContainerClass RevData );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitRevData();
-
-};
-
-
-// ================== CSupersede ========================
-
-DefineClass(CSupersede);
-DefineStreamFunctions(CSupersede);
-
-class CSupersede : public CContainerClass {
-
- public :
-
- Date sprsdeDate; // date of supersede
- IDCode idCode; // ID code of the entry
- IDCode sIdCode[8]; // ID codes of superseded entries
-
- CSupersede ();
- CSupersede ( cpstr S );
- CSupersede ( RPCStream Object );
- ~CSupersede();
-
- void PDBASCIIDump ( pstr S, int N );
- void MakeCIF ( PCMMCIFData CIF, int N );
-
- int ConvertPDBASCII ( cpstr S );
- void GetCIF ( PCMMCIFData CIF, int & Signal );
-
- int GetClassID () { return ClassID_Supersede; }
-
- void Copy ( PCContainerClass Supersede );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitSupersede();
-
-};
-
-
-// ==================== CJournal =====================
-
-DefineClass(CJournal);
-DefineStreamFunctions(CJournal);
-
-class CJournal : public CContString {
-
- public :
-
- CJournal ();
- CJournal ( cpstr S );
- CJournal ( RPCStream Object );
- ~CJournal();
-
- void PDBASCIIDump ( pstr S, int N );
- Boolean PDBASCIIDump1 ( RCFile ) { return False; }
-
- int ConvertPDBASCII ( cpstr S );
- int GetClassID () { return ClassID_Journal; }
-
-// void GetCIF ( PCMMCIFData CIF, int & Signal );
-// void MakeCIF ( PCMMCIFData CIF, int N );
-// void Copy ( PCContainerClass Journal );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitJournal();
-
-};
-
-
-// ==================== CRemark =====================
-
-DefineClass(CRemark);
-DefineStreamFunctions(CRemark);
-
-class CRemark : public CContainerClass {
-
- public :
-
- int remarkNum; // remark id
- pstr Remark; // remark line
-
- CRemark ();
- CRemark ( cpstr S );
- CRemark ( RPCStream Object );
- ~CRemark();
-
- void PDBASCIIDump ( pstr S, int N );
- void MakeCIF ( PCMMCIFData CIF, int N );
-
- int ConvertPDBASCII ( cpstr S );
- void GetCIF ( PCMMCIFData CIF, int & Signal );
-
- int GetClassID () { return ClassID_Remark; }
-
- void Copy ( PCContainerClass RemarkClass );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
-
- void InitRemark();
-
-};
-
-// ================= CBiomolecule =====================
-
-DefineClass(CBMApply);
-DefineStreamFunctions(CBMApply);
-
-class CBMApply : public CStream {
-
- public :
- PChainID chain;
- int nChains;
- pmat44 tm;
- int nMatrices;
-
- CBMApply ();
- CBMApply ( RPCStream Object );
- ~CBMApply();
-
- void FreeMemory();
-
- int addChains ( int & i, RPCRemark rem, RCTitleContainer Remark );
- int addMatrices ( int & i, RPCRemark rem, RCTitleContainer Remark );
-
- void Copy ( PCBMApply BMA ); // if BMA is NULL, then empties
- // the class
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
- void InitBMApply();
-
-};
-
-
-DefineClass(CBiomolecule);
-DefineStreamFunctions(CBiomolecule);
-
-class CBiomolecule : public CStream {
-
- public :
- PPCBMApply BMApply;
- int nBMAs;
-
- CBiomolecule ();
- CBiomolecule ( RPCStream Object );
- ~CBiomolecule();
-
- void FreeMemory();
-
- PCBMApply addBMApply();
-
- int Size();
- Boolean checkComposition ( PChainID chID, ivector occ,
- ivector wocc, int n );
-
- void Copy ( PCBiomolecule B ); // if B is NULL, then empties
- // the class
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
- void InitBiomolecule();
-
-};
-
-// ================= CMMDBTitle =======================
-
-DefineClass(CMMDBTitle);
-DefineStreamFunctions(CMMDBTitle);
-
-class CMMDBTitle : public CStream {
-
- friend class CModel;
- friend class CChain;
- friend class CMMDBFile;
-
- public :
-
- CMMDBTitle ();
- CMMDBTitle ( RPCStream Object );
- ~CMMDBTitle();
-
- void FreeMemory ( Boolean keepBiomolecules );
-
- // Fills the PDB file header
- void SetHeader ( cpstr Classification, // any length is Ok
- cpstr DepDate, // DD-MMM-YYYY
- cpstr ID_Code ); // not more than 11 chars
-
- // Interprets the ASCII PDB line belonging to the title section
- // and fills the corresponding fields.
- // Returns zero if the line was converted, otherwise returns a
- // non-negative value of Error_XXXX.
- // PDBString must be not shorter than 81 characters.
- int ConvertPDBString ( pstr PDBString );
-
- // MakePDBString() makes the ASCII PDB HEADER line from the
- // class data. PDBString must be not shorter than 81 characters.
- void MakePDBHeaderString ( pstr PDBString );
-
- // GetStructureTitle() returns the contents of TITLE record
- // unfolded into single line. If Title is missing, returns
- // contents of COMPND(:MOLECULE). If COMPND is missing, returns
- // HEADER. If Header is missing, returns PDB code. If no PDB
- // code is there, returns "Not available".
- pstr GetStructureTitle ( pstr & S );
-
- PCTitleContainer GetRemarks();
- PCTitleContainer GetJournal();
-
- realtype GetResolution(); // -1.0 mean no resolution record in file
-
- int ParseBiomolecules(); // returns the number of biomolecules,
- // -2 for general format error
- // -3 for errors in BIOMT records
-
- int GetNofBiomolecules();
- void GetBiomolecules ( PPCBiomolecule & BM, int & nBMs );
- PCBiomolecule GetBiomolecule ( int bmNo ); // bmno=0,1,..
- // returns NULL if bmNo is incorrect
-
- void PDBASCIIDump ( RCFile f );
- void MakeCIF ( PCMMCIFData CIF );
-
- // GetCIF(..) returns the same code as ConvertPDBString(..)
- // save for Error_WrongSection
- int GetCIF ( PCMMCIFData CIF );
-
- pstr GetIDCode() { return idCode; }
- Boolean GetCol73() { return col73; }
- void TrimInput ( pstr PDBString );
-
- void Copy ( PCMMDBTitle TS ); // if TS is NULL, then empties
- // the class
-
- void write ( RCFile f ); // writes header to PDB binary file
- void read ( RCFile f ); // reads header from PDB binary file
-
- protected :
-
- // Header data
- pstr classification; // classification of the molecule
- Date depDate; // deposition date DD-MMM-YYYY
- IDCode idCode; // unique PDB identifier
- realtype resolution; // resolution
- Boolean col73; // True if columns 73-80 contain PDB ID
-
- CTitleContainer ObsData; // obsoletion data
- CTitleContainer Title; // title data
- CTitleContainer CAVEAT; // error data
- CTitleContainer Compound; // compound data
- CTitleContainer Source; // source
- CKeyWords KeyWords; // key words
- CTitleContainer ExpData; // experimental data
- CTitleContainer MdlType; // model desctiptions
- CTitleContainer Author; // author data
- CTitleContainer RevData; // revision data
- CTitleContainer Supersede; // supersede records
- CTitleContainer Journal; // journal records
- CTitleContainer Remark; // remark records
-
- PPCBiomolecule Biomolecule;
- int nBiomolecules;
-
- void Init();
- void FreeBiomolecules();
-
- PCBiomolecule addBiomolecule();
-
-};
-
-extern void TestHeader();
-extern void TestTitle (); // reads PDB title from file 'in.title'
- // and rewrites it into 'out.title' and
- // 'abin.title'
-
-#endif
-
diff --git a/mmdb/mmdb_uddata.cpp b/mmdb/mmdb_uddata.cpp
deleted file mode 100755
index a76231d..0000000
--- a/mmdb/mmdb_uddata.cpp
+++ /dev/null
@@ -1,537 +0,0 @@
-// $Id: mmdb_uddata.cpp,v 1.19 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 08.07.08 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDBF_UDData <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-//
-// **** Classes : CUDData ( user-defined data )
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-
-#ifndef __MMDB_UDData__
-#include "mmdb_uddata.h"
-#endif
-
-
-// ======================== CUDRegister ==========================
-
-#define nUDRTypes 5
-
-CUDRegister::CUDRegister() : CStream() {
- InitUDRegister();
-}
-
-CUDRegister::CUDRegister ( RPCStream Object ) : CStream(Object) {
- InitUDRegister();
-}
-
-CUDRegister::~CUDRegister() {
- FreeUDRegister();
-}
-
-void CUDRegister::InitUDRegister() {
-int i;
- for (i=0;i<nUDRTypes;i++) {
- nIUDR[i] = 0;
- nRUDR[i] = 0;
- nSUDR[i] = 0;
- IUDRegister[i] = NULL;
- RUDRegister[i] = NULL;
- SUDRegister[i] = NULL;
- }
-}
-
-void CUDRegister::FreeUDRegister() {
-int i,j;
-
- for (j=0;j<nUDRTypes;j++) {
-
- if (IUDRegister[j]) {
- for (i=0;i<nIUDR[j];i++)
- if (IUDRegister[j][i]) delete[] IUDRegister[j][i];
- delete[] IUDRegister[j];
- IUDRegister[j] = NULL;
- }
- nIUDR[j] = 0;
-
- if (RUDRegister[j]) {
- for (i=0;i<nRUDR[j];i++)
- if (RUDRegister[j][i]) delete[] RUDRegister[j][i];
- delete[] RUDRegister[j];
- RUDRegister[j] = NULL;
- }
- nRUDR[j] = 0;
- if (SUDRegister[j]) {
- for (i=0;i<nRUDR[j];i++)
- if (SUDRegister[j][i]) delete[] SUDRegister[j][i];
- delete[] SUDRegister[j];
- SUDRegister[j] = NULL;
- }
- nSUDR[j] = 0;
-
- }
-
-}
-
-int CUDRegister::RegisterUDData ( psvector & UDRegister,
- int & nUDR,
- cpstr UDDataID ) {
-psvector UDReg;
-int i,UDDhandle,n;
-
- n = -1;
- UDDhandle = 0;
- for (i=0;(i<nUDR) && (!UDDhandle);i++)
- if (UDRegister[i]) {
- if (!strcmp(UDDataID,UDRegister[i]))
- UDDhandle = i+1;
- } else
- n = i;
-
- if (!UDDhandle) {
- if (n<0) {
- UDReg = new pstr[nUDR+1];
- for (i=0;i<nUDR;i++)
- UDReg[i] = UDRegister[i];
- UDReg[nUDR] = NULL;
- if (UDRegister) delete[] UDRegister;
- UDRegister = UDReg;
- n = nUDR;
- nUDR++;
- }
- CreateCopy ( UDRegister[n],UDDataID );
- UDDhandle = n+1;
- }
-
- return UDDhandle;
-
-}
-
-static int UDRegisterFlag[nUDRTypes] = {
- UDRF_ATOM,
- UDRF_RESIDUE,
- UDRF_CHAIN,
- UDRF_MODEL,
- UDRF_HIERARCHY
-};
-
-
-int CUDRegister::RegisterUDInteger ( int udr_type,
- cpstr UDDataID ) {
- if ((udr_type>=0) && (udr_type<nUDRTypes))
- return RegisterUDData ( IUDRegister[udr_type],
- nIUDR[udr_type],UDDataID ) |
- UDRegisterFlag[udr_type];
- else
- return UDDATA_WrongUDRType;
-}
-
-int CUDRegister::RegisterUDReal ( int udr_type,
- cpstr UDDataID ) {
- if ((udr_type>=0) && (udr_type<nUDRTypes))
- return RegisterUDData ( RUDRegister[udr_type],
- nRUDR[udr_type],UDDataID ) |
- UDRegisterFlag[udr_type];
- else
- return UDDATA_WrongUDRType;
-}
-
-int CUDRegister::RegisterUDString ( int udr_type,
- cpstr UDDataID ) {
- if ((udr_type>=0) && (udr_type<nUDRTypes))
- return RegisterUDData ( SUDRegister[udr_type],
- nSUDR[udr_type],UDDataID ) |
- UDRegisterFlag[udr_type];
- else
- return UDDATA_WrongUDRType;
-}
-
-int CUDRegister::GetUDDHandle ( int udr_type,
- cpstr UDDataID ) {
-int i,UDDhandle;
-
- if ((udr_type>=0) && (udr_type<nUDRTypes)) {
-
- UDDhandle = 0;
-
- for (i=0;(i<nIUDR[udr_type]) && (!UDDhandle);i++)
- if (IUDRegister[udr_type][i]) {
- if (!strcmp(UDDataID,IUDRegister[udr_type][i]))
- UDDhandle = i+1;
- }
- for (i=0;(i<nRUDR[udr_type]) && (!UDDhandle);i++)
- if (RUDRegister[udr_type][i]) {
- if (!strcmp(UDDataID,RUDRegister[udr_type][i]))
- UDDhandle = i+1;
- }
- for (i=0;(i<nSUDR[udr_type]) && (!UDDhandle);i++)
- if (SUDRegister[udr_type][i]) {
- if (!strcmp(UDDataID,SUDRegister[udr_type][i]))
- UDDhandle = i+1;
- }
-
- if (UDDhandle) return UDDhandle | UDRegisterFlag[udr_type];
- else return UDDhandle;
-
- } else
- return UDDATA_WrongUDRType;
-
-}
-
-
-void CUDRegister::write ( RCFile f ) {
-int i,j;
-byte Version=1;
- f.WriteByte ( &Version );
- for (j=0;j<nUDRTypes;j++) {
- f.WriteInt ( &nIUDR[j] );
- for (i=0;i<nIUDR[j];i++)
- f.CreateWrite ( IUDRegister[j][i] );
- f.WriteInt ( &nRUDR[j] );
- for (i=0;i<nRUDR[j];i++)
- f.CreateWrite ( RUDRegister[j][i] );
- f.WriteInt ( &nSUDR[j] );
- for (i=0;i<nSUDR[j];i++)
- f.CreateWrite ( SUDRegister[j][i] );
- }
-}
-
-void CUDRegister::read ( RCFile f ) {
-int i,j;
-byte Version;
- f.ReadByte ( &Version );
- FreeUDRegister();
- for (j=0;j<nUDRTypes;j++) {
- f.ReadInt ( &nIUDR[j] );
- if (nIUDR[j]>0) {
- IUDRegister[j] = new pstr[nIUDR[j]];
- for (i=0;i<nIUDR[j];i++) {
- IUDRegister[j][i] = NULL;
- f.CreateRead ( IUDRegister[j][i] );
- }
- }
- f.ReadInt ( &nRUDR[j] );
- if (nRUDR[j]>0) {
- RUDRegister[j] = new pstr[nRUDR[j]];
- for (i=0;i<nRUDR[j];i++) {
- RUDRegister[j][i] = NULL;
- f.CreateRead ( RUDRegister[j][i] );
- }
- }
- f.ReadInt ( &nSUDR[j] );
- if (nSUDR[j]>0) {
- SUDRegister[j] = new pstr[nSUDR[j]];
- for (i=0;i<nSUDR[j];i++) {
- SUDRegister[j][i] = NULL;
- f.CreateRead ( SUDRegister[j][i] );
- }
- }
- }
-}
-
-
-MakeStreamFunctions(CUDRegister)
-
-
-
-// ========================== CUDData ============================
-
-CUDData::CUDData() : CMask() {
- InitUDData();
-}
-
-CUDData::CUDData ( RPCStream Object ) : CMask(Object) {
- InitUDData();
-}
-
-CUDData::~CUDData() {
- FreeUDDMemory();
-}
-
-void CUDData::InitUDData() {
- IUData = NULL;
- RUData = NULL;
- SUData = NULL;
-}
-
-void CUDData::FreeUDDMemory() {
-int i,l;
- FreeVectorMemory ( IUData,0 );
- FreeVectorMemory ( RUData,0 );
- if (SUData) {
- l = getNofSUData();
- for (i=0;i<=l;i++)
- if (SUData[i]) delete[] SUData[i];
- delete[] SUData;
- }
- IUData = NULL;
- RUData = NULL;
- SUData = NULL;
-}
-
-int CUDData::getNofIUData() {
- if (!IUData) return 0;
- return IUData[0];
-}
-
-int CUDData::getNofRUData() {
- if (!RUData) return 0;
- return mround(RUData[0]);
-}
-
-int CUDData::getNofSUData() {
- if (!SUData) return 0;
- if (!SUData[0]) return 0;
- return (int(SUData[0][0]) << 24) +
- (int(SUData[0][1]) << 16) +
- (int(SUData[0][2]) << 8) +
- int(SUData[0][3]);
-}
-
-void CUDData::setNofSUData ( int newN ) {
- if (!SUData) return;
- if (!SUData[0]) return;
- SUData[0][3] = byte( newN & 0x000000FF);
- SUData[0][2] = byte((newN & 0x0000FF00) >> 8);
- SUData[0][1] = byte((newN & 0x00FF0000) >> 16);
- SUData[0][0] = byte((newN & 0xFF000000) >> 24);
-}
-
-
-int CUDData::putUDData ( int UDDhandle, int iudd ) {
-ivector IUD;
-int i,l,udh;
- udh = UDDhandle & UDRF_MASK;
- if (udh<1) return UDDATA_WrongHandle;
- l = getNofIUData();
- if (udh>l) {
- GetVectorMemory ( IUD,udh+1,0 );
- IUD[0] = udh;
- for (i=1;i<=l;i++)
- IUD[i] = IUData[i];
- for (i=l+1;i<udh;i++)
- IUD[i] = MinInt4;
- FreeVectorMemory ( IUData,0 );
- IUData = IUD;
- }
- IUData[udh] = iudd;
- return UDDATA_Ok;
-}
-
-int CUDData::putUDData ( int UDDhandle, realtype rudd ) {
-rvector RUD;
-int i,l,udh;
- udh = UDDhandle & UDRF_MASK;
- if (udh<1) return UDDATA_WrongHandle;
- l = getNofRUData();
- if (udh>l) {
- GetVectorMemory ( RUD,udh+1,0 );
- RUD[0] = udh;
- for (i=1;i<=l;i++)
- RUD[i] = RUData[i];
- for (i=l+1;i<udh;i++)
- RUD[i] = -MaxReal;
- FreeVectorMemory ( RUData,0 );
- RUData = RUD;
- }
- RUData[udh] = rudd;
- return UDDATA_Ok;
-}
-
-int CUDData::putUDData ( int UDDhandle, cpstr sudd ) {
-psvector SUD;
-int i,l,udh;
- udh = UDDhandle & UDRF_MASK;
- if (udh<1) return UDDATA_WrongHandle;
- l = getNofSUData();
- if (udh>l) {
- if (l>0) {
- GetVectorMemory ( SUD,udh+1,0 );
- for (i=0;i<=l;i++)
- SUD[i] = SUData[i];
- for (i=l+1;i<=udh;i++)
- SUD[i] = NULL;
- FreeVectorMemory ( SUData,0 );
- SUData = SUD;
- } else {
- GetVectorMemory ( SUData,udh+1,0 );
- SUData[0] = new char[4];
- for (i=1;i<=udh;i++)
- SUData[i] = NULL;
- }
- setNofSUData ( udh );
- }
- CreateCopy ( SUData[udh],sudd );
- return UDDATA_Ok;
-}
-
-int CUDData::getUDData ( int UDDhandle, int & iudd ) {
-int l,udh;
- iudd = 0;
- udh = UDDhandle & UDRF_MASK;
- if (udh<1) return UDDATA_WrongHandle;
- l = getNofIUData();
- if (udh>l) return UDDATA_NoData;
- iudd = IUData[udh];
- if (iudd==MinInt4) return UDDATA_NoData;
- return UDDATA_Ok;
-}
-
-int CUDData::getUDData ( int UDDhandle, realtype & rudd ) {
-int l,udh;
- rudd = 0.0;
- udh = UDDhandle & UDRF_MASK;
- if (udh<1) return UDDATA_WrongHandle;
- l = getNofRUData();
- if (udh>l) return UDDATA_NoData;
- rudd = RUData[udh];
- if (rudd==-MaxReal) return UDDATA_NoData;
- return UDDATA_Ok;
-}
-
-int CUDData::getUDData ( int UDDhandle, pstr sudd, int maxLen ) {
-int l,udh;
- sudd[0] = char(0);
- udh = UDDhandle & UDRF_MASK;
- if (udh<1) return UDDATA_WrongHandle;
- l = getNofSUData();
- if (udh>l) return UDDATA_NoData;
- if (!SUData[udh]) return UDDATA_NoData;
- strcpy_n0 ( sudd,SUData[udh],maxLen-1 );
- return UDDATA_Ok;
-}
-
-pstr CUDData::getUDData ( int UDDhandle, int * retcode ) {
-int l,udh;
- udh = UDDhandle & UDRF_MASK;
- if (udh<1) {
- if (retcode) *retcode = UDDATA_WrongHandle;
- return NULL;
- }
- l = getNofSUData();
- if (udh>l) {
- if (retcode) *retcode = UDDATA_NoData;
- return NULL;
- }
- if (!SUData[udh]) {
- if (retcode) *retcode = UDDATA_NoData;
- return NULL;
- }
- if (retcode) *retcode = UDDATA_Ok;
- return SUData[udh];
-}
-
-int CUDData::getUDData ( int UDDhandle, pstr & sudd ) {
-int l,udh;
- udh = UDDhandle & UDRF_MASK;
- if (udh<1) {
- if (sudd) {
- delete[] sudd;
- sudd = NULL;
- }
- return UDDATA_WrongHandle;
- }
- l = getNofSUData();
- if (udh>l) {
- if (sudd) {
- delete[] sudd;
- sudd = NULL;
- }
- return UDDATA_NoData;
- }
- if (!SUData[udh]) {
- if (sudd) {
- delete[] sudd;
- sudd = NULL;
- }
- return UDDATA_NoData;
- }
- CreateCopy ( sudd,SUData[udh] );
- return UDDATA_Ok;
-}
-
-
-void CUDData::write ( RCFile f ) {
-int i,l;
-byte Version=1;
-
- f.WriteByte ( &Version );
-
- CMask::write ( f );
-
- if (IUData) l = IUData[0];
- else l = -1;
- f.WriteVector ( IUData,l+1,0 );
- if (RUData) l = mround(RUData[0]);
- else l = -1;
- f.WriteVector ( RUData,l+1,0 );
- l = getNofSUData();
- f.WriteInt ( &l );
- for (i=1;i<=l;i++)
- f.CreateWrite ( SUData[i] );
-}
-
-void CUDData::read ( RCFile f ) {
-int i,l;
-byte Version;
-
- f.ReadByte ( &Version );
-
- FreeUDDMemory();
-
- CMask::read ( f );
-
- f.CreateReadVector ( IUData,0 );
- f.CreateReadVector ( RUData,0 );
- f.ReadInt ( &l );
- if (l>0) {
- SUData = new pstr[l+1];
- SUData[0] = new char[4];
- setNofSUData ( l );
- for (i=1;i<=l;i++) {
- SUData[i] = NULL;
- f.CreateRead ( SUData[i] );
- }
- }
-}
-
-
-MakeStreamFunctions(CUDData)
-
-
diff --git a/mmdb/mmdb_uddata.h b/mmdb/mmdb_uddata.h
deleted file mode 100755
index 7c5812f..0000000
--- a/mmdb/mmdb_uddata.h
+++ /dev/null
@@ -1,152 +0,0 @@
-// $Id: mmdb_uddata.h,v 1.19 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 08.07.08 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDBF_UDData <interface>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-//
-// **** Classes : CUDData ( user-defined data )
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-#ifndef __MMDB_UDData__
-#define __MMDB_UDData__
-
-
-#ifndef __MMDB_Mask__
-#include "mmdb_mask.h"
-#endif
-
-
-
-// ======================== CUDRegister ==========================
-
-#define UDR_ATOM 0
-#define UDR_RESIDUE 1
-#define UDR_CHAIN 2
-#define UDR_MODEL 3
-#define UDR_HIERARCHY 4
-
-#define UDRF_ATOM 0x01000000
-#define UDRF_RESIDUE 0x02000000
-#define UDRF_CHAIN 0x04000000
-#define UDRF_MODEL 0x08000000
-#define UDRF_HIERARCHY 0x10000000
-#define UDRF_MASK 0x00FFFFFF
-
-
-DefineClass(CUDRegister);
-DefineStreamFunctions(CUDRegister);
-
-class CUDRegister : public CStream {
-
- public :
-
- CUDRegister ();
- CUDRegister ( RPCStream Object );
- ~CUDRegister();
-
- int RegisterUDInteger ( int udr_type, cpstr UDDataID );
- int RegisterUDReal ( int udr_type, cpstr UDDataID );
- int RegisterUDString ( int udr_type, cpstr UDDataID );
- int GetUDDHandle ( int udr_type, cpstr UDDataID );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
- int nIUDR[5],nRUDR[5],nSUDR[5];
- psvector IUDRegister[5];
- psvector RUDRegister[5];
- psvector SUDRegister[5];
-
- void InitUDRegister ();
- void FreeUDRegister ();
- int RegisterUDData ( psvector & UDRegister,
- int & nUDR,
- cpstr UDDataID );
-
-};
-
-
-// ========================== CUDData ============================
-
-
-#define UDDATA_Ok 0
-#define UDDATA_WrongHandle -1
-#define UDDATA_WrongUDRType -2
-#define UDDATA_NoData -3
-
-DefineClass(CUDData);
-DefineStreamFunctions(CUDData);
-
-class CUDData : public CMask {
-
- friend class CMMDBSelManager;
-
- public :
-
- CUDData ();
- CUDData ( RPCStream Object );
- ~CUDData();
-
- protected :
- ivector IUData;
- rvector RUData;
- psvector SUData;
-
- void InitUDData ();
- void FreeUDDMemory();
- int getNofIUData ();
- int getNofRUData ();
- int getNofSUData ();
- void setNofSUData ( int newN );
-
- int putUDData ( int UDDhandle, int iudd );
- int putUDData ( int UDDhandle, realtype rudd );
- int putUDData ( int UDDhandle, cpstr sudd );
-
- int getUDData ( int UDDhandle, int & iudd );
- int getUDData ( int UDDhandle, realtype & rudd );
- int getUDData ( int UDDhandle, pstr sudd, int maxLen );
- pstr getUDData ( int UDDhandle, int * retcode=NULL );
- int getUDData ( int UDDhandle, pstr & sudd );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
-};
-
-
-#endif
-
diff --git a/mmdb/mmdb_utils.cpp b/mmdb/mmdb_utils.cpp
deleted file mode 100755
index 59b6e8d..0000000
--- a/mmdb/mmdb_utils.cpp
+++ /dev/null
@@ -1,1974 +0,0 @@
-// $Id: mmdb_utils.cpp,v 1.32 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 14.06.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_Utils <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-//
-// **** Classes : CContainerClass ( containered class template )
-// ~~~~~~~~~ CContString ( containered string )
-// CClassContainer ( container of classes )
-// CAtomPath ( atom path ID )
-// CQuickSort ( quick sort of integers )
-//
-// **** Functions : Date9to11 ( DD-MMM-YY -> DD-MMM-YYYY )
-// ~~~~~~~~~~~ Date11to9 ( DD-MMM-YYYY -> DD-MMM-YY )
-// Date9toCIF ( DD-MMM-YY -> YYYY-MM-DD )
-// Date11toCIF( DD-MMM-YYYY -> YYYY-MM-DD )
-// DateCIFto9 ( YYYY-MM-DD -> DD-MMM-YY )
-// DateCIFto11( YYYY-MM-DD -> DD-MMM-YYYY )
-// GetInteger ( reads integer from a string )
-// GetReal ( reads real from a string )
-// GetIntIns ( reads integer and insert code )
-// PutInteger ( writes integer into a string )
-// PutRealF ( writes real in F-foram into a string)
-// PutIntIns ( writes integer and insert code )
-// CIFGetInteger ( reads and deletes int from CIF )
-// CIFGetReal ( reads and deletes real from CIF )
-// CIFGetString (reads and deletes string from CIF)
-// CIFGetInteger1 (reads and del-s int from CIF loop)
-// CIFGetReal1 (reads and del-s int from CIF loop)
-// Mat4Inverse ( inversion of 4x4 matrices )
-// GetErrorDescription (ascii line to an Error_XXXXX)
-// ParseAtomID ( parses atom ID line )
-// ParseResID ( parses residue ID line )
-// ParseAtomPath ( parses full atom path )
-//
-// (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-#ifndef __MATH_H
-#include <math.h>
-#endif
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifndef __MMDB_Utils__
-#include "mmdb_utils.h"
-#endif
-
-#ifndef IOTBX_PDB_HYBRID_36_C_H
-#include "hybrid_36.h"
-#endif
-
-
-// ====================== Date functions =======================
-
-static cpstr Month[12] = {
- "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
- "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
-};
-
-static cpstr nMonth[12] = {
- "01", "02", "03", "04", "05", "06",
- "07", "08", "09", "10", "11", "12"
-};
-
-void Date9to11 ( cpstr Date9, pstr Date11 ) {
-// converts DD-MMM-YY to DD-MMM-YYYY
-int i;
- i = 0;
- while ((i<12) && (strncmp(Month[i],&(Date9[3]),3))) i++;
- if (i<12) { // DD-MMM-YY -> DD-MMM-YYYY
- strncpy ( Date11,Date9,7 );
- if (Date9[7]!='0') strncpy ( &(Date11[7]),"19",2 );
- else strncpy ( &(Date11[7]),"20",2 );
- strncpy ( &(Date11[9]),&(Date9[7]),2 );
- } else { // DD-MM-YY -> DD-MMM-YYYY
- strncpy ( Date11,Date9,3 );
- i = 0;
- while ((i<12) && (strncmp(nMonth[i],&(Date9[3]),2))) i++;
- if (i<12) strncpy ( &(Date11[3]),Month[i],3 );
- else {
- strncpy ( &(Date11[3]),&(Date9[3]),2 );
- Date11[5] = 'X';
- }
- if (Date9[6]!='0') strncpy ( &(Date11[7]),"19",2 );
- else strncpy ( &(Date11[7]),"20",2 );
- strncpy ( &(Date11[9]),&(Date9[6]),2 );
- }
- Date11[2] = '-';
- Date11[6] = '-';
- Date11[11] = char(0);
-}
-
-void Date11to9 ( cpstr Date11, pstr Date9 ) {
-// converts DD-MMM-YYYY to DD-MMM-YY
-int i;
- i = 0;
- while ((i<12) && (strncmp(Month[i],&(Date11[3]),3))) i++;
- if (i<12) { // DD-MMM-YYYY -> DD-MMM-YY
- strncpy ( Date9,Date11,7 );
- strncpy ( &(Date9[7]),&(Date11[9]),2 );
- } else { // DD-MM-YYYY -> DD-MMM-YY
- strncpy ( Date9,Date11,3 );
- i = 0;
- while ((i<12) && (strncmp(nMonth[i],&(Date11[3]),2))) i++;
- if (i<12) strncpy ( &(Date9[3]),Month[i],3 );
- else {
- strncpy ( &(Date9[3]),&(Date11[3]),2 );
- Date9[5] = 'X';
- }
- strncpy ( &(Date9[7]),&(Date11[8]),2 );
- }
- Date9[2] = '-';
- Date9[6] = '-';
-}
-
-void Date9toCIF ( cpstr Date9, pstr DateCIF ) {
-// DD-MMM-YY -> YYYY-MM-DD )
-int i;
- i = 0;
- while ((i<12) && (strncmp(Month[i],&(Date9[3]),3))) i++;
- if (i<12) { // DD-MMM-YY -> YYYY-MM-DD
- if (Date9[7]!='0') strcpy ( DateCIF,"19" );
- else strcpy ( DateCIF,"20" );
- strncpy ( &(DateCIF[2]),&(Date9[7]),2 );
- strncpy ( &(DateCIF[5]),nMonth[i],2 );
- } else { // DD-MM-YY -> YYYY-MM-DD
- if (Date9[6]!='0') strcpy ( DateCIF,"19" );
- else strcpy ( DateCIF,"20" );
- strncpy ( &(DateCIF[2]),&(Date9[6]),2 );
- strncpy ( &(DateCIF[5]),&(Date9[3]),2 );
- }
- DateCIF[4] = '-';
- DateCIF[7] = '-';
- strncpy ( &(DateCIF[8]),Date9,2 );
- DateCIF[10] = char(0);
-}
-
-void Date11toCIF ( cpstr Date11, pstr DateCIF ) {
-// DD-MMM-YYYY -> YYYY-MM-DD
-int i;
- i = 0;
- while ((i<12) && (strncmp(Month[i],&(Date11[3]),3))) i++;
- if (i<12) {
- strncpy ( DateCIF,&(Date11[7]),4 );
- strncpy ( &(DateCIF[5]),nMonth[i],2 );
- } else {
- strncpy ( DateCIF,&(Date11[6]),4 );
- strncpy ( &(DateCIF[5]),&(Date11[3]),2 );
- }
- DateCIF[4] = '-';
- DateCIF[7] = '-';
- strncpy ( &(DateCIF[8]),Date11,2 );
- DateCIF[10] = char(0);
-}
-
-void DateCIFto9 ( cpstr DateCIF, pstr Date9 ) {
-// YYYY-MM-DD -> DD-MMM-YY
-int i;
- strncpy ( Date9,&(DateCIF[8]),2 );
- Date9[2] = '-';
- i = 0;
- while ((i<12) && (strncmp(nMonth[i],&(DateCIF[5]),2))) i++;
- if (i<12) strncpy ( &(Date9[3]),Month[i],3 );
- else {
- strncpy ( &(Date9[3]),&(DateCIF[5]),2 );
- Date9[5] = 'X';
- }
- Date9[6] = '-';
- strncpy ( &(Date9[7]),&(DateCIF[2]),2 );
-// DateCIF[9] = char(0);
-}
-
-void DateCIFto11 ( cpstr DateCIF, pstr Date11 ) {
-// YYYY-MM-DD -> DD-MMM-YYYY
-int i;
- strncpy ( Date11,&(DateCIF[8]),2 );
- Date11[2] = '-';
- i = 0;
- while ((i<12) && (strncmp(nMonth[i],&(DateCIF[5]),2))) i++;
- if (i<12) strncpy ( &(Date11[3]),Month[i],3 );
- else {
- strncpy ( &(Date11[3]),&(DateCIF[5]),2 );
- Date11[5] = 'X';
- }
- Date11[6] = '-';
- strncpy ( &(Date11[7]),DateCIF,4 );
-// DateCIF[11] = char(0);
-}
-
-
-// =============== Format functions ===================
-
-Boolean GetInteger ( int & N, cpstr S, int M ) {
-// Returns True if S contains an integer number in its
-// first M characters. This number is returned in N.
-// The return is False if no integer number may be
-// recognized. In this case, N is assigned MinInt4 value.
-pstr endptr;
-char L[50];
- strncpy ( L,S,M );
- L[M] = char(0);
- N = mround(strtod(L,&endptr));
- if ((N==0) && (endptr==L)) {
- N = MinInt4; // no number
- return False;
- } else
- return True;
-}
-
-Boolean GetReal ( realtype & R, cpstr S, int M ) {
-// Returns True if S contains a real number in its
-// first M characters. This number is returned in R.
-// The return is False if no real number may be
-// recognized. In this case, R is assigned -MaxReal value.
-pstr endptr;
-char L[50];
- strncpy ( L,S,M );
- L[M] = char(0);
- R = strtod(L,&endptr);
- if ((R==0.0) && (endptr==L)) {
- R = -MaxReal; // no number
- return False;
- } else
- return True;
-}
-
-Boolean GetIntIns ( int & N, pstr ins, cpstr S, int M ) {
-// Returns True if S contains an integer number in its
-// first M characters. This number is returned in N. In addition
-// to that, GetIntIns() retrieves the insertion code which may
-// follow the integer and returns it in "ins" (1 character +
-// terminating 0).
-// The return is False if no integer number may be
-// recognized. In this case, N is assigned MinInt4 value,
-// "ins" just returns (M+1)th symbol of S (+terminating 0).
-pstr endptr;
-char L[50];
-
- if (S[M]!=' ') {
- ins[0] = S[M];
- ins[1] = char(0);
- } else
- ins[0] = char(0);
-
- strncpy ( L,S,M );
- L[M] = char(0);
- if ((M==4) && ((S[0]>='A') || ((S[0]=='-') && (S[1]>='A'))))
- hy36decode ( M,L,M,&N);
- else {
- endptr = NULL;
- N = mround(strtod(L,&endptr));
- if ((N==0) && (endptr==L)) {
- N = MinInt4; // no number
- return False;
- }
- }
-
- return True;
-
-}
-
-void PutInteger ( pstr S, int N, int M ) {
-// Integer N is converted into ASCII string of length M
-// and pasted onto first M characters of string S. No
-// terminating zero is added.
-// If N is set to MinInt4, then first M characters of
-// string S are set to the space character.
-int i;
-char L[50];
- if (N==MinInt4)
- for (i=0;i<M;i++)
- S[i] = ' ';
- else {
- sprintf ( L,"%*i",M,N );
- strncpy ( S,L,M );
- }
-}
-
-void PutRealF ( pstr S, realtype R, int M, int L ) {
-// Real R is converted into ASCII string of length M
-// and pasted onto first M characters of string S. No
-// terminating zero is added. The conversion is done
-// according to fixed format FM.L
-// If R is set to -MaxReal, then first M characters of
-// string S are set to the space character.
-int i;
-char N[50];
- if (R==-MaxReal)
- for (i=0;i<M;i++)
- S[i] = ' ';
- else {
- sprintf ( N,"%*.*f",M,L,R );
- strncpy ( S,N,M );
- }
-}
-
-int CIFGetIntegerD ( int & I, PCMMCIFLoop Loop, cpstr Tag,
- int defValue ) {
-int RC,Signal;
- Signal = 0;
- RC = CIFGetInteger ( I,Loop,Tag,Signal );
- if (RC)
- I = defValue;
- return RC;
-}
-
-int CIFGetInteger ( int & I, PCMMCIFLoop Loop, cpstr Tag,
- int & Signal ) {
-int RC;
-pstr F;
- RC = Loop->GetInteger ( I,Tag,Signal,True );
- if (RC==CIFRC_WrongFormat) {
- F = Loop->GetString ( Tag,Signal,RC );
- if (F) sprintf ( CIFErrorLocation,"loop %s.%s row %i data %s",
- Loop->GetCategoryName(),Tag,Signal,F );
- else sprintf ( CIFErrorLocation,"loop %s.%s row %i data [NULL]",
- Loop->GetCategoryName(),Tag,Signal );
- Signal = -Error_UnrecognizedInteger-1;
- return Error_UnrecognizedInteger;
- }
- if (RC==CIFRC_WrongIndex) {
- Signal = -1;
- return Error_NoData;
- }
- if (RC) {
- F = Loop->GetString ( Tag,Signal,RC );
- if (F) sprintf ( CIFErrorLocation,"loop %s.%s row %i data %s",
- Loop->GetCategoryName(),Tag,Signal,F );
- else sprintf ( CIFErrorLocation,"loop %s.%s row %i data [NULL]",
- Loop->GetCategoryName(),Tag,Signal );
- Signal = -Error_NoData-1;
- return Error_NoData;
- }
- return 0;
-}
-
-
-int CIFGetInteger1 ( int & I, PCMMCIFLoop Loop, cpstr Tag,
- int nrow ) {
-int RC;
-pstr F;
- RC = Loop->GetInteger ( I,Tag,nrow,True );
- if (RC==CIFRC_WrongFormat) {
- F = Loop->GetString ( Tag,nrow,RC );
- if (F) sprintf ( CIFErrorLocation,"loop %s.%s row %i data %s",
- Loop->GetCategoryName(),Tag,nrow,F );
- else sprintf ( CIFErrorLocation,"loop %s.%s row %i data [NULL]",
- Loop->GetCategoryName(),Tag,nrow );
- return Error_UnrecognizedInteger;
- }
- if (RC==CIFRC_WrongIndex)
- return Error_NoData;
- if (RC) {
- F = Loop->GetString ( Tag,nrow,RC );
- if (F) sprintf ( CIFErrorLocation,"loop %s.%s row %i data %s",
- Loop->GetCategoryName(),Tag,nrow,F );
- else sprintf ( CIFErrorLocation,"loop %s.%s row %i data [NULL]",
- Loop->GetCategoryName(),Tag,nrow );
- return Error_NoData;
- }
- return 0;
-}
-
-
-int CIFGetReal ( realtype & R, PCMMCIFLoop Loop, cpstr Tag,
- int & Signal ) {
-int RC;
-pstr F;
- RC = Loop->GetReal ( R,Tag,Signal,True );
- if (RC==CIFRC_WrongFormat) {
- F = Loop->GetString ( Tag,Signal,RC );
- if (F) sprintf ( CIFErrorLocation,"loop %s.%s row %i data %s",
- Loop->GetCategoryName(),Tag,Signal,F );
- else sprintf ( CIFErrorLocation,"loop %s.%s row %i data [NULL]",
- Loop->GetCategoryName(),Tag,Signal );
- Signal = -Error_UnrecognizedReal-1;
- return Error_UnrecognizedReal;
- }
- if (RC==CIFRC_WrongIndex) {
- Signal = -1;
- return Error_NoData;
- }
- if (RC) {
- F = Loop->GetString ( Tag,Signal,RC );
- if (F) sprintf ( CIFErrorLocation,"loop %s.%s row %i data %s",
- Loop->GetCategoryName(),Tag,Signal,F );
- else sprintf ( CIFErrorLocation,"loop %s.%s row %i data [NULL]",
- Loop->GetCategoryName(),Tag,Signal );
- Signal = -Error_NoData-1;
- return Error_NoData;
- }
- return 0;
-}
-
-
-int CIFGetReal1 ( realtype & R, PCMMCIFLoop Loop, cpstr Tag,
- int nrow ) {
-int RC;
-pstr F;
- RC = Loop->GetReal ( R,Tag,nrow,True );
- if (RC==CIFRC_WrongFormat) {
- F = Loop->GetString ( Tag,nrow,RC );
- if (F) sprintf ( CIFErrorLocation,"loop %s.%s row %i data %s",
- Loop->GetCategoryName(),Tag,nrow,F );
- else sprintf ( CIFErrorLocation,"loop %s.%s row %i data [NULL]",
- Loop->GetCategoryName(),Tag,nrow );
- return Error_UnrecognizedReal;
- }
- if (RC==CIFRC_WrongIndex)
- return Error_NoData;
- if (RC) {
- F = Loop->GetString ( Tag,nrow,RC );
- if (F) sprintf ( CIFErrorLocation,"loop %s.%s row %i data %s",
- Loop->GetCategoryName(),Tag,nrow,F );
- else sprintf ( CIFErrorLocation,"loop %s.%s row %i data [NULL]",
- Loop->GetCategoryName(),Tag,nrow );
- return Error_NoData;
- }
- return 0;
-}
-
-
-int CIFGetString ( pstr S, PCMMCIFLoop Loop, cpstr Tag,
- int row, int SLen, cpstr DefS ) {
-int RC;
-pstr F;
- F = Loop->GetString ( Tag,row,RC );
- if ((!RC) && F) {
- strncpy ( S,F,SLen-1 );
- Loop->DeleteField ( Tag,row );
- return 0;
- } else {
- strcpy ( S,DefS );
- return 1;
- }
-}
-
-
-int CIFGetInteger ( int & I, PCMMCIFStruct Struct, cpstr Tag,
- Boolean Remove ) {
-int RC;
-pstr F;
- RC = Struct->GetInteger ( I,Tag,Remove );
- if (RC==CIFRC_WrongFormat) {
- F = Struct->GetString ( Tag,RC );
- if (F) sprintf ( CIFErrorLocation,"structure %s.%s data %s",
- Struct->GetCategoryName(),Tag,F );
- else sprintf ( CIFErrorLocation,"structure %s.%s data [NULL]",
- Struct->GetCategoryName(),Tag );
- return Error_UnrecognizedInteger;
- }
- if (RC) {
- F = Struct->GetString ( Tag,RC );
- if (F) sprintf ( CIFErrorLocation,"structure %s.%s data %s",
- Struct->GetCategoryName(),Tag,F );
- else sprintf ( CIFErrorLocation,"structure %s.%s data [NULL]",
- Struct->GetCategoryName(),Tag );
- return Error_NoData;
- }
- return 0;
-}
-
-int CIFGetReal ( realtype & R, PCMMCIFStruct Struct, cpstr Tag,
- Boolean Remove ) {
-int RC;
-pstr F;
- RC = Struct->GetReal ( R,Tag,Remove );
- if (RC==CIFRC_WrongFormat) {
- F = Struct->GetString ( Tag,RC );
- if (F) sprintf ( CIFErrorLocation,"structure %s.%s data %s",
- Struct->GetCategoryName(),Tag,F );
- else sprintf ( CIFErrorLocation,"structure %s.%s data [NULL]",
- Struct->GetCategoryName(),Tag );
- return Error_UnrecognizedReal;
- }
- if (RC) {
- F = Struct->GetString ( Tag,RC );
- if (F) sprintf ( CIFErrorLocation,"structure %s.%s data %s",
- Struct->GetCategoryName(),Tag,F );
- else sprintf ( CIFErrorLocation,"structure %s.%s data [NULL]",
- Struct->GetCategoryName(),Tag );
- return Error_NoData;
- }
- return 0;
-}
-
-int CIFGetString ( pstr S, PCMMCIFStruct Struct, cpstr Tag,
- int SLen, cpstr DefS, Boolean Remove ) {
-int RC;
-pstr F;
- F = Struct->GetString ( Tag,RC );
- if ((!RC) && F) {
- strcpy_n0 ( S,F,SLen-1 );
- if (Remove) Struct->DeleteField ( Tag );
- return 0;
- } else {
- strcpy ( S,DefS );
- return 1;
- }
-}
-
-
-void PutIntIns ( pstr S, int N, int M, cpstr ins ) {
-// Integer N is converted into ASCII string of length M
-// and pasted onto first M characters of string S. No
-// terminating zero is added. The insert code ins is put
-// immediately after the integer.
-// If N is set to MinInt4, then first M+1 characters of
-// string S are set to space, and no insert code are
-// appended.
-int i;
-char L[50];
-
- if (N==MinInt4) {
- for (i=0;i<=M;i++)
- S[i] = ' ';
- } else {
- if ((M!=4) || ((N>=-999) && (N<=9999)))
- sprintf ( L,"%*i",M,N );
- else hy36encode ( M,N,L );
- strcpy_n1 ( S,L,M );
- if (ins[0]) S[M] = ins[0];
- }
-
-}
-
-
-void Mat4Inverse ( mat44 & A, mat44 & AI ) {
-// *** FORMER RBRINV(A,AI) ***
-// Function to invert 4*4 matrices (AI=A^{-1})
-mat44 c;
-mat33 x;
-realtype s,s1;
-int ii,jj,i,i1,j,j1;
-
-// ---- Get cofactors of 'a' in array 'c'
-
- s1 = 1.0;
- for (ii=0;ii<4;ii++) {
- s = s1;
- for (jj=0;jj<4;jj++) {
- i = -1;
- for (i1=0;i1<4;i1++)
- if (i1!=ii) {
- i++;
- j = -1;
- for (j1=0;j1<4;j1++)
- if (j1!=jj) {
- j++;
- x[i][j] = A[i1][j1];
- }
- }
- c[ii][jj] = s*(x[0][0]*(x[1][1]*x[2][2]-x[1][2]*x[2][1]) +
- x[0][1]*(x[1][2]*x[2][0]-x[1][0]*x[2][2]) +
- x[0][2]*(x[1][0]*x[2][1]-x[1][1]*x[2][0]));
- s = -s;
- }
- s1 = -s1;
- }
-
-// ---- Calculate determinant
-
- s = 0.0;
- for (i=0;i<4;i++)
- s += A[i][0]*c[i][0];
-
-// ---- Get inverse matrix
-
- if (s!=0.0)
- for (i=0;i<4;i++)
- for (j=0;j<4;j++)
- AI[i][j] = c[j][i]/s;
-
-}
-
-realtype Mat3Inverse ( mat33 & A, mat33 & AI ) {
-mat33 c,x;
-realtype s;
-int ii,jj,i,i1,j,j1;
-
- // Get cofactors of 'a' in array 'c'
-
- s = 1.0;
- for (ii=0;ii<3;ii++)
- for (jj=0;jj<3;jj++) {
- i = -1;
- for (i1=0;i1<3;i1++)
- if (i1!=ii) {
- i++;
- j = -1;
- for (j1=0;j1<3;j1++)
- if (j1!=jj) {
- j++;
- x[i][j] = A[i1][j1];
- }
- }
- c[ii][jj] = s*(x[0][0]*x[1][1]-x[0][1]*x[1][0]);
- s = -s;
- }
-
- // Calculate determinant
-
- s = 0.0;
- for (i=0;i<3;i++)
- s += A[i][0]*c[i][0];
-
- // Get inverse matrix
-
- if (s!=0.0)
- for (i=0;i<3;i++)
- for (j=0;j<3;j++)
- AI[i][j] = c[j][i]/s;
-
- return s;
-
-}
-
-void Mat4Mult ( mat44 & A, mat44 & B, mat44 & C ) {
-// Calculates A=B*C
-int i,j,k;
- for (i=0;i<4;i++)
- for (j=0;j<4;j++) {
- A[i][j] = 0.0;
- for (k=0;k<4;k++)
- A[i][j] += B[i][k]*C[k][j];
- }
-}
-
-void Mat4Div1 ( mat44 & A, mat44 & B, mat44 & C ) {
-// Calculates A=B^{-1}*C
-mat44 B1;
-int i,j,k;
- B1[0][0] = 1.0; // in order to supress warnings from some
- // stupid compilers
- Mat4Inverse ( B,B1 );
- for (i=0;i<4;i++)
- for (j=0;j<4;j++) {
- A[i][j] = 0.0;
- for (k=0;k<4;k++)
- A[i][j] += B1[i][k]*C[k][j];
- }
-}
-
-void Mat4Div2 ( mat44 & A, mat44 & B, mat44 & C ) {
-// Calculates A=B*C^{-1}
-mat44 C1;
-int i,j,k;
- C1[0][0] = 1.0; // in order to supress warnings from some
- // stupid compilers
- Mat4Inverse ( C,C1 );
- for (i=0;i<4;i++)
- for (j=0;j<4;j++) {
- A[i][j] = 0.0;
- for (k=0;k<4;k++)
- A[i][j] += B[i][k]*C1[k][j];
- }
-}
-
-void Mat4Init ( mat44 & A ) {
-int i,j;
- for (i=0;i<4;i++) {
- for (j=0;j<4;j++)
- A[i][j] = 0.0;
- A[i][i] = 1.0;
- }
-}
-
-realtype Mat4RotDet ( mat44 & T ) {
-// returns determinant of the rotation part
- return T[0][0]*T[1][1]*T[2][2] +
- T[0][1]*T[1][2]*T[2][0] +
- T[1][0]*T[2][1]*T[0][2] -
- T[0][2]*T[1][1]*T[2][0] -
- T[0][0]*T[1][2]*T[2][1] -
- T[2][2]*T[0][1]*T[1][0];
-}
-
-Boolean isMat4Unit ( mat44 & A, realtype eps, Boolean rotOnly ) {
-// returns True if A is a unit 4x4 matrix
-int i,j,k;
-Boolean B;
-
- if (rotOnly) k = 3;
- else k = 4;
-
- B = True;
- for (i=0;(i<k) && B;i++)
- for (j=0;(j<k) && B;j++)
- if (i==j) B = (fabs(1.0-A[i][j])<eps);
- else B = (fabs(A[i][j])<eps);
-
- return B;
-
-}
-
-void Mat3Init ( mat33 & A ) {
-int i,j;
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++)
- A[i][j] = 0.0;
- A[i][i] = 1.0;
- }
-}
-
-void Mat4Copy ( mat44 & A, mat44 & AC ) {
-int i,j;
- for (i=0;i<4;i++)
- for (j=0;j<4;j++)
- AC[i][j] = A[i][j];
-}
-
-void Mat3Copy ( mat33 & A, mat33 & AC ) {
-int i,j;
- for (i=0;i<3;i++)
- for (j=0;j<3;j++)
- AC[i][j] = A[i][j];
-}
-
-Boolean isMat4Eq ( mat44 & A, mat44 & B, realtype eps,
- Boolean rotOnly ) {
-// returns True if A is equal to B within precision eps
-int i,j,k;
-Boolean Eq;
-
- if (rotOnly) k = 3;
- else k = 4;
-
- Eq = True;
- for (i=0;(i<k) && Eq;i++)
- for (j=0;(j<k) && Eq;j++)
- Eq = (fabs(A[i][j]-B[i][j])<eps);
-
- return Eq;
-
-}
-
-
-void TransformXYZ ( mat44 & T, realtype & X, realtype & Y,
- realtype & Z ) {
-realtype x1,y1,z1;
- x1 = T[0][0]*X + T[0][1]*Y + T[0][2]*Z + T[0][3];
- y1 = T[1][0]*X + T[1][1]*Y + T[1][2]*Z + T[1][3];
- z1 = T[2][0]*X + T[2][1]*Y + T[2][2]*Z + T[2][3];
- X = x1;
- Y = y1;
- Z = z1;
-}
-
-realtype TransformX ( mat44 & T, realtype X, realtype Y,
- realtype Z ) {
- return T[0][0]*X + T[0][1]*Y + T[0][2]*Z + T[0][3];
-}
-
-realtype TransformY ( mat44 & T, realtype X, realtype Y,
- realtype Z ) {
- return T[1][0]*X + T[1][1]*Y + T[1][2]*Z + T[1][3];
-}
-
-realtype TransformZ ( mat44 & T, realtype X, realtype Y,
- realtype Z ) {
- return T[2][0]*X + T[2][1]*Y + T[2][2]*Z + T[2][3];
-}
-
-
-
-
-char CIFErrorLocation[200] = "no error";
-
-static cpstr msWrongSection =
- "Wrong section. The sections in PDB file may be put in wrong order.";
-static cpstr msWrongChainID =
- "Wrong chain ID. The input may have changed to another chain.";
-static cpstr msWrongEntryID =
- "Entry ID does not match the header.";
-
-static cpstr msSEQRES_serNum =
- "Serial numbers of SEQRES records do not increment by 1.";
-static cpstr msSEQRES_numRes =
- "Different SEQRES records show different numbers of residues.";
-static cpstr msSEQRES_extraRes =
- "SEQRES records contain more residues than specified.";
-
-static cpstr msNCSM_Unrecognized =
- "Unrecognized numerical input in MTRIXn.";
-static cpstr msNCSM_AlreadySet =
- "Duplicate MTRIXn record.";
-static cpstr msNCSM_WrongSerial =
- "Serial number in MTRIXn record is wrong.";
-static cpstr msNCSM_UnmatchIG =
- "Different MTRIXn record show different iGiven flag.";
-
-static cpstr msATOM_Unrecognized =
- "Numerical information in ATOM record is not recognized.";
-static cpstr msATOM_AlreadySet =
- "Atom is already in the system.";
-static cpstr msATOM_NoResidue =
- "No residue is found for atom.";
-static cpstr msATOM_Unmatch =
- "Unmatch in different records for the same atom.";
-
-static cpstr msCantOpenFile = "File can not be opened.";
-static cpstr msUnrecognizedInteger =
- "Wrong ASCII format of an integer.";
-static cpstr msWrongModelNo = "Wrong model number.";
-static cpstr msDuplicatedModel = "Duplicate model number.";
-static cpstr msNoModel = "No model defined.";
-static cpstr msForeignFile =
- "Attempt to read unknown-type file.";
-static cpstr msWrongEdition =
- "Attempt to read a higher-version file.";
-
-static cpstr msNoData = "Expected data field not found.";
-static cpstr msUnrecognizedReal = "Wrong ASCII format of a real.";
-static cpstr msNotACIFFile =
- "Not a CIF file ('data_' missing).";
-static cpstr msUnrecognCIFItems =
- "Unrecognized item(s) in CIF file.";
-static cpstr msMissingCIFField = "Expected CIF item(s) missing.";
-static cpstr msEmptyCIFLoop = "Empty CIF loop encountered.";
-static cpstr msUnexpEndOfCIF = "Unexpected end of CIF file.";
-static cpstr msMissgCIFLoopField = "Inconsistent CIF loop.";
-static cpstr msNotACIFStructure =
- "Wrong use of CIF structure (as a loop?).";
-static cpstr msNotACIFLoop =
- "Wrong use of CIF loop (as a structure?).";
-
-static cpstr msNoSheetID = "No Sheet ID on PDB ASCII card.";
-static cpstr msWrongSheetID = "Wrong Sheet ID.";
-static cpstr msWrongStrandNo =
- "Wrong Strand number on PDB SHEET card.";
-
-static cpstr msWrongNumberOfStrands =
- "Wrong number of strands in CIF file.";
-static cpstr msWrongSheetOrder = "Incomplete _struct_sheet_order.";
-static cpstr msHBondInconsistency =
- "Inconsistency in _struct_sheet_hbond.";
-
-static cpstr msEmptyResidueName =
- "No residue name on PDB ATOM or TER card.";
-static cpstr msDuplicateSeqNum =
- "Duplicate sequence number and insertion code.";
-
-static cpstr msEmptyFile = "Non-existent or empty file.";
-
-static cpstr msNoLogicalName = "Logical file name not found.";
-
-
-cpstr GetErrorDescription ( int ErrorCode ) {
-
- switch (ErrorCode) {
-
- case 0 : return "No errors.";
-
- case Error_WrongSection : return msWrongSection;
- case Error_WrongChainID : return msWrongChainID;
- case Error_WrongEntryID : return msWrongEntryID;
-
- case Error_SEQRES_serNum : return msSEQRES_serNum;
- case Error_SEQRES_numRes : return msSEQRES_numRes;
- case Error_SEQRES_extraRes : return msSEQRES_extraRes;
-
- case Error_NCSM_Unrecognized : return msNCSM_Unrecognized;
- case Error_NCSM_AlreadySet : return msNCSM_AlreadySet;
- case Error_NCSM_WrongSerial : return msNCSM_WrongSerial;
- case Error_NCSM_UnmatchIG : return msNCSM_UnmatchIG;
-
- case Error_ATOM_Unrecognized : return msATOM_Unrecognized;
- case Error_ATOM_AlreadySet : return msATOM_AlreadySet;
- case Error_ATOM_NoResidue : return msATOM_NoResidue;
- case Error_ATOM_Unmatch : return msATOM_Unmatch;
-
- case Error_CantOpenFile : return msCantOpenFile;
- case Error_UnrecognizedInteger : return msUnrecognizedInteger;
- case Error_WrongModelNo : return msWrongModelNo;
- case Error_DuplicatedModel : return msDuplicatedModel;
- case Error_NoModel : return msNoModel;
- case Error_ForeignFile : return msForeignFile;
- case Error_WrongEdition : return msWrongEdition;
-
- case Error_NoData : return msNoData;
- case Error_UnrecognizedReal : return msUnrecognizedReal;
- case Error_NotACIFFile : return msNotACIFFile;
- case Error_UnrecognCIFItems : return msUnrecognCIFItems;
- case Error_MissingCIFField : return msMissingCIFField;
- case Error_EmptyCIFLoop : return msEmptyCIFLoop;
- case Error_UnexpEndOfCIF : return msUnexpEndOfCIF;
- case Error_MissgCIFLoopField : return msMissgCIFLoopField;
- case Error_NotACIFStructure : return msNotACIFStructure;
- case Error_NotACIFLoop : return msNotACIFLoop;
-
- case Error_NoSheetID : return msNoSheetID;
- case Error_WrongSheetID : return msWrongSheetID;
- case Error_WrongStrandNo : return msWrongStrandNo;
-
- case Error_WrongNumberOfStrands : return msWrongNumberOfStrands;
- case Error_WrongSheetOrder : return msWrongSheetOrder;
- case Error_HBondInconsistency : return msHBondInconsistency;
-
- case Error_EmptyResidueName : return msEmptyResidueName;
- case Error_DuplicateSeqNum : return msDuplicateSeqNum;
-
- case Error_EmptyFile : return msEmptyFile;
-
- case Error_NoLogicalName : return msNoLogicalName;
-
- default : return "Unknown error.";
-
- }
-}
-
-
-// ============== CContainerClass ====================
-
-CContainerClass::CContainerClass() : CStream() {
- ContinuationNo = 0;
-}
-
-CContainerClass::CContainerClass ( RPCStream Object )
- : CStream(Object) {
- ContinuationNo = 0;
-}
-
-Boolean CContainerClass::Append ( PCContainerClass CC ) {
- return (CC->ContinuationNo>1);
-}
-
-
-// =================== CContString =====================
-
-CContString::CContString() : CContainerClass() {
- InitString();
-}
-
-CContString::CContString ( cpstr S ) : CContainerClass() {
- InitString();
- ConvertPDBASCII ( S );
-}
-
-CContString::CContString ( RPCStream Object )
- : CContainerClass(Object) {
- InitString();
-}
-
-CContString::~CContString() {
- if (Line) delete[] Line;
- if (CIFCategory) delete[] CIFCategory;
- if (CIFTag) delete[] CIFTag;
-}
-
-void CContString::InitString() {
- Line = NULL;
- CIFCategory = NULL;
- CIFTag = NULL;
-}
-
-int CContString::ConvertPDBASCII ( cpstr S ) {
- CreateCopy ( Line,S );
- return 0;
-}
-
-void CContString::PDBASCIIDump ( pstr S, int ) {
- if (Line) strcpy ( S,Line );
- else strcpy ( S,"" );
-}
-
-Boolean CContString::PDBASCIIDump1 ( RCFile f ) {
- if (Line) f.WriteLine ( Line );
- else f.LF();
- return True;
-}
-
-void CContString::GetCIF ( PCMMCIFData CIF, int & Signal ) {
-pstr F;
-int i,RC;
-char c;
- if ((!CIFCategory) || (!CIFTag)) {
- Signal = -1;
- return;
- }
- F = CIF->GetString ( CIFCategory,CIFTag,RC );
- if (RC || (!F)) {
- Signal = -1;
- return;
- }
- if (Signal>=(int)strlen(F)) {
- CIF->DeleteField ( CIFCategory,CIFTag );
- Signal = -1;
- return;
- }
- i = Signal;
- while (F[i] && (F[i]!='\n') && (F[i]!='\r')) i++;
- if ((Signal==0) && (i==0)) {
- i++;
- if (((F[Signal]=='\n') && (F[i]=='\r')) ||
- ((F[Signal]=='\r') && (F[i]=='\n'))) i++;
- Signal = i;
- while (F[i] && (F[i]!='\n') && (F[i]!='\r')) i++;
- }
- c = F[i];
- F[i] = char(0);
- CreateCopy ( Line,&(F[Signal]) );
- if (c) {
- F[i] = c;
- Signal = i+1;
- if (((c=='\n') && (F[Signal]=='\r')) ||
- ((c=='\r') && (F[Signal]=='\n'))) Signal++;
- } else
- CIF->DeleteField ( CIFCategory,CIFTag );
-}
-
-void CContString::MakeCIF ( PCMMCIFData CIF, int N ) {
-pstr S;
- if ((!CIFCategory) || (!CIFTag)) return;
- S = new char[strlen(Line)+5];
- strcpy ( S,"\n" );
- strcat ( S,Line );
- CIF->PutString ( S,CIFCategory,CIFTag,(N!=0) );
- delete[] S;
-}
-
-Boolean CContString::Append ( PCContainerClass CC ) {
- if (CContainerClass::Append(CC)) {
- if (!Line) {
- Line = PCContString(CC)->Line;
- PCContString(CC)->Line = NULL;
- } else
- CreateConcat ( Line,pstr("\n"),PCContString(CC)->Line );
- return True;
- }
- return False;
-}
-
-void CContString::Copy ( PCContainerClass CString ) {
- CreateCopy ( Line,PCContString(CString)->Line );
-}
-
-void CContString::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- f.CreateWrite ( Line );
- f.CreateWrite ( CIFCategory );
- f.CreateWrite ( CIFTag );
-}
-
-void CContString::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- f.CreateRead ( Line );
- f.CreateRead ( CIFCategory );
- f.CreateRead ( CIFTag );
-}
-
-MakeStreamFunctions(CContString)
-
-
-
-// ============== CClassContainer ====================
-
-MakeStreamFunctions(CContainerClass)
-
-CClassContainer::CClassContainer() : CStream() {
- Init();
-}
-
-CClassContainer::CClassContainer ( RPCStream Object )
- : CStream(Object) {
- Init();
-}
-
-void CClassContainer::Init() {
- length = 0;
- Container = NULL;
-}
-
-CClassContainer::~CClassContainer() {
- FreeContainer();
-}
-
-void CClassContainer::FreeContainer() {
-int i;
- if (Container) {
- for (i=0;i<length;i++)
- if (Container[i])
- delete Container[i];
- delete[] Container;
- }
- Container = NULL;
- length = 0;
-}
-
-void CClassContainer::AddData ( PCContainerClass Data ) {
-int i;
-PPCContainerClass C1;
- if (!Data) return;
- if (length>0) {
- i = length-1;
- while (i>=0) {
- if (!Container[i]) i--;
- else if (Container[i]->GetClassID()!=Data->GetClassID()) i--;
- else break;
- }
- if (i>=0) {
- if (Container[i]->Append(Data)) {
- delete Data;
- return;
- }
- }
- }
- C1 = new PCContainerClass[length+1];
- for (i=0;i<length;i++)
- C1[i] = Container[i];
- C1[length] = Data;
- if (Container) delete[] Container;
- Container = C1;
- length++;
-}
-
-void CClassContainer::PDBASCIIDump ( RCFile f ) {
-char S[500];
-int i,j;
- for (i=0;i<length;i++)
- if (Container[i]) {
- if (!Container[i]->PDBASCIIDump1(f)) {
- Container[i]->PDBASCIIDump ( S,i );
- j = strlen(S);
- while (j<80) S[j++] = ' ';
- S[80] = char(0);
- f.WriteLine ( S );
- }
- }
-}
-
-int CClassContainer::GetCIF ( PCMMCIFData CIF, int ClassID ) {
-PCContainerClass ContainerClass;
-int Signal;
- Signal = 0;
- do {
- ContainerClass = MakeContainerClass ( ClassID );
- ContainerClass->GetCIF ( CIF,Signal );
- if (Signal>=0)
- AddData ( ContainerClass );
- } while (Signal>=0);
- delete ContainerClass;
- return -(Signal+1);
-}
-
-void CClassContainer::MakeCIF ( PCMMCIFData CIF ) {
-int i;
- for (i=0;i<length;i++)
- if (Container[i])
- Container[i]->MakeCIF ( CIF,i );
-}
-
-void CClassContainer::write ( RCFile f ) {
-int i,ClassID;
-byte Version=1;
- f.WriteByte ( &Version );
- f.WriteInt ( &length );
- for (i=0;i<length;i++)
- if (Container[i]) {
- ClassID = Container[i]->GetClassID();
- f.WriteInt ( &ClassID );
- Container[i]->write ( f );
- } else {
- ClassID = -1;
- f.WriteInt ( &ClassID );
- }
-}
-
-PCContainerClass CClassContainer::MakeContainerClass ( int ClassID ) {
- if (ClassID==ClassID_String) return new CContString();
- return new CContainerClass();
-}
-
-PCContainerClass CClassContainer::GetContainerClass (int ContClassNo) {
- if ((ContClassNo<0) || (ContClassNo>=length)) return NULL;
- return Container[ContClassNo];
-}
-
-void CClassContainer::Copy ( PCClassContainer CContainer ) {
-int i;
- FreeContainer();
- if (CContainer) {
- length = CContainer->length;
- if (length>0) {
- Container = new PCContainerClass[length];
- for (i=0;i<length;i++)
- if (CContainer->Container[i]) {
- Container[i] = MakeContainerClass (
- CContainer->Container[i]->GetClassID() );
- Container[i]->Copy ( CContainer->Container[i] );
- } else
- Container[i] = NULL;
- }
- }
-}
-
-void CClassContainer::read ( RCFile f ) {
-int i,ClassID;
-byte Version;
- FreeContainer();
- f.ReadByte ( &Version );
- f.ReadInt ( &length );
- if (length>0) {
- Container = new PCContainerClass[length];
- for (i=0;i<length;i++) {
- f.ReadInt ( &ClassID );
- if (ClassID>=0) {
- Container[i] = MakeContainerClass ( ClassID );
- Container[i]->read ( f );
- } else
- Container[i] = NULL;
- }
- }
-}
-
-MakeStreamFunctions(CClassContainer)
-
-
-
-// ====================== ID parsers ==========================
-
-
-CAtomPath::CAtomPath() : CStream() {
- InitAtomPath();
-}
-
-CAtomPath::CAtomPath ( cpstr ID ) : CStream() {
- InitAtomPath();
- SetPath ( ID );
-}
-
-CAtomPath::CAtomPath ( RPCStream Object ) : CStream(Object) {
- InitAtomPath();
-}
-
-CAtomPath::~CAtomPath() {}
-
-void CAtomPath::InitAtomPath() {
- modelNo = 0;
- chainID [0] = char(0);
- seqNum = MinInt4;
- insCode [0] = char(0);
- resName [0] = char(0);
- atomName[0] = char(0);
- element [0] = char(0);
- altLoc [0] = char(0);
- isSet = 0;
-}
-
-int CAtomPath::SetPath ( cpstr ID ) {
-// 1. If ID starts with '/':
-// /mdl/chn/seq(res).i/atm[elm]:a
-//
-// 2. If ID starts with a letter:
-// chn/seq(res).i/atm[elm]:a
-//
-// 3. If ID starts with a number:
-// seq(res).i/atm[elm]:a
-//
-// 4. If ID contains colon ':' then
-// it may be just
-// atm[elm]:a
-//
-// All spaces are ignored. isSet
-// sets bit for each element present.
-// Any element may be a wildcard '*'.
-// Wildcard for model will set modelNo=0,
-// for sequence number will set
-// seqNum=MinInt4.
-//
-// Returns:
-// 0 <-> Ok
-// -1 <-> wrong numerical format for model
-// -2 <-> wrong numerical format for sequence number
-//
-char N[100];
-pstr p,p1;
-int i,k;
-
- isSet = 0; // clear all bits.
-
- p = pstr(ID);
- while (*p==' ') p++;
-
- if (!(*p)) return 0;
-
- if (*p=='/') {
- // model number
- p++;
- i = 0;
- while ((*p) && (*p!='/')) {
- if (*p!=' ') N[i++] = *p;
- p++;
- }
- N[i] = char(0);
- if ((!N[0]) || (N[0]=='*')) modelNo = 0;
- else {
- modelNo = mround(strtod(N,&p1));
- if ((modelNo==0) && (p1==N)) return -1;
- }
- isSet |= APATH_ModelNo;
- if (*p!='/') return 0;
- p++;
- while (*p==' ') p++;
- }
-
- if ((*p<'0') || (*p>'9')) {
- // chain ID
- i = 0;
- k = sizeof(ChainID)-1;
- while ((*p) && (*p!='/')) {
- if ((*p!=' ') && (i<k)) chainID[i++] = *p;
- p++;
- }
- chainID[i] = char(0);
- if (!chainID[0]) {
- chainID[0] = '*';
- chainID[1] = char(0);
- }
- isSet |= APATH_ChainID;
- if (*p!='/') return 0;
- p++;
- while (*p==' ') p++;
- }
-
- if (((*p>='0') && (*p<='9')) || (*p=='-') ||
- (*p=='(') || (*p=='.')) {
- // sequence number, residue name and insertion code
- i = 0;
- while ((*p) && (*p!='/')) {
- if (*p!=' ') N[i++] = *p;
- p++;
- }
- N[i] = char(0);
- i = ParseResID ( N,seqNum,insCode,resName );
- if (i==2) return -2;
- isSet |= APATH_SeqNum | APATH_InsCode | APATH_ResName;
- if (*p!='/') return 0;
- p++;
- while (*p==' ') p++;
- }
-
- if (strchr(p,':') || strchr(p,'[')) {
- // atom name, chemical element and alternative location
- i = 0;
- while (*p) {
- if (*p!=' ') N[i++] = *p;
- p++;
- }
- N[i] = char(0);
- ParseAtomID ( N,atomName,element,altLoc );
- isSet |= APATH_AtomName | APATH_Element | APATH_AltLoc;
- }
-
- return 0;
-
-}
-
-void CAtomPath::write ( RCFile f ) {
-byte Version=1;
- f.WriteByte ( &Version );
- CStream::write ( f );
- f.WriteInt ( &modelNo );
- f.WriteInt ( &seqNum );
- f.WriteInt ( &isSet );
- f.WriteTerLine ( chainID ,False );
- f.WriteTerLine ( insCode ,False );
- f.WriteTerLine ( resName ,False );
- f.WriteTerLine ( atomName,False );
- f.WriteTerLine ( element ,False );
- f.WriteTerLine ( altLoc ,False );
-}
-
-void CAtomPath::read ( RCFile f ) {
-byte Version;
- f.ReadByte ( &Version );
- CStream::read ( f );
- f.ReadInt ( &modelNo );
- f.ReadInt ( &seqNum );
- f.ReadInt ( &isSet );
- f.ReadTerLine ( chainID ,False );
- f.ReadTerLine ( insCode ,False );
- f.ReadTerLine ( resName ,False );
- f.ReadTerLine ( atomName,False );
- f.ReadTerLine ( element ,False );
- f.ReadTerLine ( altLoc ,False );
-}
-
-
-MakeStreamFunctions(CAtomPath)
-
-
-
-// --------------------------------------------------------
-
-CQuickSort::CQuickSort() : CStream() {
- selSortLimit = 15;
- data = NULL;
- dlen = 0;
-}
-
-CQuickSort::CQuickSort ( RPCStream Object )
- : CStream(Object) {
- selSortLimit = 15;
- data = NULL;
- dlen = 0;
-}
-
-int CQuickSort::Compare ( int i, int j ) {
-// sort by increasing data[i]
- if (((ivector)data)[i]<((ivector)data)[j]) return -1;
- if (((ivector)data)[i]>((ivector)data)[j]) return 1;
- return 0;
-}
-
-void CQuickSort::Swap ( int i, int j ) {
-int b;
- b = ((ivector)data)[i];
- ((ivector)data)[i] = ((ivector)data)[j];
- ((ivector)data)[j] = b;
-}
-
-void CQuickSort::SelectionSort ( int left, int right ) {
-int i,j,imin;
- for (i=left;i<right;i++) {
- imin = i;
- for (j=i+1;j<=right;j++)
- if (Compare(j,imin)<0) imin = j;
- Swap ( i,imin );
- }
-}
-
-int CQuickSort::Partition ( int left, int right ) {
-int lv = left;
-int lm = left-1;
-int rm = right+1;
- do {
- do
- rm--;
- while ((rm>0) && (Compare(rm,lv)>0));
- do
- lm++;
- while ((lm<dlen) && (Compare(lm,lv)<0));
- if (lm<rm) {
- if (lv==lm) lv = rm;
- else if (lv==rm) lv = lm;
- Swap ( lm,rm );
- }
- } while (lm<rm);
- return rm;
-}
-
-void CQuickSort::Quicksort ( int left, int right ) {
-int split_pt;
- if (left<(right-selSortLimit)) {
- split_pt = Partition ( left,right );
- Quicksort ( left,split_pt );
- Quicksort ( split_pt+1,right );
- } else
- SelectionSort ( left,right );
-}
-
-void CQuickSort::Sort ( void * sortdata, int data_len ) {
- data = sortdata;
- dlen = data_len-1;
- if (data) Quicksort ( 0,data_len-1 );
-}
-
-// --------------------------------------------------------
-
-void takeWord ( pstr & p, pstr wrd, cpstr ter, int l ) {
-pstr p1;
-int i;
- p1 = strpbrk ( p,ter );
- if (!p1)
- p1 = p + strlen(p);
- i = 0;
- while ((p!=p1) && (i<l)) {
- wrd[i++] = *p;
- p++;
- }
- if (i>=l) i = l-1;
- wrd[i] = char(0);
- p = p1;
-}
-
-
-void ParseAtomID ( cpstr ID, AtomName aname, Element elname,
- AltLoc aloc ) {
-pstr p;
-
- p = pstr(ID);
- while (*p==' ') p++;
-
- strcpy ( aname ,"*" );
- strcpy ( elname,"*" );
- if (*p) aloc[0] = char(0);
- else strcpy ( aloc,"*" );
-
- takeWord ( p,aname,pstr("[: "),sizeof(AtomName) );
-
- if (*p=='[') {
- p++;
- takeWord ( p,elname,pstr("]: "),sizeof(Element) );
- if (*p==']') p++;
- }
-
- if (*p==':') {
- p++;
- takeWord ( p,aloc,pstr(" "),sizeof(AltLoc) );
- }
-
-}
-
-int ParseResID ( cpstr ID, int & sn, InsCode inscode,
- ResName resname ) {
-int RC;
-pstr p,p1;
-char N[100];
-
- RC = 0;
-
- p = pstr(ID);
- while (*p==' ') p++;
-
- sn = ANY_RES;
- strcpy ( inscode,"*" );
- strcpy ( resname,"*" );
-
- N[0] = char(0);
- takeWord ( p,N,pstr("(./ "),sizeof(N) );
- if ((!N[0]) || (N[0]=='*')) {
- sn = ANY_RES;
- RC = 1;
- }
- if (!RC) {
- sn = mround(strtod(N,&p1));
- if (p1==N) RC = 2;
- else inscode[0] = char(0);
- }
-
- if (*p=='(') {
- p++;
- takeWord ( p,resname,pstr(")./ "),sizeof(ResName) );
- if (*p==')') p++;
- }
-
- if (*p=='.') {
- p++;
- takeWord ( p,inscode,pstr("/ "),sizeof(InsCode) );
- }
-
- return RC;
-
-}
-
-int ParseAtomPath ( cpstr ID,
- int & mdl,
- ChainID chn,
- int & sn,
- InsCode ic,
- ResName res,
- AtomName atm,
- Element elm,
- AltLoc aloc,
- PCAtomPath DefPath ) {
-// /mdl/chn/seq(res).i/atm[elm]:a, may be partial
-char N[100];
-pstr p,p1;
-int i,RC;
-Boolean wasRes;
-
- wasRes = False;
-
- RC = 0;
-
- p = pstr(ID);
- while (*p==' ') p++;
-
- mdl = 0;
- if (*p=='/') {
- p++;
- N[0] = char(0);
- takeWord ( p,N,pstr("/"),sizeof(N) );
- if ((!N[0]) || (N[0]=='*')) mdl = 0;
- else {
- mdl = mround(strtod(N,&p1));
- if ((mdl==0) && (p1==N)) return -1;
- }
- } else if (DefPath) {
- if (DefPath->isSet & APATH_ModelNo)
- mdl = DefPath->modelNo;
- }
-
- strcpy ( chn,"*" );
- if (*p=='/') p++;
- if ((*p<'0') || (*p>'9')) {
- p1 = p;
- chn[0] = char(0);
- takeWord ( p,chn,pstr("/"),sizeof(ChainID) );
- if (strpbrk(chn,"(.[:-")) { // this was not a chain ID!
- if (DefPath) {
- if (DefPath->isSet & APATH_ChainID)
- strcpy ( chn,DefPath->chainID );
- } else
- strcpy ( chn,"*" );
- p = p1;
- }
- } else if (DefPath) {
- if (DefPath->isSet & APATH_ChainID)
- strcpy ( chn,DefPath->chainID );
- }
-
- if (*p=='/') p++;
- sn = ANY_RES;
- strcpy ( ic ,"*" );
- strcpy ( res,"*" );
- if (((*p>='0') && (*p<='9')) || (*p=='-') ||
- (*p=='(') || (*p=='.')) {
- wasRes = True;
- N[0] = char(0);
- takeWord ( p,N,pstr("/"),sizeof(N) );
- i = ParseResID ( N,sn,ic,res );
- if (i==2) return -2;
- } else if (DefPath) {
- wasRes = (*p=='/');
- if (DefPath->isSet & APATH_SeqNum)
- sn = DefPath->seqNum;
- if (DefPath->isSet & APATH_InsCode)
- strcpy ( ic,DefPath->insCode );
- if (DefPath->isSet & APATH_ResName)
- strcpy ( res,DefPath->resName );
- }
-
- if (*p=='/') p++;
- strcpy ( atm ,"*" );
- strcpy ( elm ,"*" );
- strcpy ( aloc,"*" );
- if (wasRes || strchr(p,':') || strchr(p,'[')) {
- ParseAtomID ( p,atm,elm,aloc );
- } else if (DefPath) {
- if (DefPath->isSet & APATH_AtomName)
- strcpy ( atm,DefPath->atomName );
- if (DefPath->isSet & APATH_Element)
- strcpy ( elm,DefPath->element );
- if (DefPath->isSet & APATH_ResName)
- strcpy ( aloc,DefPath->altLoc );
- }
-
- if (mdl<=0) RC |= APATH_WC_ModelNo;
- if (chn[0]=='*') RC |= APATH_WC_ChainID;
- if (sn==ANY_RES) RC |= APATH_WC_SeqNum;
- if (ic[0]=='*') RC |= APATH_WC_InsCode;
- if (res[0]=='*') RC |= APATH_WC_ResName;
- if (atm[0]=='*') RC |= APATH_WC_AtomName;
- if (elm[0]=='*') RC |= APATH_WC_Element;
- if (aloc[0]=='*') RC |= APATH_WC_AltLoc;
-
- if (RC & (APATH_WC_ModelNo | APATH_WC_ChainID |
- APATH_WC_SeqNum | APATH_WC_InsCode |
- APATH_WC_AtomName | APATH_WC_AltLoc))
- RC |= APATH_Incomplete;
-
- return RC;
-
-}
-
-
-int ParseSelectionPath (
- cpstr CID,
- int & iModel,
- pstr Chains,
- int & sNum1,
- InsCode ic1,
- int & sNum2,
- InsCode ic2,
- pstr RNames,
- pstr ANames,
- pstr Elements,
- pstr altLocs
- ) {
-int l,j;
-pstr p,p1;
-pstr N;
-int seqNum [2];
-InsCode insCode[2];
-pstr ID;
-Boolean wasModel,wasChain,wasRes,haveNeg;
-
- l = IMax(10,strlen(CID))+1;
- ID = new char[l];
- N = new char[l];
-
- p = pstr(CID);
- p1 = ID;
- while (*p) {
- if (*p!=' ') {
- *p1 = *p;
- p1++;
- }
- p++;
- }
- *p1 = char(0);
-
- p = ID;
-
- iModel = 0;
- strcpy ( Chains,"*" );
- seqNum[0] = ANY_RES;
- seqNum[1] = ANY_RES;
- strcpy ( insCode[0],"*" );
- strcpy ( insCode[1],"*" );
- strcpy ( RNames ,"*" );
- strcpy ( ANames ,"*" );
- strcpy ( Elements ,"*" );
- strcpy ( altLocs ,"*" );
-
- wasModel = False;
- wasChain = False;
- wasRes = False;
-
- if (*p=='/') {
- // CID starts with the slash -- take model number first
- p++;
- N[0] = char(0);
- takeWord ( p,N,pstr("/"),l );
- if ((!N[0]) || (N[0]=='*')) iModel = 0;
- else {
- iModel = mround(strtod(N,&p1));
- if ((iModel==0) && (p1==N)) return -1;
- }
- if (*p=='/') p++;
- wasModel = True;
- }
-
- if ((*p) && (wasModel || (*p<'0') || (*p>'9'))) {
- p1 = p;
- Chains[0] = char(0);
- takeWord ( p,Chains,pstr("/"),l );
- if (strpbrk(Chains,"(.[:-")) { // this was not a chain ID!
- strcpy ( Chains,"*" );
- p = p1;
- } else
- wasChain = True;
- if (*p=='/') p++;
- }
-
- if ((*p) && (wasChain || ((*p>='0') && (*p<='9')) || (*p=='-') ||
- (*p=='(') || (*p=='.') || (*p=='*'))) {
- j = 0;
- do {
- // take the sequence number
- haveNeg = False;
- if (*p=='-') {
- haveNeg = True;
- p++;
- }
- N[0] = char(0);
- takeWord ( p,N,pstr("(.-/"),l );
- if ((!N[0]) || (N[0]=='*'))
- seqNum[j] = ANY_RES;
- else {
- seqNum[j] = mround(strtod(N,&p1));
- if (p1==N) return -2;
- if (haveNeg) seqNum[j] = - seqNum[j];
- }
- // take the residue list
- if (*p=='(') {
- p++;
- takeWord ( p,RNames,pstr(").-/"),l );
- if (*p==')') p++;
- }
- // take the insertion code
- if (seqNum[j]!=ANY_RES)
- insCode[j][0] = char(0);
- if (*p=='.') {
- p++;
- takeWord ( p,insCode[j],pstr("-/"),sizeof(InsCode) );
- }
- if (*p=='-') {
- p++;
- j++;
- } else {
- if (j==0) {
- seqNum[1] = seqNum[0];
- strcpy ( insCode[1],insCode[0] );
- }
- j = 10;
- }
- } while (j<2);
- wasRes = True;
- } else
- wasRes = (*p=='/');
-
- if (*p=='/') p++;
- if ((*p) && (wasRes || strchr(p,':') || strchr(p,'['))) {
- if (*p) altLocs[0] = char(0);
- takeWord ( p,ANames,pstr("[:"),l );
- if (!ANames[0]) strcpy ( ANames,"*" );
- if (*p=='[') {
- p++;
- takeWord ( p,Elements,pstr("]:"),l );
- if (*p==']') p++;
- }
- if (*p==':') {
- p++;
- takeWord ( p,altLocs,pstr(" "),l );
- }
- }
-
- /*
- printf ( " iModel = %i\n"
- " Chains = '%s'\n"
- " seqNum1 = %i\n"
- " insCode1 = '%s'\n"
- " seqNum2 = %i\n"
- " insCode2 = '%s'\n"
- " RNames = '%s'\n"
- " ANames = '%s'\n"
- " Elements = '%s'\n"
- " altLocs = '%s'\n",
- iModel,Chains,seqNum[0],insCode[0],
- seqNum[1],insCode[1],RNames,ANames,
- Elements,altLocs );
- */
-
- sNum1 = seqNum[0];
- sNum2 = seqNum[1];
- strcpy ( ic1,insCode[0] );
- strcpy ( ic2,insCode[1] );
-
- delete[] ID;
- delete[] N;
-
- return 0;
-
-}
-
-
-void MakeSelectionPath (
- pstr CID,
- int iModel,
- cpstr Chains,
- int sNum1,
- const InsCode ic1,
- int sNum2,
- const InsCode ic2,
- cpstr RNames,
- cpstr ANames,
- cpstr Elements,
- cpstr altLocs
- ) {
-char S[100];
-int k;
-
- if (iModel>0) {
- sprintf ( CID,"/%i",iModel );
- k = 1;
- } else {
- CID[0] = char(0);
- k = 0;
- }
-
- if (Chains[0]!='*') {
- if (k>0) strcat ( CID,"/" );
- strcat ( CID,Chains );
- k = 2;
- }
-
- if ((sNum1!=-MaxInt4) || (ic1[0]!='*')) {
- if (k>0) {
- if (k<2) strcat ( CID,"/*" );
- strcat ( CID,"/" );
- }
- if (sNum1>-MaxInt4) sprintf ( S,"%i",sNum1 );
- else strcpy ( S,"*" );
- if (ic1[0]!='*') {
- strcat ( S,"." );
- strcat ( S,ic1 );
- }
- strcat ( CID,S );
-
- if ((sNum2!=-MaxInt4) || (ic2[0]!='*')) {
- strcat ( CID,"-" );
- if (sNum1>-MaxInt4) sprintf ( S,"%i",sNum2 );
- else strcpy ( S,"*" );
- if (ic2[0]!='*') {
- strcat ( S,"." );
- strcat ( S,ic2 );
- }
- strcat ( CID,S );
- }
-
- k = 3;
-
- }
-
- if (RNames[0]!='*') {
- if (k<1) strcat ( CID,"(" );
- else if (k<2) strcat ( CID,"*/*(" );
- else if (k<3) strcat ( CID,"/*(" );
- strcat ( CID,RNames );
- strcat ( CID,")" );
- k = 4;
- }
-
- if (ANames[0]!='*') {
- if (k<1) strcat ( CID,"/*/*/*/" ); // full path
- else if (k<2) strcat ( CID,"/*/*/" ); // /mdl + /*/*/
- else if (k<3) strcat ( CID,"/*/" ); // /mdl/chn + /*/
- else if (k<4) strcat ( CID,"/" ); // /mdl/chn/res + /
- strcat ( CID,ANames );
- strcat ( CID,")" );
- k = 5;
- }
-
- if (Elements[0]!='*') {
- if (k<1) strcat ( CID,"[" );
- else if (k<2) strcat ( CID,"/*/*/*[" );
- else if (k<3) strcat ( CID,"/*/*[" );
- else if (k<4) strcat ( CID,"/*[" );
- else if (k<5) strcat ( CID,"[" );
- strcat ( CID,Elements );
- strcat ( CID,"]" );
- k = 6;
- }
-
- if (altLocs[0]!='*') {
- if (k<1) strcat ( CID,":" );
- else if (k<2) strcat ( CID,"/*/*/*:" );
- else if (k<3) strcat ( CID,"/*/*:" );
- else if (k<4) strcat ( CID,"/*:" );
- else if (k<6) strcat ( CID,":" );
- strcat ( CID,altLocs );
- }
-
-}
diff --git a/mmdb/mmdb_utils.h b/mmdb/mmdb_utils.h
deleted file mode 100755
index d6083b8..0000000
--- a/mmdb/mmdb_utils.h
+++ /dev/null
@@ -1,639 +0,0 @@
-// $Id: mmdb_utils.h,v 1.25 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 14.06.13 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDBF_Utils <interface>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-//
-// **** Classes : CContainerClass ( containered class template )
-// ~~~~~~~~~ CContString ( containered string )
-// CClassContainer ( container of classes )
-// CAtomPath ( atom path ID )
-// CQuickSort ( quick sort of integers )
-//
-// **** Functions : Date9to11 ( DD-MMM-YY -> DD-MMM-YYYY )
-// ~~~~~~~~~~~ Date11to9 ( DD-MMM-YYYY -> DD-MMM-YY )
-// Date9toCIF ( DD-MMM-YY -> YYYY-MM-DD )
-// Date11toCIF( DD-MMM-YYYY -> YYYY-MM-DD )
-// DateCIFto9 ( YYYY-MM-DD -> DD-MMM-YY )
-// DateCIFto11( YYYY-MM-DD -> DD-MMM-YYYY )
-// GetInteger ( reads integer from a string )
-// GetReal ( reads real from a string )
-// GetIntIns ( reads integer and insert code )
-// PutInteger ( writes integer into a string )
-// PutRealF ( writes real in F-form into a string )
-// PutIntIns ( writes integer and insert code )
-// CIFGetInteger ( reads and deletes int from CIF )
-// CIFGetReal ( reads and deletes real from CIF )
-// CIFGetString ( reads and deletes string from CIF)
-// CIFGetInteger1 (reads and del-s int from CIF loop)
-// CIFGetReal1 (reads and del-s int from CIF loop)
-// Mat4Inverse ( inversion of 4x4 matrices )
-// GetErrorDescription (ascii line to an Error_XXXXX)
-// ParseAtomID ( parses atom ID line )
-// ParseResID ( parses residue ID line )
-// ParseAtomPath ( parses full atom path )
-//
-// (C) E. Krissinel 2000-2013
-//
-// =================================================================
-//
-
-#ifndef __MMDB_Utils__
-#define __MMDB_Utils__
-
-
-#ifndef __Stream__
-#include "stream_.h"
-#endif
-
-#ifndef __MMDB_Defs__
-#include "mmdb_defs.h"
-#endif
-
-#ifndef __MMDB_MMCIF__
-#include "mmdb_mmcif.h"
-#endif
-
-
-
-// ================== Date functions ===================
-
-// converts DD-MMM-YY to DD-MMM-YYYY; appends terminating zero
-extern void Date9to11 ( cpstr Date9, pstr Date11 );
-
-// converts DD-MMM-YYYY to DD-MMM-YY; does not append terminating zero
-extern void Date11to9 ( cpstr Date11, pstr Date9 );
-
-// converts DD-MMM-YY to YYYY-MM-DD; appends terminating zero
-extern void Date9toCIF ( cpstr Date9, pstr DateCIF );
-
-// converts DD-MMM-YYYY to YYYY-MM-DD; appends terminating zero
-extern void Date11toCIF ( cpstr Date11, pstr DateCIF );
-
-// converts YYYY-MM-DD to DD-MMM-YY; appends terminating zero
-extern void DateCIFto9 ( cpstr DateCIF, pstr Date9 );
-
-// converts YYYY-MM-DD to DD-MMM-YYYY; appends terminating zero
-extern void DateCIFto11 ( cpstr DateCIF, pstr Date11 );
-
-
-// ================= Format functions ==================
-
-// Returns True if S contains an integer number in its
-// first M characters. This number is returned in N.
-// The return is False if no integer number may be
-// recognized. In this case, N is assigned MinInt4 value.
-extern Boolean GetInteger ( int & N, cpstr S, int M );
-
-// Returns True if S contains a real number in its
-// first M characters. This number is returned in R.
-// The return is False if no real number may be
-// recognized. In this case, R is assigned -MaxReal value.
-extern Boolean GetReal ( realtype & R, cpstr S, int M );
-
-// Returns True if S contains an integer number in its
-// first M characters. This number is returned in N. In addition
-// to that, GetIntIns() retrieves the insertion code which may
-// follow the integer and returns it in "ins" (1 character +
-// terminating 0).
-// The return is False if no integer number may be
-// recognized. In this case, N is assigned MinInt4 value,
-// "ins" just returns (M+1)th symbol of S (+terminating 0).
-extern Boolean GetIntIns ( int & N, pstr ins, cpstr S, int M );
-
-// Integer N is converted into ASCII string of length M
-// and pasted onto first M characters of string S. No
-// terminating zero is added.
-// If N is set to MinInt4, then first M characters of
-// string S are set to space.
-extern void PutInteger ( pstr S, int N, int M );
-
-// Real R is converted into ASCII string of length M
-// and pasted onto first M characters of string S. No
-// terminating zero is added. The conversion is done
-// according to fixed format FM.L
-// If R is set to -MaxReal, then first M characters of
-// string S are set to the space character.
-extern void PutRealF ( pstr S, realtype R, int M, int L );
-
-// Integer N is converted into ASCII string of length M
-// and pasted onto first M characters of string S. No
-// terminating zero is added. The insert code ins is put
-// immediately after the integer.
-// If N is set to MinInt4, then first M+1 characters of
-// string S are set to space, and no insert code are
-// appended.
-extern void PutIntIns ( pstr S, int N, int M, cpstr ins );
-
-
-// CIFInteger(..), CIFReal(..) and CIFGetString(..) automate
-// extraction and analysis of data from CIF file. If the data
-// is erroneous or absent, they store an error message in
-// CIFErrorLocation string (below) and return non-zero.
-extern int CIFGetInteger ( int & I, PCMMCIFStruct Struct,
- cpstr Tag,
- Boolean Remove=True );
-extern int CIFGetReal ( realtype & R, PCMMCIFStruct Struct,
- cpstr Tag,
- Boolean Remove=True );
-extern int CIFGetString ( pstr S, PCMMCIFStruct Struct,
- cpstr Tag, int SLen,
- cpstr DefS,
- Boolean Remove=True );
-
-extern int CIFGetInteger ( int & I, PCMMCIFLoop Loop, cpstr Tag,
- int & Signal );
-extern int CIFGetIntegerD ( int & I, PCMMCIFLoop Loop, cpstr Tag,
- int defValue=MinInt4 );
-extern int CIFGetInteger1 ( int & I, PCMMCIFLoop Loop, cpstr Tag,
- int nrow );
-
-extern int CIFGetReal ( realtype & R, PCMMCIFLoop Loop,
- cpstr Tag, int & Signal );
-extern int CIFGetReal1 ( realtype & R, PCMMCIFLoop Loop,
- cpstr Tag, int nrow );
-
-extern int CIFGetString ( pstr S, PCMMCIFLoop Loop, cpstr Tag,
- int row, int SLen, cpstr DefS );
-
-// Calculates AI=A^{-1}
-extern void Mat4Inverse ( mat44 & A, mat44 & AI );
-// Calculates A=B*C
-extern void Mat4Mult ( mat44 & A, mat44 & B, mat44 & C );
-// Calculates A=B^{-1}*C
-extern void Mat4Div1 ( mat44 & A, mat44 & B, mat44 & C );
-// Calculates A=B*C^{-1}
-extern void Mat4Div2 ( mat44 & A, mat44 & B, mat44 & C );
-// Calculates determinant of the rotation part
-extern realtype Mat4RotDet ( mat44 & T );
-
-// Sets up a unit matrix
-extern void Mat4Init ( mat44 & A );
-extern void Mat3Init ( mat33 & A );
-
-// Calculates AI=A^{-1}, returns determinant
-extern realtype Mat3Inverse ( mat33 & A, mat33 & AI );
-
-extern Boolean isMat4Unit ( mat44 & A, realtype eps, Boolean rotOnly );
-
-// Copies A into AC
-extern void Mat4Copy ( mat44 & A, mat44 & AC );
-extern void Mat3Copy ( mat33 & A, mat33 & AC );
-extern Boolean isMat4Eq ( mat44 & A, mat44 & B, realtype eps,
- Boolean rotOnly );
-
-extern void TransformXYZ ( mat44 & T,
- realtype & X, realtype & Y, realtype & Z );
-extern realtype TransformX ( mat44 & T,
- realtype X, realtype Y, realtype Z );
-extern realtype TransformY ( mat44 & T,
- realtype X, realtype Y, realtype Z );
-extern realtype TransformZ ( mat44 & T,
- realtype X, realtype Y, realtype Z );
-
-
-extern char CIFErrorLocation[200];
-
-// Returns ASCII string explaining the nature of
-// Error_xxxx error code.
-extern cpstr GetErrorDescription ( int ErrorCode );
-
-
-
-// ============== CContainerClass ====================
-
-DefineClass(CContainerClass)
-DefineStreamFunctions(CContainerClass)
-
-class CContainerClass : public CStream {
-
- friend class CClassContainer;
-
- public :
-
- CContainerClass ();
- CContainerClass ( RPCStream Object );
- ~CContainerClass() {}
-
- // ConvertPDBASCII(..) will return one of the Error_XXXXX
- // constants, see <mmdb_defs.h>
- virtual int ConvertPDBASCII ( cpstr ) { return 0; }
- virtual void PDBASCIIDump ( pstr, int ) {}
- virtual Boolean PDBASCIIDump1 ( RCFile ) { return False; }
- virtual void MakeCIF ( PCMMCIFData, int ) {}
-
- // Append(..) should return True if CC is appended to this class.
- // If this is not the case, CC is merely put on the top of
- // container.
- // Note: Append(..) detects the necessity to append CC and
- // performs all the necessary actions for that. The rest of CC
- // will be disposed by Class Container.
- // Note: Class Container checks every new class, which is
- // being added to it (see CClassContainer::AddData(..)), only
- // against the top of container.
- virtual Boolean Append ( PCContainerClass CC );
-
- // GetCIF(..) extracts any necessary information from CIF and
- // returns:
- // Signal>=0 : the information was successfully extracted,
- // this instance of container class should be
- // stored, and unchanged value of Signal should
- // be passed to the next (newly created) instance
- // of this container class.
- // Signal = -1 : there is no information for this type of
- // containers to extract. This instance of
- // container class should be deleted and input
- // for this type of container class terminated.
- // Signal < -1 : error. The code of error is determined as
- // -(Signal+1), then see Error_XXXXX constants
- // in <mmdb_defs.h>. This instance of container
- // class should be deleted and the whole input
- // should be stopped.
- virtual void GetCIF ( PCMMCIFData, int & Signal )
- { Signal = -1; }
- virtual int GetClassID () { return ClassID_Template; }
-
- virtual void Copy ( PCContainerClass ) {}
-
- void write ( RCFile ) {}
- void read ( RCFile ) {}
-
- protected :
- int ContinuationNo;
-
-};
-
-
-// ============== CContString ====================
-
-DefineClass(CContString)
-DefineStreamFunctions(CContString)
-
-class CContString : public CContainerClass {
-
- public :
-
- pstr Line; // a string
-
- CContString ();
- CContString ( cpstr S );
- CContString ( RPCStream Object );
- ~CContString();
-
- int ConvertPDBASCII ( cpstr S );
- void PDBASCIIDump ( pstr S, int N );
- Boolean PDBASCIIDump1 ( RCFile f );
- void MakeCIF ( PCMMCIFData CIF, int N );
- void GetCIF ( PCMMCIFData CIF, int & Signal );
- Boolean Append ( PCContainerClass ContString );
-
- int GetClassID () { return ClassID_String; }
-
- void Copy ( PCContainerClass CString );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
- pstr CIFCategory,CIFTag;
-
- void InitString();
-
-};
-
-
-// ============== CClassContainer ====================
-
-DefineClass(CClassContainer)
-DefineStreamFunctions(CClassContainer)
-
-class CClassContainer : public CStream {
-
- public :
-
- CClassContainer ();
- CClassContainer ( RPCStream Object );
- ~CClassContainer ();
-
- void FreeContainer ();
- void AddData ( PCContainerClass Data );
- virtual void PDBASCIIDump ( RCFile f );
- virtual void MakeCIF ( PCMMCIFData CIF );
- // GetCIF(..) will return one of the Error_XXXXX constants,
- // see <mmdb_defs.h>
- int GetCIF ( PCMMCIFData CIF, int ClassID );
- virtual PCContainerClass MakeContainerClass ( int ClassID );
-
- // Copy will empty the class if parameter is set to NULL
- virtual void Copy ( PCClassContainer CContainer );
-
- int Length() { return length; }
- PCContainerClass GetContainerClass ( int ContClassNo );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
- int length;
- PPCContainerClass Container;
-
- void Init();
-
-};
-
-
-// ====================== ID parsers ==========================
-
-DefineClass(CAtomPath)
-DefineStreamFunctions(CAtomPath)
-
-#define APATH_ModelNo 0x00000001
-#define APATH_ChainID 0x00000002
-#define APATH_SeqNum 0x00000004
-#define APATH_InsCode 0x00000008
-#define APATH_ResName 0x00000010
-#define APATH_AtomName 0x00000020
-#define APATH_Element 0x00000040
-#define APATH_AltLoc 0x00000080
-#define APATH_Incomplete 0x00000100
-#define APATH_WC_ModelNo 0x00001000
-#define APATH_WC_ChainID 0x00002000
-#define APATH_WC_SeqNum 0x00004000
-#define APATH_WC_InsCode 0x00008000
-#define APATH_WC_ResName 0x00010000
-#define APATH_WC_AtomName 0x00020000
-#define APATH_WC_Element 0x00040000
-#define APATH_WC_AltLoc 0x00080000
-
-class CAtomPath : public CStream {
-
- public :
-
- int modelNo;
- ChainID chainID;
- int seqNum;
- InsCode insCode;
- ResName resName;
- AtomName atomName;
- Element element;
- AltLoc altLoc;
- int isSet;
-
- CAtomPath ();
- CAtomPath ( cpstr ID );
- CAtomPath ( RPCStream Object );
- ~CAtomPath ();
-
- // SetPath(..) parses the Atom Path ID string, which
- // may be incomplete. Below {..} means blocks that
- // may be omitted; any elements within such blocks
- // may be omitted as well.
- //
- // 1. If ID starts with '/' then the ID must be of
- // the following form:
- // /mdl{/chn{/seq(res).i{/atm[elm]:a}}}
- //
- // 2. If ID starts with a letter:
- // chn{/seq(res).i{/atm[elm]:a}}
- //
- // 3. If ID starts with a number or '(':
- // seq(res).i{/atm[elm]:a}
- //
- // 4. If ID contains colon ':' or '[' then
- // it may be just
- // atm[elm]:a
- //
- // The following are valid samples of IDs:
- //
- // /1 model number 1
- // /1/A/23(GLU).A/CA[C]:A model number 1, chain A,
- // residue 23 GLU insertion code A, C-alpha
- // atom in alternative location A
- // A/23 residue 23 of chain A
- // CA[C]: atom C-alpha
- // [C] a carbon
- // *[C]:* same as above
- // :A an atom with insertion code A
- // 5 residue number 5
- // (GLU) residue GLU
- //
- // All spaces are ignored. SetPath(..) sets bit of isSet
- // for each element present. Any element may be a wildcard
- // '*'. Wildcard for model will set modelNo=0, for sequence
- // number will set seqNum=MinInt4.
- //
- // Returns:
- // 0 <-> Ok
- // -1 <-> wrong numerical format for model
- // -2 <-> wrong numerical format for sequence number
- int SetPath ( cpstr ID );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected :
- void InitAtomPath();
-
-};
-
-
-// --------------------------------------------------------------
-
-DefineClass(CQuickSort)
-
-class CQuickSort : public CStream {
-
- public :
- CQuickSort ();
- CQuickSort ( RPCStream Object );
- ~CQuickSort() {}
- virtual int Compare ( int i, int j );
- virtual void Swap ( int i, int j );
- void Sort ( void * sortdata, int data_len );
-
- protected :
- int selSortLimit,dlen;
- void * data;
-
- void SelectionSort ( int left, int right );
- int Partition ( int left, int right );
- void Quicksort ( int left, int right );
-
-};
-
-
-// --------------------------------------------------------------
-
-void takeWord ( pstr & p, pstr wrd, cpstr ter, int l );
-
-// ParseAtomID(..) reads the atom ID of the following form:
-// {name} {[element]} {:altcode}
-// (here {} means that the item may be omitted; any field may have
-// value of wildcard '*'), and returns the atom name in aname,
-// element name - in elname, and alternate location code - in aloc.
-// Except for the alternate location code, missing items are
-// replaced by wildcards. Missing alternate location code is
-// returned as empty string "".
-// Leading spaces are allowed; any other space will terminate
-// the parsing.
-// The followings are perfectly valid atom IDs:
-// CA[C]:A (carbon C_alpha in location A)
-// CA[*]:A (either C_alpha or Ca in location A)
-// CA:A (same as above)
-// CA (either C_alpha or Ca with no location indicator)
-// CA[] (same as above)
-// CA[C]: (C_alpha with no location indicator)
-// [C] (any carbon with no location indicator)
-// [C]:* (any carbon with any location indicator)
-// *[C]:* (same as above)
-// :A (any atom in location A)
-// *[*]:A (same as above)
-// *[*]:* (any atom)
-// * (any atom with no alternate location indicator)
-extern void ParseAtomID ( cpstr ID, AtomName aname,
- Element elname, AltLoc aloc );
-
-// ParseResID(..) reads the residue ID of the following form:
-// {seqnum} {(name)} {.inscode}
-// (here {} means that the item may be omitted; any field may have
-// value of wildcard '*'), and returns the sequence number in sn,
-// insertion code - in inscode, and residue name - in resname.
-// If a wildcard was specified for the sequence number, then
-// ParseResID(..) returns 1. Missing residue name is replaced by
-// the wildcard '*', and misisng insertion code is returned as empty
-// string "".
-// Leading spaces are allowed; any other space will terminate
-// the parsing.
-// Return 0 means Ok, 1 - wildcard for the sequence number,
-// 2 - an error in numerical format of the sequence number
-// (other items are parsed).
-// The followings are perfectly valid residue IDs:
-// 27(ALA).A (residue 27A ALA)
-// 27().A (residue 27A)
-// 27(*).A (same as above)
-// 27.A (same as above)
-// 27 (residue 27)
-// 27(). (same as above)
-// (ALA) (any ALA without insertion code)
-// (ALA). (same as above)
-// (ALA).* (any ALA)
-// *(ALA).* (any ALA)
-// .A (any residue with insertion code A)
-// *(*).A (same as above)
-// *(*).* (any residue)
-// * (any residue with no insertion code)
-extern int ParseResID ( cpstr ID, int & sn,
- InsCode inscode, ResName resname );
-
-
-// ParseAtomPath(..) parses an atom path string of the following
-// structure:
-// /mdl/chn/seq(res).i/atm[elm]:a
-// where all items may be represented by a wildcard '*' and
-// mdl - model number (mandatory); at least model #1 is always
-// present; returned in mdl; on a wildcard mdl is set to 0
-// chn - chain identifier ( mandatory); returned in chn; on a
-// wildcard chn is set to '*'
-// seq - residue sequence number (mandatory); returned in sn;
-// on a wild card ParseAtomPath(..) returns 1
-// (res) - residue name in round brackets (may be omitted);
-// returnded in res; on a wildcard res is set to '*'
-// .i - insert code after a dot; if '.i' or 'i' is missing
-// then a residue without an insertion code is looked for;
-// returned in ic; on a wildcard (any insertion code would
-// do) ic is set to '*'
-// atm - atom name (mandatory); returned in atm; on a wildcard
-// atm is set to '*'
-// [elm] - chemical element code in square brackets; it may
-// be omitted but could be helpful for e.g.
-// distinguishing C_alpha and CA; returned in elm;
-// in a wildcard elm is set to '*'
-// :a - alternate location indicator after colon; if
-// ':a' or 'a' is missing then an atom without
-// alternate location indicator is looked for; returned
-// in aloc; on a wildcard (any alternate code would do)
-// aloc is set to '*'.
-// All spaces are ignored, all identifiers should be in capital
-// letters (comparisons are case-sensitive).
-// The atom path string may be incomplete. If DefPath is supplied,
-// the function will try to get missing elements from there. If
-// missing items may not be found in DefPath, they are replaced by
-// wildcards.
-// ParseAtomPath(..) returns the following bits:
-// 0 - Ok
-// APATH_Incomplete - if path contains wildcards. Wildcards for
-// residue name and chemical element will be
-// ignored here if sequence number and
-// atom name, correspondingly, are provided.
-// APATH_WC_XXXXX - wildcard for different elements
-// -1 - wrong numerical format for model (fatal)
-// -2 - wrong numerical format for seqNum (fatal)
-
-extern int ParseAtomPath ( cpstr ID,
- int & mdl,
- ChainID chn,
- int & sn,
- InsCode ic,
- ResName res,
- AtomName atm,
- Element elm,
- AltLoc aloc,
- PCAtomPath DefPath=NULL );
-
-
-
-extern int ParseSelectionPath ( cpstr CID,
- int & iModel,
- pstr Chains,
- int & sNum1,
- InsCode ic1,
- int & sNum2,
- InsCode ic2,
- pstr RNames,
- pstr ANames,
- pstr Elements,
- pstr altLocs );
-
-
-
-extern void MakeSelectionPath ( pstr CID,
- int iModel,
- cpstr Chains,
- int sNum1,
- const InsCode ic1,
- int sNum2,
- const InsCode ic2,
- cpstr RNames,
- cpstr ANames,
- cpstr Elements,
- cpstr altLocs );
-
-#endif
-
diff --git a/mmdb/mmdb_xml.cpp b/mmdb/mmdb_xml.cpp
deleted file mode 100755
index 55bda48..0000000
--- a/mmdb/mmdb_xml.cpp
+++ /dev/null
@@ -1,954 +0,0 @@
-// $Id: mmdb_xml.cpp,v 1.25 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 29.01.10 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_XML <implementation>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CXMLObject
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2010
-//
-// =================================================================
-//
-
-#ifndef __STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifndef __STRING_H
-#include <string.h>
-#endif
-
-
-#ifndef __MMDB_XML__
-#include "mmdb_xml.h"
-#endif
-
-
-// ====================== CXMLObject ==========================
-
-CXMLObject::CXMLObject() : CStream() {
- InitXMLObject();
-}
-
-CXMLObject::CXMLObject ( cpstr Tag ) : CStream() {
- InitXMLObject();
- SetTag ( Tag );
-}
-
-CXMLObject::CXMLObject ( cpstr Tag, cpstr Data )
- : CStream() {
- InitXMLObject();
- SetTag ( Tag );
- SetData ( Data );
-}
-
-CXMLObject::CXMLObject ( cpstr Tag, realtype V, int length )
- : CStream() {
- InitXMLObject();
- SetTag ( Tag );
- SetData ( V,length );
-}
-
-CXMLObject::CXMLObject ( cpstr Tag, int iV, int length )
- : CStream() {
- InitXMLObject();
- SetTag ( Tag );
- SetData ( iV,length );
-}
-
-CXMLObject::CXMLObject ( cpstr Tag, Boolean bV ) : CStream() {
- InitXMLObject();
- SetTag ( Tag );
- SetData ( bV );
-}
-
-CXMLObject::CXMLObject ( cpstr Tag, PCXMLObject XMLObject )
- : CStream() {
- InitXMLObject();
- SetTag ( Tag );
- AddObject ( XMLObject );
-}
-
-
-CXMLObject::CXMLObject ( RPCStream Object ) : CStream(Object) {
- InitXMLObject();
-}
-
-CXMLObject::~CXMLObject() {
- FreeMemory();
-}
-
-void CXMLObject::InitXMLObject() {
- parent = NULL;
- objTag = NULL;
- objData = NULL;
- nObjects = 0;
- nAlloc = 0;
- object = NULL;
- nAttributes = 0;
- nAttrAlloc = 0;
- attr_name = NULL;
- attr_value = NULL;
-}
-
-void CXMLObject::FreeMemory() {
-int i;
-
- if (objTag) delete[] objTag;
- if (objData) delete[] objData;
-
- objTag = NULL;
- objData = NULL;
-
- if (object) {
- for (i=0;i<nAlloc;i++)
- if (object[i]) delete object[i];
- delete[] object;
- }
-
- nObjects = 0;
- nAlloc = 0;
- object = NULL;
-
- if (attr_name) {
- for (i=0;i<nAttrAlloc;i++) {
- if (attr_name [i]) delete[] attr_name [i];
- if (attr_value[i]) delete[] attr_value[i];
- }
- FreeVectorMemory ( attr_name ,0 );
- FreeVectorMemory ( attr_value,0 );
- }
-
- nAttributes = 0;
- nAttrAlloc = 0;
- attr_name = NULL;
- attr_value = NULL;
-
-}
-
-void CXMLObject::SetTag ( cpstr Tag ) {
-pstr p,t;
-int n;
-
- // count ampersands
- p = pstr(Tag);
- n = 0;
- while (*p) {
- if (*p=='&') n++;
- p++;
- }
- // calculate the tag length
- n = n*4 + strlen(Tag) + 1;
- // substract leading underscores
- p = pstr(Tag);
- while (*p=='_') {
- p++;
- n--;
- }
- // allocate tag space
- if (objTag) delete[] objTag;
- objTag = new char[n];
- // copy tag, replacing square brackets and ampersands
- t = objTag;
- while (*p) {
- if (*p=='[') {
- *t = '-';
- t++;
- } else if (*p==']') {
- if ((p[1]) && (p[1]!='[')) {
- *t = '-';
- t++;
- }
- } else if (*p=='&') {
- strcpy ( t,"_and_" );
- if (p[1]) t += 5;
- else t += 4;
- } else {
- *t = *p;
- t++;
- }
- p++;
- }
- *t = char(0);
-}
-
-void CXMLObject::AddAttribute ( cpstr name, cpstr value ) {
-psvector an,av;
-int i;
-
- if (nAttributes>=nAttrAlloc) {
- nAttrAlloc = nAttributes + 10;
- GetVectorMemory ( an,nAttrAlloc,0 );
- GetVectorMemory ( av,nAttrAlloc,0 );
- for (i=0;i<nAttrAlloc;i++) {
- an[i] = NULL;
- av[i] = NULL;
- }
- for (i=0;i<nAttributes;i++) {
- CreateCopy ( an[i],attr_name [i] );
- CreateCopy ( av[i],attr_value[i] );
- if (attr_name [i]) delete[] attr_name [i];
- if (attr_value[i]) delete[] attr_value[i];
- }
- FreeVectorMemory ( attr_name ,0 );
- FreeVectorMemory ( attr_value,0 );
- attr_name = an;
- attr_value = av;
- }
-
- CreateCopy ( attr_name [nAttributes],name );
- CreateCopy ( attr_value[nAttributes],value );
- nAttributes++;
-
-}
-
-void CXMLObject::AddAttribute ( cpstr name, const int iV ) {
-char S[100];
- sprintf ( S,"%i",iV );
- AddAttribute ( name,S );
-}
-
-void CXMLObject::AddAttribute ( cpstr name, const Boolean bV ) {
- if (bV) AddAttribute ( name,"Yes" );
- else AddAttribute ( name,"No" );
-}
-
-void CXMLObject::SetData ( cpstr Data ) {
-pstr p,d;
-int n;
- // count ampersands
- p = pstr(Data);
- n = 0;
- while (*p) {
- if (*p=='&') n += 4;
- p++;
- }
- // calculate the Data length
- n += strlen(Data) + 1; // eugene
- // allocate data space
- if (objData) delete[] objData;
- objData = new char[n];
- // copy data, preceeding ampersands with the escape
- p = pstr(Data);
- d = objData;
- while (*p) {
- if (*p=='&') {
- d[0] = '&';
- d[1] = 'a';
- d[2] = 'm';
- d[3] = 'p';
- d[4] = ';';
- d += 5;
- } else {
- *d = *p;
- d++;
- }
- p++;
- }
- *d = char(0);
-}
-
-void CXMLObject::AddData ( cpstr Data ) {
-pstr d1,d2;
- d1 = objData;
- objData = NULL;
- SetData ( Data );
- d2 = objData;
- objData = NULL;
- CreateConcat ( objData,d1,d2 );
-}
-
-void CXMLObject::SetData ( const realtype V, const int length ) {
-char N[500];
- sprintf ( N,"%-.*g",length,V );
- CreateCopy ( objData,N );
-}
-
-void CXMLObject::SetData ( const int iV, const int length ) {
-char N[500];
- sprintf ( N,"%*i",length,iV );
- CreateCopy ( objData,N );
-}
-
-void CXMLObject::SetData ( const Boolean bV ) {
- if (bV) CreateCopy ( objData,pstr("Yes") );
- else CreateCopy ( objData,pstr("No") );
-}
-
-
-int CXMLObject::AddMMCIFCategory ( PCMMCIFCategory mmCIFCat ) {
- if (mmCIFCat->GetCategoryID()==MMCIF_Loop)
- return AddMMCIFLoop ( PCMMCIFLoop(mmCIFCat) );
- if (mmCIFCat->GetCategoryID()==MMCIF_Struct)
- return AddMMCIFStruct ( PCMMCIFStruct(mmCIFCat) );
- return -1;
-}
-
-pstr getCCIFTag ( pstr & ccifTag, cpstr Tag ) {
- if (Tag[0]=='_') return CreateCopCat ( ccifTag,pstr("ccif") ,Tag );
- else return CreateCopCat ( ccifTag,pstr("ccif_"),Tag );
-}
-
-int CXMLObject::AddMMCIFStruct ( PCMMCIFStruct mmCIFStruct ) {
-PCXMLObject XMLObject1,XMLObject2;
-pstr SName,Tag,Field, ccifTag;
-int nTags,i,k;
-
- XMLObject1 = this;
-
- ccifTag = NULL;
-
- SName = mmCIFStruct->GetCategoryName();
- if (SName) {
- if (SName[0]!=char(1))
- XMLObject1 = new CXMLObject ( getCCIFTag(ccifTag,SName) );
- }
-
- k = 0;
- nTags = mmCIFStruct->GetNofTags();
- for (i=0;i<nTags;i++) {
- Tag = mmCIFStruct->GetTag ( i );
- if (Tag) {
- XMLObject2 = new CXMLObject ( getCCIFTag(ccifTag,Tag) );
- Field = mmCIFStruct->GetField ( i );
- if (Field) {
- if (Field[0]!=char(2)) XMLObject2->SetData ( Field );
- else XMLObject2->SetData ( &(Field[1]) );
- }
- XMLObject1->AddObject ( XMLObject2 );
- k++;
- }
- }
-
- if (SName) {
- if (SName[0]!=char(1))
- AddObject ( XMLObject1 );
- }
-
- if (ccifTag) delete[] ccifTag;
-
- return k;
-
-}
-
-int CXMLObject::AddMMCIFLoop ( PCMMCIFLoop mmCIFLoop ) {
-PCXMLObject XMLObject1,XMLObject2,XMLObject3;
-pstr SName,Tag,Field,ccifTag;
-int nTags,nRows,i,j,k;
-
- XMLObject1 = this;
-
- ccifTag = NULL;
-
- SName = mmCIFLoop->GetCategoryName();
- if (SName) {
- if (SName[0]!=char(1))
- XMLObject1 = new CXMLObject ( getCCIFTag(ccifTag,SName) );
- }
-
- k = 0;
- nTags = mmCIFLoop->GetNofTags ();
- nRows = mmCIFLoop->GetLoopLength();
- for (i=0;i<nRows;i++) {
- XMLObject2 = new CXMLObject ( pstr("row"),
- new CXMLObject(pstr("_sernum_"),i+1) );
- for (j=0;j<nTags;j++) {
- Tag = mmCIFLoop->GetTag ( j );
- if (Tag) {
- XMLObject3 = new CXMLObject ( getCCIFTag(ccifTag,Tag) );
- Field = mmCIFLoop->GetField ( i,j );
- if (Field) {
- if (Field[0]!=char(2)) XMLObject3->SetData ( Field );
- else XMLObject3->SetData ( &(Field[1]) );
- }
- XMLObject2->AddObject ( XMLObject3 );
- k++;
- }
- }
- XMLObject1->AddObject ( XMLObject2 );
- }
-
- if (SName) {
- if (SName[0]!=char(1))
- AddObject ( XMLObject1 );
- }
-
- if (ccifTag) delete[] ccifTag;
-
- return k;
-
-}
-
-int CXMLObject::AddMMCIFData ( PCMMCIFData mmCIFData ) {
-PCMMCIFCategory mmCIFCat;
-int nCats,i,k,n;
- nCats = mmCIFData->GetNumberOfCategories();
- k = 0;
- n = 0;
- for (i=0;(i<nCats) && (n>=0);i++) {
- mmCIFCat = mmCIFData->GetCategory ( i );
- if (mmCIFCat) {
- if (mmCIFCat->GetCategoryID()==MMCIF_Loop)
- n = AddMMCIFLoop ( PCMMCIFLoop(mmCIFCat) );
- else if (mmCIFCat->GetCategoryID()==MMCIF_Struct)
- n = AddMMCIFStruct ( PCMMCIFStruct(mmCIFCat) );
- else
- n = -1;
- if (n>=0) k += n;
- }
- }
- if (n<0) return -(k+1);
- return k;
-}
-
-pstr CXMLObject::GetData ( cpstr Tag, int objNo ) {
-PCXMLObject XMLObject;
- XMLObject = GetObject ( Tag,objNo );
- if (XMLObject) return XMLObject->objData;
- return NULL;
-}
-
-int CXMLObject::GetData ( pstr & Data, cpstr Tag, int objNo ) {
-PCXMLObject XMLObject;
- XMLObject = GetObject ( Tag,objNo );
- if (XMLObject) {
- Data = XMLObject->objData;
- return 0;
- } else {
- Data = NULL;
- return 1;
- }
-}
-
-int CXMLObject::GetData ( realtype & V, cpstr Tag, int objNo ) {
-int rc;
-pstr d,p;
- rc = GetData ( d,Tag,objNo );
- if (d) {
- V = strtod(d,&p);
- if ((V==0.0) && (p==d)) rc = 2;
- else rc = 0;
- } else if (!rc)
- rc = -1;
- return rc;
-}
-
-int CXMLObject::GetData ( int & iV, cpstr Tag, int objNo ) {
-int rc;
-pstr d,p;
- rc = GetData ( d,Tag,objNo );
- if (d) {
- iV = mround(strtod(d,&p));
- if ((iV==0) && (p==d)) rc = 2;
- else rc = 0;
- } else if (!rc)
- rc = -1;
- return rc;
-}
-
-int CXMLObject::GetData ( Boolean & bV, cpstr Tag, int objNo ) {
-int rc;
-pstr d;
- rc = GetData ( d,Tag,objNo );
- if (d) {
- if (!strcasecmp(d,"Yes"))
- bV = True;
- else {
- bV = False;
- if (strcasecmp(d,"No")) rc = 2;
- }
- } else if (!rc)
- rc = -1;
- return rc;
-}
-
-PCXMLObject CXMLObject::GetObject ( cpstr Tag, int objNo ) {
-// allow for "tag1>tag2>tag3>..."
-PCXMLObject XMLObject;
-int i,j,k,l;
-pstr p,p1;
- XMLObject = this;
- if (Tag) {
- p = pstr(Tag);
- do {
- p1 = p;
- l = 0;
- while (*p1 && (*p1!='>')) {
- p1++;
- l++;
- }
- if (l>0) {
- k = -1;
- j = 0;
- for (i=0;(i<XMLObject->nObjects) && (k<0);i++)
- if (XMLObject->object[i]) {
- if (!strncmp(XMLObject->object[i]->objTag,p,l)) {
- j++;
- if (j==objNo) k = i;
- }
- }
- if (k<0) {
- XMLObject = NULL;
- l = 0;
- } else {
- XMLObject = XMLObject->object[k];
- if (*p1) p = p1 + 1;
- else l = 0;
- }
- }
- } while (l>0);
- }
- return XMLObject;
-}
-
-PCXMLObject CXMLObject::GetFirstObject() {
- if (nObjects>0) return object[0];
- return NULL;
-}
-
-PCXMLObject CXMLObject::GetLastObject() {
- if (nObjects>0) return object[nObjects-1];
- return NULL;
-}
-
-PCXMLObject CXMLObject::GetObject ( int objectNo ) {
- if ((0<=objectNo) && (objectNo<nObjects))
- return object[objectNo];
- return NULL;
-}
-
-
-void CXMLObject::AddObject ( PCXMLObject XMLObject, int lenInc ) {
-PPCXMLObject obj1;
-int i;
-
- if (!XMLObject) return;
-
- if (nObjects>=nAlloc) {
- nAlloc += lenInc;
- obj1 = new PCXMLObject[nAlloc];
- for (i=0;i<nObjects;i++)
- obj1[i] = object[i];
- for (i=nObjects;i<nAlloc;i++)
- obj1[i] = NULL;
- if (object) delete[] object;
- object = obj1;
- }
-
- if (object[nObjects]) delete object[nObjects];
- object[nObjects] = XMLObject;
- XMLObject->SetParent ( this );
- nObjects++;
-
-}
-
-int CXMLObject::WriteObject ( cpstr FName, int pos, int indent ) {
-CFile f;
- f.assign ( FName,True );
- if (f.rewrite()) {
- WriteObject ( f,pos,indent );
- f.shut();
- return 0;
- }
- return 1;
-}
-
-void CXMLObject::WriteObject ( RCFile f, int pos, int indent ) {
-int i,pos1,lm,rm,tl;
-pstr indstr,p,p1,q;
-Boolean sngline;
-
- if (objTag) {
-
- pos1 = pos + indent;
- indstr = new char[pos1+1];
- for (i=0;i<pos1;i++) indstr[i] = ' ';
- indstr[pos1] = char(0);
-
- indstr[pos] = char(0);
- f.Write ( indstr );
- f.Write ( pstr("<") );
- f.Write ( objTag );
- for (i=0;i<nAttributes;i++) {
- f.Write ( " " );
- f.Write ( attr_name[i] );
- f.Write ( "=\"" );
- f.Write ( attr_value[i] );
- f.Write ( "\"" );
- }
- if ((!objData) && (nObjects<=0)) {
- f.WriteLine ( pstr("/>") );
- delete[] indstr;
- return;
- }
- f.Write ( pstr(">") );
-
- sngline = False;
- if (objData) {
- rm = 72; // right margin
- lm = IMin ( pos1,36 ); // left margin
- tl = strlen(objTag);
- if ((pos+tl+2+(int)strlen(objData)<rm-tl-2) &&
- (nObjects<=0)) {
- // single-line output
- sngline = True;
- f.Write ( objData );
- } else {
- // multiple-line output with indentation
- indstr[pos] = ' ';
- indstr[lm] = char(0);
- f.LF();
- p = objData;
- do {
- p1 = p;
- i = lm;
- q = NULL;
- while ((*p1) && ((i<rm) || (!q))) {
- if (*p1==' ') q = p1;
- p1++;
- i++;
- }
- f.Write ( indstr );
- if (*p1) { // wrap data
- *q = char(0);
- f.WriteLine ( p );
- *q = ' ';
- p = q;
- while (*p==' ') p++;
- if (*p==char(0)) p = NULL;
-
- } else { // data exchausted
- f.WriteLine ( p );
- p = NULL;
- }
- } while (p);
- indstr[lm] = ' ';
- indstr[pos] = char(0);
- }
- } else
- f.LF();
-
- for (i=0;i<nObjects;i++)
- if (object[i])
- object[i]->WriteObject ( f,pos+indent,indent );
-
- if (!sngline) f.Write ( indstr );
- f.Write ( pstr("</") );
- f.Write ( objTag );
- f.WriteLine ( pstr(">") );
-
- delete[] indstr;
-
- }
-
-}
-
-
-int CXMLObject::ReadObject ( cpstr FName ) {
-CFile f;
-char S[500];
-int i,rc;
-
- f.assign ( FName,True );
- if (f.reset(True)) {
- S[0] = char(0);
- i = 0;
- rc = ReadObject ( f,S,i,sizeof(S) );
- f.shut();
- } else
- rc = XMLR_NoFile;
-
- if (rc) FreeMemory();
-
- return rc;
-
-}
-
-int CXMLObject::ReadObject ( RCFile f, pstr S, int & pos, int slen ) {
-PCXMLObject XMLObject;
-pstr S1;
-int k,k1,k2,rc;
-Boolean Done;
-
- FreeMemory();
-
- rc = XMLR_Ok;
-
- k1 = -1;
- k2 = -1;
- while ((!f.FileEnd()) && (k1<0)) {
- k = strlen(S);
- while ((pos<k) && (k1<0))
- if (S[pos]=='<') {
- if (S[pos+1]=='?') // in this version, ignore <?xxx ?>
- // constructions
- pos++;
- else if (S[pos+1]!='<')
- k1 = pos;
- else pos += 2;
- } else
- pos++;
- if (k1>=0) {
- k2 = -1;
- while ((pos<k) && (k2<0))
- if (S[pos]=='>') {
- if (S[pos+1]!='>') k2 = pos;
- else pos += 2;
- } else
- pos++;
- if (k2<0) rc = XMLR_BrokenTag;
- }
- if (k1<0) {
- f.ReadLine ( S,slen );
- pos = 0;
- }
- }
-
- if (k1<0) return XMLR_NoTag;
- if (rc!=XMLR_Ok) return rc;
-
- pos++;
- if (S[k2-1]=='/') { // <Tag/>
- S[k2-1] = char(0);
- CreateCopy ( objTag,&(S[k1+1]) );
- return XMLR_Ok;
- }
-
- S[k2] = char(0);
- CreateCopy ( objTag,&(S[k1+1]) );
- S[k2] = '>';
-
- S1 = new char[slen+1];
- Done = False;
- while ((!f.FileEnd()) && (!Done)) {
- k = strlen(S);
- while ((pos<k) && (!Done)) {
- k1 = pos;
- k2 = -1;
- while ((pos<k) && (k2<0))
- if (S[pos]=='<') {
- if (S[pos+1]!='<') k2 = pos;
- else pos +=2;
- } else
- pos++;
- if (k2>=0) S[k2] = char(0);
- strcpy_des ( S1,&(S[k1]) );
- if (S1[0]) {
- if (objData) CreateConcat ( objData,pstr(" "),S1 );
- else CreateConcat ( objData,S1 );
- }
- if (k2>=0) {
- S[k2] = '<';
- if (S[k2+1]!='/') {
- XMLObject = new CXMLObject();
- AddObject ( XMLObject );
- rc = XMLObject->ReadObject ( f,S,pos,slen );
- Done = (rc!=XMLR_Ok);
- } else {
- Done = True;
- k1 = k2+2;
- k2 = -1;
- while ((pos<k) && (k2<0))
- if (S[pos]=='>') {
- if (S[pos+1]!='>') k2 = pos;
- else pos += 2;
- } else
- pos++;
- if (k2<0)
- rc = XMLR_BrokenTag;
- else {
- S[k2] = char(0);
- if (strcmp(objTag,&(S[k1]))) rc = XMLR_UnclosedTag;
- else pos++;
- }
- }
- }
- }
- if (!Done) {
- f.ReadLine ( S,slen );
- pos = 0;
- }
- }
-
- delete[] S1;
-
- // this keeps pairs <tag></tag> instead of replacing them for <tag/>
- // on output
- if ((!objData) && (nObjects<=0))
- CreateCopy ( objData,pstr("") );
-
- if (rc!=XMLR_Ok) FreeMemory();
- return rc;
-
-}
-
-
-void CXMLObject::Copy ( PCXMLObject XMLObject ) {
-int i;
-
- FreeMemory();
-
- CreateCopy ( objTag ,XMLObject->objTag );
- CreateCopy ( objData,XMLObject->objData );
-
- nObjects = XMLObject->nObjects;
- nAlloc = nObjects;
- if (nObjects>0) {
- object = new PCXMLObject[nObjects];
- for (i=0;i<nObjects;i++)
- if (XMLObject->object[i]) {
- object[i] = new CXMLObject();
- object[i]->Copy ( XMLObject->object[i] );
- } else
- object[i] = NULL;
- }
-
- nAttributes = XMLObject->nAttributes;
- nAttrAlloc = nAttributes;
- if (nAttributes>0) {
- GetVectorMemory ( attr_name ,nAttrAlloc,0 );
- GetVectorMemory ( attr_value,nAttrAlloc,0 );
- for (i=0;i<nAttributes;i++) {
- attr_name [i] = NULL;
- attr_value[i] = NULL;
- CreateCopy ( attr_name [i],XMLObject->attr_name [i] );
- CreateCopy ( attr_value[i],XMLObject->attr_value[i] );
- }
- }
-
-}
-
-
-void CXMLObject::write ( RCFile f ) {
-int i;
- f.CreateWrite ( objTag );
- f.CreateWrite ( objData );
- f.WriteInt ( &nObjects );
- for (i=0;i<nObjects;i++)
- StreamWrite ( f,object[i] );
- f.WriteInt ( &nAttributes );
- for (i=0;i<nAttributes;i++) {
- f.CreateWrite ( attr_name [i] );
- f.CreateWrite ( attr_value[i] );
- }
-}
-
-void CXMLObject::read ( RCFile f ) {
-int i;
-
- FreeMemory();
-
- f.CreateRead ( objTag );
- f.CreateRead ( objData );
-
- f.ReadInt ( &nObjects );
- nAlloc = nObjects;
- if (nObjects>0) {
- object = new PCXMLObject[nObjects];
- for (i=0;i<nObjects;i++) {
- object[i] = NULL;
- StreamRead ( f,object[i] );
- }
- }
-
- f.ReadInt ( &nAttributes );
- nAttrAlloc = nAttributes;
- if (nAttributes>0) {
- GetVectorMemory ( attr_name ,nAttrAlloc,0 );
- GetVectorMemory ( attr_value,nAttrAlloc,0 );
- for (i=0;i<nAttributes;i++) {
- attr_name [i] = NULL;
- attr_value[i] = NULL;
- f.CreateRead ( attr_name [i] );
- f.CreateRead ( attr_value[i] );
- }
- }
-
-}
-
-
-MakeStreamFunctions(CXMLObject)
-
-
-
-PCXMLObject mmCIF2XML ( PCMMCIFData mmCIFData, int * rc ) {
-PCXMLObject XMLObject;
-pstr dataName;
-int k;
- XMLObject = NULL;
- if (rc) *rc = -2;
- if (mmCIFData) {
- dataName = mmCIFData->GetDataName();
- if (dataName) {
- if (dataName[0])
- XMLObject = new CXMLObject ( dataName );
- }
- if (!XMLObject)
- XMLObject = new CXMLObject ( pstr("no_data_name") );
- k = XMLObject->AddMMCIFData ( mmCIFData );
- if (rc) *rc = k;
- }
- return XMLObject;
-}
-
-PCXMLObject mmCIF2XML ( cpstr XMLName, PCMMCIFFile mmCIFFile,
- int * rc ) {
-PCXMLObject XMLObject1,XMLObject2;
-PCMMCIFData mmCIFData;
-int nData,i,k,rc1;
- XMLObject1 = new CXMLObject ( XMLName );
- if (rc) *rc = -1;
- if (mmCIFFile) {
- nData = mmCIFFile->GetNofData();
- k = 0;
- rc1 = 0;
- for (i=0;(i<nData) && (rc1>=0);i++) {
- mmCIFData = mmCIFFile->GetCIFData ( i );
- if (mmCIFData) {
- XMLObject2 = mmCIF2XML ( mmCIFData,&rc1 );
- if (XMLObject2) {
- if (rc1>=0) {
- XMLObject1->AddObject ( XMLObject2 );
- k += rc1;
- } else
- delete XMLObject2;
- }
- }
- }
- if (rc1<0) {
- delete XMLObject1;
- if (rc) *rc = -2;
- } else if (rc)
- *rc = k;
- }
- return XMLObject1;
-}
-
diff --git a/mmdb/mmdb_xml.h b/mmdb/mmdb_xml.h
deleted file mode 100755
index 944dd5d..0000000
--- a/mmdb/mmdb_xml.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// $Id: mmdb_xml.h,v 1.20 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 08.07.08 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : MMDB_XML <interface>
-// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes : CXMLObject
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 2000-2008
-//
-// =================================================================
-//
-
-#ifndef __MMDB_XML__
-#define __MMDB_XML__
-
-
-#ifndef __MMDB_MMCIF__
-#include "mmdb_mmcif.h"
-#endif
-
-
-
-// ====================== CXMLObject ==========================
-
-#define XMLR_Ok 0
-#define XMLR_NoFile 1
-#define XMLR_NoTag 2
-#define XMLR_BrokenTag 3
-#define XMLR_UnclosedTag 4
-
-DefineClass(CXMLObject);
-DefineStreamFunctions(CXMLObject);
-
-class CXMLObject : public CStream {
-
- public :
-
- CXMLObject ();
- CXMLObject ( cpstr Tag );
- CXMLObject ( cpstr Tag, cpstr Data );
- CXMLObject ( cpstr Tag, realtype V, int length=11 );
- CXMLObject ( cpstr Tag, int iV, int length=0 );
- CXMLObject ( cpstr Tag, Boolean bV );
- CXMLObject ( cpstr Tag, PCXMLObject XMLObject );
- CXMLObject ( RPCStream Object );
- ~CXMLObject();
-
- void SetTag ( cpstr Tag );
- void AddAttribute ( cpstr name, cpstr value );
- void AddAttribute ( cpstr name, const int iV );
- void AddAttribute ( cpstr name, const Boolean bV );
- void SetData ( cpstr Data );
- void AddData ( cpstr Data );
- void SetData ( const realtype V, const int length=11 );
- void SetData ( const int iV, const int length=0 );
- void SetData ( const Boolean bV );
-
- int AddMMCIFCategory ( PCMMCIFCategory mmCIFCat );
- int AddMMCIFStruct ( PCMMCIFStruct mmCIFStruct );
- int AddMMCIFLoop ( PCMMCIFLoop mmCIFLoop );
- int AddMMCIFData ( PCMMCIFData mmCIFData );
-
- pstr GetTag () { return objTag; }
-
- // Here and below the functions allow for "tag1>tag2>tag3>..."
- // as a composite multi-level tag, e.g. the above may stand for
- // <tag1><tag2><tag3>data</tag3></tag2></tag1>. NULL tag
- // corresponds to "this" object.
- // objNo counts same-tag objects of the *highest* level used
- // (e.g. level tag3 for composite tag tag1>tag2>tag3 ).
- // GetData ( pstr& ... ) only copies a pointer to data.
- pstr GetData ( cpstr Tag=NULL, int objNo=1 );
- int GetData ( pstr & Data, cpstr Tag=NULL, int objNo=1 );
- int GetData ( realtype & V, cpstr Tag=NULL, int objNo=1 );
- int GetData ( int & iV, cpstr Tag=NULL, int objNo=1 );
- int GetData ( Boolean & bV, cpstr Tag=NULL, int objNo=1 );
-
- PCXMLObject GetObject ( cpstr Tag, int objNo=1 );
- PCXMLObject GetFirstObject();
- PCXMLObject GetLastObject ();
- inline int GetNumberOfObjects() { return nObjects; }
- PCXMLObject GetObject ( int objectNo ); // 0,1,...
-
- inline PCXMLObject GetParent() { return parent; }
-
- void AddObject ( PCXMLObject XMLObject , int lenInc=10 );
- int WriteObject ( cpstr FName, int pos=0, int ident=2 );
- void WriteObject ( RCFile f, int pos=0, int ident=2 );
- int ReadObject ( cpstr FName );
- int ReadObject ( RCFile f, pstr S, int & pos, int slen );
-
- virtual void Copy ( PCXMLObject XMLObject );
-
- void write ( RCFile f );
- void read ( RCFile f );
-
- protected:
- PCXMLObject parent;
- pstr objTag;
- pstr objData;
- int nObjects,nAlloc;
- PPCXMLObject object;
- int nAttributes,nAttrAlloc;
- psvector attr_name,attr_value;
-
- void InitXMLObject();
- virtual void FreeMemory ();
-
- inline void SetParent ( PCXMLObject p ) { parent = p; }
-
-};
-
-
-extern PCXMLObject mmCIF2XML ( PCMMCIFData mmCIFData, int * rc=NULL );
-extern PCXMLObject mmCIF2XML ( cpstr XMLName, PCMMCIFFile mmCIFFile,
- int * rc=NULL );
-
-#endif
-
-
diff --git a/mmdb/random_n.cpp b/mmdb/random_n.cpp
deleted file mode 100755
index a32759d..0000000
--- a/mmdb/random_n.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-// $Id: random_n.cpp,v 1.19 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 05.02.03 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : Random_N <implementation>
-// ~~~~~~~~~
-// **** Classes : CRandomNimber ( random number generator )
-// ~~~~~~~~~
-//
-// (C) E. Krissinel' 1997-2008
-//
-// =================================================================
-//
-
-#ifndef __MATH_H
-#include <math.h>
-#endif
-
-#ifndef __Random_N__
-#include "random_n.h"
-#endif
-
-
-// =================== CRandomNumber ==========================
-
-CRandomNumber::CRandomNumber ( long IJ, long KL ) {
- Init ( IJ,KL );
-}
-
-void CRandomNumber::Init ( long IJ, long KL ) {
-long i,j,k,l,m, ii,jj;
-realtype s,t;
-
- iset = 0;
- gset = 0.0;
-
- if ((IJ<0) || (IJ>_RN_MAX_IJ) ||
- (KL<0) || (KL>_RN_MAX_KL)) return;
-
- i = mod(IJ/177,177) + 2;
- j = mod(IJ,177) + 2;
- k = mod(KL/169,178) + 1;
- l = mod(KL,169);
-
- for (ii=0;ii<97;ii++) {
- s = 0.0;
- t = 0.5;
- for (jj=1;jj<=24;jj++) {
- m = mod(mod(i*j,179)*k,179);
- i = j;
- j = k;
- k = m;
- l = mod(53*l+1,169);
- if (mod(l*m,64)>=32) s += t;
- t *= 0.5;
- }
- U[ii] = s;
- }
-
- C = 362436.0 / 16777216.0;
- CD = 7654321.0 / 16777216.0;
- CM = 16777213.0 / 16777216.0;
-
- I97 = 96;
- J97 = 32;
-
-}
-
-
-// uniform [0..1] random number generator
-realtype CRandomNumber::random() {
-realtype uni;
-
- uni = U[I97] - U[J97];
- if (uni<0.0) uni += 1.0;
- U[I97] = uni;
- I97--;
- if (I97<0) I97 = 96;
- J97--;
- if (J97<0) J97 = 96;
- C -= CD;
- if (C<0.0) C += CM;
- uni -= C;
- if (uni<0.0) uni += 1.0;
-
- return uni;
-
-}
-
-
-// uniform [-1..1] random number generator
-realtype CRandomNumber::srandom() {
-realtype uni;
-
- uni = U[I97] - U[J97];
- if (uni<0.0) uni += 1.0;
- U[I97] = uni;
- I97--;
- if (I97<0) I97 = 96;
- J97--;
- if (J97<0) J97 = 96;
- C -= CD;
- if (C<0.0) C += CM;
- uni -= C;
- if (uni<0.0) uni += 1.0;
-
- return 2.0*uni - 1.0;
-
-}
-
-// gaussian random numbers
-realtype CRandomNumber::gauss_rnd() {
-realtype v1,v2,r,fac;
- if (iset==0) {
- do {
- v1 = srandom();
- v2 = srandom();
- r = v1*v1 + v2*v2;
- } while ((r>=1.0) || (r==0.0));
- fac = sqrt(-2.0*log(r)/r);
- gset = v1*fac;
- iset = 1;
- return v2*fac;
- } else {
- iset = 0;
- return gset;
- }
-}
-
-void CRandomNumber::write ( RCFile f ) {
-int Version=1;
- f.WriteFile ( &Version,sizeof(Version) );
- f.WriteFile ( &I97 ,sizeof(I97) );
- f.WriteFile ( &J97 ,sizeof(J97) );
- f.WriteFile ( U ,sizeof(U) );
- f.WriteFile ( &C ,sizeof(C) );
- f.WriteFile ( &CD ,sizeof(CD) );
- f.WriteFile ( &CM ,sizeof(CM) );
- f.WriteFile ( &gset ,sizeof(gset) );
- f.WriteFile ( &iset ,sizeof(iset) );
-}
-
-void CRandomNumber::read ( RCFile f ) {
-int Version;
- f.ReadFile ( &Version,sizeof(Version) );
- f.ReadFile ( &I97 ,sizeof(I97) );
- f.ReadFile ( &J97 ,sizeof(J97) );
- f.ReadFile ( U ,sizeof(U) );
- f.ReadFile ( &C ,sizeof(C) );
- f.ReadFile ( &CD ,sizeof(CD) );
- f.ReadFile ( &CM ,sizeof(CM) );
- f.ReadFile ( &gset ,sizeof(gset) );
- f.ReadFile ( &iset ,sizeof(iset) );
-}
-
-/*
-
-static int m1 = 259200;
-static int ia1 = 7141;
-static int ic1 = 54773;
-static realtype rm1 = 1.0/259200.0;
-
-static int m2 = 134456;
-static int ia2 = 8121;
-static int ic2 = 28411;
-static realtype rm2 = 1.0/134456.0;
-
-static int m3 = 243000;
-static int ia3 = 4561;
-static int ic3 = 51349;
-
-static int ix1 = 0;
-static int ix2 = 0;
-static int ix3 = 0;
-
-static realtype R[97];
-
-void randomize ( int iseed ) {
-int j;
- RndInit = True;
- ix1 = mod(ic1-iseed,m1);
- ix1 = mod(ia1*ix1+ic1,m1);
- ix2 = mod(ix1,m2);
- ix1 = mod(ia1*ix1+ic1,m1);
- ix3 = mod(ix1,m3);
- for (j=0;j<97;j++) {
- ix1 = mod(ia1*ix1+ic1,m1);
- ix2 = mod(ia2*ix2+ic2,m2);
- R[j] = (ix1+ix2*rm2)*rm1;
- }
-}
-
-realtype rand() {
-int j;
-realtype rnd;
- if (!RndInit) randomize();
- ix1 = mod(ia1*ix1+ic1,m1);
- ix2 = mod(ia2*ix2+ic2,m2);
- ix3 = mod(ia3*ix3+ic3,m3);
- j = 1 + (97*ix3)/m3;
- j = IMax(j,1);
- j = IMin(j,97);
- rnd = R[j-1];
- R[j] = (ix1+ix2*rm2)*rm1;
- return rnd;
-}
-*/
-
-// ===========================================================
-
-// End of Random_N
diff --git a/mmdb/stream_.cpp b/mmdb/stream_.cpp
deleted file mode 100755
index 7abf662..0000000
--- a/mmdb/stream_.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-// $Id: stream_.cpp,v 1.20 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 29.01.10 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : CStream_ <interface>
-// ~~~~~~~~~
-// **** Classes : CStream ( Basic Stream Class )
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 1995-2010
-//
-// =================================================================
-//
-
-#ifndef __Stream__
-#include "stream_.h"
-#endif
-
-// ========================== CStream ===========================
-
-// Each streamable class should be derived from CStream
-// and have constructor CClass(PCStream & Object), which should
-// initialize all memory of the class, and virtual functions
-// read(..) and write(..) (see below). Constructor CClass(PCStream&)
-// must not touch the Object variable. This constructor is used
-// only once just before read(..) function. It is assumed that
-// read/write functions of CClass provide storage/reading of
-// all vital data. Function read(..) must read data in exactly
-// the same way as function write(..) stores it.
-// For using CClass in streams, three following functions should
-// be supplied:
-//
-// 1.
-// void StreamWrite ( RCFile f, RPCClass Object ) {
-// StreamWrite ( f,(PCStream)PCClass );
-// }
-//
-// 2.
-// PCStream CClassInit ( RPCStream Object ) {
-// return (PCStream)(new CClass(Object));
-// }
-//
-// 3.
-// void StreamRead ( RCFile f, RPCClass Object ) {
-// StreamRead_ ( f,(PCStream)Object,CClassInit );
-// }
-//
-// All these functions are automatically generated by macros
-// DefineStreamFunctions(CClass) -- in the header -- and
-// MakeStreamFunctions(CClass) -- in the implementation body.
-// Then CClass may be streamed in/out using functions #1 and #3.
-// StreamRead will return NULL for Object if it was not
-// in the stream. If Object existed before StreamRead(..) but
-// was not found in the stream, it will be disposed.
-
-void StreamRead_ ( RCFile f, RPCStream Object,
- InitStreamObject Init ) {
-int i;
- f.ReadInt ( &i );
- if (i) {
- if (!Object)
- Object = Init(Object); //Object = new CStream ( Object );
- Object->read ( f );
- } else {
- if (Object) delete Object;
- Object = NULL;
- }
-}
-
-void StreamWrite_ ( RCFile f, RPCStream Object ) {
-int i;
- if (Object) {
- i = 1;
- f.WriteInt ( &i );
- Object->write ( f );
- } else {
- i = 0;
- f.WriteInt ( &i );
- }
-}
-
-MakeStreamFunctions(CStream)
diff --git a/mmdb/stream_.h b/mmdb/stream_.h
deleted file mode 100755
index 9e788d7..0000000
--- a/mmdb/stream_.h
+++ /dev/null
@@ -1,192 +0,0 @@
-// $Id: stream_.h,v 1.20 2012/01/26 17:52:21 ekr Exp $
-// =================================================================
-//
-// CCP4 Coordinate Library: support of coordinate-related
-// functionality in protein crystallography applications.
-//
-// Copyright (C) Eugene Krissinel 2000-2008.
-//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
-// of the license to address the requirements of UK law.
-//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
-// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// =================================================================
-//
-// 29.01.10 <-- Date of Last Modification.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// -----------------------------------------------------------------
-//
-// **** Module : CStream_ <interface>
-// ~~~~~~~~~
-// **** Classes : CStream ( Basic Stream Class )
-// ~~~~~~~~~
-//
-// (C) E. Krissinel 1995-2010
-//
-// =================================================================
-//
-
-#ifndef __Stream__
-#define __Stream__
-
-#ifndef __File__
-#include "file_.h"
-#endif
-
-// *******************************************************************
-
-#ifndef __ClassMacros
-
-# define __ClassMacros
-
- // A Class definition macros
-# define DefineClass(ClassName) \
- class ClassName; \
- typedef ClassName * P##ClassName; \
- typedef ClassName & R##ClassName; \
- typedef P##ClassName * PP##ClassName; \
- typedef P##ClassName & RP##ClassName;
-
- // A Structure definition macros
-# define DefineStructure(StructureName) \
- struct StructureName; \
- typedef StructureName * P##StructureName; \
- typedef StructureName & R##StructureName; \
- typedef P##StructureName * PP##StructureName; \
- typedef P##StructureName & RP##StructureName;
-
-#endif
-
-
-#define DefineStreamFunctions(ClassName) \
- extern void StreamWrite ( RCFile f, RP##ClassName Object ); \
- extern void StreamRead ( RCFile f, RP##ClassName Object );
-
-
-#define MakeStreamFunctions(ClassName) \
- void StreamWrite ( RCFile f, RP##ClassName Object ) { \
- StreamWrite_ ( f,(RPCStream)Object ); \
- } \
- PCStream StreamInit##ClassName ( RPCStream Object ) { \
- return (PCStream)(new ClassName(Object)); \
- } \
- void StreamRead ( RCFile f, RP##ClassName Object ) { \
- StreamRead_ ( f,(RPCStream)Object,StreamInit##ClassName ); \
- }
-
-
-
-#define DefineFactoryFunctions(ClassName) \
- typedef P##ClassName Make##ClassName(); \
- typedef Make##ClassName * PMake##ClassName; \
- typedef P##ClassName StreamMake##ClassName ( RPCStream Object ); \
- P##ClassName new##ClassName (); \
- P##ClassName streamNew##ClassName ( RPCStream Object ); \
- typedef StreamMake##ClassName * PStreamMake##ClassName; \
- extern void SetMakers##ClassName ( void * defMk, void * streamMk ); \
- extern void StreamWrite ( RCFile f, RP##ClassName Object ); \
- extern void StreamRead ( RCFile f, RP##ClassName Object );
-
-
-#define MakeFactoryFunctions(ClassName) \
- static PMake##ClassName make##ClassName = NULL; \
- static PStreamMake##ClassName streamMake##ClassName = NULL; \
- P##ClassName new##ClassName() { \
- if (make##ClassName) return (*make##ClassName)(); \
- else return new ClassName(); \
- } \
- P##ClassName streamNew##ClassName ( RPCStream Object ) { \
- if (streamMake##ClassName) \
- return (*streamMake##ClassName)(Object); \
- else return new ClassName(Object); \
- } \
- void SetMakers##ClassName ( void * defMk, void * streamMk ) { \
- make##ClassName = PMake##ClassName(defMk); \
- streamMake##ClassName = PStreamMake##ClassName(streamMk); \
- } \
- void StreamWrite ( RCFile f, RP##ClassName Object ) { \
- StreamWrite_ ( f,(RPCStream)Object ); \
- } \
- PCStream StreamInit##ClassName ( RPCStream Object ) { \
- return (PCStream)(streamNew##ClassName(Object)); \
- } \
- void StreamRead ( RCFile f, RP##ClassName Object ) { \
- StreamRead_ ( f,(RPCStream)Object,StreamInit##ClassName ); \
- }
-
-
-
-
-// ========================== CStream ===========================
-
-// Each streamable class should be derived from CStream
-// and have constructor CClass(PCStream & Object), which should
-// initialize all memory of the class, and virtual functions
-// read(..) and write(..) (see below). Constructor CClass(PCStream&)
-// must not touch the Object variable. This constructor is used
-// only once just before the read(..) function. It is assumed that
-// read(..)/write(..) functions of the CClass provide storage/reading
-// of all vital data. Function read(..) must read data in exactly
-// the same way as function write(..) stores it.
-// For using CClass in streams, three following functions should
-// be supplied:
-//
-// 1.
-// void StreamWrite ( CFile & f, PCClass & Object ) {
-// StreamWrite ( f,(PCStream)Object );
-// }
-//
-// 2.
-// PCStream CClassInit ( PCStream & Object ) {
-// return (PCStream)(new CClass(Object));
-// }
-//
-// 3.
-// void StreamRead ( CFile & f, PCClass & Object ) {
-// StreamRead_ ( f,(PCStream)Object,CClassInit );
-// }
-//
-// All these functions are automatically generated by macros
-// DefineStreamFunctions(CClass) -- in the header -- and
-// MakeStreamFunctions(CClass) -- in the implementation body. Note
-// that macro DefineClass(CClass) should always be issued for
-// streamable classes prior to the stream-making macros. Then
-// CClass may be streamed using functions #1 and #3.
-// StreamRead will return NULL for Object if it was not in
-// the stream. If Object existed before calling StreamRead(..)
-// but was not found in the stream, it will be disposed (NULL
-// assigned).
-
-
-DefineClass(CStream);
-DefineStreamFunctions(CStream);
-
-class CStream {
- public :
- CStream () {}
- CStream ( RPCStream ) {}
- virtual ~CStream () {}
- virtual void read ( RCFile ) {}
- virtual void write ( RCFile ) {}
-};
-
-
-typedef PCStream InitStreamObject(RPCStream Object);
-
-extern void StreamRead_ ( RCFile f, RPCStream Object,
- InitStreamObject Init );
-
-extern void StreamWrite_ ( RCFile f, RPCStream Object );
-
-
-#endif
diff --git a/mmdb.pc.in b/mmdb2.pc.in
similarity index 81%
rename from mmdb.pc.in
rename to mmdb2.pc.in
index dd654a4..567b1dd 100644
--- a/mmdb.pc.in
+++ b/mmdb2.pc.in
@@ -3,8 +3,9 @@ exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
-Name: mmdb
+Name: mmdb2
Description: Macromolecular coordinate library
Version: @VERSION@
-Libs: -L${libdir} -lmmdb
+Libs: -L${libdir} -lmmdb2
Cflags: -I${includedir}
+
diff --git a/mmdb/hybrid_36.cpp b/mmdb2/hybrid_36.cpp
old mode 100755
new mode 100644
similarity index 100%
rename from mmdb/hybrid_36.cpp
rename to mmdb2/hybrid_36.cpp
diff --git a/mmdb/hybrid_36.h b/mmdb2/hybrid_36.h
old mode 100755
new mode 100644
similarity index 100%
rename from mmdb/hybrid_36.h
rename to mmdb2/hybrid_36.h
diff --git a/mmdb2/mmdb_atom.cpp b/mmdb2/mmdb_atom.cpp
new file mode 100644
index 0000000..0dcc986
--- /dev/null
+++ b/mmdb2/mmdb_atom.cpp
@@ -0,0 +1,3486 @@
+// $Id: mmdb_atom.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 18.10.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_Atom <implementation>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::Atom ( atom class )
+// ~~~~~~~~~ mmdb::Residue ( residue class )
+// **** Functions: mmdb::BondAngle
+// ~~~~~~~~~~
+//
+// Copyright (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "mmdb_chain.h"
+#include "mmdb_model.h"
+#include "mmdb_root.h"
+#include "mmdb_tables.h"
+#include "mmdb_cifdefs.h"
+#include "hybrid_36.h"
+
+
+namespace mmdb {
+
+ // ================================================================
+
+ #define ASET_ShortBinary 0x10000000
+ #define ASET_ShortTer 0x20000000
+ #define ASET_ShortHet 0x40000000
+
+ bool ignoreSegID = false;
+ bool ignoreElement = false;
+ bool ignoreCharge = false;
+ bool ignoreNonCoorPDBErrors = false;
+ bool ignoreUnmatch = false;
+
+
+ // ========================== Atom =============================
+
+ Atom::Atom() : UDData() {
+ InitAtom();
+ }
+
+ Atom::Atom ( PResidue res ) : UDData() {
+ InitAtom();
+ if (res)
+ res->AddAtom ( this );
+ }
+
+ Atom::Atom ( io::RPStream Object ) : UDData(Object) {
+ InitAtom();
+ }
+
+ Atom::~Atom() {
+ PPAtom A;
+ int nA;
+ FreeMemory();
+ if (residue) {
+ A = NULL;
+ nA = 0;
+ if (residue->chain) {
+ if (residue->chain->model) {
+ A = residue->chain->model->GetAllAtoms();
+ nA = residue->chain->model->GetNumberOfAllAtoms();
+ }
+ }
+ residue->_ExcludeAtom ( index );
+ if ((0<index) && (index<=nA)) A[index-1] = NULL;
+ }
+ }
+
+ void Atom::InitAtom() {
+ serNum = -1; // serial number
+ index = -1; // index in the file
+ name[0] = char(0); // atom name
+ label_atom_id[0] = char(0); // assigned atom name (not aligned)
+ altLoc[0] = char(0); // alternate location indicator
+ residue = NULL; // reference to residue
+ x = 0.0; // orthogonal x-coordinate in angstroms
+ y = 0.0; // orthogonal y-coordinate in angstroms
+ z = 0.0; // orthogonal z-coordinate in angstroms
+ occupancy = 0.0; // occupancy
+ tempFactor = 0.0; // temperature factor
+ segID[0] = char(0); // segment identifier
+ strcpy ( element," " ); // chemical element symbol - RIGHT JUSTIFIED
+ energyType[0] = char(0); // chemical element symbol - RIGHT JUSTIFIED
+ charge = 0.0; // charge on the atom
+ sigX = 0.0; // standard deviation of the stored x-coord
+ sigY = 0.0; // standard deviation of the stored y-coord
+ sigZ = 0.0; // standard deviation of the stored z-coord
+ sigOcc = 0.0; // standard deviation of occupancy
+ sigTemp = 0.0; // standard deviation of temperature factor
+ u11 = 0.0; //
+ u22 = 0.0; // anisotropic
+ u33 = 0.0; //
+ u12 = 0.0; // temperature
+ u13 = 0.0; //
+ u23 = 0.0; // factors
+ su11 = 0.0; //
+ su22 = 0.0; // standard
+ su33 = 0.0; // deviations of
+ su12 = 0.0; // anisotropic
+ su13 = 0.0; // temperature
+ su23 = 0.0; // factors
+ Het = false; // indicator of atom in non-standard groups
+ Ter = false; // chain terminator
+ WhatIsSet = 0x00000000; // nothing is set
+ nBonds = 0; // no bonds
+ Bond = NULL; // empty array of bonds
+ }
+
+ void Atom::FreeMemory() {
+ FreeBonds();
+ }
+
+ void Atom::FreeBonds() {
+ if (Bond) delete[] Bond;
+ Bond = NULL;
+ nBonds = 0;
+ }
+
+ int Atom::GetNBonds() {
+ return nBonds & 0x000000FF;
+ }
+
+ void Atom::GetBonds ( RPAtomBond atomBond, int & nAtomBonds ) {
+ // This GetBonds(..) returns pointer to the Atom's
+ // internal Bond structure, IT MUST NOT BE DISPOSED.
+ nAtomBonds = nBonds & 0x000000FF;
+ atomBond = Bond;
+ }
+
+ void Atom::GetBonds ( RPAtomBondI atomBondI, int & nAtomBonds ) {
+ // This GetBonds(..) disposes AtomBondI, if it was not set
+ // to NULL, allocates AtomBondI[nAtomBonds] and returns its
+ // pointer. AtomBondI MUST BE DISPOSED BY APPLICATION.
+ int i;
+
+ if (atomBondI) delete[] atomBondI;
+
+ nAtomBonds = nBonds & 0x000000FF;
+
+ if (nAtomBonds<=0)
+ atomBondI = NULL;
+ else {
+ atomBondI = new AtomBondI[nAtomBonds];
+ for (i=0;i<nAtomBonds;i++) {
+ if (Bond[i].atom)
+ atomBondI[i].index = Bond[i].atom->index;
+ else atomBondI[i].index = -1;
+ atomBondI[i].order = Bond[i].order;
+ }
+
+ }
+
+ }
+
+ void Atom::GetBonds ( PAtomBondI AtomBondI, int & nAtomBonds,
+ int maxlength ) {
+ // This GetBonds(..) does not dispose or allocate AtomBond.
+ // It is assumed that length of AtomBond is sufficient to
+ // accomodate all bonded atoms.
+ int i;
+
+ nAtomBonds = IMin(maxlength,nBonds & 0x000000FF);
+
+ for (i=0;i<nAtomBonds;i++) {
+ if (Bond[i].atom)
+ AtomBondI[i].index = Bond[i].atom->index;
+ else AtomBondI[i].index = -1;
+ AtomBondI[i].order = Bond[i].order;
+ }
+
+ }
+
+
+ int Atom::AddBond ( PAtom bond_atom, int bond_order,
+ int nAdd_bonds ) {
+ PAtomBond B1;
+ int i,k,nb,nballoc;
+
+ nb = nBonds & 0x000000FF;
+ k = -1;
+ for (i=0;(i<nb) && (k<0);i++)
+ if (Bond[i].atom==bond_atom) k = i;
+ if (k>=0) return -k;
+
+ nballoc = (nBonds >> 8) & 0x000000FF;
+ if (nBonds>=nballoc) {
+ nballoc += nAdd_bonds;
+ B1 = new AtomBond[nballoc];
+ for (i=0;i<nb;i++) {
+ B1[i].atom = Bond[i].atom;
+ B1[i].order = Bond[i].order;
+ }
+ if (Bond) delete[] Bond;
+ Bond = B1;
+ }
+ Bond[nb].atom = bond_atom;
+ Bond[nb].order = bond_order;
+ nb++;
+
+ nBonds = nb | (nballoc << 8);
+
+ return nb;
+
+ }
+
+ void Atom::SetResidue ( PResidue res ) {
+ residue = res;
+ }
+
+ void Atom::StandardPDBOut ( cpstr Record, pstr S ) {
+ char N[10];
+ strcpy ( S,Record );
+ PadSpaces ( S,80 );
+ if (serNum>99999) {
+ hy36encode ( 5,serNum,N );
+ strcpy_n ( &(S[6]),N,5 );
+ } else if (serNum>0)
+ PutInteger ( &(S[6]),serNum,5 );
+ else if (index<=99999)
+ PutInteger ( &(S[6]),index,5 );
+ else {
+ hy36encode ( 5,index,N );
+ strcpy_n ( &(S[6]),N,5 );
+ }
+ if (!Ter) {
+ if (altLoc[0]) S[16] = altLoc[0];
+ strcpy_n ( &(S[12]),name ,4 );
+ strcpy_n ( &(S[72]),segID ,4 );
+ strcpy_nr ( &(S[76]),element,2 );
+ if (WhatIsSet & ASET_Charge) {
+ if (charge>0) sprintf ( N,"%1i+",mround(charge) );
+ else if (charge<0) sprintf ( N,"%1i-",mround(-charge) );
+ else strcpy ( N," " );
+ strcpy_n ( &(S[78]),N,2 );
+ } else
+ strcpy_n ( &(S[78])," ",2 );
+ }
+ strcpy_nr ( &(S[17]),residue->name,3 );
+ strcpy_nr ( &(S[20]),residue->chain->chainID,2 );
+ if (residue->seqNum>MinInt4) {
+ if ((-999<=residue->seqNum) && (residue->seqNum<=9999))
+ PutIntIns ( &(S[22]),residue->seqNum,4,residue->insCode );
+ else {
+ hy36encode ( 4,residue->seqNum,N );
+ strcpy_n ( &(S[22]),N,4 );
+ }
+ }
+ }
+
+ void Atom::PDBASCIIDump ( io::RFile f ) {
+ // makes the ASCII PDB ATOM, HETATM, SIGATOM, ANISOU
+ // SIGUIJ and TER lines from the class' data
+ char S[100];
+ if (Ter) {
+ if (WhatIsSet & ASET_Coordinates) {
+ StandardPDBOut ( pstr("TER"),S );
+ f.WriteLine ( S );
+ }
+ } else {
+ if (WhatIsSet & ASET_Coordinates) {
+ if (Het) StandardPDBOut ( pstr("HETATM"),S );
+ else StandardPDBOut ( pstr("ATOM") ,S );
+ PutRealF ( &(S[30]),x,8,3 );
+ PutRealF ( &(S[38]),y,8,3 );
+ PutRealF ( &(S[46]),z,8,3 );
+ if (WhatIsSet & ASET_Occupancy)
+ PutRealF ( &(S[54]),occupancy ,6,2 );
+ if (WhatIsSet & ASET_tempFactor)
+ PutRealF ( &(S[60]),tempFactor,6,2 );
+ f.WriteLine ( S );
+ }
+ if (WhatIsSet & ASET_CoordSigma) {
+ StandardPDBOut ( pstr("SIGATM"),S );
+ PutRealF ( &(S[30]),sigX,8,3 );
+ PutRealF ( &(S[38]),sigY,8,3 );
+ PutRealF ( &(S[46]),sigZ,8,3 );
+ if ((WhatIsSet & ASET_OccSigma) &&
+ (WhatIsSet & ASET_Occupancy))
+ PutRealF ( &(S[54]),sigOcc,6,2 );
+ if ((WhatIsSet & ASET_tFacSigma) &&
+ (WhatIsSet & ASET_tempFactor))
+ PutRealF ( &(S[60]),sigTemp,6,2 );
+ f.WriteLine ( S );
+ }
+ if (WhatIsSet & ASET_Anis_tFac) {
+ StandardPDBOut ( pstr("ANISOU"),S );
+ PutInteger ( &(S[28]),mround(u11*1.0e4),7 );
+ PutInteger ( &(S[35]),mround(u22*1.0e4),7 );
+ PutInteger ( &(S[42]),mround(u33*1.0e4),7 );
+ PutInteger ( &(S[49]),mround(u12*1.0e4),7 );
+ PutInteger ( &(S[56]),mround(u13*1.0e4),7 );
+ PutInteger ( &(S[63]),mround(u23*1.0e4),7 );
+ f.WriteLine ( S );
+ if (WhatIsSet & ASET_Anis_tFSigma) {
+ StandardPDBOut ( pstr("SIGUIJ"),S );
+ PutInteger ( &(S[28]),mround(su11*1.0e4),7 );
+ PutInteger ( &(S[35]),mround(su22*1.0e4),7 );
+ PutInteger ( &(S[42]),mround(su33*1.0e4),7 );
+ PutInteger ( &(S[49]),mround(su12*1.0e4),7 );
+ PutInteger ( &(S[56]),mround(su13*1.0e4),7 );
+ PutInteger ( &(S[63]),mround(su23*1.0e4),7 );
+ f.WriteLine ( S );
+ }
+ }
+ }
+ }
+
+ void Atom::MakeCIF ( mmcif::PData CIF ) {
+ mmcif::PLoop Loop;
+ AtomName AtName;
+ Element el;
+ char N[10];
+ int i,j,RC;
+ PChain chain = NULL;
+ PModel model = NULL;
+ //bool singleModel = true;
+
+ if (residue) chain = residue->chain;
+ if (chain) model = PModel(chain->model);
+ // if (model) {
+ // if (model->manager)
+ // singleModel = PRoot(model->manager)->nModels<=1;
+ // }
+
+ /*
+
+ loop_
+ *0 _atom_site.group_PDB
+ *1 _atom_site.id
+ *2 _atom_site.type_symbol <- chem elem
+ -3 _atom_site.label_atom_id <- atom name
+ *4 _atom_site.label_alt_id <- alt code
+ =5 _atom_site.label_comp_id <- res name ???
+ =6 _atom_site.label_asym_id <- chain id ???
+ =7 _atom_site.label_entity_id < ???
+ =8 _atom_site.label_seq_id <- poly seq id
+ +9 _atom_site.pdbx_PDB_ins_code <- ins code
+ -10 _atom_site.segment_id <- segment id
+ *11 _atom_site.Cartn_x
+ *12 _atom_site.Cartn_y
+ *13 _atom_site.Cartn_z
+ *14 _atom_site.occupancy
+ *15 _atom_site.B_iso_or_equiv
+ *16 _atom_site.Cartn_x_esd
+ *17 _atom_site.Cartn_y_esd
+ *18 _atom_site.Cartn_z_esd
+ *19 _atom_site.occupancy_esd
+ *20 _atom_site.B_iso_or_equiv_esd
+ *21 _atom_site.pdbx_formal_charge
+ +22 _atom_site.auth_seq_id <- seq id we want
+ +23 _atom_site.auth_comp_id <- res name we want
+ +24 _atom_site.auth_asym_id <- ch id we want ?
+ *25 _atom_site.auth_atom_id <- atom name we want ?
+ +26 _atom_site.pdbx_PDB_model_num <- model no
+
+ '+' is read in Root::CheckAtomPlace()
+ '=' new in residue
+ '-' new in atom
+
+
+ */
+
+ RC = CIF->AddLoop ( CIFCAT_ATOM_SITE,Loop );
+ if (RC!=mmcif::CIFRC_Ok) {
+ // the category was (re)created, provide tags
+
+ Loop->AddLoopTag ( CIFTAG_GROUP_PDB ); // ATOM, TER etc.
+ Loop->AddLoopTag ( CIFTAG_ID ); // serial number
+
+ Loop->AddLoopTag ( CIFTAG_TYPE_SYMBOL ); // element symbol
+ Loop->AddLoopTag ( CIFTAG_LABEL_ATOM_ID ); // atom name
+ Loop->AddLoopTag ( CIFTAG_LABEL_ALT_ID ); // alt location
+ Loop->AddLoopTag ( CIFTAG_LABEL_COMP_ID ); // residue name
+ Loop->AddLoopTag ( CIFTAG_LABEL_ASYM_ID ); // chain ID
+ Loop->AddLoopTag ( CIFTAG_LABEL_ENTITY_ID ); // entity ID
+ Loop->AddLoopTag ( CIFTAG_LABEL_SEQ_ID ); // res seq number
+ Loop->AddLoopTag ( CIFTAG_PDBX_PDB_INS_CODE ); // insertion code
+ Loop->AddLoopTag ( CIFTAG_SEGMENT_ID ); // segment ID
+
+ Loop->AddLoopTag ( CIFTAG_CARTN_X ); // x-coordinate
+ Loop->AddLoopTag ( CIFTAG_CARTN_Y ); // y-coordinate
+ Loop->AddLoopTag ( CIFTAG_CARTN_Z ); // z-coordinate
+ Loop->AddLoopTag ( CIFTAG_OCCUPANCY ); // occupancy
+ Loop->AddLoopTag ( CIFTAG_B_ISO_OR_EQUIV ); // temp factor
+
+ Loop->AddLoopTag ( CIFTAG_CARTN_X_ESD ); // x-sigma
+ Loop->AddLoopTag ( CIFTAG_CARTN_Y_ESD ); // y-sigma
+ Loop->AddLoopTag ( CIFTAG_CARTN_Z_ESD ); // z-sigma
+ Loop->AddLoopTag ( CIFTAG_OCCUPANCY_ESD ); // occupancy-sigma
+ Loop->AddLoopTag ( CIFTAG_B_ISO_OR_EQUIV_ESD ); // t-factor-sigma
+
+ Loop->AddLoopTag ( CIFTAG_PDBX_FORMAL_CHARGE ); // charge on atom
+
+ Loop->AddLoopTag ( CIFTAG_AUTH_SEQ_ID ); // res seq number
+ Loop->AddLoopTag ( CIFTAG_AUTH_COMP_ID ); // residue name
+ Loop->AddLoopTag ( CIFTAG_AUTH_ASYM_ID ); // chain id
+ Loop->AddLoopTag ( CIFTAG_AUTH_ATOM_ID ); // atom name
+
+ Loop->AddLoopTag ( CIFTAG_PDBX_PDB_MODEL_NUM ); // model number
+
+ }
+
+ if (Ter) { // ter record
+
+ if (!(WhatIsSet & ASET_Coordinates))
+ return;
+
+ // (0)
+ Loop->AddString ( pstr("TER") );
+ // (1)
+ if (serNum>0) Loop->AddInteger ( serNum );
+ else Loop->AddInteger ( index );
+ // (2,3,4)
+ Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION ); // no element symbol
+ Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION ); // no atom name
+ Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION ); // no alt code
+ if (residue) {
+ // (5)
+ Loop->AddString ( residue->label_comp_id );
+ // (6)
+ Loop->AddString ( residue->label_asym_id );
+ // (7)
+ if (residue->label_entity_id>0)
+ Loop->AddInteger ( residue->label_entity_id );
+ else Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ // (8)
+ if (residue->label_seq_id>MinInt4)
+ Loop->AddInteger ( residue->label_seq_id );
+ else Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ // (9)
+ Loop->AddString ( residue->insCode,true );
+ } else {
+ // (5,6,7,8,9)
+ Loop->AddString ( NULL );
+ Loop->AddString ( NULL );
+ Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ }
+
+ // (10-21)
+ for (i=10;i<=21;i++)
+ Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION );
+
+ // (22,23)
+ if (residue) {
+ if (residue->seqNum>MinInt4)
+ Loop->AddInteger ( residue->seqNum );
+ else Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ Loop->AddString ( residue->name );
+ } else {
+ Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ Loop->AddString ( NULL );
+ }
+
+ // (24)
+ if (chain) Loop->AddString ( chain->chainID,true );
+ else Loop->AddString ( NULL );
+
+ // (25)
+ Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION ); // no atom name
+
+ } else if (WhatIsSet & (ASET_Coordinates | ASET_CoordSigma)) {
+ // normal atom record
+
+ if (!WhatIsSet) return;
+
+ // (0)
+ if (Het) Loop->AddString ( pstr("HETATM") );
+ else Loop->AddString ( pstr("ATOM") );
+ // (1)
+ if (serNum>0) Loop->AddInteger ( serNum );
+ else Loop->AddInteger ( index );
+
+
+ if (WhatIsSet & ASET_Coordinates) {
+
+ // (2)
+ strcpy_css ( el,element );
+ Loop->AddString ( el,true );
+ // (3)
+ Loop->AddString ( label_atom_id ); // assigned atom name
+ // (4)
+ Loop->AddString ( altLoc,true ); // alt code
+
+ if (residue) {
+ // (5)
+ Loop->AddString ( residue->label_comp_id );
+ // (6)
+ Loop->AddString ( residue->label_asym_id );
+ // (7)
+ if (residue->label_entity_id>0)
+ Loop->AddInteger ( residue->label_entity_id );
+ else Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ // (8)
+ if (residue->label_seq_id>MinInt4)
+ Loop->AddInteger ( residue->label_seq_id );
+ else Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ // (9)
+ Loop->AddString ( residue->insCode,true );
+ } else {
+ // (5,6,7,8,9)
+ Loop->AddString ( NULL );
+ Loop->AddString ( NULL );
+ Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ }
+
+ // (10)
+ Loop->AddString ( segID ,true );
+ // (11,12,13)
+ Loop->AddReal ( x );
+ Loop->AddReal ( y );
+ Loop->AddReal ( z );
+ // (14)
+ if (WhatIsSet & ASET_Occupancy)
+ Loop->AddReal ( occupancy );
+ else Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION );
+ // (15)
+ if (WhatIsSet & ASET_tempFactor)
+ Loop->AddReal ( tempFactor );
+ else Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION );
+
+ // (16,17,18)
+ if (WhatIsSet & ASET_CoordSigma) {
+ Loop->AddReal ( sigX );
+ Loop->AddReal ( sigY );
+ Loop->AddReal ( sigZ );
+ } else {
+ Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION );
+ Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION );
+ Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION );
+ }
+ // (19)
+ if ((WhatIsSet & ASET_OccSigma) && (WhatIsSet & ASET_Occupancy))
+ Loop->AddReal ( sigOcc );
+ else Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION );
+ // (20)
+ if ((WhatIsSet & ASET_tFacSigma) && (WhatIsSet & ASET_tempFactor))
+ Loop->AddReal ( sigTemp );
+ else Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION );
+
+ } else
+ for (i=0;i<18;i++)
+ Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION );
+
+ // (21)
+ if (WhatIsSet & ASET_Charge) {
+ sprintf ( N,"%+2i",mround(charge) );
+ Loop->AddString ( N,true );
+ } else
+ Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION );
+
+ if (residue) {
+ // (22)
+ if (residue->seqNum>MinInt4)
+ Loop->AddInteger ( residue->seqNum );
+ else Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ // (23)
+ Loop->AddString ( residue->name );
+ } else {
+ Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ }
+
+ // (24)
+ if (chain) Loop->AddString ( chain->chainID,true );
+ else Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ // (25)
+ strcpy_css ( AtName,name );
+ Loop->AddString ( AtName ); // atom name
+
+ }
+
+ // (26)
+ if (!model) Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION );
+ else if (model->serNum>0) Loop->AddInteger ( model->serNum );
+ else Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION );
+
+
+ if (WhatIsSet & ASET_Anis_tFac) {
+
+ RC = CIF->AddLoop ( CIFCAT_ATOM_SITE_ANISOTROP,Loop );
+ if (RC!=mmcif::CIFRC_Ok) {
+ // the category was (re)created, provide tags
+ Loop->AddLoopTag ( CIFTAG_ID ); // serial number
+ Loop->AddLoopTag ( CIFTAG_U11 ); // component u11
+ Loop->AddLoopTag ( CIFTAG_U22 ); // component u22
+ Loop->AddLoopTag ( CIFTAG_U33 ); // component u33
+ Loop->AddLoopTag ( CIFTAG_U12 ); // component u12
+ Loop->AddLoopTag ( CIFTAG_U13 ); // component u13
+ Loop->AddLoopTag ( CIFTAG_U23 ); // component u23
+ Loop->AddLoopTag ( CIFTAG_U11_ESD ); // component u11 sigma
+ Loop->AddLoopTag ( CIFTAG_U22_ESD ); // component u22 sigma
+ Loop->AddLoopTag ( CIFTAG_U33_ESD ); // component u33 sigma
+ Loop->AddLoopTag ( CIFTAG_U12_ESD ); // component u12 sigma
+ Loop->AddLoopTag ( CIFTAG_U13_ESD ); // component u13 sigma
+ Loop->AddLoopTag ( CIFTAG_U23_ESD ); // component u23 sigma
+ for (i=1;i<index;i++) {
+ Loop->AddInteger ( i );
+ for (j=0;j<12;j++)
+ Loop->AddString ( NULL );
+ }
+ }
+
+ if (serNum>0) Loop->AddInteger ( serNum );
+ else Loop->AddInteger ( index );
+
+ Loop->AddReal ( u11 );
+ Loop->AddReal ( u22 );
+ Loop->AddReal ( u33 );
+ Loop->AddReal ( u12 );
+ Loop->AddReal ( u13 );
+ Loop->AddReal ( u23 );
+ if (WhatIsSet & ASET_Anis_tFSigma) {
+ Loop->AddReal ( su11 );
+ Loop->AddReal ( su22 );
+ Loop->AddReal ( su33 );
+ Loop->AddReal ( su12 );
+ Loop->AddReal ( su13 );
+ Loop->AddReal ( su23 );
+ }
+
+ }
+
+ }
+
+ ERROR_CODE Atom::ConvertPDBATOM ( int ix, cpstr S ) {
+ // Gets data from the PDB ASCII ATOM record.
+ // This function DOES NOT check the "ATOM" keyword and
+ // does not decode the chain and residue parameters! These
+ // must be treated by calling process, see
+ // Chain::ConvertPDBASCII().
+
+ index = ix;
+
+ if (WhatIsSet & ASET_Coordinates)
+ return Error_ATOM_AlreadySet;
+
+ if (!(GetReal(x,&(S[30]),8) &&
+ GetReal(y,&(S[38]),8) &&
+ GetReal(z,&(S[46]),8)))
+ return Error_ATOM_Unrecognized;
+
+ WhatIsSet |= ASET_Coordinates;
+ Het = false;
+ Ter = false;
+
+ if (GetReal(occupancy ,&(S[54]),6)) WhatIsSet |= ASET_Occupancy;
+ if (GetReal(tempFactor,&(S[60]),6)) WhatIsSet |= ASET_tempFactor;
+
+ if (WhatIsSet & (ASET_CoordSigma | ASET_Anis_tFac |
+ ASET_Anis_tFSigma))
+ // something was already submitted. check complience
+ return CheckData ( S );
+ else
+ // first data submission. just take the data
+ GetData ( S );
+
+ return Error_NoError;
+
+ }
+
+ void Atom::SetAtomName ( int ix,
+ int sN,
+ const AtomName aName,
+ const AltLoc aLoc,
+ const SegID sID,
+ const Element eName ) {
+ index = ix;
+ serNum = sN;
+ strcpy ( name ,aName );
+ strcpy ( label_atom_id,aName );
+ strcpy_css ( altLoc ,pstr(aLoc) );
+ strcpy_css ( segID ,pstr(sID) );
+ if (!eName[0]) element[0] = char(0);
+ else if (!eName[1]) {
+ element[0] = ' ';
+ strcpy ( &(element[1]),eName );
+ } else
+ strcpy ( element,eName );
+ WhatIsSet = 0;
+ }
+
+ ERROR_CODE Atom::ConvertPDBSIGATM ( int ix, cpstr S ) {
+ // Gets data from the PDB ASCII SIGATM record.
+ // This function DOES NOT check the "SIGATM" keyword and
+ // does not decode the chain and residue parameters! These
+ // must be treated by the calling process, see
+ // Chain::ConvertPDBASCII().
+
+ index = ix;
+
+ if (WhatIsSet & ASET_CoordSigma)
+ return Error_ATOM_AlreadySet;
+
+ if (!(GetReal(sigX,&(S[30]),8) &&
+ GetReal(sigY,&(S[38]),8) &&
+ GetReal(sigZ,&(S[46]),8)))
+ return Error_ATOM_Unrecognized;
+
+ WhatIsSet |= ASET_CoordSigma;
+
+ if (GetReal(sigOcc ,&(S[54]),6)) WhatIsSet |= ASET_OccSigma;
+ if (GetReal(sigTemp,&(S[60]),6)) WhatIsSet |= ASET_tFacSigma;
+
+ if (WhatIsSet & (ASET_Coordinates | ASET_Anis_tFac |
+ ASET_Anis_tFSigma))
+ // something was already submitted. check complience
+ return CheckData ( S );
+ else
+ // first data submission. just take the data
+ GetData ( S );
+
+ return Error_NoError;
+
+ }
+
+ ERROR_CODE Atom::ConvertPDBANISOU ( int ix, cpstr S ) {
+ // Gets data from the PDB ASCII ANISOU record.
+ // This function DOES NOT check the "ANISOU" keyword and
+ // does not decode chain and residue parameters! These must
+ // be treated by the calling process, see
+ // Chain::ConvertPDBASCII().
+
+ index = ix;
+
+ if (WhatIsSet & ASET_Anis_tFac)
+ return Error_ATOM_AlreadySet;
+
+ if (!(GetReal(u11,&(S[28]),7) &&
+ GetReal(u22,&(S[35]),7) &&
+ GetReal(u33,&(S[42]),7) &&
+ GetReal(u12,&(S[49]),7) &&
+ GetReal(u13,&(S[56]),7) &&
+ GetReal(u23,&(S[63]),7)))
+ return Error_ATOM_Unrecognized;
+
+ u11 /= 1.0e4;
+ u22 /= 1.0e4;
+ u33 /= 1.0e4;
+ u12 /= 1.0e4;
+ u13 /= 1.0e4;
+ u23 /= 1.0e4;
+
+ WhatIsSet |= ASET_Anis_tFac;
+
+ if (WhatIsSet & (ASET_Coordinates | ASET_CoordSigma |
+ ASET_Anis_tFSigma))
+ // something was already submitted. check complience
+ return CheckData ( S );
+ else
+ // first data submission. just take the data
+ GetData ( S );
+
+ return Error_NoError;
+
+ }
+
+ ERROR_CODE Atom::ConvertPDBSIGUIJ ( int ix, cpstr S ) {
+ // Gets data from the PDB ASCII SIGUIJ record.
+ // This function DOES NOT check the "SIGUIJ" keyword and
+ // does not decode the chain and residue parameters! These
+ // must be treated by the calling process, see
+ // Chain::ConvertPDBASCII().
+
+ index = ix;
+
+ if (WhatIsSet & ASET_Anis_tFSigma)
+ return Error_ATOM_AlreadySet;
+
+ if (!(GetReal(su11,&(S[28]),7) &&
+ GetReal(su22,&(S[35]),7) &&
+ GetReal(su33,&(S[42]),7) &&
+ GetReal(su12,&(S[49]),7) &&
+ GetReal(su13,&(S[56]),7) &&
+ GetReal(su23,&(S[63]),7)))
+ return Error_ATOM_Unrecognized;
+
+ su11 /= 1.0e4;
+ su22 /= 1.0e4;
+ su33 /= 1.0e4;
+ su12 /= 1.0e4;
+ su13 /= 1.0e4;
+ su23 /= 1.0e4;
+
+ WhatIsSet |= ASET_Anis_tFSigma;
+
+ if (WhatIsSet & (ASET_Coordinates | ASET_CoordSigma |
+ ASET_Anis_tFac))
+ // something was already submitted. check complience
+ return CheckData ( S );
+ else
+ // first data submission. just take the data
+ GetData ( S );
+
+ return Error_NoError;
+
+ }
+
+ ERROR_CODE Atom::ConvertPDBTER ( int ix, cpstr S ) {
+ // Gets data from the PDB ASCII TER record.
+ // This function DOES NOT check the "TER" keyword and
+ // does not decode the chain and residue parameters! These
+ // must be treated by the calling process, see
+ // Chain::ConvertPDBASCII().
+
+ index = ix;
+
+ if (((S[6]>='0') && (S[6]<='9')) || (S[6]==' ')) {
+ // Although against strict PDB format, 'TER' is
+ // actually allowed not to have a serial number.
+ // This negative value implies that the number is
+ // not set.
+ if (!(GetInteger(serNum,&(S[6]),5))) serNum = -1;
+ } else
+ hy36decode ( 5,&(S[6]),5,&serNum );
+
+ // if (!(GetInteger(serNum,&(S[6]),5))) serNum = -1;
+
+ if (WhatIsSet & ASET_Coordinates)
+ return Error_ATOM_AlreadySet;
+
+ WhatIsSet |= ASET_Coordinates;
+ Het = false;
+ Ter = true;
+ name[0] = char(0);
+ label_atom_id[0] = char(0);
+ element[0] = char(0);
+
+ return Error_NoError;
+
+ }
+
+
+ int Atom::GetModelNum() {
+ if (residue) {
+ if (residue->chain)
+ if (residue->chain->model)
+ return residue->chain->model->GetSerNum();
+ }
+ return 0;
+ }
+
+ pstr Atom::GetChainID() {
+ if (residue) {
+ if (residue->chain) return residue->chain->chainID;
+ }
+ return pstr("");
+ }
+
+ pstr Atom::GetLabelAsymID() {
+ if (residue) return residue->label_asym_id;
+ else return pstr("");
+ }
+
+ pstr Atom::GetResName() {
+ if (residue) return residue->name;
+ else return pstr("");
+ }
+
+ pstr Atom::GetLabelCompID() {
+ if (residue) return residue->label_comp_id;
+ else return pstr("");
+ }
+
+ int Atom::GetAASimilarity ( const ResName resName ) {
+ if (residue)
+ return mmdb::GetAASimilarity ( pstr(residue->name),
+ pstr(resName) );
+ else return -3;
+ }
+
+ int Atom::GetAASimilarity ( PAtom A ) {
+ if (residue) {
+ if (A->residue)
+ return mmdb::GetAASimilarity ( pstr(residue->name),
+ pstr(A->residue->name) );
+ else return -4;
+ } else
+ return -3;
+ }
+
+ realtype Atom::GetAAHydropathy() {
+ if (residue)
+ return mmdb::GetAAHydropathy ( pstr(residue->name) );
+ else return MaxReal;
+ }
+
+ realtype Atom::GetOccupancy() {
+ if (WhatIsSet & ASET_Occupancy) return occupancy;
+ else return 0.0;
+ }
+
+ int Atom::GetSeqNum() {
+ if (residue) return residue->seqNum;
+ else return ATOM_NoSeqNum;
+ }
+
+ int Atom::GetLabelSeqID() {
+ if (residue) return residue->label_seq_id;
+ else return ATOM_NoSeqNum;
+ }
+
+ int Atom::GetLabelEntityID() {
+ if (residue) return residue->label_entity_id;
+ else return -1;
+ }
+
+ pstr Atom::GetInsCode() {
+ if (residue) return residue->insCode;
+ else return pstr("");
+ }
+
+ int Atom::GetSSEType() {
+ // works only after SSE calculations
+ if (residue) return residue->SSE;
+ else return SSE_None;
+ }
+
+ pstr Atom::GetAtomCharge ( pstr chrg ) {
+ if (WhatIsSet & ASET_Charge) sprintf ( chrg,"%+2i",mround(charge) );
+ else strcpy ( chrg," " );
+ return chrg;
+ }
+
+ PResidue Atom::GetResidue() {
+ return residue;
+ }
+
+ PChain Atom::GetChain() {
+ if (residue) return residue->chain;
+ else return NULL;
+ }
+
+ PModel Atom::GetModel() {
+ if (residue) {
+ if (residue->chain) return (PModel)residue->chain->model;
+ }
+ return NULL;
+ }
+
+ int Atom::GetResidueNo() {
+ if (residue) {
+ if (residue->chain)
+ return residue->chain->GetResidueNo (
+ residue->seqNum,residue->insCode );
+ else return -2;
+ } else
+ return -1;
+ }
+
+
+ void * Atom::GetCoordHierarchy() {
+ if (residue) return residue->GetCoordHierarchy();
+ return NULL;
+ }
+
+
+ void Atom::GetStat ( realtype v,
+ realtype & v_min, realtype & v_max,
+ realtype & v_m, realtype & v_m2 ) {
+ if (v<v_min) v_min = v;
+ if (v>v_max) v_max = v;
+ v_m += v;
+ v_m2 += v*v;
+ }
+
+
+
+ void Atom::GetChainCalphas ( PPAtom & Calphas, int & nCalphas,
+ cpstr altLoc ) {
+ // GetChainCalphas(...) is a specialized function for quick
+ // access to C-alphas of chain which includes given atom.
+ // This function works faster than an equivalent implementation
+ // through MMDB's selection procedures.
+ // Parameters:
+ // Calphas - array to accept pointers on C-alpha atoms
+ // If Calphas!=NULL, then the function will
+ // delete and re-allocate it. When the array
+ // is no longer needed, the application MUST
+ // delete it: delete[] Calphas; Deleting
+ // Calphas does not delete atoms from MMDB.
+ // nCalphas - integer to accept number of C-alpha atoms
+ // and the length of Calphas array.
+ // altLoc - alternative location indicator. By default
+ // (""), maximum-occupancy locations are taken.
+ PChain chain;
+ PPResidue res;
+ PPAtom atom;
+ int nResidues, nAtoms, i,j,k;
+
+ if (Calphas) {
+ delete[] Calphas;
+ Calphas = NULL;
+ }
+ nCalphas = 0;
+
+ if (residue) chain = residue->chain;
+ else chain = NULL;
+
+ if (chain) {
+
+ chain->GetResidueTable ( res,nResidues );
+
+ if (nResidues>0) {
+
+ Calphas = new PAtom[nResidues];
+
+ if ((!altLoc[0]) || (altLoc[0]==' ')) { // main conformation
+
+ for (i=0;i<nResidues;i++) {
+ nAtoms = res[i]->nAtoms;
+ atom = res[i]->atom;
+ for (j=0;j<nAtoms;j++)
+ if (!strcmp(atom[j]->name," CA ")) {
+ Calphas[nCalphas++] = atom[j];
+ break;
+ }
+ }
+
+ } else { // specific conformation
+
+ for (i=0;i<nResidues;i++) {
+ nAtoms = res[i]->nAtoms;
+ atom = res[i]->atom;
+ k = 0;
+ for (j=0;j<nAtoms;j++)
+ if (!strcmp(atom[j]->name," CA ")) {
+ k = 1;
+ if (!atom[j]->altLoc[0]) {
+ // take main conformation now as we do not know if
+ // the specific one is in the file
+ Calphas[nCalphas] = atom[j];
+ k = 2;
+ } else if (atom[j]->altLoc[0]==altLoc[0]) {
+ // get specific conformation and quit
+ Calphas[nCalphas] = atom[j];
+ k = 2;
+ break;
+ }
+ } else if (k)
+ break;
+ if (k==2) nCalphas++;
+ }
+
+ }
+
+ }
+
+ } else if (residue) { // check just this atom's residue
+
+ Calphas = new PAtom[1]; // can't be more than 1 C-alpha!
+
+ nAtoms = residue->nAtoms;
+ atom = residue->atom;
+
+ if ((!altLoc[0]) || (altLoc[0]==' ')) { // main conformation
+
+ for (j=0;j<nAtoms;j++)
+ if (!strcmp(atom[j]->name," CA ")) {
+ Calphas[nCalphas++] = atom[j];
+ break;
+ }
+
+ } else { // specific conformation
+
+ k = 0;
+ for (j=0;j<nAtoms;j++)
+ if (!strcmp(atom[j]->name," CA ")) {
+ k = 1;
+ if (!atom[j]->altLoc[0]) {
+ Calphas[nCalphas] = atom[j];
+ k = 2;
+ } else if (atom[j]->altLoc[0]==altLoc[0]) {
+ Calphas[nCalphas] = atom[j];
+ k = 2;
+ break;
+ }
+ } else if (k)
+ break;
+ if (k==2) nCalphas++;
+
+ }
+
+ }
+
+ if (Calphas && (!nCalphas)) {
+ delete[] Calphas;
+ Calphas = NULL;
+ }
+
+ }
+
+ bool Atom::isMetal() {
+ return mmdb::isMetal ( element );
+ }
+
+ bool Atom::isSolvent() {
+ if (residue) return residue->isSolvent();
+ return false;
+ }
+
+ bool Atom::isInSelection ( int selHnd ) {
+ PRoot manager = (PRoot)GetCoordHierarchy();
+ PMask mask;
+ if (manager) {
+ mask = manager->GetSelMask ( selHnd );
+ if (mask) return CheckMask ( mask );
+ }
+ return false;
+ }
+
+ bool Atom::isNTerminus() {
+ if (residue) return residue->isNTerminus();
+ return false;
+ }
+
+ bool Atom::isCTerminus() {
+ if (residue) return residue->isCTerminus();
+ return false;
+ }
+
+ void Atom::CalAtomStatistics ( RAtomStat AS ) {
+ // AS must be initialized. The function only accumulates
+ // the statistics.
+
+ if (!Ter) {
+
+ AS.nAtoms++;
+
+ if (AS.WhatIsSet & WhatIsSet & ASET_Coordinates) {
+ GetStat ( x,AS.xmin,AS.xmax,AS.xm,AS.xm2 );
+ GetStat ( y,AS.ymin,AS.ymax,AS.ym,AS.ym2 );
+ GetStat ( z,AS.zmin,AS.zmax,AS.zm,AS.zm2 );
+ } else
+ AS.WhatIsSet &= ~ASET_Coordinates;
+
+ if (AS.WhatIsSet & WhatIsSet & ASET_Occupancy)
+ GetStat(occupancy,AS.occ_min,AS.occ_max,AS.occ_m,AS.occ_m2);
+ else AS.WhatIsSet &= ~ASET_Occupancy;
+
+ if (AS.WhatIsSet & WhatIsSet & ASET_tempFactor)
+ GetStat ( tempFactor,AS.tFmin,AS.tFmax,AS.tFm,AS.tFm2 );
+ else AS.WhatIsSet &= ~ASET_tempFactor;
+
+ if (AS.WhatIsSet & WhatIsSet & ASET_Anis_tFac) {
+ GetStat ( u11,AS.u11_min,AS.u11_max,AS.u11_m,AS.u11_m2 );
+ GetStat ( u22,AS.u22_min,AS.u22_max,AS.u22_m,AS.u22_m2 );
+ GetStat ( u33,AS.u33_min,AS.u33_max,AS.u33_m,AS.u33_m2 );
+ GetStat ( u12,AS.u12_min,AS.u12_max,AS.u12_m,AS.u12_m2 );
+ GetStat ( u13,AS.u13_min,AS.u13_max,AS.u13_m,AS.u13_m2 );
+ GetStat ( u23,AS.u23_min,AS.u23_max,AS.u23_m,AS.u23_m2 );
+ } else
+ AS.WhatIsSet &= ~ASET_Anis_tFac;
+
+ }
+
+ }
+
+
+ realtype Atom::GetDist2 ( PAtom a ) {
+ realtype dx,dy,dz;
+ dx = a->x - x;
+ dy = a->y - y;
+ dz = a->z - z;
+ return dx*dx + dy*dy + dz*dz;
+ }
+
+ realtype Atom::GetDist2 ( PAtom a, mat44 & tm ) {
+ realtype dx,dy,dz;
+ dx = tm[0][0]*a->x + tm[0][1]*a->y + tm[0][2]*a->z + tm[0][3] - x;
+ dy = tm[1][0]*a->x + tm[1][1]*a->y + tm[1][2]*a->z + tm[1][3] - y;
+ dz = tm[2][0]*a->x + tm[2][1]*a->y + tm[2][2]*a->z + tm[2][3] - z;
+ return dx*dx + dy*dy + dz*dz;
+ }
+
+ realtype Atom::GetDist2 ( PAtom a, mat33 & r, vect3 & t ) {
+ realtype dx,dy,dz;
+ dx = r[0][0]*a->x + r[0][1]*a->y + r[0][2]*a->z + t[0] - x;
+ dy = r[1][0]*a->x + r[1][1]*a->y + r[1][2]*a->z + t[1] - y;
+ dz = r[2][0]*a->x + r[2][1]*a->y + r[2][2]*a->z + t[2] - z;
+ return dx*dx + dy*dy + dz*dz;
+ }
+
+ realtype Atom::GetDist2 ( realtype ax, realtype ay, realtype az ) {
+ realtype dx,dy,dz;
+ dx = ax - x;
+ dy = ay - y;
+ dz = az - z;
+ return dx*dx + dy*dy + dz*dz;
+ }
+
+ realtype Atom::GetCosine ( PAtom a1, PAtom a2 ) {
+ // Calculates cosing of angle a1-this-a2, i.e. that between
+ // bond [a1,this] and [this,a2].
+ realtype dx1,dy1,dz1, dx2,dy2,dz2,r;
+
+ dx1 = a1->x - x;
+ dy1 = a1->y - y;
+ dz1 = a1->z - z;
+ r = dx1*dx1 + dy1*dy1 + dz1*dz1;
+
+ dx2 = a2->x - x;
+ dy2 = a2->y - y;
+ dz2 = a2->z - z;
+ r *= dx2*dx2 + dy2*dy2 + dz2*dz2;
+
+ if (r>0.0) return (dx1*dx2 + dy1*dy2 + dz1*dz2)/sqrt(r);
+ else return 0.0;
+
+ }
+
+
+ void Atom::MakeTer() {
+ WhatIsSet |= ASET_Coordinates;
+ Het = false;
+ Ter = true;
+ }
+
+
+ void Atom::SetAtomName ( const AtomName atomName ) {
+ strcpy ( name,atomName );
+ }
+
+
+ void Atom::SetElementName ( const Element elName ) {
+ strcpy ( element,elName );
+ if (!element[0]) strcpy ( element," " );
+ else if ((!element[1]) || (element[1]==' ')) {
+ element[2] = char(0);
+ element[1] = element[0];
+ element[0] = ' ';
+ }
+ }
+
+ void Atom::SetCharge ( cpstr chrg ) {
+ pstr p;
+ charge = strtod ( chrg,&p );
+ if (p!=chrg) {
+ WhatIsSet |= ASET_Charge;
+ if ((charge>0.0) && (*p=='-'))
+ charge = -charge;
+ }
+ }
+
+ void Atom::SetCharge ( realtype chrg ) {
+ if (chrg<MaxReal) {
+ charge = chrg;
+ WhatIsSet |= ASET_Charge;
+ }
+ }
+
+ void Atom::SetAtomIndex ( int ix ) {
+ // don't use in your applications!
+ index = ix;
+ }
+
+ pstr Atom::GetAtomID ( pstr AtomID ) {
+ char S[50];
+ AtomID[0] = char(0);
+ if (residue) {
+ if (residue->chain) {
+ if (residue->chain->model)
+ sprintf (AtomID,"/%i/",residue->chain->model->GetSerNum());
+ else strcpy ( AtomID,"/-/" );
+ strcat ( AtomID,residue->chain->chainID );
+ } else
+ strcpy ( AtomID,"/-/-" );
+ ParamStr ( AtomID,pstr("/"),residue->seqNum );
+ if (residue->name[0]) {
+ strcat ( AtomID,"(" );
+ strcat ( AtomID,residue->name );
+ strcat ( AtomID,")" );
+ }
+ if (residue->insCode[0]) {
+ strcat ( AtomID,"." );
+ strcat ( AtomID,residue->insCode );
+ }
+ strcat ( AtomID,"/" );
+ } else
+ strcpy ( AtomID,"/-/-/-/" );
+ strcpy_css ( S,name );
+ if (!S[0]) strcpy ( S,"-" );
+ strcat ( AtomID,S );
+ strcpy_css ( S,element );
+ if (S[0]) {
+ strcat ( AtomID,"[" );
+ strcat ( AtomID,S );
+ strcat ( AtomID,"]" );
+ }
+ if (altLoc[0]) {
+ strcat ( AtomID,":" );
+ strcat ( AtomID,altLoc );
+ }
+ return AtomID;
+ }
+
+ pstr Atom::GetAtomIDfmt ( pstr AtomID ) {
+ int n;
+ char S[50];
+ AtomID[0] = char(0);
+ if (residue) {
+ if (residue->chain) {
+ if (residue->chain->model) {
+ n = residue->chain->model->GetNumberOfModels();
+ if (n<10) strcpy ( S,"/%1i/" );
+ else if (n<100) strcpy ( S,"/%2i/" );
+ else if (n<1000) strcpy ( S,"/%3i/" );
+ else strcpy ( S,"/%i/" );
+ sprintf ( AtomID,S,residue->chain->model->GetSerNum() );
+ } else
+ strcpy ( AtomID,"/-/" );
+ strcat ( AtomID,residue->chain->chainID );
+ } else
+ strcpy ( AtomID,"/-/-" );
+ if ((-999<=residue->seqNum) && (residue->seqNum<=9999))
+ sprintf ( S,"/%4i",residue->seqNum );
+ else sprintf ( S,"/%i" ,residue->seqNum );
+ strcat ( AtomID,S );
+ sprintf ( S,"(%3s).%1s/",residue->name,residue->insCode );
+ strcat ( AtomID,S );
+ } else
+ strcpy ( AtomID,"/-/-/----(---).-/" );
+ sprintf ( S,"%4s[%2s]:%1s",name,element,altLoc );
+ strcat ( AtomID,S );
+ return AtomID;
+ }
+
+
+
+ ERROR_CODE Atom::ConvertPDBHETATM ( int ix, cpstr S ) {
+ // Gets data from the PDB ASCII HETATM record.
+ // This function DOES NOT check the "HETATM" keyword and
+ // does not decode the chain and residue parameters! These
+ // must be treated by the calling process, see
+ // Chain::ConvertPDBASCII().
+ ERROR_CODE RC;
+ RC = ConvertPDBATOM ( ix,S );
+ Het = true;
+ return RC;
+ }
+
+ void Atom::GetData ( cpstr S ) {
+ pstr p;
+
+ if (((S[6]>='0') && (S[6]<='9')) || (S[6]==' ')) {
+ // Here we forgive cards with unreadable serial numbers
+ // as we always have index (ix) for the card. For the sake
+ // of strict PDB syntax we would have to return
+ // Error_UnrecognizedInteger here.
+ if (!(GetInteger(serNum,&(S[6]),5))) serNum = -1;
+ } else
+ hy36decode ( 5,&(S[6]),5,&serNum );
+
+ // if (!(GetInteger(serNum,&(S[6]),5))) serNum = index;
+
+ altLoc[0] = S[16];
+ if (altLoc[0]==' ') altLoc[0] = char(0);
+ else altLoc[1] = char(0);
+ GetString ( name ,&(S[12]),4 );
+ strcpy_ncss ( segID ,&(S[72]),4 );
+ GetString ( element,&(S[76]),2 );
+ charge = strtod ( &(S[78]),&p );
+ if ((charge!=0.0) && (p!=&(S[78]))) {
+ WhatIsSet |= ASET_Charge;
+ if ((charge>0.0) && (*p=='-'))
+ charge = -charge;
+ }
+
+ RestoreElementName();
+ strcpy ( label_atom_id,name );
+
+ }
+
+ ERROR_CODE Atom::CheckData ( cpstr S ) {
+ int sN;
+ AltLoc aloc;
+ SegID sID;
+ Element elmnt;
+ pstr p;
+ realtype achrg;
+
+ aloc[0] = S[16];
+ if (aloc[0]==' ') aloc[0] = char(0);
+ else aloc[1] = char(0);
+
+ strcpy_ncss ( sID ,&(S[72]),4 );
+ GetString ( elmnt,&(S[76]),2 );
+
+ if (ignoreCharge)
+ achrg = charge;
+ else {
+ achrg = strtod ( &(S[78]),&p );
+ if ((achrg!=0.0) && (p!=&(S[78]))) {
+ if ((achrg>0.0) && (*p=='-'))
+ achrg = -achrg;
+ }
+ }
+
+ // if (!(GetInteger(sN,&(S[6]),5)))
+ // sN = index;
+
+ if (hy36decode(5,&(S[6]),5,&sN))
+ sN = index;
+
+ if (ignoreSegID) {
+ if (segID[0]) strcpy ( sID,segID );
+ else strcpy ( segID,sID );
+ }
+
+ if (ignoreElement) {
+ if (element[0]) strcpy ( elmnt,element );
+ else strcpy ( element,elmnt );
+ }
+
+ if (ignoreUnmatch) return Error_NoError;
+
+ // Here we forgive cards with unreadable serial numbers
+ // as we always have index (ix) for the card. For the sake
+ // of strict PDB syntax we would have to return
+ // Error_UnrecognizedInteger .
+ if ((sN!=serNum) ||
+ (strcmp (altLoc ,aloc )) ||
+ (strncmp(name ,&(S[12]),4)) ||
+ (strcmp (segID ,sID )) ||
+ (strcmp (element,elmnt )) ||
+ (charge!=achrg)) {
+ /*
+ char name1[100];
+ strncpy ( name1,&(S[12]),4 ); name1[4] = char(0);
+ printf ( "\n serNum %5i %5i\n"
+ " residue '%s' '%s'\n"
+ " altLoc '%s' '%s'\n"
+ " name '%s' '%s'\n"
+ " segId '%s' '%s'\n"
+ " element '%s' '%s'\n"
+ " charge '%s' '%s'\n",
+ sN,serNum, res->name,residue->name,
+ altLoc ,aloc, name,name1,
+ segID ,sID,
+ element,elmnt,
+ charge ,achrg );
+ if (res!=residue) printf (" it's a residue\n" );
+ */
+ return Error_ATOM_Unmatch;
+ }
+
+ return Error_NoError;
+
+ }
+
+
+ ERROR_CODE Atom::GetCIF ( int ix, mmcif::PLoop Loop,
+ mmcif::PLoop LoopAnis ) {
+ char PDBGroup[30];
+ int k;
+ ERROR_CODE RC;
+
+ index = ix;
+
+ if (WhatIsSet & ASET_Coordinates)
+ return Error_ATOM_AlreadySet;
+
+ /*
+
+ loop_
+ *0 _atom_site.group_PDB
+ *1 _atom_site.id
+ *2 _atom_site.type_symbol <- chem elem
+ -3 _atom_site.label_atom_id <- atom name
+ *4 _atom_site.label_alt_id <- alt code
+ =5 _atom_site.label_comp_id <- res name ???
+ =6 _atom_site.label_asym_id <- chain id ???
+ =7 _atom_site.label_entity_id < ???
+ =8 _atom_site.label_seq_id <- poly seq id
+ +9 _atom_site.pdbx_PDB_ins_code <- ins code
+ -10 _atom_site.segment_id <- segment id
+ *11 _atom_site.Cartn_x
+ *12 _atom_site.Cartn_y
+ *13 _atom_site.Cartn_z
+ *14 _atom_site.occupancy
+ *15 _atom_site.B_iso_or_equiv
+ *16 _atom_site.Cartn_x_esd
+ *17 _atom_site.Cartn_y_esd
+ *18 _atom_site.Cartn_z_esd
+ *19 _atom_site.occupancy_esd
+ *20 _atom_site.B_iso_or_equiv_esd
+ *21 _atom_site.pdbx_formal_charge
+ +22 _atom_site.auth_seq_id <- seq id we want
+ +23 _atom_site.auth_comp_id <- res name we want
+ +24 _atom_site.auth_asym_id <- ch id we want ?
+ *25 _atom_site.auth_atom_id <- atom name we want ?
+ +26 _atom_site.pdbx_PDB_model_num <- model no
+
+ '+' read in Root::CheckAtomPlace()
+ '=' new in residue, read in Root::CheckAtomPlace()
+ '-' new in atom
+
+ */
+
+
+ // (0)
+ k = ix-1;
+ CIFGetString ( PDBGroup,Loop,CIFTAG_GROUP_PDB,k,
+ sizeof(PDBGroup),pstr("") );
+
+ Ter = !strcmp(PDBGroup,pstr("TER") );
+ Het = !strcmp(PDBGroup,pstr("HETATM"));
+
+ // (1)
+ RC = CIFGetInteger1 ( serNum,Loop,CIFTAG_ID,k );
+ if (RC) {
+ if (Ter) serNum = -1;
+ else if (RC==Error_NoData) serNum = index;
+ else
+ return RC;
+ }
+
+ if (Ter) {
+ Loop->DeleteRow ( k );
+ WhatIsSet |= ASET_Coordinates;
+ return Error_NoError;
+ }
+
+ // (25)
+ CIFGetString ( name,Loop,CIFTAG_AUTH_ATOM_ID,k,
+ sizeof(name) ,pstr("") );
+ // (3)
+ CIFGetString ( label_atom_id,Loop,CIFTAG_LABEL_ATOM_ID,k,
+ sizeof(label_atom_id),pstr("") );
+ if (!name[0])
+ strcpy ( name,label_atom_id );
+ // (4)
+ CIFGetString ( altLoc,Loop,CIFTAG_LABEL_ALT_ID ,k,
+ sizeof(altLoc),pstr("") );
+
+ // (11,12,13)
+ RC = CIFGetReal1 ( x,Loop,CIFTAG_CARTN_X,k );
+ if (!RC) RC = CIFGetReal1 ( y,Loop,CIFTAG_CARTN_Y,k );
+ if (!RC) RC = CIFGetReal1 ( z,Loop,CIFTAG_CARTN_Z,k );
+ if (RC) return Error_ATOM_Unrecognized;
+ WhatIsSet |= ASET_Coordinates;
+
+ // (14)
+ if (!CIFGetReal1(occupancy,Loop,CIFTAG_OCCUPANCY,k))
+ WhatIsSet |= ASET_Occupancy;
+ // (15)
+ if (!CIFGetReal1(tempFactor,Loop,CIFTAG_B_ISO_OR_EQUIV,k))
+ WhatIsSet |= ASET_tempFactor;
+
+ // (10)
+ CIFGetString ( segID,Loop,CIFTAG_SEGMENT_ID,k,
+ sizeof(segID) ,pstr("") );
+ // (21)
+ if (!CIFGetReal1(charge,Loop,CIFTAG_PDBX_FORMAL_CHARGE,k))
+ WhatIsSet |= ASET_Charge;
+ // (2)
+ RC = CIFGetString ( element,Loop,CIFTAG_TYPE_SYMBOL,k,
+ sizeof(element),pstr("") );
+ if (RC)
+ CIFGetString ( element,Loop,CIFTAG_ATOM_TYPE_SYMBOL,k,
+ sizeof(element),pstr("") );
+
+ RestoreElementName();
+ MakePDBAtomName();
+
+ // (16,17,18)
+ RC = CIFGetReal1 ( sigX,Loop,CIFTAG_CARTN_X_ESD,k );
+ if (!RC) RC = CIFGetReal1 ( sigY,Loop,CIFTAG_CARTN_Y_ESD,k );
+ if (!RC) RC = CIFGetReal1 ( sigZ,Loop,CIFTAG_CARTN_Z_ESD,k );
+ if (RC==Error_UnrecognizedReal)
+ return RC;
+ if (!RC) WhatIsSet |= ASET_CoordSigma;
+
+ // (19)
+ if (!CIFGetReal1(sigOcc,Loop,CIFTAG_OCCUPANCY_ESD,k))
+ WhatIsSet |= ASET_OccSigma;
+ // (20)
+ if (!CIFGetReal1(sigTemp,Loop,CIFTAG_B_ISO_OR_EQUIV_ESD,k))
+ WhatIsSet |= ASET_tFacSigma;
+
+ Loop->DeleteRow ( k );
+
+ if (LoopAnis) {
+
+ RC = CIFGetReal1 ( u11,LoopAnis,CIFTAG_U11,k );
+ if (!RC) RC = CIFGetReal1 ( u22,LoopAnis,CIFTAG_U22,k );
+ if (!RC) RC = CIFGetReal1 ( u33,LoopAnis,CIFTAG_U33,k );
+ if (!RC) RC = CIFGetReal1 ( u13,LoopAnis,CIFTAG_U13,k );
+ if (!RC) RC = CIFGetReal1 ( u12,LoopAnis,CIFTAG_U12,k );
+ if (!RC) RC = CIFGetReal1 ( u23,LoopAnis,CIFTAG_U23,k );
+ if (RC==Error_UnrecognizedReal)
+ return RC;
+ if (!RC) WhatIsSet |= ASET_Anis_tFac;
+
+ RC = CIFGetReal1 ( su11,LoopAnis,CIFTAG_U11_ESD,k );
+ if (!RC) RC = CIFGetReal1 ( su22,LoopAnis,CIFTAG_U22_ESD,k );
+ if (!RC) RC = CIFGetReal1 ( su33,LoopAnis,CIFTAG_U33_ESD,k );
+ if (!RC) RC = CIFGetReal1 ( su13,LoopAnis,CIFTAG_U13_ESD,k );
+ if (!RC) RC = CIFGetReal1 ( su12,LoopAnis,CIFTAG_U12_ESD,k );
+ if (!RC) RC = CIFGetReal1 ( su23,LoopAnis,CIFTAG_U23_ESD,k );
+ if (RC==Error_UnrecognizedReal)
+ return RC;
+ if (!RC) WhatIsSet |= ASET_Anis_tFSigma;
+
+ LoopAnis->DeleteRow ( k );
+
+ }
+
+ return Error_NoError;
+
+ }
+
+ bool Atom::RestoreElementName() {
+ // This function works only if element name is not given.
+
+ if (Ter) {
+ name[0] = char(0);
+ element[0] = char(0);
+ return false;
+ }
+ if ((!element[0]) ||
+ ((element[0]==' ') && ((!element[1]) || (element[1]==' ')))) {
+ if (strlen(name)==4) {
+ if ((name[0]>='A') && (name[0]<='Z')) {
+ element[0] = name[0];
+ element[1] = name[1];
+ } else {
+ element[0] = ' ';
+ element[1] = name[1];
+ }
+ } else { // nasty hack for mmcif files without element column
+ element[0] = ' ';
+ element[1] = name[0];
+ }
+ element[2] = char(0);
+ return false;
+ } else if (!element[1]) {
+ // not aligned element name, possibly coming from mmCIF
+ element[1] = element[0];
+ element[0] = ' ';
+ element[2] = char(0);
+ return false;
+ }
+ return true;
+ }
+
+ bool Atom::MakePDBAtomName() {
+ int i,k;
+
+ if (Ter) {
+ name [0] = char(0);
+ element[0] = char(0);
+ return false;
+ }
+ UpperCase ( name );
+ UpperCase ( element );
+ if ((element[0]==' ') && (element[1]==' ')) {
+ // element name not given, make one from the atom name
+ if ((name[0]>='A') && (name[0]<='Z')) {
+ if (!name[1]) {
+ name[4] = char(0);
+ name[3] = ' ';
+ name[2] = ' ';
+ name[1] = name[0];
+ name[0] = ' ';
+ }
+ /* the commented part looks like a wrong inheritance
+ from FORTRAN RWBrook. Commented on 04.03.2004,
+ to be removed.
+ else if ((name[0]=='C') && (name[1]=='A')) {
+ name[4] = char(0);
+ name[3] = name[2];
+ name[2] = name[1];
+ name[1] = name[0];
+ name[0] = ' ';
+ }
+ */
+ element[0] = name[0];
+ element[1] = name[1];
+ } else {
+ element[0] = ' ';
+ element[1] = name[1];
+ }
+ element[2] = char(0);
+ return false;
+ } else if ((name[0]>='A') && (name[0]<='Z')) {
+ if (!element[1]) {
+ element[2] = char(0);
+ element[1] = element[0];
+ element[0] = ' ';
+ k = strlen(name);
+ if (k<4) {
+ for (i=3;i>0;i--)
+ name[i] = name[i-1];
+ name[0] = ' ';
+ k++;
+ while (k<4)
+ name[k++] = ' ';
+ name[k] = char(0);
+ }
+ } else if ((element[0]==' ') && (element[1]!=name[1])) {
+ for (i=3;i>0;i--)
+ name[i] = name[i-1];
+ name[0] = ' ';
+ name[4] = char(0);
+ k = strlen(name);
+ while (k<4)
+ name[k++] = ' ';
+ name[k] = char(0);
+ } else {
+ k = strlen(name);
+ while (k<4)
+ name[k++] = ' ';
+ name[k] = char(0);
+ }
+ }
+ return true;
+ }
+
+ void Atom::SetCoordinates ( realtype xx, realtype yy, realtype zz,
+ realtype occ, realtype tFac ) {
+ x = xx;
+ y = yy;
+ z = zz;
+ occupancy = occ;
+ tempFactor = tFac;
+ WhatIsSet |= ASET_Coordinates | ASET_Occupancy | ASET_tempFactor;
+ }
+
+ void Atom::Transform ( mat33 & tm, vect3 & v ) {
+ realtype x1,y1,z1;
+ x1 = tm[0][0]*x + tm[0][1]*y + tm[0][2]*z + v[0];
+ y1 = tm[1][0]*x + tm[1][1]*y + tm[1][2]*z + v[1];
+ z1 = tm[2][0]*x + tm[2][1]*y + tm[2][2]*z + v[2];
+ x = x1;
+ y = y1;
+ z = z1;
+ }
+
+ void Atom::Transform ( mat44 & tm ) {
+ realtype x1,y1,z1;
+ x1 = tm[0][0]*x + tm[0][1]*y + tm[0][2]*z + tm[0][3];
+ y1 = tm[1][0]*x + tm[1][1]*y + tm[1][2]*z + tm[1][3];
+ z1 = tm[2][0]*x + tm[2][1]*y + tm[2][2]*z + tm[2][3];
+ x = x1;
+ y = y1;
+ z = z1;
+ }
+
+ void Atom::TransformCopy ( mat44 & tm,
+ realtype & xx,
+ realtype & yy,
+ realtype & zz ) {
+ xx = tm[0][0]*x + tm[0][1]*y + tm[0][2]*z + tm[0][3];
+ yy = tm[1][0]*x + tm[1][1]*y + tm[1][2]*z + tm[1][3];
+ zz = tm[2][0]*x + tm[2][1]*y + tm[2][2]*z + tm[2][3];
+ }
+
+ void Atom::TransformSet ( mat44 & tm,
+ realtype xx,
+ realtype yy,
+ realtype zz ) {
+ x = tm[0][0]*xx + tm[0][1]*yy + tm[0][2]*zz + tm[0][3];
+ y = tm[1][0]*xx + tm[1][1]*yy + tm[1][2]*zz + tm[1][3];
+ z = tm[2][0]*xx + tm[2][1]*yy + tm[2][2]*zz + tm[2][3];
+ }
+
+
+ // ------- user-defined data handlers
+
+ int Atom::PutUDData ( int UDDhandle, int iudd ) {
+ if (UDDhandle & UDRF_ATOM)
+ return UDData::putUDData ( UDDhandle,iudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Atom::PutUDData ( int UDDhandle, realtype rudd ) {
+ if (UDDhandle & UDRF_ATOM)
+ return UDData::putUDData ( UDDhandle,rudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Atom::PutUDData ( int UDDhandle, cpstr sudd ) {
+ if (UDDhandle & UDRF_ATOM)
+ return UDData::putUDData ( UDDhandle,sudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Atom::GetUDData ( int UDDhandle, int & iudd ) {
+ if (UDDhandle & UDRF_ATOM)
+ return UDData::getUDData ( UDDhandle,iudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Atom::GetUDData ( int UDDhandle, realtype & rudd ) {
+ if (UDDhandle & UDRF_ATOM)
+ return UDData::getUDData ( UDDhandle,rudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Atom::GetUDData ( int UDDhandle, pstr sudd, int maxLen ) {
+ if (UDDhandle & UDRF_ATOM)
+ return UDData::getUDData ( UDDhandle,sudd,maxLen );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Atom::GetUDData ( int UDDhandle, pstr & sudd ) {
+ if (UDDhandle & UDRF_ATOM)
+ return UDData::getUDData ( UDDhandle,sudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+
+ void Atom::Copy ( PAtom atom ) {
+ // this does not make any references in residues and does
+ // not change indices!! it does change serial numbers, though.
+
+ serNum = atom->serNum;
+ x = atom->x;
+ y = atom->y;
+ z = atom->z;
+ occupancy = atom->occupancy;
+ tempFactor = atom->tempFactor;
+ sigX = atom->sigX;
+ sigY = atom->sigY;
+ sigZ = atom->sigZ;
+ sigOcc = atom->sigOcc;
+ sigTemp = atom->sigTemp;
+ u11 = atom->u11;
+ u22 = atom->u22;
+ u33 = atom->u33;
+ u12 = atom->u12;
+ u13 = atom->u13;
+ u23 = atom->u23;
+ su11 = atom->su11;
+ su22 = atom->su22;
+ su33 = atom->su33;
+ su12 = atom->su12;
+ su13 = atom->su13;
+ su23 = atom->su23;
+ Het = atom->Het;
+ Ter = atom->Ter;
+ WhatIsSet = atom->WhatIsSet;
+
+ strcpy ( name ,atom->name );
+ strcpy ( label_atom_id,atom->label_atom_id );
+ strcpy ( altLoc ,atom->altLoc );
+ strcpy ( segID ,atom->segID );
+ strcpy ( element ,atom->element );
+ strcpy ( energyType ,atom->energyType );
+ charge = atom->charge;
+
+ }
+
+ int Atom::CheckID ( const AtomName aname, const Element elname,
+ const AltLoc aloc ) {
+ pstr p1,p2;
+ if (aname) {
+ if (aname[0]!='*') {
+ p1 = name;
+ while (*p1==' ') p1++;
+ p2 = pstr(aname);
+ while (*p2==' ') p2++;
+ while ((*p2) && (*p1) && (*p1!=' ') && (*p2!=' ')) {
+ if (*p1!=*p2) return 0;
+ p1++;
+ p2++;
+ }
+ if (*p1!=*p2) {
+ if (((*p1) && (*p1!=' ')) ||
+ ((*p2) && (*p2!=' '))) return 0;
+ }
+ }
+ }
+ if (elname) {
+ if (elname[0]!='*') {
+ p1 = element;
+ while (*p1==' ') p1++;
+ p2 = pstr(elname);
+ while (*p2==' ') p2++;
+ while ((*p2) && (*p1) && (*p1!=' ') && (*p2!=' ')) {
+ if (*p1!=*p2) return 0;
+ p1++;
+ p2++;
+ }
+ if (*p1!=*p2) return 0;
+ }
+ }
+ if (aloc) {
+ if ((aloc[0]!='*') && (strcmp(aloc,altLoc))) return 0;
+ }
+ return 1;
+ }
+
+ int Atom::CheckIDS ( cpstr ID ) {
+ AtomName aname;
+ Element elname;
+ AltLoc aloc;
+ pstr p;
+ p = strrchr ( ID,'/' );
+ if (p) p++;
+ else p = pstr(ID);
+ ParseAtomID ( p,aname,elname,aloc );
+ return CheckID ( aname,elname,aloc );
+ }
+
+ void Atom::SetShortBinary() {
+ WhatIsSet |= ASET_ShortBinary;
+ }
+
+ void Atom::write ( io::RFile f ) {
+ int i,k;
+ byte Version=2;
+ byte nb;
+
+ f.WriteWord ( &WhatIsSet );
+ if (WhatIsSet & ASET_ShortBinary) {
+ if (Ter) WhatIsSet |= ASET_ShortTer;
+ if (Het) WhatIsSet |= ASET_ShortHet;
+ f.WriteInt ( &index );
+ f.WriteTerLine ( name ,false );
+ f.WriteTerLine ( altLoc ,false );
+ f.WriteTerLine ( element,false );
+ if (WhatIsSet & ASET_Coordinates) {
+ f.WriteFloat ( &x );
+ f.WriteFloat ( &y );
+ f.WriteFloat ( &z );
+ }
+ return;
+ }
+
+ f.WriteByte ( &Version );
+
+ UDData::write ( f );
+
+ f.WriteInt ( &serNum );
+ f.WriteInt ( &index );
+ f.WriteTerLine ( name ,false );
+ f.WriteTerLine ( label_atom_id,false );
+ f.WriteTerLine ( altLoc ,false );
+ f.WriteTerLine ( segID ,false );
+ f.WriteTerLine ( element ,false );
+ f.WriteTerLine ( energyType ,false );
+ f.WriteFloat ( &charge );
+ f.WriteBool ( &Het );
+ f.WriteBool ( &Ter );
+
+ if (WhatIsSet & ASET_Coordinates) {
+ f.WriteFloat ( &x );
+ f.WriteFloat ( &y );
+ f.WriteFloat ( &z );
+ if (WhatIsSet & ASET_Occupancy)
+ f.WriteFloat ( &occupancy );
+ if (WhatIsSet & ASET_tempFactor)
+ f.WriteFloat ( &tempFactor );
+ }
+
+ if (WhatIsSet & ASET_CoordSigma) {
+ f.WriteFloat ( &sigX );
+ f.WriteFloat ( &sigY );
+ f.WriteFloat ( &sigZ );
+ if ((WhatIsSet & ASET_Occupancy) &&
+ (WhatIsSet & ASET_OccSigma))
+ f.WriteFloat ( &sigOcc );
+ if ((WhatIsSet & ASET_tempFactor) &&
+ (WhatIsSet & ASET_tFacSigma))
+ f.WriteFloat ( &sigTemp );
+ }
+
+ if (WhatIsSet & ASET_Anis_tFac) {
+ f.WriteFloat ( &u11 );
+ f.WriteFloat ( &u22 );
+ f.WriteFloat ( &u33 );
+ f.WriteFloat ( &u12 );
+ f.WriteFloat ( &u13 );
+ f.WriteFloat ( &u23 );
+ if (WhatIsSet & ASET_Anis_tFSigma) {
+ f.WriteFloat ( &su11 );
+ f.WriteFloat ( &su22 );
+ f.WriteFloat ( &su33 );
+ f.WriteFloat ( &su12 );
+ f.WriteFloat ( &su13 );
+ f.WriteFloat ( &su23 );
+ }
+ }
+
+ nb = byte(nBonds & 0x000000FF);
+ f.WriteByte ( &nb );
+ for (i=0;i<nb;i++)
+ if (Bond[i].atom) {
+ f.WriteInt ( &(Bond[i].atom->index) );
+ f.WriteByte ( &(Bond[i].order) );
+ } else {
+ k = -1;
+ f.WriteInt ( &k );
+ }
+
+ }
+
+ void Atom::read ( io::RFile f ) {
+ int i,k;
+ byte nb,Version;
+
+ FreeMemory();
+
+ f.ReadWord ( &WhatIsSet );
+ if (WhatIsSet & ASET_ShortBinary) {
+ f.ReadInt ( &index );
+ f.ReadTerLine ( name ,false );
+ f.ReadTerLine ( altLoc ,false );
+ f.ReadTerLine ( element,false );
+ if (WhatIsSet & ASET_Coordinates) {
+ f.ReadFloat ( &x );
+ f.ReadFloat ( &y );
+ f.ReadFloat ( &z );
+ }
+ serNum = index;
+ Ter = WhatIsSet & ASET_ShortTer;
+ Het = WhatIsSet & ASET_ShortHet;
+ name [4] = char(0);
+ altLoc [1] = char(0);
+ element[2] = char(0);
+ segID [0] = char(0);
+ charge = 0.0;
+ WhatIsSet &= ASET_All;
+ return;
+ }
+
+ f.ReadByte ( &Version );
+
+ UDData::read ( f );
+
+ f.ReadInt ( &serNum );
+ f.ReadInt ( &index );
+ f.ReadTerLine ( name ,false );
+ if (Version>1)
+ f.ReadTerLine ( label_atom_id,false );
+ f.ReadTerLine ( altLoc ,false );
+ f.ReadTerLine ( segID ,false );
+ f.ReadTerLine ( element ,false );
+ f.ReadTerLine ( energyType,false );
+ f.ReadFloat ( &charge );
+ f.ReadBool ( &Het );
+ f.ReadBool ( &Ter );
+
+ if (WhatIsSet & ASET_Coordinates) {
+ f.ReadFloat ( &x );
+ f.ReadFloat ( &y );
+ f.ReadFloat ( &z );
+ if (WhatIsSet & ASET_Occupancy) f.ReadFloat ( &occupancy );
+ else occupancy = 0.0;
+ if (WhatIsSet & ASET_tempFactor) f.ReadFloat ( &tempFactor );
+ else tempFactor = 0.0;
+ } else {
+ x = 0.0;
+ y = 0.0;
+ z = 0.0;
+ occupancy = 0.0;
+ tempFactor = 0.0;
+ }
+
+ if (WhatIsSet & ASET_CoordSigma) {
+ f.ReadFloat ( &sigX );
+ f.ReadFloat ( &sigY );
+ f.ReadFloat ( &sigZ );
+ if ((WhatIsSet & ASET_Occupancy) &&
+ (WhatIsSet & ASET_OccSigma))
+ f.ReadFloat ( &sigOcc );
+ else sigOcc = 0.0;
+ if ((WhatIsSet & ASET_tempFactor) &&
+ (WhatIsSet & ASET_tFacSigma))
+ f.ReadFloat ( &sigTemp );
+ else sigTemp = 0.0;
+ } else {
+ sigX = 0.0;
+ sigY = 0.0;
+ sigZ = 0.0;
+ sigOcc = 0.0;
+ sigTemp = 0.0;
+ }
+
+ if (WhatIsSet & ASET_Anis_tFac) {
+ f.ReadFloat ( &u11 );
+ f.ReadFloat ( &u22 );
+ f.ReadFloat ( &u33 );
+ f.ReadFloat ( &u12 );
+ f.ReadFloat ( &u13 );
+ f.ReadFloat ( &u23 );
+ if (WhatIsSet & ASET_Anis_tFSigma) {
+ f.ReadFloat ( &su11 );
+ f.ReadFloat ( &su22 );
+ f.ReadFloat ( &su33 );
+ f.ReadFloat ( &su12 );
+ f.ReadFloat ( &su13 );
+ f.ReadFloat ( &su23 );
+ } else {
+ su11 = 0.0;
+ su22 = 0.0;
+ su33 = 0.0;
+ su12 = 0.0;
+ su13 = 0.0;
+ su23 = 0.0;
+ }
+ } else {
+ u11 = 0.0;
+ u22 = 0.0;
+ u33 = 0.0;
+ u12 = 0.0;
+ u13 = 0.0;
+ u23 = 0.0;
+ su11 = 0.0;
+ su22 = 0.0;
+ su33 = 0.0;
+ su12 = 0.0;
+ su13 = 0.0;
+ su23 = 0.0;
+ }
+
+ f.ReadByte ( &nb );
+ if (nb>0) {
+ Bond = new AtomBond[nb];
+ for (i=0;i<nb;i++) {
+ f.ReadInt ( &k );
+ if (k>0) f.ReadByte ( &(Bond[i].order) );
+ else Bond[i].order = 0;
+ // we place *index* of bonded atom temporary on the place
+ // of its pointer, and the pointer will be calculated
+ // after Residue::read calls _setBonds(..).
+ memcpy ( &(Bond[i].atom),&k,4 );
+ }
+ }
+ nBonds = nb;
+ nBonds = nBonds | (nBonds << 8);
+
+ }
+
+ void Atom::_setBonds ( PPAtom A ) {
+ int i,k,nb;
+ nb = nBonds & 0x000000FF;
+ for (i=0;i<nb;i++) {
+ memcpy ( &k,&(Bond[i].atom),4 );
+ if (k>0) Bond[i].atom = A[k];
+ else Bond[i].atom = NULL;
+ }
+ }
+
+
+ MakeFactoryFunctions(Atom)
+
+
+
+ // =========================== Residue ===========================
+
+
+ void AtomStat::Init() {
+
+ nAtoms = 0;
+
+ xmin = MaxReal; xmax = MinReal; xm = 0.0; xm2 = 0.0;
+ ymin = MaxReal; ymax = MinReal; ym = 0.0; ym2 = 0.0;
+ zmin = MaxReal; zmax = MinReal; zm = 0.0; zm2 = 0.0;
+
+ occ_min = MaxReal; occ_max = MinReal; occ_m = 0.0; occ_m2 = 0.0;
+ tFmin = MaxReal; tFmax = MinReal; tFm = 0.0; tFm2 = 0.0;
+
+ u11_min = MaxReal; u11_max = MinReal; u11_m = 0.0; u11_m2 = 0.0;
+ u22_min = MaxReal; u22_max = MinReal; u22_m = 0.0; u22_m2 = 0.0;
+ u33_min = MaxReal; u33_max = MinReal; u33_m = 0.0; u33_m2 = 0.0;
+ u12_min = MaxReal; u12_max = MinReal; u12_m = 0.0; u12_m2 = 0.0;
+ u13_min = MaxReal; u13_max = MinReal; u13_m = 0.0; u13_m2 = 0.0;
+ u23_min = MaxReal; u23_max = MinReal; u23_m = 0.0; u23_m2 = 0.0;
+
+ WhatIsSet = ASET_All;
+
+ finished = false;
+
+ }
+
+ void AtomStat::Finish() {
+ realtype v;
+
+ if (!finished) {
+
+ finished = true;
+
+ if (nAtoms>0) {
+
+ v = nAtoms;
+
+ xm /= v; xm2 /= v;
+ ym /= v; ym2 /= v;
+ zm /= v; zm2 /= v;
+
+ occ_m /= v; occ_m2 /= v;
+ tFm /= v; tFm2 /= v;
+
+ u11_m /= v; u11_m2 /= v;
+ u22_m /= v; u22_m2 /= v;
+ u33_m /= v; u33_m2 /= v;
+ u12_m /= v; u12_m2 /= v;
+ u13_m /= v; u13_m2 /= v;
+ u23_m /= v; u23_m2 /= v;
+ }
+ }
+
+ }
+
+ realtype AtomStat::GetMaxSize() {
+ realtype r;
+ r = RMax(xmax-xmin,ymax-ymin);
+ r = RMax(r,zmax-zmin);
+ return RMax(r,0.0);
+ }
+
+
+ // ----------------------------------------------------------------
+
+
+ Residue::Residue() : UDData() {
+ InitResidue();
+ }
+
+ Residue::Residue ( PChain Chain_Owner ) : UDData() {
+ InitResidue();
+ if (Chain_Owner)
+ Chain_Owner->AddResidue ( this );
+ }
+
+ Residue::Residue ( PChain Chain_Owner,
+ const ResName resName,
+ int sqNum,
+ const InsCode ins ) : UDData() {
+ InitResidue();
+ seqNum = sqNum;
+ strcpy_css ( name,pstr(resName) );
+ strcpy_css ( insCode,pstr(ins) );
+ if (Chain_Owner)
+ Chain_Owner->AddResidue ( this );
+ }
+
+ Residue::Residue ( io::RPStream Object ) : UDData(Object) {
+ InitResidue();
+ }
+
+ Residue::~Residue() {
+ FreeMemory();
+ if (chain) chain->_ExcludeResidue ( name,seqNum,insCode );
+ }
+
+
+ void Residue::InitResidue() {
+ strcpy ( name ,"---" ); // residue name
+ strcpy ( label_comp_id,"---" ); // assigned residue name
+ label_asym_id[0] = char(0); // assigned chain Id
+ seqNum = -MaxInt; // residue sequence number
+ label_seq_id = -MaxInt; // assigned residue sequence number
+ label_entity_id = 1; // assigned entity id
+ strcpy ( insCode,"" ); // residue insertion code
+ chain = NULL; // reference to chain
+ index = -1; // undefined index in chain
+ nAtoms = 0; // number of atoms in the residue
+ AtmLen = 0; // length of atom array
+ atom = NULL; // array of atoms
+ Exclude = true;
+ SSE = SSE_None;
+ }
+
+ void Residue::SetChain ( PChain Chain_Owner ) {
+ chain = Chain_Owner;
+ }
+
+
+ int Residue::GetResidueNo() {
+ if (chain) return chain->GetResidueNo ( seqNum,insCode );
+ else return -1;
+ }
+
+ void Residue::SetChainID ( const ChainID chID ) {
+ if (chain)
+ chain->SetChainID ( chID );
+ }
+
+
+ int Residue::GetCenter ( realtype & x, realtype & y,
+ realtype & z ) {
+ int i,k;
+ x = 0.0;
+ y = 0.0;
+ z = 0.0;
+ k = 0;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (!atom[i]->Ter) {
+ x += atom[i]->x;
+ y += atom[i]->y;
+ z += atom[i]->z;
+ k++;
+ }
+ }
+ if (k>0) {
+ x /= k;
+ y /= k;
+ z /= k;
+ return 0;
+ }
+ return 1;
+ }
+
+ void * Residue::GetCoordHierarchy() {
+ if (chain) return chain->GetCoordHierarchy();
+ return NULL;
+ }
+
+ void Residue::GetAltLocations ( int & nAltLocs,
+ PAltLoc & aLoc,
+ rvector & occupancy,
+ int & alflag ) {
+ int i,j,k, nal,nal1;
+ realtype occ1;
+ bool B;
+ PAltLoc aL;
+ rvector occ;
+ bvector alv;
+
+ aLoc = NULL;
+ occupancy = NULL;
+ nAltLocs = 0;
+ alflag = ALF_NoAltCodes;
+
+ if (nAtoms>0) {
+
+ // temporary array for altcodes
+ aL = new AltLoc[nAtoms];
+ // temporary array for occupancies
+ GetVectorMemory ( occ,nAtoms,0 );
+ // temporary array for checking altcodes
+ GetVectorMemory ( alv,nAtoms,0 );
+ for (i=0;i<nAtoms;i++)
+ alv[i] = false;
+
+ k = 0; // counts unique alternation codes
+ nal = 0;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (!atom[i]->Ter) {
+ // Find if the alternation code of ith atom is
+ // a new one.
+ B = false;
+ for (j=0;(j<k) && (!B);j++)
+ B = !strcmp(atom[i]->altLoc,aL[j]);
+ if (!B) {
+ // that's a new altcode, get its occupancy
+ if (atom[i]->WhatIsSet & ASET_Occupancy)
+ occ[k] = atom[i]->occupancy;
+ else occ[k] = -1.0;
+ // store new altcode in temporary array
+ strcpy ( aL[k],atom[i]->altLoc );
+ // check consistency of the altcode data if:
+ // a) the data was not found wrong so far
+ // b) this atom name has not been checked before
+ // c) altcode is not the "empty"-altcode
+ if ((!(alflag & ALF_Mess)) && (!alv[i]) &&
+ (atom[i]->altLoc[0])) {
+ B = false; // will be set true if "empty"-altcode
+ // is found for current atom name
+ nal1 = 0; // counts the number of different altcodes
+ // for current atom name
+ occ1 = 0.0; // will count the sum of occupancies for
+ // current atom name
+ for (j=0;j<nAtoms;j++)
+ if (atom[j]) {
+ if ((!atom[j]->Ter) &&
+ (!strcmp(atom[j]->name,atom[i]->name))) {
+ if (atom[j]->WhatIsSet & ASET_Occupancy)
+ occ1 += atom[j]->occupancy;
+ if (!atom[j]->altLoc[0]) B = true;
+ alv[j] = true; // mark it as "checked"
+ nal1++;
+ }
+ }
+ if (!(alflag & (ALF_EmptyAltLoc | ALF_NoEmptyAltLoc))) {
+ if (B) alflag |= ALF_EmptyAltLoc;
+ else alflag |= ALF_NoEmptyAltLoc;
+ } else if (((alflag & ALF_EmptyAltLoc) && (!B)) ||
+ ((alflag & ALF_NoEmptyAltLoc) && (B)))
+ alflag |= ALF_Mess;
+ if ((occ[k]>=0) && (fabs(1.0-occ1)>0.01))
+ alflag |= ALF_Occupancy;
+ if (nal==0) // first time just remember the number
+ nal = nal1; // of different altcodes
+ else if (nal!=nal1) // check if number of different altcodes
+ alflag |= ALF_Mess; // is not the same through the residue
+ }
+ k++;
+ }
+ }
+ }
+ if (k>0) {
+ aLoc = new AltLoc[k];
+ GetVectorMemory ( occupancy,k,0 );
+ for (i=0;i<k;i++) {
+ strcpy ( aLoc[i],aL[i] );
+ occupancy[i] = occ[i];
+ }
+ nAltLocs = k;
+ }
+
+ delete[] aL;
+ FreeVectorMemory ( occ,0 );
+ FreeVectorMemory ( alv,0 );
+
+ }
+
+ }
+
+ int Residue::GetNofAltLocations() {
+ int i,j,k;
+ bool B;
+ k = 0;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (!atom[i]->Ter) {
+ B = false;
+ for (j=0;(j<i) && (!B);j++)
+ if (atom[j]) {
+ if (!atom[j]->Ter)
+ B = !strcmp(atom[i]->altLoc,atom[j]->altLoc);
+ }
+ if (!B) k++;
+ }
+ }
+ return k;
+ }
+
+ void Residue::SetResID ( const ResName resName, int sqNum,
+ const InsCode ins ) {
+ strcpy_css ( name,pstr(resName) );
+ seqNum = sqNum;
+ strcpy_css ( insCode,pstr(ins) );
+ strcpy (label_comp_id,name );
+ }
+
+ void Residue::FreeMemory() {
+ // NOTE: individual atoms are disposed here as well!
+ DeleteAllAtoms();
+ if (atom) delete[] atom;
+ atom = NULL;
+ nAtoms = 0;
+ AtmLen = 0;
+ }
+
+ void Residue::ExpandAtomArray ( int nAdd ) {
+ int i;
+ PPAtom atom1;
+ AtmLen += abs(nAdd);
+ atom1 = new PAtom[AtmLen];
+ for (i=0;i<nAtoms;i++)
+ atom1[i] = atom[i];
+ for (i=nAtoms;i<AtmLen;i++)
+ atom1[i] = NULL;
+ if (atom) delete[] atom;
+ atom = atom1;
+ }
+
+ int Residue::_AddAtom ( PAtom atm ) {
+ // Adds atom to the residue
+ int i;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]==atm) return -i; // this atom is already there
+ if (nAtoms>=AtmLen)
+ ExpandAtomArray ( nAtoms+10-AtmLen );
+ atom[nAtoms] = atm;
+ atom[nAtoms]->residue = this;
+ nAtoms++;
+ return 0;
+ }
+
+ int Residue::AddAtom ( PAtom atm ) {
+ // AddAtom(..) adds atom to the residue. If residue is associated
+ // with a coordinate hierarchy, and atom 'atm' is not, the latter
+ // is checked in automatically. If atom 'atm' belongs to any
+ // coordinate hierarchy (even though that of the residue), it is
+ // *copied* rather than simply taken over, and is checked in.
+ // If residue is not associated with a coordinate hierarchy, all
+ // added atoms will be checked in automatically once the residue
+ // is checked in.
+ PRoot manager;
+ PResidue res;
+ int i;
+
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]==atm) return -i; // this atom is already there
+
+ if (nAtoms>=AtmLen)
+ ExpandAtomArray ( nAtoms+10-AtmLen );
+
+ if (atm->GetCoordHierarchy()) {
+ atom[nAtoms] = newAtom();
+ atom[nAtoms]->Copy ( atm );
+ } else {
+ res = atm->GetResidue();
+ if (res)
+ for (i=0;i<res->nAtoms;i++)
+ if (res->atom[i]==atm) {
+ res->atom[i] = NULL;
+ break;
+ }
+ atom[nAtoms] = atm;
+ }
+
+ atom[nAtoms]->residue = this;
+ manager = PRoot(GetCoordHierarchy());
+ if (manager)
+ manager->CheckInAtom ( 0,atom[nAtoms] );
+
+ nAtoms++;
+
+ return nAtoms;
+
+ }
+
+ int Residue::InsertAtom ( PAtom atm, int position ) {
+ // InsertAtom(..) inserts atom into the specified position of
+ // the residue. If residue is associated with a coordinate hierarchy,
+ // and atom 'atm' is not, the latter is checked in automatically.
+ // If atom 'atm' belongs to any coordinate hierarchy (even though
+ // that of the residue), it is *copied* rather than simply taken
+ // over, and is checked in.
+ // If residue is not associated with a coordinate hierarchy, all
+ // added atoms will be checked in automatically once the residue
+ // is checked in.
+ PRoot manager;
+ PResidue res;
+ int i,pos;
+
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]==atm) return -i; // this atom is already there
+
+ if (nAtoms>=AtmLen)
+ ExpandAtomArray ( nAtoms+10-AtmLen );
+
+ pos = IMin(position,nAtoms);
+ for (i=nAtoms;i>pos;i--)
+ atom[i] = atom[i-1];
+
+ if (atm->GetCoordHierarchy()) {
+ atom[pos] = newAtom();
+ atom[pos]->Copy ( atm );
+ } else {
+ res = atm->GetResidue();
+ if (res)
+ for (i=0;i<res->nAtoms;i++)
+ if (res->atom[i]==atm) {
+ res->atom[i] = NULL;
+ break;
+ }
+ atom[pos] = atm;
+ }
+
+ atom[pos]->residue = this;
+ manager = PRoot(GetCoordHierarchy());
+ if (manager)
+ manager->CheckInAtom ( 0,atom[pos] );
+
+ nAtoms++;
+
+ return nAtoms;
+
+ }
+
+ int Residue::InsertAtom ( PAtom atm, const AtomName aname ) {
+ // This version inserts before the atom with given name. If such
+ // name is not found, the atom is appended to the end.
+ int i;
+ i = 0;
+ while (i<nAtoms)
+ if (!atom[i]) i++;
+ else if (!strcmp(aname,atom[i]->name)) break;
+ else i++;
+ return InsertAtom ( atm,i );
+ }
+
+
+ void Residue::CheckInAtoms() {
+ PRoot manager;
+ int i;
+ manager = PRoot(GetCoordHierarchy());
+ if (manager)
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (atom[i]->index<0)
+ manager->CheckInAtom ( 0,atom[i] );
+ }
+ }
+
+
+ int Residue::_ExcludeAtom ( int kndex ) {
+ // deletes atom from the residue
+ int i,k;
+
+ if (!Exclude) return 0;
+
+ k = -1;
+ for (i=0;(i<nAtoms) && (k<0);i++)
+ if (atom[i]) {
+ if (atom[i]->index==kndex) k = i;
+ }
+
+ if (k>=0) {
+ for (i=k+1;i<nAtoms;i++)
+ atom[i-1] = atom[i];
+ nAtoms--;
+ }
+
+ if (nAtoms<=0) return 1;
+ else return 0;
+
+ }
+
+
+ void Residue::PDBASCIIAtomDump ( io::RFile f ) {
+ int i;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i])
+ atom[i]->PDBASCIIDump ( f );
+ }
+
+ void Residue::MakeAtomCIF ( mmcif::PData CIF ) {
+ int i;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i])
+ atom[i]->MakeCIF ( CIF );
+ }
+
+
+ void Residue::Copy ( PResidue res ) {
+ //
+ // Modify Residue::Copy and both Residues::_copy methods
+ // simultaneously!
+ //
+ // This function will nake a copy of residue res in 'this' one.
+ // All atoms are copied, none is moved regardless to the association
+ // with coordinate hierarchy. If 'this' residue is associated with
+ // a coordinate hierarchy, all atoms are checked in.
+ PRoot manager;
+ int i;
+
+ FreeMemory();
+
+ seqNum = res->seqNum;
+ label_seq_id = res->label_seq_id;
+ label_entity_id = res->label_entity_id;
+ index = res->index;
+ AtmLen = res->nAtoms;
+ SSE = res->SSE;
+ strcpy ( name ,res->name );
+ strcpy ( label_comp_id,res->label_comp_id );
+ strcpy ( label_asym_id,res->label_asym_id );
+ strcpy ( insCode ,res->insCode );
+
+ if (AtmLen>0) {
+ atom = new PAtom[AtmLen];
+ nAtoms = 0;
+ for (i=0;i<res->nAtoms;i++)
+ if (res->atom[i]) {
+ atom[nAtoms] = newAtom();
+ atom[nAtoms]->Copy ( res->atom[i] );
+ atom[nAtoms]->SetResidue ( this );
+ nAtoms++;
+ }
+ for (i=nAtoms;i<AtmLen;i++)
+ atom[i] = NULL;
+ manager = PRoot(GetCoordHierarchy());
+ if (manager)
+ manager->CheckInAtoms ( 0,atom,nAtoms );
+ }
+
+ }
+
+
+ void Residue::_copy ( PResidue res ) {
+ // Modify both Residue::_copy and Residue::Copy methods
+ // simultaneously!
+ //
+ // will work properly only if atomic arrays
+ // this->chain->model->GetAtom() and
+ // res->chain->model->GetAtom() are identical
+ //
+ int i;
+ PPAtom A;
+
+ FreeMemory();
+
+ seqNum = res->seqNum;
+ label_seq_id = res->label_seq_id;
+ label_entity_id = res->label_entity_id;
+ index = res->index;
+ nAtoms = res->nAtoms;
+ SSE = res->SSE;
+ strcpy ( name ,res->name );
+ strcpy ( label_comp_id,res->label_comp_id );
+ strcpy ( label_asym_id,res->label_asym_id );
+ strcpy ( insCode ,res->insCode );
+
+ AtmLen = nAtoms;
+ A = NULL;
+ if (chain) {
+ if (chain->model)
+ A = chain->model->GetAllAtoms();
+ }
+ if ((nAtoms>0) && (A)) {
+ atom = new PAtom[nAtoms];
+ for (i=0;i<nAtoms;i++) {
+ atom[i] = A[res->atom[i]->index-1];
+ atom[i]->SetResidue ( this );
+ }
+ } else {
+ nAtoms = 0;
+ AtmLen = 0;
+ }
+
+ }
+
+ void Residue::_copy ( PResidue res, PPAtom atm,
+ int & atom_index ) {
+ // modify both Residue::_copy and Residue::Copy methods
+ // simultaneously!
+ //
+ // This function physically copies the atoms, creating new atom
+ // instances and putting them into array 'atm' sequentially from
+ // 'atom_index' position. 'atom_index' is modified (advanced).
+ //
+ int i;
+
+ FreeMemory();
+
+ seqNum = res->seqNum;
+ label_seq_id = res->label_seq_id;
+ label_entity_id = res->label_entity_id;
+ index = res->index;
+ nAtoms = res->nAtoms;
+ SSE = res->SSE;
+ strcpy ( name ,res->name );
+ strcpy ( label_comp_id,res->label_comp_id );
+ strcpy ( label_asym_id,res->label_asym_id );
+ strcpy ( insCode ,res->insCode );
+
+ AtmLen = nAtoms;
+ if (AtmLen>0) {
+ atom = new PAtom[AtmLen];
+ for (i=0;i<nAtoms;i++)
+ if (res->atom[i]) {
+ if (!atm[atom_index]) atm[atom_index] = newAtom();
+ atm[atom_index]->Copy ( res->atom[i] );
+ atm[atom_index]->residue = this;
+ atm[atom_index]->index = atom_index+1;
+ atom[i] = atm[atom_index];
+ atom_index++;
+ } else
+ atom[i] = NULL;
+ }
+
+ }
+
+
+ void Residue::GetAtomStatistics ( RAtomStat AS ) {
+ AS.Init();
+ CalAtomStatistics ( AS );
+ AS.Finish();
+ }
+
+ void Residue::CalAtomStatistics ( RAtomStat AS ) {
+ // AS must be initialized. The function only accumulates
+ // the statistics.
+ int i;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i])
+ atom[i]->CalAtomStatistics ( AS );
+ }
+
+
+ PChain Residue::GetChain() {
+ return chain;
+ }
+
+ PModel Residue::GetModel() {
+ if (chain) return (PModel)chain->model;
+ else return NULL;
+ }
+
+
+ int Residue::GetModelNum() {
+ if (chain) {
+ if (chain->model)
+ return chain->model->GetSerNum();
+ }
+ return 0;
+ }
+
+ pstr Residue::GetChainID() {
+ if (chain) return chain->chainID;
+ return pstr("");
+ }
+
+ pstr Residue::GetLabelAsymID() {
+ return label_asym_id;
+ }
+
+ pstr Residue::GetResName() {
+ return name;
+ }
+
+ pstr Residue::GetLabelCompID() {
+ return label_comp_id;
+ }
+
+ int Residue::GetAASimilarity ( const ResName resName ) {
+ return mmdb::GetAASimilarity ( pstr(name),pstr(resName) );
+ }
+
+ int Residue::GetAASimilarity ( PResidue res ) {
+ return mmdb::GetAASimilarity ( name,res->name );
+ }
+
+ realtype Residue::GetAAHydropathy() {
+ return mmdb::GetAAHydropathy ( name );
+ }
+
+ void Residue::SetResName ( const ResName resName ) {
+ strcpy ( name,resName );
+ }
+
+ int Residue::GetSeqNum() {
+ return seqNum;
+ }
+
+ int Residue::GetLabelSeqID() {
+ return label_seq_id;
+ }
+
+ int Residue::GetLabelEntityID() {
+ return label_entity_id;
+ }
+
+ pstr Residue::GetInsCode() {
+ return insCode;
+ }
+
+ bool Residue::isAminoacid () {
+ return mmdb::isAminoacid ( name );
+ }
+
+ bool Residue::isNucleotide() {
+ return mmdb::isNucleotide ( name );
+ }
+
+ int Residue::isDNARNA() {
+ return mmdb::isDNARNA ( name );
+ }
+
+ bool Residue::isSugar() {
+ return mmdb::isSugar ( name );
+ }
+
+ bool Residue::isSolvent() {
+ return mmdb::isSolvent ( name );
+ }
+
+ bool Residue::isModRes() {
+ PChain chn;
+ PModRes modRes;
+ int nModRes,i;
+ chn = GetChain();
+ if (chn) {
+ nModRes = chn->GetNofModResidues();
+ for (i=0;i<nModRes;i++) {
+ modRes = chn->GetModResidue ( i );
+ if (modRes) {
+ if ((!strcmp(modRes->resName,name)) &&
+ (modRes->seqNum==seqNum) &&
+ (!strcmp(modRes->insCode,insCode)))
+ return true;
+ }
+ }
+
+ }
+ return false;
+ }
+
+ bool Residue::isInSelection ( int selHnd ) {
+ PRoot manager = (PRoot)GetCoordHierarchy();
+ PMask mask;
+ if (manager) {
+ mask = manager->GetSelMask ( selHnd );
+ if (mask) return CheckMask ( mask );
+ }
+ return false;
+ }
+
+
+ bool Residue::isNTerminus() {
+ PPResidue Res;
+ int i,j,nRes;
+ if (chain) {
+ chain->GetResidueTable ( Res,nRes );
+ i = 0;
+ j = -1;
+ while ((i<nRes) && (j<0)) {
+ if (Res[i]) j = i;
+ i++;
+ }
+ if (j>=0)
+ return (Res[j]->index==index);
+ }
+ return false;
+ }
+
+ bool Residue::isCTerminus() {
+ PPResidue Res;
+ int i,j,nRes;
+ if (chain) {
+ chain->GetResidueTable ( Res,nRes );
+ i = nRes-1;
+ j = -1;
+ while ((i>=0) && (j<0)) {
+ if (Res[i]) j = i;
+ i--;
+ }
+ if (j>=0)
+ return (Res[j]->index==index);
+ }
+ return false;
+ }
+
+
+ pstr Residue::GetResidueID ( pstr ResidueID ) {
+ ResidueID[0] = char(0);
+ if (chain) {
+ if (chain->model)
+ sprintf ( ResidueID,"/%i/",chain->model->GetSerNum() );
+ else strcpy ( ResidueID,"/-/" );
+ strcat ( ResidueID,chain->chainID );
+ } else
+ strcpy ( ResidueID,"/-/-" );
+ ParamStr ( ResidueID,pstr("/"),seqNum );
+ strcat ( ResidueID,"(" );
+ strcat ( ResidueID,name );
+ strcat ( ResidueID,")" );
+ if (insCode[0]) {
+ strcat ( ResidueID,"." );
+ strcat ( ResidueID,insCode );
+ }
+ return ResidueID;
+ }
+
+
+ int Residue::CheckID ( int * snum,
+ const InsCode inscode,
+ const ResName resname ) {
+ if (snum) {
+ if (*snum!=seqNum) return 0;
+ }
+ if (inscode) {
+ if ((inscode[0]!='*') && (strcmp(inscode,insCode))) return 0;
+ }
+ if (!resname) return 1;
+ if ((resname[0]!='*') && (strcmp(resname,name))) return 0;
+ return 1;
+ }
+
+ int Residue::CheckIDS ( cpstr CID ) {
+ ChainID chn;
+ InsCode inscode;
+ ResName resname;
+ AtomName atm;
+ Element elm;
+ AltLoc aloc;
+ pstr p1,p2;
+ int mdl,sn,rc;
+
+ rc = ParseAtomPath ( CID,mdl,chn,sn,inscode,resname,
+ atm,elm,aloc,NULL );
+ // rc = ParseResID ( CID,sn,inscode,resname );
+
+ if (rc>=0) {
+ p1 = NULL;
+ p2 = NULL;
+ if (inscode[0]!='*') p1 = inscode;
+ if (resname[0]!='*') p2 = resname;
+ if (!rc) return CheckID ( &sn ,p1,p2 );
+ else return CheckID ( NULL,p1,p2 );
+ }
+ return 0;
+
+ }
+
+
+ // -------------------- Extracting atoms -------------------------
+
+ int Residue::GetNumberOfAtoms() {
+ return nAtoms;
+ }
+
+ int Residue::GetNumberOfAtoms ( bool countTers ) {
+ int i,na;
+ na = 0;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (countTers || (!atom[i]->Ter)) na++;
+ }
+ return na;
+ }
+
+ PAtom Residue::GetAtom ( const AtomName aname,
+ const Element elname,
+ const AltLoc aloc ) {
+ int i;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (atom[i]->CheckID(aname,elname,aloc))
+ return atom[i];
+ }
+ return NULL;
+ }
+
+ PAtom Residue::GetAtom ( int atomNo ) {
+ if ((0<=atomNo) && (atomNo<nAtoms))
+ return atom[atomNo];
+ return NULL;
+ }
+
+ void Residue::GetAtomTable ( PPAtom & atomTable, int & NumberOfAtoms ) {
+ atomTable = atom;
+ NumberOfAtoms = nAtoms;
+ }
+
+ void Residue::GetAtomTable1 ( PPAtom & atomTable, int & NumberOfAtoms ) {
+ int i,j;
+ if (atomTable) delete[] atomTable;
+ if (nAtoms>0) {
+ atomTable = new PAtom[nAtoms];
+ j = 0;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (!atom[i]->Ter)
+ atomTable[j++] = atom[i];
+ }
+ NumberOfAtoms = j;
+ } else {
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ }
+ }
+
+ void Residue::TrimAtomTable() {
+ int i,j;
+ j = 0;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (j<i) {
+ atom[j] = atom[i];
+ atom[i] = NULL;
+ }
+ j++;
+ }
+ nAtoms = j;
+ }
+
+
+ // --------------------- Deleting atoms --------------------------
+
+ int Residue::DeleteAtom ( const AtomName aname,
+ const Element elname,
+ const AltLoc aloc ) {
+ // apply Root::FinishStructEdit() after all editings are done!
+ // returns number of deleted atoms
+ int i,k,nA,kndex;
+ PPAtom A;
+
+ A = NULL;
+ nA = 0;
+ if (chain) {
+ if (chain->model) {
+ A = chain->model->GetAllAtoms();
+ nA = chain->model->GetNumberOfAllAtoms();
+ }
+ }
+
+ k = 0;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (atom[i]->CheckID(aname,elname,aloc)) {
+ k++;
+ kndex = atom[i]->index;
+ if ((0<kndex) && (kndex<=nA)) A[kndex-1] = NULL;
+ Exclude = false;
+ delete atom[i];
+ atom[i] = NULL;
+ Exclude = true;
+ }
+ }
+
+ return k;
+
+ }
+
+ int Residue::DeleteAtom ( int atomNo ) {
+ // apply Root::FinishStructEdit() after all editings are done!
+ // returns number of deleted atoms
+ int kndex,nA;
+ PPAtom A;
+
+ if ((0<=atomNo) && (atomNo<nAtoms)) {
+ if (atom[atomNo]) {
+ A = NULL;
+ nA = 0;
+ if (chain) {
+ if (chain->model) {
+ A = chain->model->GetAllAtoms();
+ nA = chain->model->GetNumberOfAllAtoms();
+ }
+ }
+ kndex = atom[atomNo]->index;
+ if ((0<kndex) && (kndex<=nA)) A[kndex-1] = NULL;
+ Exclude = false;
+ delete atom[atomNo];
+ atom[atomNo] = NULL;
+ Exclude = true;
+ return 1;
+ }
+ }
+
+ return 0;
+
+ }
+
+
+ int Residue::DeleteAllAtoms() {
+ int i,k,nA,kndex;
+ PPAtom A;
+
+ Exclude = false;
+
+ A = NULL;
+ nA = 0;
+ if (chain) {
+ if (chain->model) {
+ A = chain->model->GetAllAtoms();
+ nA = chain->model->GetNumberOfAllAtoms();
+ }
+ }
+
+ k = 0;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ k++;
+ kndex = atom[i]->index;
+ if ((0<kndex) && (kndex<=nA)) A[kndex-1] = NULL;
+ delete atom[i];
+ atom[i] = NULL;
+ }
+ nAtoms = 0;
+
+ Exclude = true;
+
+ return k;
+
+ }
+
+
+ int Residue::DeleteAltLocs() {
+ // This function leaves only alternative location with maximal
+ // occupancy, if those are equal or unspecified, the one with
+ // "least" alternative location indicator.
+ // The function returns the number of deleted atoms. The atom
+ // table remains untrimmed, so that nAtoms are wrong until that
+ // is done. Tables are trimmed by FinishStructEdit() or
+ // explicitely.
+ PPAtom A;
+ AtomName aname;
+ AltLoc aLoc,aL;
+ realtype occupancy,occ;
+ int nA,i,i1,i2,j,k,n,kndex;
+
+ A = NULL;
+ nA = 0;
+ if (chain) {
+ if (chain->model) {
+ A = chain->model->GetAllAtoms();
+ nA = chain->model->GetNumberOfAllAtoms();
+ }
+ }
+ Exclude = false;
+
+ n = 0;
+ for (i=0;i<nAtoms;i++)
+
+ if (atom[i]) {
+ if (!atom[i]->Ter) {
+ occupancy = atom[i]->GetOccupancy();
+ strcpy ( aname,atom[i]->name );
+ strcpy ( aLoc ,atom[i]->altLoc );
+ i1 = -1;
+ i2 = i;
+ k = 0;
+ for (j=i+1;j<nAtoms;j++)
+ if (atom[j]) {
+ if ((!atom[j]->Ter) && (!strcmp(atom[j]->name,aname))) {
+ k++;
+ occ = atom[j]->GetOccupancy();
+ if (occ>occupancy) {
+ occupancy = occ;
+ i1 = j;
+ }
+ if (aLoc[0]) {
+ strcpy ( aL,atom[j]->altLoc );
+ if (!aL[0]) {
+ aLoc[0] = char(0);
+ i2 = j;
+ } else if (strcmp(aL,aLoc)<0) {
+ strcpy ( aLoc,aL );
+ i2 = j;
+ }
+ }
+ }
+ }
+ if (k>0) {
+ if (i1<0) {
+ if (atom[i]->WhatIsSet & ASET_Occupancy) i1 = i;
+ else i1 = i2;
+ }
+ for (j=i;j<nAtoms;j++)
+ if ((j!=i1) && atom[j]) {
+ if ((!atom[j]->Ter) && (!strcmp(atom[j]->name,aname))) {
+ n++;
+ kndex = atom[j]->index;
+ if ((0<kndex) && (kndex<=nA)) A[kndex-1] = NULL;
+ delete atom[j];
+ atom[j] = NULL;
+ }
+ }
+ }
+ }
+ }
+
+ Exclude = true;
+
+ return n;
+
+ }
+
+ void Residue::ApplyTransform ( mat44 & TMatrix ) {
+ // transforms all coordinates by multiplying with matrix TMatrix
+ int i;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (!atom[i]->Ter)
+ atom[i]->Transform ( TMatrix );
+ }
+ }
+
+
+
+ // -----------------------------------------------------------------
+
+
+ void Residue::MaskAtoms ( PMask Mask ) {
+ int i;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) atom[i]->SetMask ( Mask );
+ }
+
+ void Residue::UnmaskAtoms ( PMask Mask ) {
+ int i;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) atom[i]->RemoveMask ( Mask );
+ }
+
+
+
+ // ------- user-defined data handlers
+
+ int Residue::PutUDData ( int UDDhandle, int iudd ) {
+ if (UDDhandle & UDRF_RESIDUE)
+ return UDData::putUDData ( UDDhandle,iudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Residue::PutUDData ( int UDDhandle, realtype rudd ) {
+ if (UDDhandle & UDRF_RESIDUE)
+ return UDData::putUDData ( UDDhandle,rudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Residue::PutUDData ( int UDDhandle, cpstr sudd ) {
+ if (UDDhandle & UDRF_RESIDUE)
+ return UDData::putUDData ( UDDhandle,sudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Residue::GetUDData ( int UDDhandle, int & iudd ) {
+ if (UDDhandle & UDRF_RESIDUE)
+ return UDData::getUDData ( UDDhandle,iudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Residue::GetUDData ( int UDDhandle, realtype & rudd ) {
+ if (UDDhandle & UDRF_RESIDUE)
+ return UDData::getUDData ( UDDhandle,rudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Residue::GetUDData ( int UDDhandle, pstr sudd, int maxLen ) {
+ if (UDDhandle & UDRF_RESIDUE)
+ return UDData::getUDData ( UDDhandle,sudd,maxLen );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Residue::GetUDData ( int UDDhandle, pstr & sudd ) {
+ if (UDDhandle & UDRF_RESIDUE)
+ return UDData::getUDData ( UDDhandle,sudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+
+ #define NOmaxdist2 12.25
+
+ bool Residue::isMainchainHBond ( PResidue res ) {
+ // Test if there is main chain Hbond between PCRes1 (donor) and
+ // PCRes2 (acceptor).
+ // As defined Kabsch & Sanders
+ // This probably needs the option of supporting alternative criteria
+ PAtom NAtom,OAtom,Atom;
+ realtype abx,aby,abz;
+ realtype acx,acy,acz;
+ realtype bcx,bcy,bcz;
+ realtype absq,acsq,bcsq;
+
+ NAtom = GetAtom ( "N" );
+ OAtom = res->GetAtom ( "O" );
+ Atom = res->GetAtom ( "C" );
+
+ if (NAtom && OAtom && Atom) {
+
+ abx = OAtom->x - NAtom->x;
+ aby = OAtom->y - NAtom->y;
+ abz = OAtom->z - NAtom->z;
+ absq = abx*abx + aby*aby + abz*abz;
+
+
+ if (absq<=NOmaxdist2) {
+
+ acx = NAtom->x - Atom->x;
+ acy = NAtom->y - Atom->y;
+ acz = NAtom->z - Atom->z;
+
+ bcx = Atom->x - OAtom->x;
+ bcy = Atom->y - OAtom->y;
+ bcz = Atom->z - OAtom->z;
+
+ acsq = acx*acx + acy*acy + acz*acz;
+ bcsq = bcx*bcx + bcy*bcy + bcz*bcz;
+
+ return (acos((bcsq+absq-acsq)/(2.0*sqrt(bcsq*absq)))>=Pi/2.0);
+
+ }
+
+ }
+
+ return false;
+
+ }
+
+
+ void Residue::write ( io::RFile f ) {
+ int i;
+ byte Version=2;
+
+ UDData::write ( f );
+
+ f.WriteByte ( &Version );
+ f.WriteInt ( &seqNum );
+ f.WriteInt ( &label_seq_id );
+ f.WriteInt ( &label_entity_id );
+ f.WriteInt ( &index );
+ f.WriteInt ( &nAtoms );
+ f.WriteByte ( &SSE );
+ f.WriteTerLine ( name ,false );
+ f.WriteTerLine ( label_comp_id,false );
+ f.WriteTerLine ( label_asym_id,false );
+ f.WriteTerLine ( insCode ,false );
+ for (i=0;i<nAtoms;i++)
+ f.WriteInt ( &(atom[i]->index) );
+
+ }
+
+ void Residue::read ( io::RFile f ) {
+ // IMPORTANT: array Atom in Root class should be
+ // read prior calling this function!
+ PPAtom A;
+ int i,k;
+ byte Version;
+
+ FreeMemory ();
+
+ UDData::read ( f );
+
+ f.ReadByte ( &Version );
+ f.ReadInt ( &seqNum );
+ if (Version>1) {
+ f.ReadInt ( &label_seq_id );
+ f.ReadInt ( &label_entity_id );
+ }
+ f.ReadInt ( &index );
+ f.ReadInt ( &nAtoms );
+ f.ReadByte ( &SSE );
+ f.ReadTerLine ( name,false );
+ if (Version>1) {
+ f.ReadTerLine ( label_comp_id,false );
+ f.ReadTerLine ( label_asym_id,false );
+ }
+ f.ReadTerLine ( insCode,false );
+ AtmLen = nAtoms;
+ A = NULL;
+ if (chain) {
+ if (chain->model)
+ A = chain->model->GetAllAtoms();
+ }
+ if ((nAtoms>0) && (A)) {
+ atom = new PAtom[nAtoms];
+ for (i=0;i<nAtoms;i++) {
+ f.ReadInt ( &k );
+ atom[i] = A[k-1];
+ atom[i]->SetResidue ( this );
+ atom[i]->_setBonds ( A );
+ }
+ } else {
+ for (i=0;i<nAtoms;i++)
+ f.ReadInt ( &k );
+ nAtoms = 0;
+ AtmLen = 0;
+ }
+ }
+
+
+ MakeFactoryFunctions(Residue)
+
+} // namespace mmdb
diff --git a/mmdb2/mmdb_atom.h b/mmdb2/mmdb_atom.h
new file mode 100644
index 0000000..63d5cb3
--- /dev/null
+++ b/mmdb2/mmdb_atom.h
@@ -0,0 +1,732 @@
+// $Id: mmdb_atom.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_Atom <interface>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::Atom ( atom class )
+// ~~~~~~~~~ mmdb::Residue ( residue class )
+// **** Functions: mmdb::BondAngle
+// ~~~~~~~~~~
+//
+// Copyright (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_Atom__
+#define __MMDB_Atom__
+
+#include "mmdb_io_stream.h"
+#include "mmdb_uddata.h"
+#include "mmdb_utils.h"
+#include "mmdb_defs.h"
+
+
+namespace mmdb {
+
+ // ====================== Atom ==========================
+
+ // constants for the WhatIsSet field
+ enum ASET_FLAG {
+ ASET_Coordinates = 0x00000001,
+ ASET_Occupancy = 0x00000002,
+ ASET_tempFactor = 0x00000004,
+ ASET_CoordSigma = 0x00000010,
+ ASET_OccSigma = 0x00000020,
+ ASET_tFacSigma = 0x00000040,
+ ASET_Anis_tFac = 0x00000100,
+ ASET_Anis_tFSigma = 0x00001000,
+ ASET_Charge = 0x00000080,
+ ASET_All = 0x000FFFFF
+ };
+
+ const int ATOM_NoSeqNum = MinInt4;
+
+ extern bool ignoreSegID;
+ extern bool ignoreElement;
+ extern bool ignoreCharge;
+ extern bool ignoreNonCoorPDBErrors;
+ extern bool ignoreUnmatch;
+
+
+ DefineStructure(AtomStat);
+
+ struct AtomStat {
+
+ public :
+ int nAtoms; // number of atoms in statistics
+
+ realtype xmin,ymin,zmin; // minimums of coordinates
+ realtype xmax,ymax,zmax; // maximums of coordinates
+ realtype xm ,ym ,zm; // mediums of coordinates
+ realtype xm2 ,ym2 ,zm2; // square mediums of coordinates
+
+ realtype occ_min,occ_max; // minimum/maximum occupancy
+ realtype occ_m ,occ_m2; // medium and square medium occupancy
+
+ realtype tFmin,tFmax; // minimum/maximum temperature factor
+ realtype tFm ,tFm2; // medium and sq. med. temp. factor
+
+ realtype u11_min,u11_max; // minimums and
+ realtype u22_min,u22_max; // maximums of
+ realtype u33_min,u33_max; // anisotropic
+ realtype u12_min,u12_max; // temperature
+ realtype u13_min,u13_max; // factors
+ realtype u23_min,u23_max;
+
+ realtype u11_m,u11_m2; // mediums and
+ realtype u22_m,u22_m2; // square mediums of
+ realtype u33_m,u33_m2; // anisotropic
+ realtype u12_m,u12_m2; // temperature
+ realtype u13_m,u13_m2; // factors
+ realtype u23_m,u23_m2;
+
+ word WhatIsSet; // mask field
+
+ void Init ();
+ void Finish();
+
+ realtype GetMaxSize();
+
+ private :
+ bool finished;
+
+ };
+
+
+ DefineStructure(AtomBondI);
+
+ struct AtomBondI {
+ int index; //!< bonded atom index
+ byte order; //!< bond order
+ };
+
+
+ DefineStructure(AtomBond);
+
+ struct AtomBond {
+ PAtom atom; //!< bonded atom pointer
+ byte order; //!< bond order
+ };
+
+
+ DefineFactoryFunctions(Atom);
+
+ class Atom : public UDData {
+
+ friend class Residue;
+ friend class Model;
+ friend class Root;
+ friend class CoorManager;
+ friend class SelManager;
+
+ public :
+ int serNum; //!< serial number
+ AtomName name; //!< atom name (ALIGNED)
+ AtomName label_atom_id; //!< assigned atom name (not aligned)
+ AltLoc altLoc; //!< alternative location indicator ("" for none)
+ SegID segID; //!< segment identifier
+ Element element; //!< element symbol (ALIGNED TO RIGHT)
+ EnergyType energyType; //!< energy type (without spaces)
+ PResidue residue; //!< reference to residue
+ realtype x,y,z; //!< orthogonal coordinates in angstroms
+ realtype occupancy; //!< occupancy
+ realtype tempFactor; //!< temperature factor
+ realtype charge; //!< charge on the atom
+ realtype sigX,sigY,sigZ; //!< standard deviations of the coords
+ realtype sigOcc; //!< standard deviation of occupancy
+ realtype sigTemp; //!< standard deviation of temp. factor
+ realtype u11,u22,u33; //!< anisotropic temperature
+ realtype u12,u13,u23; /// factors
+ realtype su11,su22,su33; //!< standard deviations of
+ realtype su12,su13,su23; /// anisotropic temperature factors
+ bool Het; //!< indicator of het atom
+ bool Ter; //!< chain terminator
+
+ word WhatIsSet; //!< mask field
+ /// 0x0001 atomic coordinates
+ /// 0x0002 occupancy
+ /// 0x0004 temperature factor
+ /// 0x0010 coordinate standard deviations
+ /// 0x0020 deviation of occupancy
+ /// 0x0040 deviation of temperature factor
+ /// 0x0100 anisotropic temperature factors
+ /// 0x1000 anis. temp. fact-s st-d deviations
+
+ Atom ();
+ Atom ( PResidue res );
+ Atom ( io::RPStream Object );
+ ~Atom();
+
+ void SetResidue ( PResidue res );
+ void PDBASCIIDump ( io::RFile f );
+ void MakeCIF ( mmcif::PData CIF );
+
+ // AddBond(...) adds a bond to the atom, that is a pointer
+ // to the bonded atom and the bond order. nAdd_bonds allows
+ // one to minimize the memory reallocations, if number of
+ // bonds is known apriori: Atom adds space for nAdd_bonds
+ // if currently allocated space is exchausted.
+ // Return: <=0 - error: bond_atom is already "bonded"
+ // >0 - Ok, returns current number of bonds
+ int AddBond ( PAtom bond_atom, int bond_order,
+ int nAdd_bonds=1 );
+ int GetNBonds();
+
+ // This GetBonds(..) returns pointer to the Atom's
+ // internal Bond structure, IT MUST NOT BE DISPOSED.
+ void GetBonds ( RPAtomBond atomBond, int & nAtomBonds );
+ void FreeBonds();
+
+ // This GetBonds(..) disposes AtomBondI, if it was not set
+ // to NULL, allocates AtomBondI[nAtomBonds] and returns its
+ // pointer. AtomBondI MUST BE DISPOSED BY APPLICATION.
+ void GetBonds ( RPAtomBondI atomBondI, int & nAtomBonds );
+
+ // This GetBonds(..) does not dispose or allocate AtomBondI.
+ // It is assumed that length of AtomBondI is sufficient to
+ // accomodate all bonded atoms.
+ void GetBonds ( PAtomBondI atomBondI, int & nAtomBonds,
+ int maxlength );
+
+
+ // ConvertPDBxxxxxx() gets data from the PDB ASCII xxxxxx
+ // record (xxxxxx stands for ATOM, SIGATM, ANISOU, SIGUIJ,
+ // TER or HETATM).
+ // These functions DO NOT check the xxxxxx keyword and
+ // do not decode the chain and residue parameters! These
+ // must be treated by the calling process, see
+ // CMMDBFile::ReadPDBAtom().
+ // The atom reference is updated in the corresponding
+ // residue.
+ ERROR_CODE ConvertPDBATOM ( int ix, cpstr S );
+ ERROR_CODE ConvertPDBSIGATM ( int ix, cpstr S );
+ ERROR_CODE ConvertPDBANISOU ( int ix, cpstr S );
+ ERROR_CODE ConvertPDBSIGUIJ ( int ix, cpstr S );
+ ERROR_CODE ConvertPDBTER ( int ix, cpstr S );
+ ERROR_CODE ConvertPDBHETATM ( int ix, cpstr S );
+
+ ERROR_CODE GetCIF ( int ix, mmcif::PLoop Loop,
+ mmcif::PLoop LoopAnis );
+
+ bool RestoreElementName();
+ bool MakePDBAtomName();
+
+ void SetAtomName ( int ix, // index
+ int sN, // serial number
+ const AtomName aName, // atom name
+ const AltLoc aLoc, // alternative location
+ const SegID sID, // segment ID
+ const Element eName ); // element name
+
+ // This only renames the atom
+ void SetAtomName ( const AtomName atomName );
+ void SetElementName ( const Element elName );
+ void SetCharge ( cpstr chrg );
+ void SetCharge ( realtype chrg );
+
+ void SetAtomIndex ( int ix ); // don't use in your applications!
+
+ void MakeTer(); // converts atom into 'ter'
+
+ void SetCoordinates ( realtype xx, realtype yy, realtype zz,
+ realtype occ, realtype tFac );
+
+ int GetModelNum ();
+ pstr GetChainID ();
+ pstr GetLabelAsymID ();
+ pstr GetResName ();
+ pstr GetLabelCompID ();
+ int GetAASimilarity ( const ResName resName );
+ int GetAASimilarity ( PAtom A );
+ realtype GetAAHydropathy();
+ realtype GetOccupancy ();
+ int GetSeqNum ();
+ int GetLabelSeqID ();
+ int GetLabelEntityID ();
+ pstr GetInsCode ();
+ int GetSSEType (); // works only after SSE calculations
+ pstr GetAtomName () { return name; }
+ pstr GetElementName () { return element; }
+ pstr GetAtomCharge ( pstr chrg );
+
+ // GetChainCalphas(...) is a specialized function for quick
+ // access to C-alphas of chain which includes given atom.
+ // This function works faster than an equivalent implementation
+ // through MMDB's selection procedures.
+ // Parameters:
+ // Calphas - array to accept pointers on C-alpha atoms
+ // If Calphas!=NULL, then the function will
+ // delete and re-allocate it. When the array
+ // is no longer needed, the application MUST
+ // delete it: delete[] Calphas; Deleting
+ // Calphas does not delete atoms from MMDB.
+ // nCalphas - integer to accept number of C-alpha atoms
+ // and the length of Calphas array.
+ // altLoc - alternative location indicator. By default
+ // (""), maximum-occupancy locations are taken.
+ void GetChainCalphas ( PPAtom & Calphas, int & nCalphas,
+ cpstr altLoc = "" );
+
+ bool isTer () { return Ter; }
+ bool isMetal ();
+ bool isSolvent (); // works only for atom in a residue!
+ bool isInSelection ( int selHnd );
+ bool isNTerminus ();
+ bool isCTerminus ();
+
+ void CalAtomStatistics ( RAtomStat AS );
+
+ realtype GetDist2 ( PAtom a );
+ realtype GetDist2 ( PAtom a, mat44 & tm ); // tm applies to A
+ realtype GetDist2 ( PAtom a, mat33 & r, vect3 & t );// tm applies to A
+ realtype GetDist2 ( realtype ax, realtype ay, realtype az );
+
+ // GetCosine(a1,a2) calculates cosine of angle a1-this-a2,
+ // i.e. that between vectors [a1,this] and [this,a2].
+ realtype GetCosine ( PAtom a1, PAtom a2 );
+
+ PResidue GetResidue ();
+ PChain GetChain ();
+ PModel GetModel ();
+ int GetResidueNo();
+ void * GetCoordHierarchy(); // PRoot
+
+ // GetAtomID(..) generates atom ID in the form
+ // /m/c/r(rn).i/n[e]:a
+ // where m - model number
+ // c - chain ID
+ // r - residue sequence number
+ // rn - residue name
+ // i - insertion code
+ // n - atom name
+ // e - chemical element specification
+ // a - alternate location indicator
+ // If any of the fields is undefined, it is replaced by
+ // hyphen '-'.
+ // No checks on the sufficiency of string buffer AtomID
+ // is made.
+ // GetAtomID returns AtomID.
+ pstr GetAtomID ( pstr AtomID );
+
+ pstr GetAtomIDfmt ( pstr AtomID );
+
+ // ------- checking atom ID
+ // CheckID(..) returns 1 if atom is identified, and 0 otherwise.
+ // Parameters:
+ // aname - atom name. It may or may not be aligned (as in
+ // a PDB file), only first word of the name will
+ // be taken ("CA", " CA" and " CA B" are all
+ // considered as "CA"). aname may be set to NULL
+ // or '*', then this parameter is ignored.
+ // elname - element code. It will work only if element code
+ // is supplied (which might not be the case if
+ // the atom was created in a tricky way). elname
+ // should be used to distinguih between, e.g.
+ // "Ca" and "C_alpha"). elname may be set to NULL,
+ // or '*', then this parameter is ignored.
+ // aloc - the alternate location code. aloc may be set to
+ // NULL or '*', then this parameter is ignored.
+ // IMPORTANT: comparison is case-sensitive.
+ // The atom is considered as identified, if all non-NULL
+ // parameters do match. If all parameters are set NULL, any atom
+ // is identified.
+ // DEFAULT values correspond to 'any element' and
+ // 'no alternate location code'
+ // NOTE that " " is not an empty item.
+ int CheckID ( const AtomName aname, const Element elname=NULL,
+ const AltLoc aloc=pstr("") );
+
+ // CheckIDS(..) works exactly like CheckID(..), but it takes
+ // the only parameter, the atom ID, which is of the form:
+ // {name} {[element]} {:altcode}
+ // Here {} means that the item may be omitted. Any item may be
+ // represented by a wildcard '*', which means 'any value'. Just
+ // absence of an item means 'empty', which makes sense only for
+ // alternate location code. Missing name or element therefore
+ // mean 'any name' or 'any element', correspondingly (same as a
+ // wildcard). There should be no spaces in ID except for leading
+ // spaces; any following space will terminate parsing.
+ // The followings are perfectly valid IDs:
+ // CA[C]:A (carbon C_alpha in location A)
+ // CA[*]:A (either C_alpha or Ca in location A)
+ // CA:A (same as above)
+ // CA (either C_alpha or Ca with no location indicator)
+ // CA[] (same as above)
+ // CA[C]: (C_alpha with no location indicator)
+ // [C] (any carbon with no location indicator)
+ // [C]:* (any carbon with any location indicator)
+ // *[C]:* (same as above)
+ // :A (any atom in location A)
+ // *[*]:A (same as above)
+ // *[*]:* (any atom)
+ // * (any atom with no alternate location indicator)
+ int CheckIDS ( cpstr ID );
+
+
+ // ------- transform coordinates: x := m*x + v
+ void Transform ( mat33 & tm, vect3 & v );
+ void Transform ( mat44 & tm );
+ void TransformCopy ( mat44 & tm,
+ realtype & xx, realtype & yy, realtype & zz );
+ void TransformSet ( mat44 & tm,
+ realtype xx, realtype yy, realtype zz );
+
+
+ // ------- user-defined data handlers
+ int PutUDData ( int UDDhandle, int iudd );
+ int PutUDData ( int UDDhandle, realtype rudd );
+ int PutUDData ( int UDDhandle, cpstr sudd );
+
+ int GetUDData ( int UDDhandle, int & iudd );
+ int GetUDData ( int UDDhandle, realtype & rudd );
+ int GetUDData ( int UDDhandle, pstr sudd, int maxLen );
+ int GetUDData ( int UDDhandle, pstr & sudd );
+
+
+ int GetIndex() { return index; }
+
+ virtual void Copy ( PAtom atom ); // without references in
+ // residues
+
+ void SetShortBinary(); // leaves only coordinates in binary files
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+ int index; // index in the file
+ int nBonds; // number of bonds in the lowest byte (!)
+ PAtomBond Bond; // atom bonds
+
+ void InitAtom ();
+ void FreeMemory ();
+ void StandardPDBOut ( cpstr Record, pstr S );
+ void GetData ( cpstr S );
+ ERROR_CODE CheckData ( cpstr S );
+ void GetStat ( realtype v,
+ realtype & v_min, realtype & v_max,
+ realtype & v_m, realtype & v_m2 );
+ void _setBonds ( PPAtom A ); // used only in Residue
+
+ };
+
+
+ // ====================== Residue ==========================
+
+ enum ALTLOC_FLAG {
+ ALF_NoAltCodes = 0x00000000,
+ ALF_EmptyAltLoc = 0x00000001,
+ ALF_NoEmptyAltLoc = 0x00000002,
+ ALF_Mess = 0x00000004,
+ ALF_Occupancy = 0x00000008
+ };
+
+ enum SSE_FLAG {
+ SSE_None = 0,
+ SSE_Strand = 1,
+ SSE_Bulge = 2,
+ SSE_3Turn = 3,
+ SSE_4Turn = 4,
+ SSE_5Turn = 5,
+ SSE_Helix = 6
+ };
+
+ DefineFactoryFunctions(Residue);
+
+ class Residue : public UDData {
+
+ friend class Atom;
+ friend class Chain;
+ friend class Root;
+
+ public :
+
+ ResName name; //!< residue name - all spaces cut
+ ResName label_comp_id; //!< assigned residue name
+ ChainID label_asym_id; //!< assigned chain Id
+ InsCode insCode; //!< residue insertion code
+ PChain chain; //!< reference to chain
+ PPAtom atom; //!< array of atoms
+ int seqNum; //!< residue sequence number
+ int label_seq_id; //!< assigned residue sequence number
+ int label_entity_id; //!< assigned entity id
+ int index; //!< index in the chain
+ int nAtoms; //!< number of atoms in the residue
+ byte SSE; //!< SSE type
+
+ Residue ();
+ Residue ( PChain Chain_Owner );
+ Residue ( PChain Chain_Owner, const ResName resName,
+ int sqNum, const InsCode ins );
+ Residue ( io::RPStream Object );
+ ~Residue();
+
+ void SetChain ( PChain Chain_Owner );
+ void SetResID ( const ResName resName, int sqNum,
+ const InsCode ins );
+ void SetChainID ( const ChainID chID );
+
+ void PDBASCIIAtomDump ( io::RFile f );
+ void MakeAtomCIF ( mmcif::PData CIF );
+
+ PChain GetChain();
+ PModel GetModel();
+
+ int GetModelNum ();
+ pstr GetChainID ();
+ pstr GetLabelAsymID();
+ pstr GetResName ();
+ pstr GetLabelCompID();
+ int GetAASimilarity ( const ResName resName );
+ int GetAASimilarity ( PResidue res );
+ realtype GetAAHydropathy();
+ void SetResName ( const ResName resName );
+ int GetSeqNum ();
+ int GetLabelSeqID ();
+ int GetLabelEntityID();
+ pstr GetInsCode ();
+ int GetResidueNo ();
+ int GetCenter ( realtype & x, realtype & y, realtype & z );
+ void * GetCoordHierarchy(); // PCMMDBFile
+
+ void GetAtomStatistics ( RAtomStat AS );
+ void CalAtomStatistics ( RAtomStat AS );
+
+ pstr GetResidueID ( pstr ResidueID );
+
+ // GetAltLocations(..) returns the number of different
+ // alternative locations in nAltLocs, the locations themselves
+ // - in aLoc and the corresponding occupancies - in occupancy.
+ // aLoc and occupancy are allocated dynamically; it is
+ // responsibility of the application to deallocate aLoc prior
+ // calling GetAltLocations(..) if they were previously allocated.
+ // Either, the application is responsible for deallocating aLoc and
+ // occupancy after use.
+ // occupancy[i] may return -1.0 if occupancies were not read
+ // from coordinate file.
+ // alflag returns ALF_NoAltCodes if no alt codes was found,
+ // otherwise the output is decoded according to bits:
+ // ALF_EmptyAltLoc alternative locations include the
+ // "no alt loc indicator" ("" for
+ // Atom::altLoc).
+ // This means that each atom that has alt locs
+ // different of "", also includes one marked as
+ // "".
+ // ALF_NoEmptyAltLoc alternative locations do not include the
+ // "no alt loc indicator" ("" for
+ // Atom::altLoc).
+ // This means that each atom has either ""
+ // alt loc or at least two alt locs different
+ // of "".
+ // ALF_Mess incorrect residue: it mixes both
+ // ""-including and not-""-including schemes
+ // ALF_Occupancy warning that sum of occupancies for alt
+ // located atoms differ from 1.0 by more
+ // than 0.01.
+ void GetAltLocations ( int & nAltLocs, PAltLoc & aLoc,
+ rvector & occupancy, int & alflag );
+ int GetNofAltLocations();
+
+ bool isAminoacid ();
+ bool isNucleotide ();
+ int isDNARNA (); // 0(neither),1(DNA),2(RNA)
+ bool isSugar ();
+ bool isSolvent ();
+ bool isModRes ();
+ bool isInSelection ( int selHnd );
+ bool isNTerminus ();
+ bool isCTerminus ();
+
+ // ------- checking residue ID
+ // CheckID(..) returns 1 if residue is identified, and 0 otherwise.
+ // Parameters:
+ // sname - pointer to sequence number; if NULL then ignored.
+ // inscode - insertion code; if NULL or '*' then ignored.
+ // resname - residue name; if NULL or '*' then ignored.
+ // IMPORTANT: comparison is case-sensitive.
+ // The residue is considered as identified, if all non-NULL
+ // parameters do match. If all parameters are set NULL, any
+ // residue is identified.
+ // DEFAULT values correspond to 'any residue name' and
+ // 'no insertion code'
+ // NOTE that " " is not an empty item.
+ int CheckID ( int * snum, const InsCode inscode=pstr(""),
+ const ResName resname=NULL );
+
+ // CheckIDS(..) works exactly like CheckID(..), but it takes
+ // the only parameter, the residue ID, which is of the form:
+ // {seqnum} {(name)} {.inscode}
+ // Here {} means that the item may be omitted. Any item may be
+ // represented by a wildcard '*', which means 'any value'. Just
+ // absence of a value means 'empty', which is meaningful only for
+ // the insertion code. Missing sequence number or residue name
+ // therefore mean 'any sequence number' or 'any residue name',
+ // correspondingly (same as a wildcard). There should be no
+ // spaces in ID except for leading spaces; any following space will
+ // terminate parsing. The followings are perfectly valid IDs:
+ // 27(ALA).A (residue 27A ALA)
+ // 27().A (residue 27A)
+ // 27(*).A (same as above)
+ // 27.A (same as above)
+ // 27 (residue 27)
+ // 27(). (same as above)
+ // (ALA) (any ALA without insertion code)
+ // (ALA). (same as above)
+ // (ALA).* (any ALA)
+ // *(ALA).* (any ALA)
+ // .A (any residue with insertion code A)
+ // *(*).A (same as above)
+ // *(*).* (any residue)
+ // * (any residue with no insertion code)
+ int CheckIDS ( cpstr ID );
+
+
+ // -------------------- Extracting atoms ----------------------
+
+ int GetNumberOfAtoms ();
+ int GetNumberOfAtoms ( bool countTers );
+
+ PAtom GetAtom ( const AtomName aname, const Element elname=NULL,
+ const AltLoc aloc=cpstr("") );
+ PAtom GetAtom ( int atomNo );
+
+ void GetAtomTable ( PPAtom & atomTable, int & NumberOfAtoms );
+
+ // GetAtomTable1(..) returns atom table without TER atoms and
+ // without NULL atom pointers. NumberOfAtoms returns the actual
+ // number of atom pointers in atomTable.
+ // atomTable is allocated withing the function. If it was
+ // not set to NULL before calling the function, the latter will
+ // attempt to deallocate it first.
+ // The application is responsible for deleting atomTable,
+ // however it must not touch atom pointers, i.e. use simply
+ // "delete[] atomTable;". Never pass atomTable from GetAtomTable()
+ // into this function, unless you set it to NULL before doing that.
+ void GetAtomTable1 ( PPAtom & atomTable, int & NumberOfAtoms );
+
+
+ // --------------------- Deleting atoms -----------------------
+
+ int DeleteAtom ( const AtomName aname, const Element elname=NULL,
+ const AltLoc aloc=cpstr("") );
+ int DeleteAtom ( int atomNo );
+ int DeleteAllAtoms();
+
+ // DeleteAltLocs() leaves only alternative location with maximal
+ // occupancy, if those are equal or unspecified, the one with
+ // "least" alternative location indicator.
+ // The function returns the number of deleted atoms. The atom
+ // table remains untrimmed, so that nAtoms are wrong until that
+ // is done. Tables are trimmed by FinishStructEdit() or
+ // explicitely.
+ int DeleteAltLocs ();
+
+ void TrimAtomTable ();
+
+ // ---------------------- Adding atoms ------------------------
+
+ // AddAtom(..) adds atom to the residue. If residue is associated
+ // with a coordinate hierarchy, and atom 'atm' is not, the latter
+ // is checked in automatically. If atom 'atm' belongs to any
+ // coordinate hierarchy (even though that of the residue), it is
+ // *copied* rather than simply taken over, and is checked in.
+ // If residue is not associated with a coordinate hierarchy, all
+ // added atoms will be checked in automatically once the residue
+ // is checked in.
+ int AddAtom ( PAtom atm );
+
+ // InsertAtom(..) inserts atom into the specified position of
+ // the residue. If residue is associated with a coordinate
+ // hierarchy, and atom 'atm' is not, the latter is checked in
+ // automatically. If atom 'atm' belongs to any coordinate
+ // hierarchy (even though that of the residue), it is *copied*
+ // rather than simply taken over, and is checked in.
+ // If residue is not associated with a coordinate hierarchy, all
+ // added atoms will be checked in automatically once the residue
+ // is checked in.
+ int InsertAtom ( PAtom atm, int position );
+
+ // This version inserts before the atom with given name. If such
+ // name is not found, the atom is appended to the end.
+ int InsertAtom ( PAtom atm, const AtomName aname );
+
+ // --------------------------------------------------------------
+
+ void ApplyTransform ( mat44 & TMatrix ); // transforms all
+ // coordinates by
+ // multiplying with
+ // matrix TMatrix
+
+ void MaskAtoms ( PMask Mask );
+ void UnmaskAtoms ( PMask Mask );
+
+
+ // ------- user-defined data handlers
+ int PutUDData ( int UDDhandle, int iudd );
+ int PutUDData ( int UDDhandle, realtype rudd );
+ int PutUDData ( int UDDhandle, cpstr sudd );
+
+ int GetUDData ( int UDDhandle, int & iudd );
+ int GetUDData ( int UDDhandle, realtype & rudd );
+ int GetUDData ( int UDDhandle, pstr sudd, int maxLen );
+ int GetUDData ( int UDDhandle, pstr & sudd );
+
+
+ bool isMainchainHBond ( PResidue res );
+
+ void Copy ( PResidue res );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ int AtmLen; // length of atom array
+ bool Exclude; // used internally
+
+ void InitResidue ();
+ void FreeMemory ();
+ int _AddAtom ( PAtom atm );
+ int _ExcludeAtom ( int kndex ); // 1: residue gets empty,
+ // 0 otherwise
+ void _copy ( PResidue res );
+ void _copy ( PResidue res, PPAtom atm, int & atom_index );
+ void ExpandAtomArray ( int nAdd );
+ void CheckInAtoms ();
+
+ };
+
+
+ extern realtype BondAngle ( PAtom A, PAtom B, PAtom C );
+
+} // namespace mmdb
+
+#endif
+
diff --git a/mmdb2/mmdb_bondmngr.cpp b/mmdb2/mmdb_bondmngr.cpp
new file mode 100644
index 0000000..6c7b99f
--- /dev/null
+++ b/mmdb2/mmdb_bondmngr.cpp
@@ -0,0 +1,121 @@
+// $Id: mmdb_bondmngr.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 15.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : mmdb_bondmngr <implementation>
+// ~~~~~~~~~
+// Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::BondManager ( MMDB bonds maker )
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+
+#include <string.h>
+
+#include "mmdb_bondmngr.h"
+#include "mmdb_math_graph.h"
+
+namespace mmdb {
+
+ // ===================== BondManager =====================
+
+ BondManager::BondManager() : SelManager() {
+ }
+
+ BondManager::BondManager ( io::RPStream Object )
+ : SelManager(Object) {
+ }
+
+ BondManager::~BondManager() {}
+
+ void BondManager::MakeBonds ( bool calc_only ) {
+ UNUSED_ARGUMENT(calc_only);
+ PModel mdl;
+ PChain chain;
+ PResidue res;
+ math::Graph graph;
+ math::PPVertex V;
+ math::PPEdge E;
+ int i, im,ic,ir, nV,nE, k1,k2;
+
+ RemoveBonds();
+
+ for (im=0;im<nModels;im++) {
+ mdl = model[im];
+ if (mdl)
+ for (ic=0;ic<mdl->nChains;ic++) {
+ chain = mdl->chain[ic];
+ if (chain)
+ for (ir=0;ir<chain->nResidues;ir++) {
+ res = chain->residue[ir];
+ if (res) {
+ graph.MakeGraph ( res,NULL );
+ graph.GetVertices ( V,nV );
+ graph.GetEdges ( E,nE );
+ for (i=0;i<nE;i++) {
+ k1 = V[E[i]->GetVertex1()-1]->GetUserID();
+ k2 = V[E[i]->GetVertex2()-1]->GetUserID();
+ res->atom[k1]->AddBond ( res->atom[k2],E[i]->GetType() );
+ res->atom[k2]->AddBond ( res->atom[k1],E[i]->GetType() );
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ void BondManager::RemoveBonds() {
+ int i;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i])
+ atom[i]->FreeBonds();
+ }
+
+ // ------------------- Stream functions ----------------------
+
+ void BondManager::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ SelManager::write ( f );
+ }
+
+ void BondManager::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ SelManager::read ( f );
+ }
+
+
+ MakeStreamFunctions(BondManager)
+
+} // namespace mmdb
diff --git a/mmdb/mmdb_bondmngr.h b/mmdb2/mmdb_bondmngr.h
old mode 100755
new mode 100644
similarity index 66%
rename from mmdb/mmdb_bondmngr.h
rename to mmdb2/mmdb_bondmngr.h
index 0df4c96..9186232
--- a/mmdb/mmdb_bondmngr.h
+++ b/mmdb2/mmdb_bondmngr.h
@@ -1,18 +1,18 @@
-// $Id: mmdb_bondmngr.h,v 1.20 2012/01/26 17:52:20 ekr Exp $
+// $Id: mmdb_bondmngr.h $
// =================================================================
//
// CCP4 Coordinate Library: support of coordinate-related
// functionality in protein crystallography applications.
//
-// Copyright (C) Eugene Krissinel 2000-2008.
+// Copyright (C) Eugene Krissinel 2000-2013.
//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
// of the license to address the requirements of UK law.
//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
//
// This program is distributed in the hope that it will be useful,
@@ -22,7 +22,7 @@
//
// =================================================================
//
-// 17.11.00 <-- Date of Last Modification.
+// 15.09.13 <-- Date of Last Modification.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// -----------------------------------------------------------------
//
@@ -30,10 +30,10 @@
// ~~~~~~~~~
// Project : MacroMolecular Data Base (MMDB)
// ~~~~~~~~~
-// **** Classes : CMMDBBondManager ( MMDB bonds maker )
+// **** Classes : mmdb::BondManager ( MMDB bonds maker )
// ~~~~~~~~~
//
-// (C) E. Krissinel 2000-2008
+// (C) E. Krissinel 2000-2013
//
// =================================================================
//
@@ -41,33 +41,33 @@
#ifndef __MMDB_BondMngr__
#define __MMDB_BondMngr__
-#ifndef __MMDB_SelMngr__
#include "mmdb_selmngr.h"
-#endif
+namespace mmdb {
-// ======================= CMMDBBondManager =======================
+ // ======================= BondManager =======================
+ DefineClass(BondManager);
+ DefineStreamFunctions(BondManager);
-DefineClass(CMMDBBondManager);
-DefineStreamFunctions(CMMDBBondManager);
+ class BondManager : public SelManager {
-class CMMDBBondManager : public CMMDBSelManager {
+ public :
- public :
+ BondManager ();
+ BondManager ( io::RPStream Object );
+ ~BondManager();
- CMMDBBondManager ();
- CMMDBBondManager ( RPCStream Object );
- ~CMMDBBondManager();
+ void MakeBonds ( bool calc_only );
+ void RemoveBonds();
- void MakeBonds ( Boolean calc_only );
- void RemoveBonds();
+ protected :
+ void write ( io::RFile f );
+ void read ( io::RFile f );
- protected :
- void write ( RCFile f );
- void read ( RCFile f );
+ };
-};
+} // namespace mmdb
#endif
diff --git a/mmdb2/mmdb_chain.cpp b/mmdb2/mmdb_chain.cpp
new file mode 100644
index 0000000..1c3ab8e
--- /dev/null
+++ b/mmdb2/mmdb_chain.cpp
@@ -0,0 +1,2575 @@
+// $Id: mmdb_chain.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 16.05.14 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_Chain <implementation>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::ProModel ( a virtue of Model )
+// ~~~~~~~~~ mmdb::DBReference ( DBREF records )
+// mmdb::ChainContainer ( container of in-chain classes )
+// mmdb::ContainerChain ( chain containered class template)
+// mmdb::SeqAdv ( SEQADV records )
+// mmdb::SeqRes ( SEQRES records )
+// mmdb::ModRes ( MODRES records )
+// mmdb::HetRec ( HET records )
+// mmdb::Chain ( chain class )
+//
+// Copyright (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "mmdb_chain.h"
+#include "mmdb_model.h"
+#include "mmdb_root.h"
+#include "mmdb_cifdefs.h"
+
+namespace mmdb {
+
+ // ================== ProModel ======================
+
+ MakeStreamFunctions(ProModel)
+
+ // ============== ChainContainer ====================
+
+ PContainerClass ChainContainer::MakeContainerClass ( int ClassID ) {
+ switch (ClassID) {
+ default :
+ case ClassID_Template : return
+ ClassContainer::MakeContainerClass(ClassID);
+ case ClassID_DBReference : return new DBReference ( chain );
+ case ClassID_SeqAdv : return new SeqAdv ( chain );
+ case ClassID_ModRes : return new ModRes ( chain );
+ case ClassID_Het : return new HetRec ( chain );
+ }
+ }
+
+ void ChainContainer::SetChain ( PChain Chain_Owner ) {
+ int i;
+ chain = Chain_Owner;
+ for (i=0;i<length;i++)
+ if (Container[i])
+ (void)PContainerChain(Container[i])->SetChain ( chain );
+ }
+
+ cpstr ChainContainer::Get1stChainID() {
+ int i;
+ i = 0;
+ if (Container) {
+ while ((i<length-1) && (!Container[i])) i++;
+ if (Container[i])
+ return PContainerChain(Container[i])->chainID;
+ else return NULL;
+ } else
+ return NULL;
+ }
+
+ void ChainContainer::MoveByChainID ( const ChainID chainID,
+ PChainContainer ChainContainer ) {
+ int i;
+ for (i=0;i<length;i++)
+ if (Container[i]) {
+ if (!strcmp(PContainerChain(Container[i])->chainID,chainID)) {
+ ChainContainer->AddData ( Container[i] );
+ Container[i] = NULL;
+ }
+ }
+ }
+
+
+ MakeStreamFunctions(ChainContainer)
+
+
+ // ================ ContainerChain ===================
+
+ ContainerChain::ContainerChain() : ContainerClass() {
+ chain = NULL;
+ chainID[0] = char(0);
+ }
+
+ ContainerChain::ContainerChain ( PChain Chain_Owner)
+ : ContainerClass() {
+ chain = Chain_Owner;
+ if (chain) strcpy ( chainID,chain->GetChainID() );
+ else chainID[0] = char(0);
+ }
+
+ void ContainerChain::SetChain ( PChain Chain_Owner ) {
+ chain = Chain_Owner;
+ if (chain) strcpy ( chainID,chain->GetChainID() );
+ else strcpy ( chainID,"" );
+ }
+
+ MakeStreamFunctions(ContainerChain)
+
+
+ // ================ DBReference ===================
+
+ DBReference::DBReference() : ContainerChain() {
+ InitDBReference();
+ }
+
+ DBReference::DBReference( PChain Chain_Owner )
+ : ContainerChain(Chain_Owner) {
+ InitDBReference();
+ }
+
+ DBReference::DBReference ( PChain Chain_Owner, cpstr S )
+ : ContainerChain(Chain_Owner) {
+ InitDBReference();
+ ConvertPDBASCII ( S );
+ }
+
+ DBReference::DBReference ( io::RPStream Object )
+ : ContainerChain(Object) {
+ InitDBReference();
+ }
+
+ DBReference::~DBReference() {}
+
+ void DBReference::InitDBReference() {
+ seqBeg = 0;
+ strcpy ( insBeg ,"-" );
+ seqEnd = 0;
+ strcpy ( insEnd ,"-" );
+ strcpy ( database ,"------" );
+ strcpy ( dbAccession,"--------" );
+ strcpy ( dbIdCode ,"------------" );
+ dbseqBeg = 0;
+ strcpy ( dbinsBeg,"-" );
+ dbseqEnd = 0;
+ strcpy ( dbinsEnd,"-" );
+ }
+
+ void DBReference::PDBASCIIDump ( pstr S, int N ) {
+ UNUSED_ARGUMENT(N);
+ // makes the ASCII PDB DBREF line number N
+ // from the class' data
+ strcpy ( S,"DBREF" );
+ PadSpaces ( S,80 );
+ strcpy_n ( &(S[7]),chain->GetEntryID(),4 );
+ if (chain->chainID[0]) S[12] = chain->chainID[0];
+ PutIntIns ( &(S[14]),seqBeg,4,insBeg );
+ PutIntIns ( &(S[20]),seqEnd,4,insEnd );
+ strcpy_n ( &(S[26]),database ,6 );
+ strcpy_n ( &(S[33]),dbAccession,8 );
+ strcpy_n ( &(S[42]),dbIdCode ,12 );
+ PutIntIns ( &(S[55]),dbseqBeg,5,dbinsBeg );
+ PutIntIns ( &(S[62]),dbseqEnd,5,dbinsEnd );
+ }
+
+ void DBReference::MakeCIF ( mmcif::PData CIF, int N ) {
+ UNUSED_ARGUMENT(N);
+ mmcif::PLoop Loop1,Loop2;
+ int RC1,RC2;
+
+ RC1 = CIF->AddLoop ( CIFCAT_STRUCT_REF_SEQ,Loop1 );
+ RC2 = CIF->AddLoop ( CIFCAT_STRUCT_REF ,Loop2 );
+
+ if ((RC1!=mmcif::CIFRC_Ok) || (RC2!=mmcif::CIFRC_Ok)) {
+ // the category was (re)created, provide tags
+ Loop1->AddLoopTag ( CIFTAG_NDB_PDB_ID_CODE );
+ Loop1->AddLoopTag ( CIFTAG_NDB_CHAIN_ID );
+ Loop1->AddLoopTag ( CIFTAG_SEQ_ALIGN_BEG );
+ Loop1->AddLoopTag ( CIFTAG_NDB_SEQ_ALIGN_BEG_INS_CODE );
+ Loop1->AddLoopTag ( CIFTAG_SEQ_ALIGN_END );
+ Loop1->AddLoopTag ( CIFTAG_NDB_SEQ_ALIGN_END_INS_CODE );
+ Loop1->AddLoopTag ( CIFTAG_NDB_DB_ACCESSION );
+ Loop1->AddLoopTag ( CIFTAG_DB_ALIGN_BEG );
+ Loop1->AddLoopTag ( CIFTAG_NDB_DB_ALIGN_BEG_INS_CODE );
+ Loop1->AddLoopTag ( CIFTAG_DB_ALIGN_END );
+ Loop1->AddLoopTag ( CIFTAG_NDB_DB_ALIGN_END_INS_CODE );
+ Loop2->AddLoopTag ( CIFTAG_DB_NAME );
+ Loop2->AddLoopTag ( CIFTAG_DB_CODE );
+ }
+
+ Loop1->AddString ( chain->GetEntryID(),true );
+ Loop1->AddString ( chain->chainID ,true );
+ Loop1->AddInteger ( seqBeg );
+ Loop1->AddString ( insBeg ,true );
+ Loop1->AddInteger ( seqEnd );
+ Loop1->AddString ( insEnd ,true );
+ Loop1->AddString ( dbAccession ,true );
+ Loop1->AddInteger ( dbseqBeg );
+ Loop1->AddString ( dbinsBeg ,true );
+ Loop1->AddInteger ( dbseqEnd );
+ Loop1->AddString ( dbinsEnd ,true );
+
+ Loop2->AddString ( database,true );
+ Loop2->AddString ( dbIdCode,true );
+
+ }
+
+ ERROR_CODE DBReference::GetCIF ( mmcif::PData CIF, int & n ) {
+ // GetCIF(..) must be always run without reference to Chain,
+ // see CModel::GetCIF(..).
+ mmcif::PLoop Loop1,Loop2;
+ mmcif::PStruct Struct2;
+ pstr F;
+ int RC,ref_id1,ref_id2;
+ CIF_MODE CIFMode;
+ ERROR_CODE rc;
+
+ Loop1 = CIF->GetLoop ( CIFCAT_STRUCT_REF_SEQ );
+
+ if (!Loop1) {
+ n = -1;
+ return Error_EmptyCIF;
+ }
+
+ if (n>=Loop1->GetLoopLength()) {
+ n = -1;
+ return Error_EmptyCIF;
+ }
+
+
+ // Determine the ChainID first and store it locally. It will
+ // be used by CModel for generating chains and placing the
+ // primary structure data BEFORE reading the coordinate section.
+ CIFMode = CIF_NDB;
+ F = Loop1->GetString ( CIFName(TAG_CHAIN_ID,CIFMode),n,RC );
+ if ((RC) || (!F)) {
+ CIFMode = CIF_PDBX;
+ F = Loop1->GetString ( CIFName(TAG_CHAIN_ID,CIFMode),n,RC );
+ }
+ if ((!RC) && F) {
+ strcpy_n0 ( chainID,F,sizeof(ChainID)-1 );
+ Loop1->DeleteField ( CIFName(TAG_CHAIN_ID,CIFMode),n );
+ } else
+ strcpy ( chainID,"" );
+
+
+ rc = CIFGetInteger(seqBeg,Loop1,CIFName(TAG_SEQ_ALIGN_BEG,CIFMode),n );
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+ CIFGetString ( insBeg,Loop1,CIFName(TAG_SEQ_ALIGN_BEG_INS_CODE,CIFMode),
+ n,sizeof(InsCode),pstr(" ") );
+
+ rc = CIFGetInteger(seqEnd,Loop1,CIFName(TAG_SEQ_ALIGN_END,CIFMode),n );
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+ CIFGetString ( insEnd,Loop1,CIFName(TAG_SEQ_ALIGN_END_INS_CODE,CIFMode),
+ n,sizeof(InsCode),pstr(" ") );
+ CIFGetString ( dbAccession,Loop1,CIFName(TAG_DB_ACCESSION,CIFMode),
+ n,sizeof(DBAcCode),pstr(" ") );
+
+ rc = CIFGetInteger(dbseqBeg,Loop1,CIFName(TAG_DB_ALIGN_BEG,CIFMode),n);
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+ CIFGetString ( dbinsBeg,Loop1,CIFName(TAG_DB_ALIGN_BEG_INS_CODE,CIFMode),
+ n,sizeof(InsCode),pstr(" ") );
+
+ rc = CIFGetInteger(dbseqEnd,Loop1,CIFName(TAG_DB_ALIGN_END,CIFMode),n);
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+ CIFGetString ( dbinsEnd,Loop1,CIFName(TAG_DB_ALIGN_END_INS_CODE,CIFMode),
+ n,sizeof(InsCode),pstr(" ") );
+
+ Loop2 = CIF->GetLoop ( CIFCAT_STRUCT_REF );
+ if (Loop2) {
+ CIFGetString ( database,Loop2,CIFTAG_DB_NAME,n,
+ sizeof(DBName) ,pstr(" ") );
+ CIFGetString ( dbIdCode,Loop2,CIFTAG_DB_CODE,n,
+ sizeof(DBIdCode),pstr(" ") );
+ } else if (CIFMode==CIF_PDBX) {
+ Struct2 = CIF->GetStructure ( CIFCAT_STRUCT_REF );
+ if (Struct2 &&
+ (!CIFGetInteger(ref_id1,Loop1,CIFTAG_REF_ID,n)) &&
+ (!CIFGetInteger(ref_id2,Struct2,CIFTAG_ID,false))) {
+ if (ref_id1==ref_id2) {
+ CIFGetString ( database,Struct2,CIFTAG_DB_NAME,
+ sizeof(DBName) ,pstr(" ") ,false );
+ CIFGetString ( dbIdCode,Struct2,CIFTAG_DB_CODE,
+ sizeof(DBIdCode),pstr(" "),false );
+ }
+ }
+ }
+
+ n++;
+
+ return Error_NoError;
+
+ }
+
+
+ ERROR_CODE DBReference::ConvertPDBASCII ( cpstr S ) {
+ IDCode idCode;
+ if (chain->chainID[0]) {
+ if (S[12]!=chain->chainID[0])
+ return Error_WrongChainID;
+ } else if (S[12]!=' ') {
+ chain->chainID[0] = S[12];
+ chain->chainID[1] = char(0);
+ } else
+ chain->chainID[0] = char(0);
+ strcpy ( idCode,chain->GetEntryID() );
+ if (idCode[0]) {
+ if (strncmp(&(S[7]),idCode,4) && (!ignoreNonCoorPDBErrors))
+ return Error_WrongEntryID;
+ } else {
+ GetString ( idCode,&(S[7]),4 );
+ chain->SetEntryID ( idCode );
+ }
+ GetIntIns ( seqBeg,insBeg,&(S[14]),4 );
+ GetIntIns ( seqEnd,insEnd,&(S[20]),4 );
+ strcpy_ncs ( database ,&(S[26]),6 );
+ strcpy_ncs ( dbAccession ,&(S[33]),8 );
+ strcpy_ncs ( dbIdCode ,&(S[42]),12 );
+ GetIntIns ( dbseqBeg,dbinsBeg,&(S[55]),5 );
+ GetIntIns ( dbseqEnd,dbinsEnd,&(S[62]),5 );
+ return Error_NoError;
+ }
+
+ void DBReference::Copy ( PContainerClass DBRef ) {
+
+ ContainerChain::Copy ( DBRef );
+
+ seqBeg = PDBReference(DBRef)->seqBeg;
+ seqEnd = PDBReference(DBRef)->seqEnd;
+ dbseqBeg = PDBReference(DBRef)->dbseqBeg;
+ dbseqEnd = PDBReference(DBRef)->dbseqEnd;
+ strcpy ( insBeg ,PDBReference(DBRef)->insBeg );
+ strcpy ( insEnd ,PDBReference(DBRef)->insEnd );
+ strcpy ( database ,PDBReference(DBRef)->database );
+ strcpy ( dbAccession,PDBReference(DBRef)->dbAccession );
+ strcpy ( dbIdCode ,PDBReference(DBRef)->dbIdCode );
+ strcpy ( dbinsBeg ,PDBReference(DBRef)->dbinsBeg );
+ strcpy ( dbinsEnd ,PDBReference(DBRef)->dbinsEnd );
+
+ }
+
+ void DBReference::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &seqBeg );
+ f.WriteInt ( &seqEnd );
+ f.WriteInt ( &dbseqBeg );
+ f.WriteInt ( &dbseqEnd );
+ f.WriteTerLine ( insBeg ,false );
+ f.WriteTerLine ( insEnd ,false );
+ f.WriteTerLine ( database ,false );
+ f.WriteTerLine ( dbAccession,false );
+ f.WriteTerLine ( dbIdCode ,false );
+ f.WriteTerLine ( dbinsBeg ,false );
+ f.WriteTerLine ( dbinsEnd ,false );
+ }
+
+ void DBReference::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ f.ReadInt ( &seqBeg );
+ f.ReadInt ( &seqEnd );
+ f.ReadInt ( &dbseqBeg );
+ f.ReadInt ( &dbseqEnd );
+ f.ReadTerLine ( insBeg ,false );
+ f.ReadTerLine ( insEnd ,false );
+ f.ReadTerLine ( database ,false );
+ f.ReadTerLine ( dbAccession,false );
+ f.ReadTerLine ( dbIdCode ,false );
+ f.ReadTerLine ( dbinsBeg ,false );
+ f.ReadTerLine ( dbinsEnd ,false );
+ }
+
+ MakeStreamFunctions(DBReference)
+
+
+
+ // ================ SeqAdv ===================
+
+ SeqAdv::SeqAdv() : ContainerChain() {
+ InitSeqAdv();
+ }
+
+ SeqAdv::SeqAdv ( PChain Chain_Owner )
+ : ContainerChain(Chain_Owner) {
+ InitSeqAdv();
+ }
+
+ SeqAdv::SeqAdv ( PChain Chain_Owner, cpstr S )
+ : ContainerChain(Chain_Owner) {
+ InitSeqAdv();
+ ConvertPDBASCII ( S );
+ }
+
+ SeqAdv::SeqAdv ( io::RPStream Object ) : ContainerChain(Object) {
+ InitSeqAdv();
+ }
+
+ SeqAdv::~SeqAdv() {
+ if (conflict) delete[] conflict;
+ }
+
+ void SeqAdv::InitSeqAdv() {
+ strcpy ( resName ,"---" );
+ seqNum = 0;
+ strcpy ( insCode ,"-" );
+ strcpy ( database ,"------" );
+ strcpy ( dbAccession,"---------" );
+ strcpy ( dbRes ,"---" );
+ dbSeq = 0;
+ conflict = NULL;
+ CreateCopy ( conflict,pstr(" ") );
+ }
+
+ void SeqAdv::PDBASCIIDump ( pstr S, int N ) {
+ UNUSED_ARGUMENT(N);
+ // makes the ASCII PDB SEQADV line number N
+ // from the class' data
+ strcpy ( S,"SEQADV" );
+ PadSpaces ( S,80 );
+ strcpy_n ( &(S[7]) ,chain->GetEntryID(),4 );
+ strcpy_n ( &(S[12]),resName ,3 );
+ if (chain->chainID[0]) S[16] = chain->chainID[0];
+ PutIntIns ( &(S[18]),seqNum,4,insCode );
+ strcpy_n ( &(S[24]),database ,4 );
+ strcpy_n ( &(S[29]),dbAccession,9 );
+ strcpy_n ( &(S[39]),dbRes ,3 );
+ PutInteger ( &(S[43]),dbSeq ,5 );
+ strcpy_n ( &(S[49]),conflict,IMin(strlen(conflict),21) );
+ }
+
+ ERROR_CODE SeqAdv::ConvertPDBASCII ( cpstr S ) {
+ IDCode idCode;
+ if (chain->chainID[0]) {
+ if (S[16]!=chain->chainID[0])
+ return Error_WrongChainID;
+ } else if (S[16]!=' ') {
+ chain->chainID[0] = S[16];
+ chain->chainID[1] = char(0);
+ } else
+ chain->chainID[0] = char(0);
+ strcpy ( idCode,chain->GetEntryID() );
+ if (idCode[0]) {
+ if (strncmp(&(S[7]),idCode,4) && (!ignoreNonCoorPDBErrors))
+ return Error_WrongEntryID;
+ } else {
+ GetString ( idCode,&(S[7]),4 );
+ chain->SetEntryID ( idCode );
+ }
+ strcpy_ncs ( resName ,&(S[12]),3 );
+ GetIntIns ( seqNum,insCode,&(S[18]),4 );
+ strcpy_ncs ( database ,&(S[24]),4 );
+ strcpy_ncs ( dbAccession ,&(S[29]),9 );
+ strcpy_ncs ( dbRes ,&(S[39]),3 );
+ GetInteger ( dbSeq,&(S[43]),5 );
+ CreateCopy ( conflict,&(S[49]) );
+ CutSpaces ( conflict,SCUTKEY_END );
+ return Error_NoError;
+ }
+
+
+ void SeqAdv::MakeCIF ( mmcif::PData CIF, int N ) {
+ UNUSED_ARGUMENT(N);
+ mmcif::PLoop Loop;
+ int RC;
+
+ RC = CIF->AddLoop ( CIFCAT_STRUCT_REF_SEQ_DIF,Loop );
+
+ if (RC!=mmcif::CIFRC_Ok) {
+ // the category was (re)created, provide tags
+ Loop->AddLoopTag ( CIFTAG_NDB_PDB_ID_CODE );
+ Loop->AddLoopTag ( CIFTAG_MON_ID );
+ Loop->AddLoopTag ( CIFTAG_NDB_PDB_CHAIN_ID );
+ Loop->AddLoopTag ( CIFTAG_SEQ_NUM );
+ Loop->AddLoopTag ( CIFTAG_NDB_PDB_INS_CODE );
+ Loop->AddLoopTag ( CIFTAG_NDB_SEQ_DB_NAME );
+ Loop->AddLoopTag ( CIFTAG_NDB_SEQ_DB_ACCESSION_CODE );
+ Loop->AddLoopTag ( CIFTAG_DB_MON_ID );
+ Loop->AddLoopTag ( CIFTAG_NDB_SEQ_DB_SEQ_NUM );
+ Loop->AddLoopTag ( CIFTAG_DETAILS );
+ }
+
+ Loop->AddString ( chain->GetEntryID(),true );
+ Loop->AddString ( resName ,true );
+ Loop->AddString ( chain->chainID ,true );
+ Loop->AddInteger ( seqNum );
+ Loop->AddString ( insCode ,true );
+ Loop->AddString ( database ,true );
+ Loop->AddString ( dbAccession ,true );
+ Loop->AddString ( dbRes ,true );
+ Loop->AddInteger ( dbSeq );
+ Loop->AddString ( conflict ,true );
+
+ }
+
+ ERROR_CODE SeqAdv::GetCIF ( mmcif::PData CIF, int & n ) {
+ // GetCIF(..) must be always run without reference to Chain,
+ // see CModel::GetCIF(..).
+ mmcif::PLoop Loop;
+ pstr F;
+ int RC;
+
+ Loop = CIF->GetLoop ( CIFCAT_STRUCT_REF_SEQ_DIF );
+ if (!Loop) {
+ n = -1;
+ return Error_EmptyCIF;
+ }
+
+ if (n>=Loop->GetLoopLength()) {
+ n = -1;
+ return Error_EmptyCIF;
+ }
+
+ // Determine the ChainID first and store it locally. It will
+ // be used by CModel for generating chains and placing the
+ // primary structure data BEFORE reading the coordinate section.
+
+ F = Loop->GetString ( CIFTAG_NDB_PDB_CHAIN_ID,n,RC );
+ if ((!RC) && F) {
+ strcpy_n0 ( chainID,F,sizeof(ChainID)-1 );
+ Loop->DeleteField ( CIFTAG_NDB_PDB_CHAIN_ID,n );
+ } else
+ strcpy ( chainID,"" );
+
+ CIFGetString ( resName,Loop,CIFTAG_MON_ID,n,sizeof(ResName),
+ pstr("UNK") );
+
+ CIFGetIntegerD ( seqNum,Loop,CIFTAG_SEQ_NUM );
+
+ CIFGetString ( insCode,Loop,CIFTAG_NDB_PDB_INS_CODE,
+ n,sizeof(InsCode),pstr(" ") );
+
+ CIFGetString ( database,Loop,CIFTAG_NDB_SEQ_DB_NAME,n,
+ sizeof(DBName),pstr(" ") );
+
+ CIFGetString ( dbAccession,Loop,CIFTAG_NDB_SEQ_DB_ACCESSION_CODE,
+ n,sizeof(DBAcCode),pstr(" ") );
+
+ CIFGetString ( dbRes,Loop,CIFTAG_DB_MON_ID,n,sizeof(ResName),
+ pstr(" ") );
+
+ CIFGetIntegerD ( dbSeq,Loop,CIFTAG_NDB_SEQ_DB_SEQ_NUM );
+ // if (CIFGetInteger1(dbSeq,Loop,CIFTAG_NDB_SEQ_DB_SEQ_NUM,n))
+ // dbSeq = MinInt4;
+
+ F = Loop->GetString ( CIFTAG_DETAILS,n,RC );
+ if ((!RC) && F) {
+ CreateCopy ( conflict,F );
+ Loop->DeleteField ( CIFTAG_DETAILS,n );
+ } else
+ CreateCopy ( conflict,pstr(" ") );
+
+ n++;
+
+ return Error_NoError;
+
+ }
+
+ void SeqAdv::Copy ( PContainerClass SeqAdv ) {
+
+ ContainerClass::Copy ( SeqAdv );
+
+ seqNum = PSeqAdv(SeqAdv)->seqNum;
+ dbSeq = PSeqAdv(SeqAdv)->dbSeq;
+ strcpy ( resName ,PSeqAdv(SeqAdv)->resName );
+ strcpy ( insCode ,PSeqAdv(SeqAdv)->insCode );
+ strcpy ( database ,PSeqAdv(SeqAdv)->database );
+ strcpy ( dbAccession,PSeqAdv(SeqAdv)->dbAccession );
+ strcpy ( dbRes ,PSeqAdv(SeqAdv)->dbRes );
+ CreateCopy ( conflict,PSeqAdv(SeqAdv)->conflict );
+
+ }
+
+ void SeqAdv::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &seqNum );
+ f.WriteInt ( &dbSeq );
+ f.WriteTerLine ( resName ,false );
+ f.WriteTerLine ( insCode ,false );
+ f.WriteTerLine ( database ,false );
+ f.WriteTerLine ( dbAccession,false );
+ f.WriteTerLine ( dbRes ,false );
+ f.CreateWrite ( conflict );
+ }
+
+ void SeqAdv::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ f.ReadInt ( &seqNum );
+ f.ReadInt ( &dbSeq );
+ f.ReadTerLine ( resName ,false );
+ f.ReadTerLine ( insCode ,false );
+ f.ReadTerLine ( database ,false );
+ f.ReadTerLine ( dbAccession,false );
+ f.ReadTerLine ( dbRes ,false );
+ f.CreateRead ( conflict );
+ }
+
+ MakeStreamFunctions(SeqAdv)
+
+
+
+ // ================ SeqRes ===================
+
+ SeqRes::SeqRes() : io::Stream() {
+ InitSeqRes();
+ }
+
+ SeqRes::SeqRes ( io::RPStream Object ) : io::Stream(Object) {
+ InitSeqRes();
+ }
+
+ SeqRes::~SeqRes() {
+ FreeMemory();
+ }
+
+ void SeqRes::SetChain ( PChain Chain_Owner ) {
+ chain = Chain_Owner;
+ if (chain) strcpy ( chainID,chain->chainID );
+ else strcpy ( chainID,"" );
+ }
+
+ void SeqRes::InitSeqRes() {
+ chain = NULL;
+ numRes = -1;
+ resName = NULL;
+ serNum = 0;
+ strcpy ( chainID,"" );
+ }
+
+ void SeqRes::FreeMemory() {
+ if (resName) delete[] resName;
+ resName = NULL;
+ numRes = -1;
+ serNum = 0;
+ }
+
+ void SeqRes::PDBASCIIDump ( io::RFile f ) {
+ // writes the ASCII PDB SEQRES lines into file f
+ char S[100];
+ int i,k,sN;
+ if (numRes<0) return;
+ strcpy ( S,"SEQRES" );
+ PadSpaces ( S,80 );
+ if (chain->chainID[0])
+ S[11] = chain->chainID[0];
+ PutInteger ( &(S[13]),numRes,4 );
+ if (resName) {
+ i = 0;
+ sN = 1;
+ while (i<numRes) {
+ PutInteger ( &(S[7]),sN,3 );
+ k = 19;
+ while ((i<numRes) && (k<70)) {
+ if (resName[i][0])
+ strcpy_n ( &(S[k]),resName[i],3 );
+ else strcpy_n ( &(S[k]),pstr(" "),3 );
+ i++;
+ k += 4;
+ }
+ while (k<70) {
+ strcpy_n ( &(S[k]),pstr(" "),3 );
+ k += 4;
+ }
+ f.WriteLine ( S );
+ sN++;
+ }
+ } else {
+ S[9] = '0';
+ strcpy_n ( &(S[19]),pstr("UNK"),3 );
+ f.WriteLine ( S );
+ }
+ }
+
+ ERROR_CODE SeqRes::ConvertPDBASCII ( cpstr S ) {
+ int i,k,sN,nR;
+ if (chain->chainID[0]) {
+ if (S[11]!=chain->chainID[0])
+ return Error_WrongChainID;
+ } else if (S[11]!=' ') {
+ chain->chainID[0] = S[11];
+ chain->chainID[1] = char(0);
+ } else
+ chain->chainID[0] = char(0);
+ GetInteger ( sN,&(S[8]) ,3 );
+ GetInteger ( nR,&(S[13]),4 );
+ if (sN==0) {
+ FreeMemory();
+ numRes = nR;
+ } else {
+ serNum++;
+ if (sN!=serNum)
+ return Error_SEQRES_serNum;
+ if (sN==1) {
+ FreeMemory();
+ resName = new ResName[nR];
+ for (i=0;i<nR;i++)
+ resName[i][0] = char(0);
+ numRes = nR;
+ serNum = sN;
+ } else if (nR!=numRes)
+ return Error_SEQRES_numRes;
+ i = 0;
+ while ((i<nR) && (resName[i][0])) i++;
+ if (i>=nR)
+ return Error_SEQRES_extraRes;
+ k = 19;
+ while ((i<nR) && (k<70)) {
+ GetString ( resName[i],&(S[k]),3 );
+ if (!strcmp(resName[i]," ")) resName[i][0] = char(0);
+ else i++;
+ k += 4;
+ }
+ }
+ return Error_NoError;
+ }
+
+
+ void SeqRes::MakeCIF ( mmcif::PData CIF ) {
+ // Note that SeqRes only adds sequence to the CIF loop common
+ // to all chains. Therefore this loop should be wiped off from
+ // CIF structure before putting first sequence into it.
+ mmcif::PLoop Loop;
+ int RC,i;
+
+ if (numRes<0) return;
+
+ RC = CIF->AddLoop ( CIFCAT_NDB_POLY_SEQ_SCHEME,Loop );
+ if (RC!=mmcif::CIFRC_Ok) {
+ // the category was (re)created, provide tags
+ Loop->AddLoopTag ( CIFTAG_ID );
+ Loop->AddLoopTag ( CIFTAG_MON_ID );
+ }
+
+ if (resName)
+ for (i=0;i<numRes;i++) {
+ Loop->AddString ( chain->chainID,true );
+ Loop->AddString ( resName[i] ,true );
+ }
+ else
+ for (i=0;i<numRes;i++) {
+ Loop->AddString ( chain->GetEntryID(),true );
+ Loop->AddString ( pstr("UNK") ,true );
+ }
+
+ }
+
+ ERROR_CODE SeqRes::GetCIF ( mmcif::PData CIF ) {
+ // Tries to get sequence from the CIF structure. A sequence
+ // for first met chain is extracted and then removed from
+ // the CIF structure, so that sequential calls will extract
+ // all sequencies. Chain ID is stored locally in chainID;
+ // reference to parent chain is neither used nor checked.
+ // Returns 0 if sequence was extracted and 1 otherwise.
+ mmcif::PLoop Loop;
+ ResName * rN;
+ ChainID chID;
+ pstr F;
+ cpstr CHAIN_ID;
+ int RC,i,l;
+ CIF_MODE CIFMode;
+ bool isMon;
+
+ FreeMemory();
+
+ CIFMode = CIF_NDB;
+ Loop = CIF->GetLoop ( CIFName(CAT_POLY_SEQ_SCHEME,CIFMode) );
+ if (!Loop) {
+ CIFMode = CIF_PDBX;
+ Loop = CIF->GetLoop ( CIFName(CAT_POLY_SEQ_SCHEME,CIFMode) );
+ if (!Loop) return Error_NoLoop;
+ }
+
+ l = Loop->GetLoopLength();
+ if (l<=0) return Error_NoLoop;
+
+ rN = new ResName[l];
+ chainID[0] = char(1);
+ numRes = 0;
+ isMon = false;
+ CHAIN_ID = CIFName(TAG_SEQ_CHAIN_ID,CIFMode);
+ for (i=0;i<l;i++) {
+ F = Loop->GetString ( CHAIN_ID,i,RC );
+ if (!RC) {
+ if (F) strcpy ( chID,F );
+ else chID[0] = char(0);
+ if (chainID[0]==char(1)) strcpy ( chainID,chID );
+ if (!strcmp(chainID,chID)) {
+ CIFGetString ( rN[numRes],Loop,CIFTAG_MON_ID,i,
+ sizeof(ResName),pstr("UNK") );
+ Loop->DeleteField ( CHAIN_ID,i );
+ if (strcmp(rN[numRes],"UNK")) isMon = true;
+ numRes++;
+ }
+ }
+ }
+
+ if (numRes==0) {
+ numRes = -1;
+ delete[] rN;
+ return Error_EmptyCIFLoop;
+ }
+
+ if (isMon) {
+ resName = new ResName[numRes];
+ for (i=0;i<numRes;i++)
+ strcpy ( resName[i],rN[i] );
+ }
+
+ delete[] rN;
+
+ return Error_NoError;
+
+ }
+
+ void SeqRes::Copy ( PSeqRes SeqRes ) {
+ int i;
+
+ FreeMemory();
+
+ numRes = SeqRes->numRes;
+ serNum = SeqRes->serNum;
+
+ if (SeqRes->resName) {
+ resName = new ResName[numRes];
+ for (i=0;i<numRes;i++)
+ strcpy ( resName[i],SeqRes->resName[i] );
+ }
+
+ }
+
+ void SeqRes::write ( io::RFile f ) {
+ int i;
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &numRes );
+ f.WriteInt ( &serNum );
+ if (resName) i = 1;
+ else i = 0;
+ f.WriteInt ( &i );
+ if (resName)
+ for (i=0;i<numRes;i++)
+ f.WriteTerLine ( resName[i],false );
+ }
+
+ void SeqRes::read ( io::RFile f ) {
+ int i;
+ byte Version;
+ FreeMemory();
+ f.ReadByte ( &Version );
+ f.ReadInt ( &numRes );
+ f.ReadInt ( &serNum );
+ f.ReadInt ( &i );
+ if (i) {
+ resName = new ResName[numRes];
+ for (i=0;i<numRes;i++)
+ f.ReadTerLine ( resName[i],false );
+ }
+ }
+
+
+ MakeStreamFunctions(SeqRes)
+
+
+
+ // ================ ModRes ===================
+
+ ModRes::ModRes() : ContainerChain() {
+ InitModRes();
+ }
+
+ ModRes::ModRes ( PChain Chain_Owner )
+ : ContainerChain(Chain_Owner) {
+ InitModRes();
+ }
+
+ ModRes::ModRes ( PChain Chain_Owner, cpstr S )
+ : ContainerChain(Chain_Owner) {
+ InitModRes();
+ ConvertPDBASCII ( S );
+ }
+
+ ModRes::ModRes ( io::RPStream Object ) : ContainerChain(Object) {
+ InitModRes();
+ }
+
+ ModRes::~ModRes() {
+ if (comment) delete[] comment;
+ }
+
+ void ModRes::InitModRes() {
+ strcpy ( resName,"---" );
+ seqNum = 0;
+ strcpy ( insCode,"-" );
+ comment = NULL;
+ CreateCopy ( comment,pstr(" ") );
+ strcpy ( stdRes ,"---" );
+ }
+
+ void ModRes::PDBASCIIDump ( pstr S, int N ) {
+ UNUSED_ARGUMENT(N);
+ // makes the ASCII PDB MODRES line number N
+ // from the class' data
+ strcpy ( S,"MODRES" );
+ PadSpaces ( S,80 );
+ strcpy_n ( &(S[7]) ,chain->GetEntryID(),4 );
+ strcpy_n ( &(S[12]),resName ,3 );
+ if (chain->chainID[0]) S[16] = chain->chainID[0];
+ PutIntIns ( &(S[18]),seqNum,4,insCode );
+ strcpy_n ( &(S[24]),stdRes ,3 );
+ strcpy_n ( &(S[29]),comment,IMin(strlen(comment),41) );
+ }
+
+ ERROR_CODE ModRes::ConvertPDBASCII ( cpstr S ) {
+ IDCode idCode;
+ if (chain->chainID[0]) {
+ if (S[16]!=chain->chainID[0])
+ return Error_WrongChainID;
+ } else if (S[16]!=' ') {
+ chain->chainID[0] = S[16];
+ chain->chainID[1] = char(0);
+ } else
+ chain->chainID[0] = char(0);
+ strcpy ( idCode,chain->GetEntryID() );
+ if (idCode[0]) {
+ if (strncmp(&(S[7]),idCode,4) && (!ignoreNonCoorPDBErrors))
+ return Error_WrongEntryID;
+ } else {
+ GetString ( idCode,&(S[7]),4 );
+ chain->SetEntryID ( idCode );
+ }
+ GetString ( resName ,&(S[12]),3 );
+ GetIntIns ( seqNum,insCode,&(S[18]),4 );
+ GetString ( stdRes ,&(S[24]),3 );
+ CreateCopy ( comment ,&(S[29]) );
+ CutSpaces ( comment,SCUTKEY_END );
+ return Error_NoError;
+ }
+
+ void ModRes::MakeCIF ( mmcif::PData CIF, int N ) {
+ UNUSED_ARGUMENT(CIF);
+ UNUSED_ARGUMENT(N);
+ /* -- apparently wrong use of _struct_conn, to be revised
+ mmcif::PLoop Loop;
+ int RC;
+
+ RC = CIF->AddLoop ( CIFCAT_STRUCT_CONN,Loop );
+
+ if (RC!=mmcif::CIFRC_Ok) {
+ // the category was (re)created, provide tags
+ Loop->AddLoopTag ( CIFTAG_CONN_TYPE_ID );
+ Loop->AddLoopTag ( CIFTAG_NDB_PDB_ID );
+ Loop->AddLoopTag ( CIFTAG_PTNR1_LABEL_COMP_ID );
+ Loop->AddLoopTag ( CIFTAG_PTNR1_LABEL_ASYM_ID );
+ Loop->AddLoopTag ( CIFTAG_PTNR1_LABEL_SEQ_ID );
+ Loop->AddLoopTag ( CIFTAG_NDB_PTNR1_LABEL_INS_CODE );
+ Loop->AddLoopTag ( CIFTAG_NDB_PTNR1_STANDARD_COMP_ID );
+ Loop->AddLoopTag ( CIFTAG_DETAILS );
+ }
+
+ Loop->AddString ( pstr("MODRES") );
+ Loop->AddString ( chain->GetEntryID(),true );
+ Loop->AddString ( resName ,true );
+ Loop->AddString ( chain->chainID ,true );
+ Loop->AddInteger ( seqNum );
+ Loop->AddString ( insCode ,true );
+ Loop->AddString ( stdRes ,true );
+ Loop->AddString ( comment ,true );
+
+ */
+
+ }
+
+ ERROR_CODE ModRes::GetCIF ( mmcif::PData CIF, int & n ) {
+ UNUSED_ARGUMENT(CIF);
+ // GetCIF(..) must be always run without reference to Chain,
+ // see CModel::GetCIF(..).
+
+ /* -- apparently wrong use of _struct_conn, to be revised
+ mmcif::PLoop Loop;
+ pstr F;
+ int l,RC;
+
+ Loop = CIF->GetLoop ( CIFCAT_STRUCT_CONN );
+ if (!Loop) {
+ n = -1;
+ return;
+ }
+
+ l = Loop->GetLoopLength();
+ while (n<l) {
+ F = Loop->GetString ( CIFTAG_CONN_TYPE_ID,n,RC );
+ if ((!RC) && F) {
+ if (!strcmp(F,"MODRES")) break;
+ }
+ n++;
+ }
+ if (n>=l) {
+ n = -1;
+ return;
+ }
+
+ Loop->DeleteField ( CIFTAG_CONN_TYPE_ID,n );
+
+ // Determine the ChainID first and store it locally. It will
+ // be used by CModel for generating chains and placing the
+ // primary structure data BEFORE reading the coordinate section.
+ F = Loop->GetString ( CIFTAG_PTNR1_LABEL_ASYM_ID,n,RC );
+ if ((!RC) && F) {
+ strcpy_n0 ( chainID,F,sizeof(ChainID)-1 );
+ Loop->DeleteField ( CIFTAG_PTNR1_LABEL_ASYM_ID,n );
+ } else
+ strcpy ( chainID,"" );
+
+
+ CIFGetString ( resName,Loop,CIFTAG_PTNR1_LABEL_COMP_ID,n,
+ sizeof(ResName),pstr("UNK") );
+
+ if (CIFGetInteger(seqNum,Loop,CIFTAG_PTNR1_LABEL_SEQ_ID,n))
+ return;
+
+ CIFGetString ( insCode,Loop,CIFTAG_NDB_PTNR1_LABEL_INS_CODE,
+ n,sizeof(InsCode),pstr(" ") );
+
+ CIFGetString ( stdRes,Loop,CIFTAG_NDB_PTNR1_STANDARD_COMP_ID,n,
+ sizeof(ResName),pstr("UNK") );
+
+ F = Loop->GetString ( CIFTAG_DETAILS,n,RC );
+ if ((!RC) && F) {
+ CreateCopy ( comment,F );
+ Loop->DeleteField ( CIFTAG_DETAILS,n );
+ } else
+ CreateCopy ( comment,pstr(" ") );
+
+ n++;
+
+ */
+
+ n = -1;
+
+ return Error_EmptyCIF;
+
+ }
+
+ void ModRes::Copy ( PContainerClass ModRes ) {
+ seqNum = PModRes(ModRes)->seqNum;
+ strcpy ( resName,PModRes(ModRes)->resName );
+ strcpy ( insCode,PModRes(ModRes)->insCode );
+ strcpy ( stdRes ,PModRes(ModRes)->stdRes );
+ CreateCopy ( comment,PModRes(ModRes)->comment );
+ }
+
+ void ModRes::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &seqNum );
+ f.WriteTerLine ( resName,false );
+ f.WriteTerLine ( insCode,false );
+ f.WriteTerLine ( stdRes ,false );
+ f.CreateWrite ( comment );
+ }
+
+ void ModRes::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ f.ReadInt ( &seqNum );
+ f.ReadTerLine ( resName,false );
+ f.ReadTerLine ( insCode,false );
+ f.ReadTerLine ( stdRes ,false );
+ f.CreateRead ( comment );
+ }
+
+ MakeStreamFunctions(ModRes)
+
+
+
+ // ================ HetRec ======================
+
+ HetRec::HetRec() : ContainerChain() {
+ InitHetRec();
+ }
+
+ HetRec::HetRec ( PChain Chain_Owner )
+ : ContainerChain(Chain_Owner) {
+ InitHetRec();
+ }
+
+ HetRec::HetRec ( PChain Chain_Owner, cpstr S )
+ : ContainerChain(Chain_Owner) {
+ InitHetRec();
+ ConvertPDBASCII ( S );
+ }
+
+ HetRec::HetRec ( io::RPStream Object ) : ContainerChain(Object) {
+ InitHetRec();
+ }
+
+ HetRec::~HetRec() {
+ if (comment) delete[] comment;
+ }
+
+ void HetRec::InitHetRec() {
+ strcpy ( hetID ,"---" );
+ strcpy ( insCode,"-" );
+ seqNum = 0;
+ numHetAtoms = 0;
+ comment = NULL;
+ CreateCopy ( comment,pstr(" ") );
+ }
+
+ void HetRec::PDBASCIIDump ( pstr S, int N ) {
+ UNUSED_ARGUMENT(N);
+ // makes the ASCII PDB MODRES line number N
+ // from the class' data
+ strcpy ( S,"HET" );
+ PadSpaces ( S,80 );
+ strcpy_n ( &(S[7]) ,hetID,3 );
+ if (chain->chainID[0]) S[12] = chain->chainID[0];
+ PutIntIns ( &(S[13]),seqNum,4,insCode );
+ PutInteger ( &(S[20]),numHetAtoms,5 );
+ strcpy_n ( &(S[30]),comment,IMin(strlen(comment),40) );
+ }
+
+ ERROR_CODE HetRec::ConvertPDBASCII ( cpstr S ) {
+ if (chain->chainID[0]) {
+ if (S[12]!=chain->chainID[0])
+ return Error_WrongChainID;
+ } else if (S[12]!=' ') {
+ chain->chainID[0] = S[12];
+ chain->chainID[1] = char(0);
+ } else
+ chain->chainID[0] = char(0);
+ GetString ( hetID ,&(S[7]) ,3 );
+ GetIntIns ( seqNum,insCode,&(S[13]),4 );
+ GetInteger ( numHetAtoms ,&(S[20]),5 );
+ CreateCopy ( comment ,&(S[30]) );
+ CutSpaces ( comment,SCUTKEY_END );
+ return Error_NoError;
+ }
+
+ void HetRec::MakeCIF ( mmcif::PData CIF, int N ) {
+ UNUSED_ARGUMENT(N);
+ mmcif::PLoop Loop;
+ int RC;
+
+ RC = CIF->AddLoop ( CIFCAT_NDB_NONSTANDARD_LIST,Loop );
+
+ if (RC!=mmcif::CIFRC_Ok) {
+ // the category was (re)created, provide tags
+ Loop->AddLoopTag ( CIFTAG_ID );
+ Loop->AddLoopTag ( CIFTAG_AUTH_ASYM_ID );
+ Loop->AddLoopTag ( CIFTAG_AUTH_SEQ_ID );
+ Loop->AddLoopTag ( CIFTAG_INS_CODE );
+ Loop->AddLoopTag ( CIFTAG_NUMBER_ATOMS_NH );
+ Loop->AddLoopTag ( CIFTAG_DETAILS );
+ }
+
+ Loop->AddString ( hetID ,true );
+ Loop->AddString ( chain->chainID,true );
+ Loop->AddInteger ( seqNum );
+ Loop->AddString ( insCode ,true );
+ Loop->AddInteger ( numHetAtoms );
+ Loop->AddString ( comment ,true );
+
+ }
+
+ ERROR_CODE HetRec::GetCIF ( mmcif::PData CIF, int & n ) {
+ // GetCIF(..) must be always run without reference to Chain,
+ // see CModel::GetCIF(..).
+ mmcif::PLoop Loop;
+ pstr F;
+ int RC;
+ ERROR_CODE rc;
+
+ Loop = CIF->GetLoop ( CIFCAT_NDB_NONSTANDARD_LIST );
+ if (!Loop) {
+ n = -1;
+ return Error_EmptyCIF;
+ }
+
+ if (n>=Loop->GetLoopLength()) {
+ n = -1;
+ return Error_EmptyCIF;
+ }
+
+ // Determine the ChainID first and store it locally. It will
+ // be used by CModel for generating chains and placing the
+ // primary structure data BEFORE reading the coordinate section.
+ F = Loop->GetString ( CIFTAG_AUTH_ASYM_ID,n,RC );
+ if ((!RC) && F) {
+ strcpy_n0 ( chainID,F,sizeof(ChainID)-1 );
+ Loop->DeleteField ( CIFTAG_AUTH_ASYM_ID,n );
+ } else
+ strcpy ( chainID,"" );
+
+
+ CIFGetString ( hetID,Loop,CIFTAG_ID,n,sizeof(ResName),
+ pstr("UNK") );
+
+ rc = CIFGetInteger ( seqNum,Loop,CIFTAG_AUTH_SEQ_ID,n );
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+
+ CIFGetString ( insCode,Loop,CIFTAG_INS_CODE,n,sizeof(InsCode),
+ pstr(" ") );
+
+ rc = CIFGetInteger ( numHetAtoms,Loop,CIFTAG_NUMBER_ATOMS_NH,n );
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+
+ F = Loop->GetString ( CIFTAG_DETAILS,n,RC );
+ if ((!RC) && F) {
+ CreateCopy ( comment,F );
+ Loop->DeleteField ( CIFTAG_DETAILS,n );
+ } else
+ CreateCopy ( comment,pstr(" ") );
+
+ n++;
+
+ return Error_NoError;
+
+ }
+
+ void HetRec::Copy ( PContainerClass Het ) {
+ seqNum = PHetRec(Het)->seqNum;
+ numHetAtoms = PHetRec(Het)->numHetAtoms;
+ strcpy ( hetID ,PHetRec(Het)->hetID );
+ strcpy ( insCode,PHetRec(Het)->insCode );
+ CreateCopy ( comment,PHetRec(Het)->comment );
+ }
+
+ void HetRec::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &seqNum );
+ f.WriteInt ( &numHetAtoms );
+ f.WriteTerLine ( hetID ,false );
+ f.WriteTerLine ( insCode,false );
+ f.CreateWrite ( comment );
+ }
+
+ void HetRec::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ f.ReadInt ( &seqNum );
+ f.ReadInt ( &numHetAtoms );
+ f.ReadTerLine ( hetID ,false );
+ f.ReadTerLine ( insCode,false );
+ f.CreateRead ( comment );
+ }
+
+ MakeStreamFunctions(HetRec)
+
+
+
+ // ===================== Chain =======================
+
+ Chain::Chain() : UDData() {
+ InitChain();
+ SetChain ( pstr("") );
+ }
+
+ Chain::Chain ( PProModel Model, const ChainID chID ) : UDData() {
+ InitChain();
+ SetChain ( chID );
+ if (Model) Model->AddChain ( this );
+ }
+
+ Chain::Chain ( io::RPStream Object ) : UDData(Object) {
+ InitChain();
+ SetChain ( pstr("") );
+ }
+
+ void Chain::InitChain() {
+ nResidues = 0;
+ resLen = 0;
+ residue = NULL;
+ model = NULL;
+ chainID[0] = char(0);
+ prevChainID[0] = char(0);
+ nWeights = 0;
+ Weight = 0.0;
+ Exclude = true;
+ }
+
+ void Chain::SetChain ( const ChainID chID ) {
+ strcpy ( chainID,chID );
+ if (chID[0]==' ') chainID[0] = char(0);
+ DBRef .SetChain ( this );
+ seqAdv.SetChain ( this );
+ seqRes.SetChain ( this );
+ modRes.SetChain ( this );
+ Het .SetChain ( this );
+ }
+
+ void Chain::SetChainID ( const ChainID chID ) {
+ strcpy ( chainID,chID );
+ if (chID[0]==' ') chainID[0] = char(0);
+ }
+
+ Chain::~Chain() {
+ FreeMemory();
+ if (model) model->_ExcludeChain ( chainID );
+ }
+
+ void Chain::FreeMemory() {
+ DeleteAllResidues();
+ if (residue) delete[] residue;
+ resLen = 0;
+ nResidues = 0;
+ residue = NULL;
+ FreeAnnotations();
+ }
+
+ void Chain::FreeAnnotations() {
+ DBRef .FreeContainer();
+ seqAdv.FreeContainer();
+ seqRes.FreeMemory ();
+ modRes.FreeContainer();
+ Het .FreeContainer();
+ }
+
+ void Chain::SetModel ( PProModel Model ) {
+ model = Model;
+ }
+
+ PManager Chain::GetCoordHierarchy() {
+ if (model) return model->GetCoordHierarchy();
+ return NULL;
+ }
+
+ void Chain::CheckInAtoms() {
+ int i;
+ if (GetCoordHierarchy())
+ for (i=0;i<nResidues;i++)
+ if (residue[i])
+ residue[i]->CheckInAtoms();
+ }
+
+ ERROR_CODE Chain::ConvertDBREF ( cpstr PDBString ) {
+ PContainerChain ContainerChain;
+ ERROR_CODE RC;
+ ContainerChain = new DBReference(this);
+ RC = ContainerChain->ConvertPDBASCII ( PDBString );
+ if (RC) {
+ delete ContainerChain;
+ return RC;
+ }
+ DBRef.AddData ( ContainerChain );
+ return Error_NoError;
+ }
+
+ ERROR_CODE Chain::ConvertSEQADV ( cpstr PDBString ) {
+ PContainerChain ContainerChain;
+ ERROR_CODE RC;
+ ContainerChain = new SeqAdv(this);
+ RC = ContainerChain->ConvertPDBASCII ( PDBString );
+ if (RC) {
+ delete ContainerChain;
+ return RC;
+ }
+ seqAdv.AddData ( ContainerChain );
+ return Error_NoError;
+ }
+
+ ERROR_CODE Chain::ConvertSEQRES ( cpstr PDBString ) {
+ return seqRes.ConvertPDBASCII ( PDBString );
+ }
+
+ ERROR_CODE Chain::ConvertMODRES ( cpstr PDBString ) {
+ PContainerChain ContainerChain;
+ ERROR_CODE RC;
+ ContainerChain = new ModRes(this);
+ RC = ContainerChain->ConvertPDBASCII ( PDBString );
+ if (RC) {
+ delete ContainerChain;
+ return RC;
+ }
+ modRes.AddData ( ContainerChain );
+ return Error_NoError;
+ }
+
+ ERROR_CODE Chain::ConvertHET ( cpstr PDBString ) {
+ PContainerChain ContainerChain;
+ ERROR_CODE RC;
+ ContainerChain = new HetRec(this);
+ RC = ContainerChain->ConvertPDBASCII ( PDBString );
+ if (RC) {
+ delete ContainerChain;
+ return RC;
+ }
+ Het.AddData ( ContainerChain );
+ return Error_NoError;
+ }
+
+
+ void Chain::PDBASCIIDump ( io::RFile f ) {
+ // this function was for test purposes and is not used
+ // for normal function of MMDB
+ DBRef .PDBASCIIDump ( f );
+ seqAdv.PDBASCIIDump ( f );
+ seqRes.PDBASCIIDump ( f );
+ modRes.PDBASCIIDump ( f );
+ Het .PDBASCIIDump ( f );
+ }
+
+ void Chain::PDBASCIIAtomDump ( io::RFile f ) {
+ int i;
+ for (i=0;i<nResidues;i++)
+ if (residue[i])
+ residue[i]->PDBASCIIAtomDump ( f );
+ }
+
+ void Chain::MakeAtomCIF ( mmcif::PData CIF ) {
+ int i;
+ for (i=0;i<nResidues;i++)
+ if (residue[i])
+ residue[i]->MakeAtomCIF ( CIF );
+ }
+
+
+ int Chain::GetNumberOfResidues() {
+ return nResidues;
+ }
+
+ PResidue Chain::GetResidue ( int resNo ) {
+ if ((0<=resNo) && (resNo<nResidues))
+ return residue[resNo];
+ else return NULL;
+ }
+
+
+ PResidue Chain::GetResidueCreate ( const ResName resName,
+ int seqNum,
+ const InsCode insCode,
+ bool Enforce ) {
+ // Returns pointer on residue, whose name, sequence number and
+ // insert code are given in resName, seqNum and insCode, respectively.
+ // If such a residue is absent in the chain, one is created at
+ // the end of the chain.
+ int i;
+
+ // check if such a residue is already in the chain
+ if (insCode[0]) {
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) {
+ if ((seqNum==residue[i]->seqNum) &&
+ (!strcmp(insCode,residue[i]->insCode))) {
+ if (!strcmp(resName,residue[i]->name))
+ return residue[i]; // it is there; just return the pointer
+ else if (!Enforce)
+ return NULL; // duplicate seqNum and insCode!
+ }
+ }
+ } else {
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) {
+ if ((seqNum==residue[i]->seqNum) &&
+ (!residue[i]->insCode[0])) {
+ if (!strcmp(resName,residue[i]->name))
+ return residue[i]; // it is there; just return the pointer
+ else if (!Enforce)
+ return NULL; // duplicate seqNum and insCode!
+ }
+ }
+ }
+
+ // expand the residue array, if necessary
+ if (nResidues>=resLen)
+ ExpandResidueArray ( 100 );
+
+ // create new residue
+ residue[nResidues] = newResidue();
+ residue[nResidues]->SetChain ( this );
+ residue[nResidues]->SetResID ( resName,seqNum,insCode );
+ residue[nResidues]->index = nResidues;
+ nResidues++;
+
+ return residue[nResidues-1];
+
+ }
+
+ void Chain::ExpandResidueArray ( int inc ) {
+ PPResidue Residue1;
+ int i;
+ resLen += inc;
+ Residue1 = new PResidue[resLen];
+ for (i=0;i<nResidues;i++)
+ Residue1[i] = residue[i];
+ if (residue) delete[] residue;
+ residue = Residue1;
+ for (i=nResidues;i<resLen;i++)
+ residue[i] = NULL;
+ }
+
+ PResidue Chain::GetResidue ( int seqNum, const InsCode insCode ) {
+ // Returns pointer on residue, whose sequence number and
+ // insert code are given in seqNum and insCode, respectively.
+ // If such a residue is absent in the chain, returns NULL.
+ int i;
+ bool isInsCode;
+ if (insCode) isInsCode = insCode[0]!=char(0);
+ else isInsCode = false;
+ if (isInsCode) {
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) {
+ if ((seqNum==residue[i]->seqNum) &&
+ (!strcmp(insCode,residue[i]->insCode)))
+ return residue[i];
+ }
+ } else {
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) {
+ if ((seqNum==residue[i]->seqNum) && (!residue[i]->insCode[0]))
+ return residue[i];
+ }
+ }
+ return NULL;
+ }
+
+ int Chain::GetResidueNo ( int seqNum, const InsCode insCode ) {
+ // GetResidueNo(..) returns the residue number in the chain's
+ // residues table. Residues are numbered as 0..nres-1 as they appear
+ // in the coordinate file.
+ // If residue is not found, the function returns -1.
+ int i;
+ bool isInsCode;
+ if (insCode) isInsCode = insCode[0]!=char(0);
+ else isInsCode = false;
+ if (isInsCode) {
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) {
+ if ((seqNum==residue[i]->seqNum) &&
+ (!strcmp(insCode,residue[i]->insCode)))
+ return i;
+ }
+ } else {
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) {
+ if ((seqNum==residue[i]->seqNum) && (!residue[i]->insCode[0]))
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ void Chain::GetResidueTable ( PPResidue & resTable,
+ int & NumberOfResidues ) {
+ resTable = residue;
+ NumberOfResidues = nResidues;
+ }
+
+ int Chain::_ExcludeResidue ( const ResName resName, int seqNum,
+ const InsCode insCode ) {
+ // ExcludeResidue(..) excludes (but does not dispose!) a residue
+ // from the chain. Returns 1 if the chain gets empty and 0 otherwise.
+ int i,k;
+
+ if (!Exclude) return 0;
+
+ // find the residue
+ k = -1;
+ for (i=0;(i<nResidues) && (k<0);i++)
+ if ((seqNum==residue[i]->seqNum) &&
+ (!strcmp(insCode,residue[i]->insCode)) &&
+ (!strcmp(resName,residue[i]->name)))
+ k = i;
+
+ if (k>=0) {
+ for (i=k+1;i<nResidues;i++) {
+ residue[i-1] = residue[i];
+ if (residue[i-1])
+ residue[i-1]->index = i-1;
+ }
+ nResidues--;
+ residue[nResidues] = NULL;
+ }
+
+ if (nResidues<=0) return 1;
+ else return 0;
+
+ }
+
+
+
+ // ------------------ Deleting residues --------------------------
+
+ int Chain::DeleteResidue ( int resNo ) {
+ if ((0<=resNo) && (resNo<nResidues)) {
+ if (residue[resNo]) {
+ Exclude = false;
+ delete residue[resNo];
+ residue[resNo] = NULL;
+ Exclude = true;
+ return 1;
+ }
+ }
+ return 0;
+ }
+
+ int Chain::DeleteResidue ( int seqNum, const InsCode insCode ) {
+ int i;
+ if (insCode[0]) {
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) {
+ if ((seqNum==residue[i]->seqNum) &&
+ (!strcmp(insCode,residue[i]->insCode))) {
+ Exclude = false;
+ delete residue[i];
+ residue[i] = NULL;
+ Exclude = true;
+ return 1;
+ }
+ }
+ } else {
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) {
+ if ((seqNum==residue[i]->seqNum) && (!residue[i]->insCode[0])) {
+ Exclude = false;
+ delete residue[i];
+ residue[i] = NULL;
+ Exclude = true;
+ return 1;
+ }
+ }
+ }
+ return 0;
+ }
+
+
+ int Chain::DeleteAllResidues() {
+ int i,k;
+ Exclude = false;
+ k = 0;
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) {
+ delete residue[i];
+ residue[i] = NULL;
+ k++;
+ }
+ nResidues = 0;
+ Exclude = true;
+ return k;
+ }
+
+
+ int Chain::DeleteSolvent() {
+ int i,k;
+ Exclude = false;
+ k = 0;
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) {
+ if (residue[i]->isSolvent()) {
+ delete residue[i];
+ residue[i] = NULL;
+ k++;
+ }
+ }
+ Exclude = true;
+ return k;
+ }
+
+
+ void Chain::TrimResidueTable() {
+ int i,j;
+ Exclude = false;
+ j = 0;
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) {
+ if (residue[i]->nAtoms>0) {
+ if (j<i) {
+ residue[j] = residue[i];
+ residue[j]->index = j;
+ residue[i] = NULL;
+ }
+ j++;
+ } else {
+ delete residue[i];
+ residue[i] = NULL;
+ }
+ }
+ nResidues = j;
+ Exclude = true;
+ }
+
+ int Chain::AddResidue ( PResidue res ) {
+ // modify both CModel::Copy methods simultaneously!
+ //
+ // Copy(PCModel,PPAtom,int&) copies atoms into array 'atom'
+ // starting from position atom_index. 'atom' should be able to
+ // accept all new atoms - no checks on the length of 'atom'
+ // is being made. This function should not be used in applications.
+ return InsResidue ( res,nResidues );
+ }
+
+ /*
+ PCmmdbRoot mmdbRoot;
+ PChain chain1;
+ int i;
+
+ for (i=0;i<nResidues;i++)
+ if (residue[i]==res) return -i; // this residue is already there
+
+ if (res) {
+
+ mmdbRoot = PCmmdbRoot(GetCoordHierarchy());
+
+ // get space for new residue
+ if (nResidues>=resLen)
+ ExpandResidueArray ( 100 );
+
+ if (res->GetCoordHierarchy()) {
+ residue[nResidues] = newResidue();
+ residue[nResidues]->SetChain ( this );
+ residue[nResidues]->SetResID ( res->name,res->seqNum,res->insCode );
+ if (mmdbRoot) {
+ // get space for new atoms
+ mmdbRoot->AddAtomArray ( res->GetNumberOfAtoms(true) );
+ residue[nResidues]->Copy ( res,mmdbRoot->Atom,mmdbRoot->nAtoms );
+ } else {
+ for (i=0;i<res->nAtoms;i++)
+ residue[nResidues]->AddAtom ( res->atom[i] );
+ }
+ } else {
+ residue[nResidues] = res;
+ chain1 = res->GetChain();
+ if (chain1)
+ for (i=0;i<chain1->nResidues;i++)
+ if (chain1->residue[i]==res) {
+ chain1->residue[i] = NULL;
+ break;
+ }
+ residue[nResidues]->SetChain ( this );
+ if (mmdbRoot)
+ residue[nResidues]->CheckInAtoms();
+ }
+ nResidues++;
+
+ }
+
+ return nResidues;
+
+ }
+ */
+
+ int Chain::InsResidue ( PResidue res, int seqNum,
+ const InsCode insCode ) {
+ return InsResidue ( res,GetResidueNo(seqNum,insCode) );
+ }
+
+ int Chain::InsResidue ( PResidue res, int pos ) {
+ // Inserts residue res onto position pos of the chain,
+ // pos=0..nResidues-1 . Residues pos..nResidues-1 are
+ // shifted up the chain.
+ // The function places new atoms on the top of atom
+ // index. It is advisable to call
+ // CmmdbRoot::PDBCleanup ( PDBCLEAN_INDEX ) after all
+ // insertions are done.
+ PRoot mmdbRoot;
+ PChain chain1;
+ int i,pp;
+
+ pp = IMax ( 0,IMin(nResidues,pos) );
+
+ for (i=0;i<nResidues;i++)
+ if (residue[i]==res) return -i; // this residue is already there
+
+ if (res) {
+
+ mmdbRoot = PRoot(GetCoordHierarchy());
+
+ // get space for new residue
+ if (nResidues>=resLen)
+ ExpandResidueArray ( 100 );
+
+ // shift residues to the end of the chain as necessary
+ for (i=nResidues;i>pp;i--)
+ residue[i] = residue[i-1];
+
+ // insert the new residue
+ if (res->GetCoordHierarchy()) {
+ residue[pp] = newResidue();
+ residue[pp]->SetChain ( this );
+ residue[pp]->SetResID ( res->name,res->seqNum,res->insCode );
+ if (mmdbRoot) {
+ // get space for new atoms
+ mmdbRoot->AddAtomArray ( res->GetNumberOfAtoms(true) );
+ residue[pp]->_copy ( res,mmdbRoot->atom,mmdbRoot->nAtoms );
+ } else {
+ for (i=0;i<res->nAtoms;i++)
+ residue[pp]->AddAtom ( res->atom[i] );
+ }
+ } else {
+ residue[pp] = res;
+ chain1 = res->GetChain();
+ if (chain1)
+ for (i=0;i<chain1->nResidues;i++)
+ if (chain1->residue[i]==res) {
+ chain1->residue[i] = NULL;
+ break;
+ }
+ residue[pp]->SetChain ( this );
+ if (mmdbRoot)
+ residue[pp]->CheckInAtoms();
+ }
+ nResidues++;
+
+ }
+
+ return nResidues;
+
+ }
+
+
+ // -------------------- Extracting atoms -----------------------
+
+ int Chain::GetNumberOfAtoms ( bool countTers ) {
+ int i,na;
+ na = 0;
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) na += residue[i]->GetNumberOfAtoms ( countTers );
+ return na;
+ }
+
+ int Chain::GetNumberOfAtoms ( int seqNo, const InsCode insCode ) {
+ PResidue res;
+ res = GetResidue ( seqNo,insCode );
+ if (res) return res->nAtoms;
+ return 0;
+ }
+
+ int Chain::GetNumberOfAtoms ( int resNo ) {
+ if ((0<=resNo) && (resNo<nResidues)) {
+ if (residue[resNo]) return residue[resNo]->nAtoms;
+ }
+ return 0;
+ }
+
+ PAtom Chain::GetAtom ( int seqNo,
+ const InsCode insCode,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc ) {
+ PResidue res;
+ res = GetResidue ( seqNo,insCode );
+ if (res) return res->GetAtom ( aname,elmnt,aloc );
+ return NULL;
+ }
+
+ PAtom Chain::GetAtom ( int seqNo, const InsCode insCode,
+ int atomNo ) {
+ PResidue res;
+ res = GetResidue ( seqNo,insCode );
+ if (res) {
+ if ((0<=atomNo) && (atomNo<res->nAtoms))
+ return res->atom[atomNo];
+ }
+ return NULL;
+ }
+
+ PAtom Chain::GetAtom ( int resNo,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc ) {
+ if ((0<=resNo) && (resNo<nResidues)) {
+ if (residue[resNo])
+ return residue[resNo]->GetAtom ( aname,elmnt,aloc );
+ }
+ return NULL;
+ }
+
+ PAtom Chain::GetAtom ( int resNo, int atomNo ) {
+ PResidue res;
+ if ((0<=resNo) && (resNo<nResidues)) {
+ res = residue[resNo];
+ if (res) {
+ if ((0<=atomNo) && (atomNo<res->nAtoms))
+ return res->atom[atomNo];
+ }
+ }
+ return NULL;
+ }
+
+ void Chain::GetAtomTable ( int seqNo, const InsCode insCode,
+ PPAtom & atomTable, int & NumberOfAtoms ) {
+ PResidue res;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ res = GetResidue ( seqNo,insCode );
+ if (res) {
+ atomTable = res->atom;
+ NumberOfAtoms = res->nAtoms;
+ }
+ }
+
+ void Chain::GetAtomTable ( int resNo, PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ if ((0<=resNo) && (resNo<nResidues)) {
+ res = residue[resNo];
+ if (res) {
+ atomTable = res->atom;
+ NumberOfAtoms = res->nAtoms;
+ }
+ }
+ }
+
+
+ void Chain::GetAtomTable1 ( int seqNo, const InsCode insCode,
+ PPAtom & atomTable, int & NumberOfAtoms ) {
+ PResidue res;
+ res = GetResidue ( seqNo,insCode );
+ if (res)
+ res->GetAtomTable1 ( atomTable,NumberOfAtoms );
+ else {
+ if (atomTable) delete[] atomTable;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ }
+ }
+
+ void Chain::GetAtomTable1 ( int resNo, PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ if ((0<=resNo) && (resNo<nResidues))
+ res = residue[resNo];
+ else res = NULL;
+ if (res)
+ res->GetAtomTable1 ( atomTable,NumberOfAtoms );
+ else {
+ if (atomTable) delete[] atomTable;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ }
+ }
+
+ int Chain::DeleteAtom ( int seqNo,
+ const InsCode insCode,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc ) {
+ PResidue res;
+ res = GetResidue ( seqNo,insCode );
+ if (res) return res->DeleteAtom ( aname,elmnt,aloc );
+ return 0;
+ }
+
+ int Chain::DeleteAtom ( int seqNo, const InsCode insCode,
+ int atomNo ) {
+ PResidue res;
+ res = GetResidue ( seqNo,insCode );
+ if (res) return res->DeleteAtom ( atomNo );
+ return 0;
+ }
+
+ int Chain::DeleteAtom ( int resNo,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc ) {
+ if ((0<=resNo) && (resNo<nResidues)) {
+ if (residue[resNo])
+ return residue[resNo]->DeleteAtom ( aname,elmnt,aloc );
+ }
+ return 0;
+ }
+
+ int Chain::DeleteAtom ( int resNo, int atomNo ) {
+ if ((0<=resNo) && (resNo<nResidues)) {
+ if (residue[resNo])
+ return residue[resNo]->DeleteAtom ( atomNo );
+ }
+ return 0;
+ }
+
+
+ int Chain::DeleteAllAtoms ( int seqNo, const InsCode insCode ) {
+ PResidue res;
+ res = GetResidue ( seqNo,insCode );
+ if (res) return res->DeleteAllAtoms();
+ return 0;
+ }
+
+ int Chain::DeleteAllAtoms ( int resNo ) {
+ if ((0<=resNo) && (resNo<nResidues)) {
+ if (residue[resNo])
+ return residue[resNo]->DeleteAllAtoms();
+ }
+ return 0;
+ }
+
+ int Chain::DeleteAllAtoms() {
+ int i,k;
+ k = 0;
+ for (i=0;i<nResidues;i++)
+ if (residue[i])
+ k += residue[i]->DeleteAllAtoms();
+ return k;
+ }
+
+ int Chain::DeleteAltLocs() {
+ // This function leaves only alternative location with maximal
+ // occupancy, if those are equal or unspecified, the one with
+ // "least" alternative location indicator.
+ // The function returns the number of deleted. All tables remain
+ // untrimmed, so that explicit trimming or calling FinishStructEdit()
+ // is required.
+ int i,n;
+
+ n = 0;
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) n += residue[i]->DeleteAltLocs();
+
+ return n;
+
+ }
+
+
+ int Chain::AddAtom ( int seqNo, const InsCode insCode,
+ PAtom atom ) {
+ PResidue res;
+ res = GetResidue ( seqNo,insCode );
+ if (res) return res->AddAtom ( atom );
+ return 0;
+ }
+
+ int Chain::AddAtom ( int resNo, PAtom atom ) {
+ if ((0<=resNo) && (resNo<nResidues)) {
+ if (residue[resNo])
+ return residue[resNo]->AddAtom ( atom );
+ }
+ return 0;
+ }
+
+
+ void Chain::Copy ( PChain chain ) {
+ // modify both Chain::_copy and Chain::Copy methods simultaneously!
+ int i;
+
+ FreeMemory();
+
+ if (chain) {
+
+ CopyAnnotations ( chain );
+
+ nResidues = chain->nResidues;
+ resLen = nResidues;
+ if (nResidues>0) {
+ residue = new PResidue[nResidues];
+ for (i=0;i<nResidues;i++) {
+ residue[i] = newResidue();
+ residue[i]->SetChain ( this );
+ residue[i]->Copy ( chain->residue[i] );
+ }
+ }
+
+ }
+
+ }
+
+ void Chain::CopyAnnotations ( PChain chain ) {
+ if (chain) {
+ strcpy ( chainID ,chain->chainID );
+ strcpy ( prevChainID,chain->prevChainID );
+ DBRef .Copy ( &(chain->DBRef) );
+ seqAdv.Copy ( &(chain->seqAdv) ); // SEQADV records
+ seqRes.Copy ( &(chain->seqRes) ); // SEQRES data
+ modRes.Copy ( &(chain->modRes) ); // MODRES records
+ Het .Copy ( &(chain->Het) ); // HET records
+ }
+ }
+
+
+ void Chain::_copy ( PChain chain ) {
+ // modify both Chain::_copy and Chain::Copy methods simultaneously!
+ int i;
+
+ FreeMemory();
+
+ strcpy ( chainID ,chain->chainID );
+ strcpy ( prevChainID,chain->prevChainID );
+
+ DBRef .Copy ( &(chain->DBRef) );
+ seqAdv.Copy ( &(chain->seqAdv) ); // SEQADV records
+ seqRes.Copy ( &(chain->seqRes) ); // SEQRES data
+ modRes.Copy ( &(chain->modRes) ); // MODRES records
+ Het .Copy ( &(chain->Het) ); // HET records
+
+ nResidues = chain->nResidues;
+ resLen = nResidues;
+ if (nResidues>0) {
+ residue = new PResidue[nResidues];
+ for (i=0;i<nResidues;i++) {
+ residue[i] = newResidue();
+ residue[i]->SetChain ( this );
+ residue[i]->_copy ( chain->residue[i] );
+ }
+ }
+
+ }
+
+ void Chain::_copy ( PChain chain, PPAtom atom, int & atom_index ) {
+ // modify both Chain::_copy and Chain::Copy methods simultaneously!
+ int i;
+
+ FreeMemory();
+
+ strcpy ( chainID ,chain->chainID );
+ strcpy ( prevChainID,chain->prevChainID );
+
+ DBRef .Copy ( &(chain->DBRef) );
+ seqAdv.Copy ( &(chain->seqAdv) ); // SEQADV records
+ seqRes.Copy ( &(chain->seqRes) ); // SEQRES data
+ modRes.Copy ( &(chain->modRes) ); // MODRES records
+ Het .Copy ( &(chain->Het) ); // HET records
+
+ nResidues = chain->nResidues;
+ resLen = nResidues;
+ if (nResidues>0) {
+ residue = new PResidue[nResidues];
+ for (i=0;i<nResidues;i++)
+ if (chain->residue[i]) {
+ residue[i] = newResidue();
+ residue[i]->SetChain ( this );
+ residue[i]->_copy ( chain->residue[i],atom,atom_index );
+ } else
+ residue[i] = NULL;
+ }
+
+ }
+
+ /*
+ void Chain::Duplicate ( PChain Chain ) {
+ int i;
+
+ FreeMemory();
+
+ strcpy ( chainID ,chain->chainID );
+ strcpy ( prevChainID,chain->prevChainID );
+
+ DBReference.Copy ( &(chain->DBReference) );
+ SeqAdv .Copy ( &(chain->SeqAdv) ); // SEQADV records
+ SeqRes .Copy ( &(chain->SeqRes) ); // SEQRES data
+ ModRes .Copy ( &(chain->ModRes) ); // MODRES records
+ Het .Copy ( &(chain->Het) ); // HET records
+
+ nResidues = chain->nResidues;
+ resLen = nResidues;
+ if (nResidues>0) {
+ Residue = new PResidue[nResidues];
+ for (i=0;i<nResidues;i++) {
+ residue[i] = newResidue();
+ residue[i]->SetChain ( this );
+ residue[i]->Duplicate ( chain->residue[i] );
+ }
+ }
+
+ }
+ */
+
+ cpstr Chain::GetEntryID() {
+ if (model) return model->GetEntryID();
+ else return pstr("");
+ }
+
+ void Chain::SetEntryID ( const IDCode idCode ) {
+ if (model) model->SetEntryID ( idCode );
+ }
+
+ int Chain::GetModelNum() {
+ if (model) return model->GetSerNum();
+ return 0;
+ }
+
+ cpstr Chain::GetChainID ( pstr ChID ) {
+ ChID[0] = char(0);
+ if (model)
+ sprintf ( ChID,"/%i/",model->GetSerNum() );
+ else strcpy ( ChID,"/-/" );
+ strcat ( ChID,chainID );
+ return ChID;
+ }
+
+
+ void Chain::GetAtomStatistics ( RAtomStat AS ) {
+ AS.Init();
+ CalAtomStatistics ( AS );
+ AS.Finish();
+ }
+
+ void Chain::CalAtomStatistics ( RAtomStat AS ) {
+ int i;
+ for (i=0;i<nResidues;i++)
+ if (residue[i])
+ residue[i]->CalAtomStatistics ( AS );
+ }
+
+ void Chain::ApplyTransform ( mat44 & TMatrix ) {
+ // transforms all coordinates by multiplying with matrix TMatrix
+ int i;
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) residue[i]->ApplyTransform ( TMatrix );
+ }
+
+ bool Chain::isSolventChain() {
+ // returns true if chain contains only solvent molecules
+ bool B,P;
+ int i;
+ B = true;
+ P = false;
+ for (i=0;(i<nResidues) && B;i++)
+ if (residue[i]) {
+ P = true;
+ B = residue[i]->isSolvent();
+ }
+ return (B && P);
+ }
+
+ bool Chain::isInSelection ( int selHnd ) {
+ PRoot mmdbRoot = (PRoot)GetCoordHierarchy();
+ PMask mask;
+ if (mmdbRoot) {
+ mask = mmdbRoot->GetSelMask ( selHnd );
+ if (mask) return CheckMask ( mask );
+ }
+ return false;
+ }
+
+ bool Chain::isAminoacidChain() {
+ // returns true if chain contains at least one aminoacid residue
+ bool B,P;
+ int i;
+ B = false;
+ P = false;
+ for (i=0;(i<nResidues) && (!B);i++)
+ if (residue[i]) {
+ P = true;
+ B = residue[i]->isAminoacid();
+ }
+ return (B && P);
+ }
+
+ bool Chain::isNucleotideChain() {
+ // returns true if chain contains at least one nucleotide residue
+ bool B,P;
+ int i;
+ B = false;
+ P = false;
+ for (i=0;(i<nResidues) && (!B);i++)
+ if (residue[i]) {
+ P = true;
+ B = residue[i]->isNucleotide();
+ }
+ return (B && P);
+ }
+
+ int Chain::CheckID ( const ChainID chID ) {
+ if (chID) {
+ if (!strcmp(chID,chainID)) return 1;
+ }
+ return 0;
+ }
+
+ int Chain::CheckIDS ( cpstr CID ) {
+ ChainID chn;
+ InsCode inscode;
+ ResName resname;
+ AtomName atm;
+ Element elm;
+ AltLoc aloc;
+ int mdl,sn,rc;
+
+ rc = ParseAtomPath ( CID,mdl,chn,sn,inscode,resname,
+ atm,elm,aloc,NULL );
+ if (rc>=0) {
+ if (!strcmp(chn,chainID)) return 1;
+ }
+ return 0;
+
+ }
+
+ int Chain::GetNumberOfDBRefs() {
+ return DBRef.Length();
+ }
+
+ PDBReference Chain::GetDBRef ( int dbRefNo ) {
+ return (PDBReference)DBRef.GetContainerClass ( dbRefNo );
+ }
+
+
+ void Chain::MaskAtoms ( PMask mask ) {
+ int i;
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) residue[i]->MaskAtoms ( mask );
+ }
+
+ void Chain::MaskResidues ( PMask mask ) {
+ int i;
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) residue[i]->SetMask ( mask );
+ }
+
+ void Chain::UnmaskAtoms ( PMask mask ) {
+ int i;
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) residue[i]->UnmaskAtoms ( mask );
+ }
+
+ void Chain::UnmaskResidues ( PMask mask ) {
+ int i;
+ for (i=0;i<nResidues;i++)
+ if (residue[i]) residue[i]->RemoveMask ( mask );
+ }
+
+
+
+
+ // ------- user-defined data handlers
+
+ int Chain::PutUDData ( int UDDhandle, int iudd ) {
+ if (UDDhandle & UDRF_CHAIN)
+ return UDData::putUDData ( UDDhandle,iudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Chain::PutUDData ( int UDDhandle, realtype rudd ) {
+ if (UDDhandle & UDRF_CHAIN)
+ return UDData::putUDData ( UDDhandle,rudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Chain::PutUDData ( int UDDhandle, cpstr sudd ) {
+ if (UDDhandle & UDRF_CHAIN)
+ return UDData::putUDData ( UDDhandle,sudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Chain::GetUDData ( int UDDhandle, int & iudd ) {
+ if (UDDhandle & UDRF_CHAIN)
+ return UDData::getUDData ( UDDhandle,iudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Chain::GetUDData ( int UDDhandle, realtype & rudd ) {
+ if (UDDhandle & UDRF_CHAIN)
+ return UDData::getUDData ( UDDhandle,rudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Chain::GetUDData ( int UDDhandle, pstr sudd, int maxLen ) {
+ if (UDDhandle & UDRF_CHAIN)
+ return UDData::getUDData ( UDDhandle,sudd,maxLen );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Chain::GetUDData ( int UDDhandle, pstr & sudd ) {
+ if (UDDhandle & UDRF_CHAIN)
+ return UDData::getUDData ( UDDhandle,sudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+
+ // -------------------------------------------------------------------
+
+ DefineClass(SortResidues)
+
+ class QSortResidues : public QuickSort {
+ public :
+ QSortResidues() : QuickSort() {}
+ int Compare ( int i, int j );
+ void Swap ( int i, int j );
+ void Sort ( PPResidue res, int nresidues );
+ };
+
+ int QSortResidues::Compare ( int i, int j ) {
+ int diff;
+ diff = ((PPResidue)data)[i]->seqNum - ((PPResidue)data)[j]->seqNum;
+ if (diff==0)
+ diff = strcmp( (PPResidue(data))[i]->insCode,
+ (PPResidue(data))[j]->insCode );
+ if (diff>0) return 1;
+ if (diff<0) return -1;
+ return 0;
+ }
+
+ void QSortResidues::Swap ( int i, int j ) {
+ PResidue res;
+ res = ((PPResidue)data)[i];
+ ((PPResidue)data)[i] = ((PPResidue)data)[j];
+ ((PPResidue)data)[j] = res;
+ }
+
+ void QSortResidues::Sort ( PPResidue res, int nresidues ) {
+ QuickSort::Sort ( &(res[0]),nresidues );
+ }
+
+ void Chain::SortResidues() {
+ QSortResidues SR;
+ TrimResidueTable();
+ SR.Sort ( residue,nResidues );
+ }
+
+ int Chain::GetNofModResidues() {
+ return modRes.Length();
+ }
+
+ PModRes Chain::GetModResidue ( int modResNo ) {
+ return PModRes(modRes.GetContainerClass(modResNo));
+ }
+
+ void Chain::write ( io::RFile f ) {
+ int i;
+ byte Version=1;
+
+ f.WriteByte ( &Version );
+
+ UDData::write ( f );
+
+ f.WriteTerLine ( chainID ,false );
+ f.WriteTerLine ( prevChainID,false );
+
+ DBRef .write ( f ); // Database reference
+ seqAdv.write ( f ); // SEQADV records
+ seqRes.write ( f ); // SEQRES data
+ modRes.write ( f ); // MODRES records
+ Het .write ( f ); // HET records
+
+ f.WriteInt ( &nResidues );
+ for (i=0;i<nResidues;i++)
+ residue[i]->write ( f );
+
+ }
+
+ void Chain::read ( io::RFile f ) {
+ // The Atom array in CmmdbRoot must be already read
+ // prior to calling this function!
+ int i;
+ byte Version;
+
+ FreeMemory();
+
+ f.ReadByte ( &Version );
+
+ UDData::read ( f );
+
+ f.ReadTerLine ( chainID ,false );
+ f.ReadTerLine ( prevChainID,false );
+
+ DBRef .read ( f ); // Database reference
+ seqAdv.read ( f ); // SEQADV records
+ seqRes.read ( f ); // SEQRES data
+ modRes.read ( f ); // MODRES records
+ Het .read ( f ); // HET records
+
+ SetChain ( chainID );
+
+ f.ReadInt ( &nResidues );
+ resLen = nResidues;
+ if (nResidues>0) {
+ residue = new PResidue[nResidues];
+ for (i=0;i<nResidues;i++) {
+ residue[i] = newResidue();
+ residue[i]->SetChain ( this );
+ residue[i]->read ( f );
+ }
+ }
+
+ }
+
+
+ MakeFactoryFunctions(Chain)
+
+} // namespace mmdb
+
+
+// ===================================================================
+
+ /*
+void TestChain() {
+// reads from 'in.chain', writes into
+// 'out.chain' and 'abin.chain'
+CFile f;
+char S[81];
+PChain Chain;
+
+ Chain = newChain();
+
+ f.assign ( "in.chain",true );
+ if (f.reset()) {
+ while (!f.FileEnd()) {
+ f.ReadLine ( S,sizeof(S) );
+ chain->ConvertPDBString ( S );
+ }
+ f.shut();
+ } else {
+ printf ( " Can't open input file 'in.chain' \n" );
+ delete Chain;
+ return;
+ }
+
+ f.assign ( "out.chain",true );
+ if (f.rewrite()) {
+ chain->PDBASCIIDump ( f );
+ f.shut();
+ } else {
+ printf ( " Can't open output file 'out.chain' \n" );
+ delete Chain;
+ return;
+ }
+
+
+ f.assign ( "mmdb.chain.bin",false );
+ if (f.rewrite()) {
+ chain->write ( f );
+ f.shut();
+ } else {
+ printf ( " Can't open binary chain file for writing.\n" );
+ delete Chain;
+ return;
+ }
+
+ delete Chain;
+ printf ( " Chain deleted.\n" );
+
+ Chain = newChain();
+ if (f.reset()) {
+ chain->read ( f );
+ f.shut();
+ } else {
+ printf ( " Can't open binary chain file for reading.\n" );
+ delete Chain;
+ return;
+ }
+
+ f.assign ( "abin.chain",true );
+ if (f.rewrite()) {
+ chain->PDBASCIIDump ( f );
+ f.shut();
+ } else
+ printf ( " Can't open output file 'abin.chain' \n" );
+
+ delete Chain;
+
+}
+ */
diff --git a/mmdb2/mmdb_chain.h b/mmdb2/mmdb_chain.h
new file mode 100644
index 0000000..db46f0e
--- /dev/null
+++ b/mmdb2/mmdb_chain.h
@@ -0,0 +1,662 @@
+// $Id: mmdb_chain.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_Chain <interface>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::ProModel ( a virtue of Model )
+// ~~~~~~~~~ mmdb::DBReference ( DBREF records )
+// mmdb::ChainContainer ( container of in-chain classes )
+// mmdb::ContainerChain ( chain containered class template)
+// mmdb::SeqAdv ( SEQADV records )
+// mmdb::SeqRes ( SEQRES records )
+// mmdb::ModRes ( MODRES records )
+// mmdb::HetRec ( HET records )
+// mmdb::Chain ( chain class )
+//
+// Copyright (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_Chain__
+#define __MMDB_Chain__
+
+#include "mmdb_io_stream.h"
+#include "mmdb_utils.h"
+#include "mmdb_atom.h"
+#include "mmdb_defs.h"
+
+namespace mmdb {
+
+ // ==================== ProModel ======================
+
+ // This class is a virtue needed only for defining certain
+ // functions of Model, which are used by Chain and
+ // Residue
+
+ DefineClass(ProModel);
+ DefineStreamFunctions(ProModel);
+
+ DefineClass(Manager);
+
+ class ProModel : public UDData {
+
+ friend class Chain;
+
+ public :
+
+ ProModel () : UDData () {}
+ ProModel ( io::RPStream Object ) : UDData ( Object ) {}
+ ~ProModel () {}
+
+ virtual cpstr GetEntryID () { return ""; }
+ virtual void SetEntryID ( const IDCode ) {}
+
+ virtual int AddChain ( PChain ) { return 0; }
+
+ // returns pointer to Root
+ virtual PManager GetCoordHierarchy() { return NULL; }
+
+ // GetNumberOfModels() returns TOTAL number of models
+ virtual int GetNumberOfModels() { return 0; }
+
+ // GetNumberOfAllAtoms() returns TOTAL number of atoms in
+ // all models
+ virtual int GetNumberOfAllAtoms() { return 0; }
+
+ // returns pointer to the general Atom array
+ virtual PPAtom GetAllAtoms() { return NULL; }
+
+ virtual int GetSerNum () { return 0; }
+
+ virtual void ExpandAtomArray ( int ) {}
+ virtual void AddAtomArray ( int ) {}
+
+ protected :
+
+ virtual int _ExcludeChain ( const ChainID ) { return 0; }
+
+ };
+
+
+
+ // ==================== ChainContainer ======================
+
+ DefineClass(ChainContainer);
+ DefineStreamFunctions(ChainContainer);
+
+ class ChainContainer : public ClassContainer {
+
+ public :
+
+ ChainContainer () : ClassContainer () {}
+ ChainContainer ( io::RPStream Object )
+ : ClassContainer ( Object ) {}
+ ~ChainContainer () {}
+
+ PContainerClass MakeContainerClass ( int ClassID );
+
+ void SetChain ( PChain Chain_Owner ); // must be set before using
+ // the Container
+
+ // special functions used in Model::GetCIF(..)
+ cpstr Get1stChainID ();
+ void MoveByChainID ( const ChainID chainID,
+ PChainContainer chainContainer );
+
+ protected :
+ PChain chain;
+
+ };
+
+
+ // ================== ContainerChain =====================
+
+ DefineClass(ContainerChain);
+ DefineStreamFunctions(ContainerChain);
+
+ class ContainerChain : public ContainerClass {
+
+ friend class ChainContainer;
+
+ public :
+
+ ContainerChain ();
+ ContainerChain ( PChain Chain_Owner );
+ ContainerChain ( io::RPStream Object ) : ContainerClass(Object) {}
+
+ void SetChain ( PChain Chain_Owner );
+
+ protected :
+ PChain chain;
+ ChainID chainID; // just a copy of Chain->chainID
+
+ };
+
+
+ // ================== DBReference ========================
+
+ DefineClass(DBReference);
+ DefineStreamFunctions(DBReference);
+
+ class DBReference : public ContainerChain {
+
+ public :
+
+ int seqBeg; // initial seq num of the PDB seq-ce segment
+ InsCode insBeg; // initial ins code of the PDB seq-ce segm-t
+ int seqEnd; // ending seq number of the PDB seq-ce segm-t
+ InsCode insEnd; // ending ins code of the PDB seq-ce segment
+ DBName database; // sequence database name
+ DBAcCode dbAccession; // sequence database accession code
+ DBIdCode dbIdCode; // sequence database identification code
+ int dbseqBeg; // initial seq number of the database segment
+ InsCode dbinsBeg; // ins code of initial residue of the segment
+ int dbseqEnd; // ending seq number of the database segment
+ InsCode dbinsEnd; // ins code of the ending residue of the seg-t
+
+ DBReference ();
+ DBReference ( PChain Chain_Owner );
+ DBReference ( PChain Chain_Owner, cpstr S );
+ DBReference ( io::RPStream Object );
+ ~DBReference();
+
+ void PDBASCIIDump ( pstr S, int N );
+ void MakeCIF ( mmcif::PData CIF, int N );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ ERROR_CODE GetCIF ( mmcif::PData CIF, int & n );
+ CLASS_ID GetClassID () { return ClassID_DBReference; }
+
+ void Copy ( PContainerClass DBRef );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitDBReference();
+
+ };
+
+
+ // ==================== SeqAdv ===========================
+
+ DefineClass(SeqAdv);
+ DefineStreamFunctions(SeqAdv);
+
+ class SeqAdv : public ContainerChain {
+
+ public :
+
+ ResName resName; // residue name in conflict
+ int seqNum; // residue sequence number
+ InsCode insCode; // residue insertion code
+ DBName database; // sequence database name
+ DBAcCode dbAccession; // sequence database accession code
+ ResName dbRes; // sequence database residue name
+ int dbSeq; // sequence database sequence number
+ pstr conflict; // conflict comment
+
+ SeqAdv ();
+ SeqAdv ( PChain Chain_Owner );
+ SeqAdv ( PChain Chain_Owner, cpstr S );
+ SeqAdv ( io::RPStream Object );
+ ~SeqAdv();
+
+ void PDBASCIIDump ( pstr S, int N );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ void MakeCIF ( mmcif::PData CIF, int N );
+ ERROR_CODE GetCIF ( mmcif::PData CIF, int & n );
+ CLASS_ID GetClassID () { return ClassID_SeqAdv; }
+
+ void Copy ( PContainerClass seqAdv );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitSeqAdv();
+
+ };
+
+
+ // ================== SeqRes ========================
+
+ DefineClass(SeqRes);
+ DefineStreamFunctions(SeqRes);
+
+ class SeqRes : public io::Stream {
+
+ friend class Model;
+ friend class Chain;
+
+ public :
+
+ int numRes; // number of residues in the chain
+ PResName resName; // residue names
+
+ SeqRes ();
+ SeqRes ( io::RPStream Object );
+ ~SeqRes();
+
+ void SetChain ( PChain Chain_Owner );
+ void PDBASCIIDump ( io::RFile f );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+
+ void MakeCIF ( mmcif::PData CIF );
+ ERROR_CODE GetCIF ( mmcif::PData CIF );
+
+ void Copy ( PSeqRes seqRes );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+ PChain chain;
+ ChainID chainID;
+ int serNum;
+
+ void InitSeqRes();
+ void FreeMemory();
+
+ };
+
+
+ // ================== ModRes ========================
+
+ DefineClass(ModRes);
+ DefineStreamFunctions(ModRes);
+
+ class ModRes : public ContainerChain {
+
+ public :
+
+ ResName resName; // residue name used
+ int seqNum; // residue sequence number
+ InsCode insCode; // residue insertion code
+ ResName stdRes; // standard residue name
+ pstr comment; // description of the residue modification
+
+ ModRes ();
+ ModRes ( PChain Chain_Owner );
+ ModRes ( PChain Chain_Owner, cpstr S );
+ ModRes ( io::RPStream Object );
+ ~ModRes();
+
+ void PDBASCIIDump ( pstr S, int N );
+ void MakeCIF ( mmcif::PData CIF, int N );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ ERROR_CODE GetCIF ( mmcif::PData CIF, int & n );
+ CLASS_ID GetClassID () { return ClassID_ModRes; }
+
+ void Copy ( PContainerClass modRes );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitModRes();
+
+ };
+
+
+ // ================== HetRec ===========================
+
+ DefineClass(HetRec);
+ DefineStreamFunctions(HetRec);
+
+ class HetRec : public ContainerChain {
+
+ public :
+
+ ResName hetID; // Het identifier (right-justified)
+ int seqNum; // sequence number
+ InsCode insCode; // insertion code
+ int numHetAtoms; // number of HETATM records for the
+ // group present in the entry
+ pstr comment; // text describing Het group
+
+ HetRec ();
+ HetRec ( PChain Chain_Owner );
+ HetRec ( PChain Chain_Owner, cpstr S );
+ HetRec ( io::RPStream Object );
+ ~HetRec();
+
+ void PDBASCIIDump ( pstr S, int N );
+ void MakeCIF ( mmcif::PData CIF, int N );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ ERROR_CODE GetCIF ( mmcif::PData CIF, int & n );
+ CLASS_ID GetClassID () { return ClassID_Het; }
+
+ void Copy ( PContainerClass Het );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitHetRec();
+
+ };
+
+
+ // ================= Chain =======================
+
+ DefineFactoryFunctions(Chain);
+
+ class Chain : public UDData {
+
+ friend class DBReference;
+ friend class SeqAdv;
+ friend class SeqRes;
+ friend class ModRes;
+ friend class HetRec;
+ friend class Residue;
+ friend class Atom;
+ friend class Model;
+ friend class Root;
+ friend class SelManager;
+ friend class BondManager;
+ friend class CoorManager;
+ friend class Manager;
+
+ public :
+
+ ChainContainer DBRef; // database reference
+ ChainContainer seqAdv; // SEQADV records
+ SeqRes seqRes; // Sequence residues, SEQRES records
+ ChainContainer modRes; // modification descriptions
+ ChainContainer Het; // non-standard residues descriptions
+
+ Chain (); // SetModel() MUST be used after this constructor!
+ Chain ( PProModel model, const ChainID chID );
+ Chain ( io::RPStream Object );
+ ~Chain();
+
+ void FreeAnnotations();
+
+ void SetModel ( PProModel model );
+ void SetChain ( const ChainID chID );
+
+ PManager GetCoordHierarchy(); // PRoot
+
+ // ConvertXXXXX(..) functions do not check for record name
+ // and assume that PDBString is at least 81 symbols long
+ // (including the terminating null).
+ ERROR_CODE ConvertDBREF ( cpstr PDBString );
+ ERROR_CODE ConvertSEQADV ( cpstr PDBString );
+ ERROR_CODE ConvertSEQRES ( cpstr PDBString );
+ ERROR_CODE ConvertMODRES ( cpstr PDBString );
+ ERROR_CODE ConvertHET ( cpstr PDBString );
+
+ // This function should be used for testing purposes only.
+ // A full PDB ASCII dump for all models and chains involved
+ // is done by Root class.
+ void PDBASCIIDump ( io::RFile f );
+
+ void PDBASCIIAtomDump ( io::RFile f );
+ void MakeAtomCIF ( mmcif::PData CIF );
+
+
+ // ----------------- Extracting residues -------------------------
+
+ int GetNumberOfResidues(); // returns number of res-s in the chain
+ PResidue GetResidue ( int resNo ); // returns resNo-th residue
+ // in the chain;
+ // 0<=resNo<nResidues
+
+ // GetResidue(..) returns pointer on residue, whose sequence
+ // number and insert code are given in seqNum and insCode,
+ // respectively. If such a residue is absent in the chain,
+ // returns NULL.
+ PResidue GetResidue ( int seqNum, const InsCode insCode );
+
+ // GetResidueNo(..) returns the residue number in the chain's
+ // residues table. Residues are numbered as 0..nres-1 as they
+ // appear in the coordinate file.
+ // If residue is not found, the function returns -1.
+ int GetResidueNo ( int seqNum, const InsCode insCode );
+
+ void GetResidueTable ( PPResidue & resTable,
+ int & NumberOfResidues );
+
+ // GetResidueCreate(..) returns pointer on residue, whose name,
+ // sequence number and insertion code are given by resName, seqNum
+ // and insCode, respectively. If such a residue is absent in the
+ // chain, one is created at the end of chain.
+ // If a residue with given sequence number and insertion code
+ // is present in the chain but has a different name, the function
+ // returns NULL unless Enforce is set True. In the latter case,
+ // a new residue is still created at the end of chain, but there
+ // is no guarantee that any function operating on the sequence
+ // number and insertion code will work properly.
+ PResidue GetResidueCreate ( const ResName resName, int seqNum,
+ const InsCode insCode, bool Enforce );
+
+
+ // ------------------ Deleting residues ----------------------
+
+ int DeleteResidue ( int resNo ); // returns num of deleted res-s
+ int DeleteResidue ( int seqNum, const InsCode insCode );
+ int DeleteAllResidues();
+ int DeleteSolvent ();
+ void TrimResidueTable (); // do not forget to call after all dels
+
+ // ------------------- Adding residues -----------------------
+
+ // AddResidue(..) adds residue to the chain, InsResidue inserts
+ // the residue on the specified position of the chain (other
+ // residues are shifted up to the end of chain). Position in the
+ // chain may be specified by a serial number (that is position in
+ // the residue table) or by seqNum and insCode of one of the
+ // chain's residues (the new residue is then inserted before that
+ // one). If the chain is associated with a coordinate hierarchy,
+ // and residue 'res' is not, the latter is checked in
+ // automatically. If residue 'res' belongs to any coordinate
+ // hierarchy (even though that of the residue), it is *copied*
+ // rather than simply taken over, and is checked in.
+ // If the chain is not associated with a coordinate hierarchy,
+ // all added residues will be checked in automatically once the
+ // chain is checked in.
+ int AddResidue ( PResidue res );
+ int InsResidue ( PResidue res, int pos );
+ int InsResidue ( PResidue res, int seqNum, const InsCode insCode );
+
+ // -------------------- Extracting atoms ---------------------
+
+ int GetNumberOfAtoms ( bool countTers );
+ int GetNumberOfAtoms ( int seqNo, const InsCode insCode );
+ int GetNumberOfAtoms ( int resNo );
+
+ PAtom GetAtom ( int seqNo,
+ const InsCode insCode,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc );
+ PAtom GetAtom ( int seqNo, const InsCode insCode, int atomNo );
+ PAtom GetAtom ( int resNo,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc );
+ PAtom GetAtom ( int resNo, int atomNo );
+
+ void GetAtomTable ( int seqNo, const InsCode insCode,
+ PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable ( int resNo,
+ PPAtom & atomTable, int & NumberOfAtoms );
+
+ // GetAtomTable1(..) returns atom table without TER atoms and
+ // without NULL atom pointers. NumberOfAtoms returns the actual
+ // number of atom pointers in atomTable.
+ // atomTable is allocated withing the function. If it was
+ // not set to NULL before calling the function, the latter will
+ // attempt to deallocate it first.
+ // The application is responsible for deleting atomTable,
+ // however it must not touch atom pointers, i.e. use simply
+ // "delete[] atomTable;". Never pass atomTable from
+ // GetAtomTable(..) into this function, unless you set it to NULL
+ // before doing that.
+ void GetAtomTable1 ( int seqNo, const InsCode insCode,
+ PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable1 ( int resNo,
+ PPAtom & atomTable, int & NumberOfAtoms );
+
+ // --------------------- Deleting atoms ----------------------
+
+ int DeleteAtom ( int seqNo,
+ const InsCode insCode,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc );
+ int DeleteAtom ( int seqNo,
+ const InsCode insCode,
+ int atomNo );
+ int DeleteAtom ( int resNo,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc );
+ int DeleteAtom ( int resNo, int atomNo );
+
+ int DeleteAllAtoms ( int seqNo, const InsCode insCode );
+ int DeleteAllAtoms ( int resNo );
+ int DeleteAllAtoms ();
+
+ // DeleteAltLocs() leaves only alternative location with maximal
+ // occupancy, if those are equal or unspecified, the one with
+ // "least" alternative location indicator.
+ // The function returns the number of deleted. All tables remain
+ // untrimmed, so that explicit trimming or calling
+ // FinishStructEdit() is required.
+ int DeleteAltLocs();
+
+ // ---------------------- Adding atoms -----------------------
+
+ int AddAtom ( int seqNo, const InsCode insCode, PAtom atom );
+ int AddAtom ( int resNo, PAtom atom );
+
+ // -------------------------------------------------------------
+
+ void ApplyTransform ( mat44 & TMatrix ); // transforms all
+ // coordinates by multiplying
+ // with matrix TMatrix
+
+ int GetModelNum();
+ PModel GetModel () { return (PModel)model; }
+ cpstr GetChainID () { return chainID; }
+ void SetChainID ( const ChainID chID );
+ cpstr GetChainID ( pstr ChID ); // returns /m/c
+
+ void GetAtomStatistics ( RAtomStat AS );
+ void CalAtomStatistics ( RAtomStat AS );
+
+ int CheckID ( const ChainID chID );
+ int CheckIDS ( cpstr CID );
+
+ cpstr GetEntryID ();
+ void SetEntryID ( const IDCode idCode );
+
+ int GetNumberOfDBRefs ();
+ PDBReference GetDBRef ( int dbRefNo ); // 0..nDBRefs-1
+
+ void MaskAtoms ( PMask Mask );
+ void MaskResidues ( PMask Mask );
+ void UnmaskAtoms ( PMask Mask );
+ void UnmaskResidues ( PMask Mask );
+
+ void SortResidues ();
+
+ int GetNofModResidues();
+ PModRes GetModResidue ( int modResNo ); // 0.. on
+
+ bool isSolventChain ();
+ bool isInSelection ( int selHnd );
+ bool isAminoacidChain ();
+ bool isNucleotideChain();
+
+
+ // ------- user-defined data handlers
+ int PutUDData ( int UDDhandle, int iudd );
+ int PutUDData ( int UDDhandle, realtype rudd );
+ int PutUDData ( int UDDhandle, cpstr sudd );
+
+ int GetUDData ( int UDDhandle, int & iudd );
+ int GetUDData ( int UDDhandle, realtype & rudd );
+ int GetUDData ( int UDDhandle, pstr sudd, int maxLen );
+ int GetUDData ( int UDDhandle, pstr & sudd );
+
+ void Copy ( PChain chain );
+ void CopyAnnotations ( PChain chain );
+
+ void write ( io::RFile f ); // writes header to PDB binary file
+ void read ( io::RFile f ); // reads header from PDB binary file
+
+ protected :
+
+ ChainID chainID; // chain ID
+ ChainID prevChainID; // if chain is renamed, its original
+ // name may be saved here.
+ PProModel model; // pointer to model class
+
+ int nWeights; // used externally for sorting
+ realtype Weight; // chains
+
+ int nResidues; // number of residues
+ PPResidue residue; // array of residues
+
+ bool Exclude; // used internally
+
+ void InitChain ();
+ void FreeMemory();
+
+ void ExpandResidueArray ( int inc );
+ // _ExcludeResidue(..) excludes (but does not dispose!) a residue
+ // from the chain. Returns 1 if the chain gets empty and 0
+ // otherwise.
+ int _ExcludeResidue ( const ResName resName, int seqNum,
+ const InsCode insCode );
+ void _copy ( PChain chain );
+ void _copy ( PChain chain, PPAtom atom, int & atom_index );
+ void CheckInAtoms();
+
+ private :
+ int resLen; // length of Residue array
+
+ };
+
+
+ extern void TestChain(); // reads from 'in.chain', writes into
+ // 'out.chain' and 'abin.chain'
+
+} // namespace mmdb
+
+#endif
+
diff --git a/mmdb2/mmdb_cifdefs.cpp b/mmdb2/mmdb_cifdefs.cpp
new file mode 100644
index 0000000..270a0ad
--- /dev/null
+++ b/mmdb2/mmdb_cifdefs.cpp
@@ -0,0 +1,369 @@
+// $Id: mmdb_cifdefs.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 21.11.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDBF_Defs <implementation>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Namespace: mmdb::
+//
+// CIF Definitions
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include "mmdb_cifdefs.h"
+
+namespace mmdb {
+
+ // ------------------------------------------------------------------
+
+ cpstr CIFName ( int NameID, CIF_MODE Mode ) {
+ // Gives CIF name according to CIF Mode.
+
+ switch (Mode) {
+
+ case CIF_NDB :
+
+ switch (NameID) {
+ case CAT_POLY_SEQ_SCHEME :
+ return CIFCAT_NDB_POLY_SEQ_SCHEME;
+ case TAG_ID_CODE :
+ return CIFTAG_NDB_PDB_ID_CODE;
+ case TAG_CHAIN_ID :
+ return CIFTAG_NDB_CHAIN_ID;
+ case TAG_SEQ_ALIGN_BEG :
+ return CIFTAG_SEQ_ALIGN_BEG;
+ case TAG_SEQ_ALIGN_BEG_INS_CODE :
+ return CIFTAG_NDB_SEQ_ALIGN_BEG_INS_CODE;
+ case TAG_SEQ_ALIGN_END :
+ return CIFTAG_SEQ_ALIGN_END;
+ case TAG_SEQ_ALIGN_END_INS_CODE :
+ return CIFTAG_NDB_SEQ_ALIGN_END_INS_CODE;
+ case TAG_DB_ACCESSION :
+ return CIFTAG_NDB_DB_ACCESSION;
+ case TAG_DB_ALIGN_BEG :
+ return CIFTAG_DB_ALIGN_BEG;
+ case TAG_DB_ALIGN_BEG_INS_CODE :
+ return CIFTAG_NDB_DB_ALIGN_BEG_INS_CODE;
+ case TAG_DB_ALIGN_END :
+ return CIFTAG_DB_ALIGN_END;
+ case TAG_DB_ALIGN_END_INS_CODE :
+ return CIFTAG_NDB_DB_ALIGN_END_INS_CODE;
+ case TAG_SEQ_CHAIN_ID :
+ return CIFTAG_ID;
+ default : return pstr("ERROR_IN_CIF_NAME_1");
+ }
+
+ case CIF_PDBX :
+
+ switch (NameID) {
+ case CAT_POLY_SEQ_SCHEME :
+ return CIFCAT_PDBX_POLY_SEQ_SCHEME;
+ case TAG_ID_CODE :
+ return CIFTAG_PDBX_PDB_ID_CODE;
+ case TAG_CHAIN_ID :
+ return CIFTAG_PDBX_STRAND_ID;
+ case TAG_SEQ_ALIGN_BEG :
+ return CIFTAG_SEQ_ALIGN_BEG;
+ case TAG_SEQ_ALIGN_BEG_INS_CODE :
+ return CIFTAG_PDBX_SEQ_ALIGN_BEG_INS_CODE;
+ case TAG_SEQ_ALIGN_END :
+ return CIFTAG_SEQ_ALIGN_END;
+ case TAG_SEQ_ALIGN_END_INS_CODE :
+ return CIFTAG_PDBX_SEQ_ALIGN_END_INS_CODE;
+ case TAG_DB_ACCESSION :
+ return CIFTAG_PDBX_DB_ACCESSION;
+ case TAG_DB_ALIGN_BEG :
+ return CIFTAG_DB_ALIGN_BEG;
+ case TAG_DB_ALIGN_BEG_INS_CODE :
+ return CIFTAG_PDBX_DB_ALIGN_BEG_INS_CODE;
+ case TAG_DB_ALIGN_END :
+ return CIFTAG_DB_ALIGN_END;
+ case TAG_DB_ALIGN_END_INS_CODE :
+ return CIFTAG_PDBX_DB_ALIGN_END_INS_CODE;
+ case TAG_SEQ_CHAIN_ID :
+ return CIFTAG_ASYM_ID;
+ default : return pstr("ERROR_IN_CIF_NAME_2");
+ }
+
+ default : return pstr("ERROR_IN_CIF_NAME_3");
+
+ }
+
+ }
+
+ cpstr CIFCAT_ATOM_SITE = cpstr("_atom_site");
+ cpstr CIFCAT_ATOM_SITE_ANISOTROP = cpstr("_atom_site_anisotrop");
+ cpstr CIFCAT_ATOM_SITES = cpstr("_atom_sites");
+ cpstr CIFCAT_AUDIT_AUTHOR = cpstr("_audit_author");
+ cpstr CIFCAT_CELL = cpstr("_cell");
+ cpstr CIFCAT_CHEM_COMP = cpstr("_chem_comp");
+ cpstr CIFCAT_CITATION = cpstr("_citation");
+ cpstr CIFCAT_DATABASE = cpstr("_database");
+ cpstr CIFCAT_DATABASE_PDB_CAVEAT = cpstr("_database_pdb_caveat");
+ cpstr CIFCAT_DATABASE_PDB_MATRIX = cpstr("_database_pdb_matrix");
+ cpstr CIFCAT_DATABASE_PDB_REV = cpstr("_database_pdb_rev");
+ cpstr CIFCAT_DATABASE_PDB_TVECT = cpstr("_database_pdb_tvect");
+ cpstr CIFCAT_ENTITY = cpstr("_entity");
+ cpstr CIFCAT_EXPTL = cpstr("_exptl");
+ cpstr CIFCAT_NDB_DATABASE_REMARK = cpstr("_ndb_database_remark");
+ cpstr CIFCAT_NDB_NONSTANDARD_LIST = cpstr("_ndb_nonstandard_list");
+ cpstr CIFCAT_NDB_POLY_SEQ_SCHEME = cpstr("_ndb_poly_seq_scheme");
+ cpstr CIFCAT_PDBX_POLY_SEQ_SCHEME = cpstr("_pdbx_poly_seq_scheme");
+ cpstr CIFCAT_REFINE = cpstr("_refine");
+ cpstr CIFCAT_SPRSDE = cpstr("_ndb_database_pdb_obs_spr");
+ cpstr CIFCAT_STRUCT = cpstr("_struct");
+ cpstr CIFCAT_STRUCT_ASYM = cpstr("_struct_asym");
+ cpstr CIFCAT_STRUCT_CONF = cpstr("_struct_conf");
+ cpstr CIFCAT_STRUCT_CONN = cpstr("_struct_conn");
+ cpstr CIFCAT_STRUCT_LINKR = cpstr("_struct_linkr");
+ cpstr CIFCAT_STRUCT_KEYWORDS = cpstr("_struct_keywords");
+ cpstr CIFCAT_STRUCT_NCS_OPER = cpstr("_struct_ncs_oper");
+ cpstr CIFCAT_STRUCT_REF = cpstr("_struct_ref");
+ cpstr CIFCAT_STRUCT_REF_SEQ = cpstr("_struct_ref_seq");
+ cpstr CIFCAT_STRUCT_REF_SEQ_DIF = cpstr("_struct_ref_seq_dif");
+ cpstr CIFCAT_STRUCT_SHEET = cpstr("_struct_sheet");
+ cpstr CIFCAT_STRUCT_SHEET_RANGE = cpstr("_struct_sheet_range");
+ cpstr CIFCAT_STRUCT_SHEET_ORDER = cpstr("_struct_sheet_order");
+ cpstr CIFCAT_STRUCT_SHEET_HBOND = cpstr("_struct_sheet_hbond");
+ cpstr CIFCAT_SYMMETRY = cpstr("_symmetry");
+ cpstr CIFCAT_OBSLTE = cpstr("_ndb_database_pdb_obs_spr");
+
+
+ cpstr CIFTAG_ANGLE_ALPHA = cpstr("angle_alpha");
+ cpstr CIFTAG_ANGLE_BETA = cpstr("angle_beta");
+ cpstr CIFTAG_ANGLE_GAMMA = cpstr("angle_gamma");
+ cpstr CIFTAG_ASYM_ID = cpstr("asym_id");
+ cpstr CIFTAG_ATOM_TYPE_SYMBOL = cpstr("atom_type_symbol");
+ cpstr CIFTAG_AUTH_ASYM_ID = cpstr("auth_asym_id");
+ cpstr CIFTAG_AUTH_ATOM_ID = cpstr("auth_atom_id");
+ cpstr CIFTAG_AUTH_COMP_ID = cpstr("auth_comp_id");
+ cpstr CIFTAG_AUTH_SEQ_ID = cpstr("auth_seq_id");
+ cpstr CIFTAG_B_ISO_OR_EQUIV = cpstr("B_iso_or_equiv");
+ cpstr CIFTAG_B_ISO_OR_EQUIV_ESD = cpstr("B_iso_or_equiv_esd");
+ cpstr CIFTAG_BEG_LABEL_ASYM_ID = cpstr("beg_label_asym_id");
+ cpstr CIFTAG_BEG_LABEL_COMP_ID = cpstr("beg_label_comp_id");
+ cpstr CIFTAG_BEG_LABEL_SEQ_ID = cpstr("beg_label_seq_id");
+ cpstr CIFTAG_CARTN_X = cpstr("cartn_x");
+ cpstr CIFTAG_CARTN_X_ESD = cpstr("cartn_x_esd");
+ cpstr CIFTAG_CARTN_Y = cpstr("cartn_y");
+ cpstr CIFTAG_CARTN_Y_ESD = cpstr("cartn_y_esd");
+ cpstr CIFTAG_CARTN_Z = cpstr("cartn_z");
+ cpstr CIFTAG_CARTN_Z_ESD = cpstr("cartn_z_esd");
+ cpstr CIFTAG_PDBX_FORMAL_CHARGE = cpstr("pdbx_formal_charge");
+ cpstr CIFTAG_CODE = cpstr("code");
+ cpstr CIFTAG_CODE_NDB = cpstr("code_NDB");
+ cpstr CIFTAG_CODE_PDB = cpstr("code_PDB");
+ cpstr CIFTAG_CONF_TYPE_ID = cpstr("conf_type_id");
+ cpstr CIFTAG_CONN_TYPE_ID = cpstr("conn_type_id");
+ cpstr CIFTAG_DATE = cpstr("date");
+ cpstr CIFTAG_DATE_ORIGINAL = cpstr("date_original");
+ cpstr CIFTAG_DB_ALIGN_BEG = cpstr("db_align_beg");
+ cpstr CIFTAG_DB_ALIGN_END = cpstr("db_align_end");
+ cpstr CIFTAG_DB_CODE = cpstr("db_code");
+ cpstr CIFTAG_DB_MON_ID = cpstr("db_mon_id");
+ cpstr CIFTAG_DB_NAME = cpstr("db_name");
+ cpstr CIFTAG_DETAILS = cpstr("details");
+ cpstr CIFTAG_END_LABEL_ASYM_ID = cpstr("end_label_asym_id");
+ cpstr CIFTAG_END_LABEL_COMP_ID = cpstr("end_label_comp_id");
+ cpstr CIFTAG_END_LABEL_SEQ_ID = cpstr("end_label_seq_id");
+ cpstr CIFTAG_ENTITY_ID = cpstr("entity_id");
+ cpstr CIFTAG_ENTRY_ID = cpstr("entry_id");
+ cpstr CIFTAG_FORMULA = cpstr("formula");
+ cpstr CIFTAG_FRACT_TRANSF_MATRIX11 = cpstr("fract_transf_matrix[1][1]");
+ cpstr CIFTAG_FRACT_TRANSF_MATRIX12 = cpstr("fract_transf_matrix[1][2]");
+ cpstr CIFTAG_FRACT_TRANSF_MATRIX13 = cpstr("fract_transf_matrix[1][3]");
+ cpstr CIFTAG_FRACT_TRANSF_MATRIX21 = cpstr("fract_transf_matrix[2][1]");
+ cpstr CIFTAG_FRACT_TRANSF_MATRIX22 = cpstr("fract_transf_matrix[2][2]");
+ cpstr CIFTAG_FRACT_TRANSF_MATRIX23 = cpstr("fract_transf_matrix[2][3]");
+ cpstr CIFTAG_FRACT_TRANSF_MATRIX31 = cpstr("fract_transf_matrix[3][1]");
+ cpstr CIFTAG_FRACT_TRANSF_MATRIX32 = cpstr("fract_transf_matrix[3][2]");
+ cpstr CIFTAG_FRACT_TRANSF_MATRIX33 = cpstr("fract_transf_matrix[3][3]");
+ cpstr CIFTAG_FRACT_TRANSF_VECTOR1 = cpstr("fract_transf_vector[1]");
+ cpstr CIFTAG_FRACT_TRANSF_VECTOR2 = cpstr("fract_transf_vector[2]");
+ cpstr CIFTAG_FRACT_TRANSF_VECTOR3 = cpstr("fract_transf_vector[3]");
+ cpstr CIFTAG_GROUP_PDB = cpstr("group_PDB" );
+ cpstr CIFTAG_ID = cpstr("id");
+ cpstr CIFTAG_INS_CODE = cpstr("ins_code");
+ cpstr CIFTAG_LABEL_ALT_ID = cpstr("label_alt_id");
+ cpstr CIFTAG_LABEL_ATOM_ID = cpstr("label_atom_id");
+ cpstr CIFTAG_LABEL_ASYM_ID = cpstr("label_asym_id");
+ cpstr CIFTAG_LABEL_COMP_ID = cpstr("label_comp_id");
+ cpstr CIFTAG_LABEL_ENTITY_ID = cpstr("label_entity_id");
+ cpstr CIFTAG_LABEL_SEQ_ID = cpstr("label_seq_id");
+ cpstr CIFTAG_LENGTH_A = cpstr("length_a");
+ cpstr CIFTAG_LENGTH_B = cpstr("length_b");
+ cpstr CIFTAG_LENGTH_C = cpstr("length_c");
+ cpstr CIFTAG_LS_D_RES_HIGH = cpstr("ls_d_res_high");
+ cpstr CIFTAG_MATRIX11 = cpstr("matrix[1][1]");
+ cpstr CIFTAG_MATRIX12 = cpstr("matrix[1][2]");
+ cpstr CIFTAG_MATRIX13 = cpstr("matrix[1][3]");
+ cpstr CIFTAG_MATRIX21 = cpstr("matrix[2][1]");
+ cpstr CIFTAG_MATRIX22 = cpstr("matrix[2][2]");
+ cpstr CIFTAG_MATRIX23 = cpstr("matrix[2][3]");
+ cpstr CIFTAG_MATRIX31 = cpstr("matrix[3][1]");
+ cpstr CIFTAG_MATRIX32 = cpstr("matrix[3][2]");
+ cpstr CIFTAG_MATRIX33 = cpstr("matrix[3][3]");
+ cpstr CIFTAG_METHOD = cpstr("method");
+ cpstr CIFTAG_MOD_TYPE = cpstr("mod_type");
+ cpstr CIFTAG_MON_ID = cpstr("mon_id");
+ cpstr CIFTAG_NAME = cpstr("name");
+ cpstr CIFTAG_NDB_BEG_LABEL_INS_CODE_PDB = cpstr("ndb_beg_label_ins_code_pdb");
+ cpstr CIFTAG_NDB_CHAIN_ID = cpstr("ndb_chain_id");
+ cpstr CIFTAG_NDB_COMPONENT_NO = cpstr("ndb_component_no");
+ cpstr CIFTAG_NDB_DESCRIPTOR = cpstr("ndb_descriptor");
+ cpstr CIFTAG_NDB_DB_ACCESSION = cpstr("ndb_db_accession");
+ cpstr CIFTAG_NDB_DB_ALIGN_BEG_INS_CODE = cpstr("ndb_db_align_beg_ins_code");
+ cpstr CIFTAG_NDB_DB_ALIGN_END_INS_CODE = cpstr("ndb_db_align_end_ins_code");
+ cpstr CIFTAG_NDB_END_LABEL_INS_CODE_PDB = cpstr("ndb_end_label_ins_code_pdb");
+ //cpstr CIFTAG_NDB_INS_CODE = cpstr("ndb_ins_code");
+ cpstr CIFTAG_PDBX_PDB_INS_CODE = cpstr("pdbx_PDB_ins_code");
+ cpstr CIFTAG_NDB_HELIX_CLASS_PDB = cpstr("ndb_helix_class_pdb");
+ cpstr CIFTAG_NDB_KEYWORDS = cpstr("ndb_keywords");
+ cpstr CIFTAG_NDB_LABEL_ALT_ID = cpstr("ndb_label_alt_id");
+ cpstr CIFTAG_NDB_LABEL_ATOM_ID = cpstr("ndb_label_atom_id");
+ cpstr CIFTAG_NDB_LABEL_ASYM_ID = cpstr("ndb_label_asym_id");
+ cpstr CIFTAG_NDB_LABEL_COMP_ID = cpstr("ndb_label_comp_id");
+ cpstr CIFTAG_NDB_LABEL_INS_CODE = cpstr("ndb_label_ins_code");
+ cpstr CIFTAG_NDB_LABEL_SEQ_NUM = cpstr("ndb_label_seq_num");
+ cpstr CIFTAG_NDB_LENGTH = cpstr("ndb_length");
+ cpstr CIFTAG_NDB_MODEL = cpstr("ndb_model");
+ cpstr CIFTAG_NDB_PDB_CHAIN_ID = cpstr("ndb_pdb_chain_id");
+ cpstr CIFTAG_NDB_PDB_ID = cpstr("ndb_pdb_id");
+ cpstr CIFTAG_NDB_PDB_ID_CODE = cpstr("ndb_pdb_id_code");
+ cpstr CIFTAG_NDB_PDB_INS_CODE = cpstr("ndb_pdb_ins_code");
+ cpstr CIFTAG_NDB_PTNR1_LABEL_INS_CODE = cpstr("ndb_ptnr1_label_ins_code");
+ cpstr CIFTAG_NDB_PTNR1_STANDARD_COMP_ID = cpstr("ndb_ptnr1_standard_comp_id");
+ cpstr CIFTAG_NDB_RANGE_1_BEG_LABEL_COMP_ID = cpstr("ndb_range_1_beg_label_comp_id");
+ cpstr CIFTAG_NDB_RANGE_1_BEG_LABEL_ASYM_ID = cpstr("ndb_range_1_beg_label_asym_id");
+ cpstr CIFTAG_NDB_RANGE_1_BEG_LABEL_INS_CODE= cpstr("ndb_range_1_beg_label_ins_code");
+ cpstr CIFTAG_NDB_RANGE_1_END_LABEL_COMP_ID = cpstr("ndb_range_1_end_label_comp_id");
+ cpstr CIFTAG_NDB_RANGE_1_END_LABEL_ASYM_ID = cpstr("ndb_range_1_end_label_asym_id");
+ cpstr CIFTAG_NDB_RANGE_1_END_LABEL_INS_CODE= cpstr("ndb_range_1_end_label_ins_code");
+ cpstr CIFTAG_NDB_SEQ_ALIGN_BEG = cpstr("ndb_seq_align_beg");
+ cpstr CIFTAG_NDB_SEQ_ALIGN_BEG_INS_CODE = cpstr("ndb_seq_align_beg_ins_code");
+ cpstr CIFTAG_NDB_SEQ_ALIGN_END = cpstr("ndb_seq_align_end");
+ cpstr CIFTAG_NDB_SEQ_ALIGN_END_INS_CODE = cpstr("ndb_seq_align_end_ins_code");
+ cpstr CIFTAG_NDB_SEQ_DB_NAME = cpstr("ndb_seq_db_name");
+ cpstr CIFTAG_NDB_SEQ_DB_ACCESSION_CODE = cpstr("ndb_seq_db_accession_code");
+ cpstr CIFTAG_NDB_SEQ_DB_SEQ_NUM = cpstr("ndb_seq_db_seq_num");
+ cpstr CIFTAG_NDB_SYNONYMS = cpstr("ndb_synonyms");
+ cpstr CIFTAG_NUM = cpstr("num");
+ cpstr CIFTAG_NUMBER_ATOMS_NH = cpstr("number_atoms_nh");
+ cpstr CIFTAG_NUMBER_STRANDS = cpstr("number_strands");
+ cpstr CIFTAG_OCCUPANCY = cpstr("occupancy");
+ cpstr CIFTAG_OCCUPANCY_ESD = cpstr("occupancy_esd");
+ cpstr CIFTAG_ORIGX11 = cpstr("origx[1][1]");
+ cpstr CIFTAG_ORIGX12 = cpstr("origx[1][2]");
+ cpstr CIFTAG_ORIGX13 = cpstr("origx[1][3]");
+ cpstr CIFTAG_ORIGX21 = cpstr("origx[2][1]");
+ cpstr CIFTAG_ORIGX22 = cpstr("origx[2][2]");
+ cpstr CIFTAG_ORIGX23 = cpstr("origx[2][3]");
+ cpstr CIFTAG_ORIGX31 = cpstr("origx[3][1]");
+ cpstr CIFTAG_ORIGX32 = cpstr("origx[3][2]");
+ cpstr CIFTAG_ORIGX33 = cpstr("origx[3][3]");
+ cpstr CIFTAG_ORIGX_VECTOR1 = cpstr("origx_vector[1]");
+ cpstr CIFTAG_ORIGX_VECTOR2 = cpstr("origx_vector[2]");
+ cpstr CIFTAG_ORIGX_VECTOR3 = cpstr("origx_vector[3]");
+ cpstr CIFTAG_PDB_ID = cpstr("pdb_id");
+ cpstr CIFTAG_PDB_MON_ID = cpstr("pdb_mon_id");
+ cpstr CIFTAG_PDB_STRAND_ID = cpstr("pdb_strand_id");
+ cpstr CIFTAG_PDBX_DB_ACCESSION = cpstr("pdbx_db_accession");
+ cpstr CIFTAG_PDBX_DB_ALIGN_BEG_INS_CODE = cpstr("pdbx_db_align_beg_ins_code");
+ cpstr CIFTAG_PDBX_DB_ALIGN_END_INS_CODE = cpstr("pdbx_db_align_end_ins_code");
+ cpstr CIFTAG_PDBX_PDB_ID_CODE = cpstr("pdbx_PDB_id_code");
+ cpstr CIFTAG_PDBX_PDB_MODEL_NUM = cpstr("pdbx_PDB_model_num");
+ cpstr CIFTAG_PDBX_STRAND_ID = cpstr("pdbx_strand_id");
+ cpstr CIFTAG_RANGE_1_BEG_LABEL_ATOM_ID = cpstr("range_1_beg_label_atom_id");
+ cpstr CIFTAG_RANGE_1_BEG_LABEL_SEQ_ID = cpstr("range_1_beg_label_seq_id");
+ cpstr CIFTAG_RANGE_1_END_LABEL_ATOM_ID = cpstr("range_1_end_label_atom_id");
+ cpstr CIFTAG_RANGE_1_END_LABEL_SEQ_ID = cpstr("range_1_end_label_seq_id");
+ cpstr CIFTAG_RANGE_ID_1 = cpstr("range_id_1");
+ cpstr CIFTAG_RANGE_ID_2 = cpstr("range_id_2");
+ cpstr CIFTAG_RCSB_RECORD_REVISED_1 = cpstr("rcsb_record_revised_1");
+ cpstr CIFTAG_RCSB_RECORD_REVISED_2 = cpstr("rcsb_record_revised_2");
+ cpstr CIFTAG_RCSB_RECORD_REVISED_3 = cpstr("rcsb_record_revised_3");
+ cpstr CIFTAG_RCSB_RECORD_REVISED_4 = cpstr("rcsb_record_revised_4");
+ cpstr CIFTAG_PDBX_SEQ_ALIGN_BEG_INS_CODE = cpstr("pdbx_seq_align_beg_ins_code");
+ cpstr CIFTAG_PDBX_SEQ_ALIGN_END_INS_CODE = cpstr("pdbx_seq_align_end_ins_code");
+ cpstr CIFTAG_PTNR1_LABEL_ASYM_ID = cpstr("ptnr1_label_asym_id");
+ cpstr CIFTAG_PTNR1_LABEL_COMP_ID = cpstr("ptnr1_label_comp_id");
+ cpstr CIFTAG_PTNR1_LABEL_SEQ_ID = cpstr("ptnr1_label_seq_id");
+ cpstr CIFTAG_REF_ID = cpstr("ref_id");
+ cpstr CIFTAG_REPLACES = cpstr("replaces");
+ cpstr CIFTAG_REPLACE_PDB_ID = cpstr("replace_pdb_id");
+ cpstr CIFTAG_SEGMENT_ID = cpstr("segment_id");
+ cpstr CIFTAG_SEQ_ALIGN_BEG = cpstr("seq_align_beg");
+ cpstr CIFTAG_SEQ_ALIGN_END = cpstr("seq_align_end");
+ cpstr CIFTAG_SEQ_NUM = cpstr("seq_num");
+ cpstr CIFTAG_SENSE = cpstr("sense");
+ cpstr CIFTAG_SHEET_ID = cpstr("sheet_id");
+ cpstr CIFTAG_SOURCE = cpstr("source");
+ cpstr CIFTAG_SPACE_GROUP_NAME_H_M = cpstr("space_group_name_H-M");
+ cpstr CIFTAG_TEXT = cpstr("text");
+ cpstr CIFTAG_TITLE = cpstr("title");
+ cpstr CIFTAG_TYPE = cpstr("type");
+ cpstr CIFTAG_TYPE_SYMBOL = cpstr("type_symbol");
+ cpstr CIFTAG_VECTOR1 = cpstr("vector[1]");
+ cpstr CIFTAG_VECTOR2 = cpstr("vector[2]");
+ cpstr CIFTAG_VECTOR3 = cpstr("vector[3]");
+ cpstr CIFTAG_U11 = cpstr("u[1][1]");
+ cpstr CIFTAG_U11_ESD = cpstr("u[1][1]_esd");
+ cpstr CIFTAG_U12 = cpstr("u[1][2]");
+ cpstr CIFTAG_U12_ESD = cpstr("u[1][2]_esd");
+ cpstr CIFTAG_U13 = cpstr("u[1][3]");
+ cpstr CIFTAG_U13_ESD = cpstr("u[1][3]_esd");
+ cpstr CIFTAG_U22 = cpstr("u[2][2]");
+ cpstr CIFTAG_U22_ESD = cpstr("u[2][2]_esd");
+ cpstr CIFTAG_U23 = cpstr("u[2][3]");
+ cpstr CIFTAG_U23_ESD = cpstr("u[2][3]_esd");
+ cpstr CIFTAG_U33 = cpstr("u[3][3]");
+ cpstr CIFTAG_U33_ESD = cpstr("u[3][3]_esd");
+ cpstr CIFTAG_Z_PDB = cpstr("z_pdb");
+
+ cpstr CIFTAG_CONN_PTNR1_AUTH_ATOM_ID = cpstr("ptnr1_auth_atom_id");
+ cpstr CIFTAG_CONN_PDBX_PTNR1_AUTH_ALT_ID = cpstr("pdbx_ptnr1_auth_alt_id");
+ cpstr CIFTAG_CONN_PTNR1_AUTH_COMP_ID = cpstr("ptnr1_auth_comp_id");
+ cpstr CIFTAG_CONN_PTNR1_AUTH_ASYM_ID = cpstr("ptnr1_auth_asym_id");
+ cpstr CIFTAG_CONN_PTNR1_AUTH_SEQ_ID = cpstr("ptnr1_auth_seq_id");
+ cpstr CIFTAG_CONN_PDBX_PTNR1_PDB_INS_CODE = cpstr("pdbx_ptnr1_PDB_ins_code");
+ cpstr CIFTAG_CONN_DIST = cpstr("link_dist");
+ cpstr CIFTAG_CONN_PTNR2_AUTH_ATOM_ID = cpstr("ptnr2_auth_atom_id");
+ cpstr CIFTAG_CONN_PDBX_PTNR2_AUTH_ALT_ID = cpstr("pdbx_ptnr2_auth_alt_id");
+ cpstr CIFTAG_CONN_PTNR2_AUTH_COMP_ID = cpstr("ptnr2_auth_comp_id");
+ cpstr CIFTAG_CONN_PTNR2_AUTH_ASYM_ID = cpstr("ptnr2_auth_asym_id");
+ cpstr CIFTAG_CONN_PTNR2_AUTH_SEQ_ID = cpstr("ptnr2_auth_seq_id");
+ cpstr CIFTAG_CONN_PDBX_PTNR2_PDB_INS_CODE = cpstr("pdbx_ptnr2_PDB_ins_code");
+ cpstr CIFTAG_CONN_PTNR1_SYMMETRY = cpstr("ptnr1_symmetry");
+ cpstr CIFTAG_CONN_PTNR2_SYMMETRY = cpstr("ptnr2_symmetry");
+ cpstr CIFTAG_CONN_NAME = cpstr("link_name");
+
+} // namespace mmdb
diff --git a/mmdb2/mmdb_cifdefs.h b/mmdb2/mmdb_cifdefs.h
new file mode 100644
index 0000000..2185b85
--- /dev/null
+++ b/mmdb2/mmdb_cifdefs.h
@@ -0,0 +1,329 @@
+// $Id: mmdb_cifdefs.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 21.11.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDBF_Defs <interface>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Namespace: mmdb::
+//
+// CIF Definitions
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_CIFDefs__
+#define __MMDB_CIFDefs__
+
+#include "mmdb_mattype.h"
+
+namespace mmdb {
+
+ // ------------------------------------------------------------------
+
+ // Mode IDs
+
+ enum CIF_MODE {
+ CIF_NDB = 0,
+ CIF_PDBX = 1
+ };
+
+ // CIF IDs for mode-dependent CIF names
+
+ enum CIF_ID {
+ CAT_POLY_SEQ_SCHEME = 1,
+ TAG_CHAIN_ID = 101,
+ TAG_DB_ACCESSION = 102,
+ TAG_DB_ALIGN_BEG = 103,
+ TAG_DB_ALIGN_BEG_INS_CODE = 104,
+ TAG_DB_ALIGN_END = 105,
+ TAG_DB_ALIGN_END_INS_CODE = 106,
+ TAG_ID_CODE = 107,
+ TAG_SEQ_CHAIN_ID = 108,
+ TAG_SEQ_ALIGN_BEG = 109,
+ TAG_SEQ_ALIGN_BEG_INS_CODE = 110,
+ TAG_SEQ_ALIGN_END = 111,
+ TAG_SEQ_ALIGN_END_INS_CODE = 112
+ };
+
+ // CIFName(..) gives CIF name according to CIF Mode.
+ extern cpstr CIFName ( int NameID, CIF_MODE Mode );
+
+ // ------------------------------------------------------------------
+
+ extern cpstr CIFCAT_ATOM_SITE ;
+ extern cpstr CIFCAT_ATOM_SITE_ANISOTROP ;
+ extern cpstr CIFCAT_ATOM_SITES ;
+ extern cpstr CIFCAT_AUDIT_AUTHOR ;
+ extern cpstr CIFCAT_CELL ;
+ extern cpstr CIFCAT_CHEM_COMP ;
+ extern cpstr CIFCAT_CITATION ;
+ extern cpstr CIFCAT_DATABASE ;
+ extern cpstr CIFCAT_DATABASE_PDB_CAVEAT ;
+ extern cpstr CIFCAT_DATABASE_PDB_MATRIX ;
+ extern cpstr CIFCAT_DATABASE_PDB_REV ;
+ extern cpstr CIFCAT_DATABASE_PDB_TVECT ;
+ extern cpstr CIFCAT_ENTITY ;
+ extern cpstr CIFCAT_EXPTL ;
+ extern cpstr CIFCAT_NDB_DATABASE_REMARK ;
+ extern cpstr CIFCAT_NDB_NONSTANDARD_LIST ;
+ extern cpstr CIFCAT_NDB_POLY_SEQ_SCHEME ;
+ extern cpstr CIFCAT_PDBX_POLY_SEQ_SCHEME ;
+ extern cpstr CIFCAT_REFINE ;
+ extern cpstr CIFCAT_SPRSDE ;
+ extern cpstr CIFCAT_STRUCT ;
+ extern cpstr CIFCAT_STRUCT_ASYM ;
+ extern cpstr CIFCAT_STRUCT_CONF ;
+ extern cpstr CIFCAT_STRUCT_CONN ;
+ extern cpstr CIFCAT_STRUCT_LINKR ;
+ extern cpstr CIFCAT_STRUCT_KEYWORDS ;
+ extern cpstr CIFCAT_STRUCT_NCS_OPER ;
+ extern cpstr CIFCAT_STRUCT_REF ;
+ extern cpstr CIFCAT_STRUCT_REF_SEQ ;
+ extern cpstr CIFCAT_STRUCT_REF_SEQ_DIF ;
+ extern cpstr CIFCAT_STRUCT_SHEET ;
+ extern cpstr CIFCAT_STRUCT_SHEET_RANGE ;
+ extern cpstr CIFCAT_STRUCT_SHEET_ORDER ;
+ extern cpstr CIFCAT_STRUCT_SHEET_HBOND ;
+ extern cpstr CIFCAT_SYMMETRY ;
+ extern cpstr CIFCAT_OBSLTE ;
+
+
+ extern cpstr CIFTAG_ANGLE_ALPHA ;
+ extern cpstr CIFTAG_ANGLE_BETA ;
+ extern cpstr CIFTAG_ANGLE_GAMMA ;
+ extern cpstr CIFTAG_ASYM_ID ;
+ extern cpstr CIFTAG_ATOM_TYPE_SYMBOL ;
+ extern cpstr CIFTAG_AUTH_ASYM_ID ;
+ extern cpstr CIFTAG_AUTH_ATOM_ID ;
+ extern cpstr CIFTAG_AUTH_COMP_ID ;
+ extern cpstr CIFTAG_AUTH_SEQ_ID ;
+ extern cpstr CIFTAG_B_ISO_OR_EQUIV ;
+ extern cpstr CIFTAG_B_ISO_OR_EQUIV_ESD ;
+ extern cpstr CIFTAG_BEG_LABEL_ASYM_ID ;
+ extern cpstr CIFTAG_BEG_LABEL_COMP_ID ;
+ extern cpstr CIFTAG_BEG_LABEL_SEQ_ID ;
+ extern cpstr CIFTAG_CARTN_X ;
+ extern cpstr CIFTAG_CARTN_X_ESD ;
+ extern cpstr CIFTAG_CARTN_Y ;
+ extern cpstr CIFTAG_CARTN_Y_ESD ;
+ extern cpstr CIFTAG_CARTN_Z ;
+ extern cpstr CIFTAG_CARTN_Z_ESD ;
+ extern cpstr CIFTAG_PDBX_FORMAL_CHARGE ;
+ extern cpstr CIFTAG_CODE ;
+ extern cpstr CIFTAG_CODE_NDB ;
+ extern cpstr CIFTAG_CODE_PDB ;
+ extern cpstr CIFTAG_CONF_TYPE_ID ;
+ extern cpstr CIFTAG_CONN_TYPE_ID ;
+ extern cpstr CIFTAG_DATE ;
+ extern cpstr CIFTAG_DATE_ORIGINAL ;
+ extern cpstr CIFTAG_DB_ALIGN_BEG ;
+ extern cpstr CIFTAG_DB_ALIGN_END ;
+ extern cpstr CIFTAG_DB_CODE ;
+ extern cpstr CIFTAG_DB_MON_ID ;
+ extern cpstr CIFTAG_DB_NAME ;
+ extern cpstr CIFTAG_DETAILS ;
+ extern cpstr CIFTAG_END_LABEL_ASYM_ID ;
+ extern cpstr CIFTAG_END_LABEL_COMP_ID ;
+ extern cpstr CIFTAG_END_LABEL_SEQ_ID ;
+ extern cpstr CIFTAG_ENTITY_ID ;
+ extern cpstr CIFTAG_ENTRY_ID ;
+ extern cpstr CIFTAG_FORMULA ;
+ extern cpstr CIFTAG_FRACT_TRANSF_MATRIX11 ;
+ extern cpstr CIFTAG_FRACT_TRANSF_MATRIX12 ;
+ extern cpstr CIFTAG_FRACT_TRANSF_MATRIX13 ;
+ extern cpstr CIFTAG_FRACT_TRANSF_MATRIX21 ;
+ extern cpstr CIFTAG_FRACT_TRANSF_MATRIX22 ;
+ extern cpstr CIFTAG_FRACT_TRANSF_MATRIX23 ;
+ extern cpstr CIFTAG_FRACT_TRANSF_MATRIX31 ;
+ extern cpstr CIFTAG_FRACT_TRANSF_MATRIX32 ;
+ extern cpstr CIFTAG_FRACT_TRANSF_MATRIX33 ;
+ extern cpstr CIFTAG_FRACT_TRANSF_VECTOR1 ;
+ extern cpstr CIFTAG_FRACT_TRANSF_VECTOR2 ;
+ extern cpstr CIFTAG_FRACT_TRANSF_VECTOR3 ;
+ extern cpstr CIFTAG_GROUP_PDB ;
+ extern cpstr CIFTAG_ID ;
+ extern cpstr CIFTAG_INS_CODE ;
+ extern cpstr CIFTAG_LABEL_ALT_ID ;
+ extern cpstr CIFTAG_LABEL_ATOM_ID ;
+ extern cpstr CIFTAG_LABEL_ASYM_ID ;
+ extern cpstr CIFTAG_LABEL_COMP_ID ;
+ extern cpstr CIFTAG_LABEL_ENTITY_ID ;
+ extern cpstr CIFTAG_LABEL_SEQ_ID ;
+ extern cpstr CIFTAG_LENGTH_A ;
+ extern cpstr CIFTAG_LENGTH_B ;
+ extern cpstr CIFTAG_LENGTH_C ;
+ extern cpstr CIFTAG_LS_D_RES_HIGH ;
+ extern cpstr CIFTAG_MATRIX11 ;
+ extern cpstr CIFTAG_MATRIX12 ;
+ extern cpstr CIFTAG_MATRIX13 ;
+ extern cpstr CIFTAG_MATRIX21 ;
+ extern cpstr CIFTAG_MATRIX22 ;
+ extern cpstr CIFTAG_MATRIX23 ;
+ extern cpstr CIFTAG_MATRIX31 ;
+ extern cpstr CIFTAG_MATRIX32 ;
+ extern cpstr CIFTAG_MATRIX33 ;
+ extern cpstr CIFTAG_METHOD ;
+ extern cpstr CIFTAG_MOD_TYPE ;
+ extern cpstr CIFTAG_MON_ID ;
+ extern cpstr CIFTAG_NAME ;
+ extern cpstr CIFTAG_NDB_BEG_LABEL_INS_CODE_PDB ;
+ extern cpstr CIFTAG_NDB_CHAIN_ID ;
+ extern cpstr CIFTAG_NDB_COMPONENT_NO ;
+ extern cpstr CIFTAG_NDB_DESCRIPTOR ;
+ extern cpstr CIFTAG_NDB_DB_ACCESSION ;
+ extern cpstr CIFTAG_NDB_DB_ALIGN_BEG_INS_CODE ;
+ extern cpstr CIFTAG_NDB_DB_ALIGN_END_INS_CODE ;
+ extern cpstr CIFTAG_NDB_END_LABEL_INS_CODE_PDB ;
+ extern cpstr CIFTAG_PDBX_PDB_INS_CODE ;
+ extern cpstr CIFTAG_NDB_HELIX_CLASS_PDB ;
+ extern cpstr CIFTAG_NDB_KEYWORDS ;
+ extern cpstr CIFTAG_NDB_LABEL_ALT_ID ;
+ extern cpstr CIFTAG_NDB_LABEL_ATOM_ID ;
+ extern cpstr CIFTAG_NDB_LABEL_ASYM_ID ;
+ extern cpstr CIFTAG_NDB_LABEL_COMP_ID ;
+ extern cpstr CIFTAG_NDB_LABEL_INS_CODE ;
+ extern cpstr CIFTAG_NDB_LABEL_SEQ_NUM ;
+ extern cpstr CIFTAG_NDB_LENGTH ;
+ extern cpstr CIFTAG_NDB_MODEL ;
+ extern cpstr CIFTAG_NDB_PDB_CHAIN_ID ;
+ extern cpstr CIFTAG_NDB_PDB_ID ;
+ extern cpstr CIFTAG_NDB_PDB_ID_CODE ;
+ extern cpstr CIFTAG_NDB_PDB_INS_CODE ;
+ extern cpstr CIFTAG_NDB_PTNR1_LABEL_INS_CODE ;
+ extern cpstr CIFTAG_NDB_PTNR1_STANDARD_COMP_ID ;
+ extern cpstr CIFTAG_NDB_RANGE_1_BEG_LABEL_COMP_ID ;
+ extern cpstr CIFTAG_NDB_RANGE_1_BEG_LABEL_ASYM_ID ;
+ extern cpstr CIFTAG_NDB_RANGE_1_BEG_LABEL_INS_CODE;
+ extern cpstr CIFTAG_NDB_RANGE_1_END_LABEL_COMP_ID ;
+ extern cpstr CIFTAG_NDB_RANGE_1_END_LABEL_ASYM_ID ;
+ extern cpstr CIFTAG_NDB_RANGE_1_END_LABEL_INS_CODE;
+ extern cpstr CIFTAG_NDB_SEQ_ALIGN_BEG ;
+ extern cpstr CIFTAG_NDB_SEQ_ALIGN_BEG_INS_CODE ;
+ extern cpstr CIFTAG_NDB_SEQ_ALIGN_END ;
+ extern cpstr CIFTAG_NDB_SEQ_ALIGN_END_INS_CODE ;
+ extern cpstr CIFTAG_NDB_SEQ_DB_NAME ;
+ extern cpstr CIFTAG_NDB_SEQ_DB_ACCESSION_CODE ;
+ extern cpstr CIFTAG_NDB_SEQ_DB_SEQ_NUM ;
+ extern cpstr CIFTAG_NDB_SYNONYMS ;
+ extern cpstr CIFTAG_NUM ;
+ extern cpstr CIFTAG_NUMBER_ATOMS_NH ;
+ extern cpstr CIFTAG_NUMBER_STRANDS ;
+ extern cpstr CIFTAG_OCCUPANCY ;
+ extern cpstr CIFTAG_OCCUPANCY_ESD ;
+ extern cpstr CIFTAG_ORIGX11 ;
+ extern cpstr CIFTAG_ORIGX12 ;
+ extern cpstr CIFTAG_ORIGX13 ;
+ extern cpstr CIFTAG_ORIGX21 ;
+ extern cpstr CIFTAG_ORIGX22 ;
+ extern cpstr CIFTAG_ORIGX23 ;
+ extern cpstr CIFTAG_ORIGX31 ;
+ extern cpstr CIFTAG_ORIGX32 ;
+ extern cpstr CIFTAG_ORIGX33 ;
+ extern cpstr CIFTAG_ORIGX_VECTOR1 ;
+ extern cpstr CIFTAG_ORIGX_VECTOR2 ;
+ extern cpstr CIFTAG_ORIGX_VECTOR3 ;
+ extern cpstr CIFTAG_PDB_ID ;
+ extern cpstr CIFTAG_PDB_MON_ID ;
+ extern cpstr CIFTAG_PDB_STRAND_ID ;
+ extern cpstr CIFTAG_PDBX_DB_ACCESSION ;
+ extern cpstr CIFTAG_PDBX_DB_ALIGN_BEG_INS_CODE ;
+ extern cpstr CIFTAG_PDBX_DB_ALIGN_END_INS_CODE ;
+ extern cpstr CIFTAG_PDBX_PDB_ID_CODE ;
+ extern cpstr CIFTAG_PDBX_PDB_MODEL_NUM ;
+ extern cpstr CIFTAG_PDBX_STRAND_ID ;
+ extern cpstr CIFTAG_RANGE_1_BEG_LABEL_ATOM_ID ;
+ extern cpstr CIFTAG_RANGE_1_BEG_LABEL_SEQ_ID ;
+ extern cpstr CIFTAG_RANGE_1_END_LABEL_ATOM_ID ;
+ extern cpstr CIFTAG_RANGE_1_END_LABEL_SEQ_ID ;
+ extern cpstr CIFTAG_RANGE_ID_1 ;
+ extern cpstr CIFTAG_RANGE_ID_2 ;
+ extern cpstr CIFTAG_RCSB_RECORD_REVISED_1 ;
+ extern cpstr CIFTAG_RCSB_RECORD_REVISED_2 ;
+ extern cpstr CIFTAG_RCSB_RECORD_REVISED_3 ;
+ extern cpstr CIFTAG_RCSB_RECORD_REVISED_4 ;
+ extern cpstr CIFTAG_PDBX_SEQ_ALIGN_BEG_INS_CODE ;
+ extern cpstr CIFTAG_PDBX_SEQ_ALIGN_END_INS_CODE ;
+ extern cpstr CIFTAG_PTNR1_LABEL_ASYM_ID ;
+ extern cpstr CIFTAG_PTNR1_LABEL_COMP_ID ;
+ extern cpstr CIFTAG_PTNR1_LABEL_SEQ_ID ;
+ extern cpstr CIFTAG_REF_ID ;
+ extern cpstr CIFTAG_REPLACES ;
+ extern cpstr CIFTAG_REPLACE_PDB_ID ;
+ extern cpstr CIFTAG_SEGMENT_ID ;
+ extern cpstr CIFTAG_SEQ_ALIGN_BEG ;
+ extern cpstr CIFTAG_SEQ_ALIGN_END ;
+ extern cpstr CIFTAG_SEQ_NUM ;
+ extern cpstr CIFTAG_SENSE ;
+ extern cpstr CIFTAG_SHEET_ID ;
+ extern cpstr CIFTAG_SOURCE ;
+ extern cpstr CIFTAG_SPACE_GROUP_NAME_H_M ;
+ extern cpstr CIFTAG_TEXT ;
+ extern cpstr CIFTAG_TITLE ;
+ extern cpstr CIFTAG_TYPE ;
+ extern cpstr CIFTAG_TYPE_SYMBOL ;
+ extern cpstr CIFTAG_VECTOR1 ;
+ extern cpstr CIFTAG_VECTOR2 ;
+ extern cpstr CIFTAG_VECTOR3 ;
+ extern cpstr CIFTAG_U11 ;
+ extern cpstr CIFTAG_U11_ESD ;
+ extern cpstr CIFTAG_U12 ;
+ extern cpstr CIFTAG_U12_ESD ;
+ extern cpstr CIFTAG_U13 ;
+ extern cpstr CIFTAG_U13_ESD ;
+ extern cpstr CIFTAG_U22 ;
+ extern cpstr CIFTAG_U22_ESD ;
+ extern cpstr CIFTAG_U23 ;
+ extern cpstr CIFTAG_U23_ESD ;
+ extern cpstr CIFTAG_U33 ;
+ extern cpstr CIFTAG_U33_ESD ;
+ extern cpstr CIFTAG_Z_PDB ;
+
+ extern cpstr CIFTAG_CONN_PTNR1_AUTH_ATOM_ID ;
+ extern cpstr CIFTAG_CONN_PDBX_PTNR1_AUTH_ALT_ID ;
+ extern cpstr CIFTAG_CONN_PTNR1_AUTH_COMP_ID ;
+ extern cpstr CIFTAG_CONN_PTNR1_AUTH_ASYM_ID ;
+ extern cpstr CIFTAG_CONN_PTNR1_AUTH_SEQ_ID ;
+ extern cpstr CIFTAG_CONN_PDBX_PTNR1_PDB_INS_CODE ;
+ extern cpstr CIFTAG_CONN_DIST ;
+ extern cpstr CIFTAG_CONN_PTNR2_AUTH_ATOM_ID ;
+ extern cpstr CIFTAG_CONN_PDBX_PTNR2_AUTH_ALT_ID ;
+ extern cpstr CIFTAG_CONN_PTNR2_AUTH_COMP_ID ;
+ extern cpstr CIFTAG_CONN_PTNR2_AUTH_ASYM_ID ;
+ extern cpstr CIFTAG_CONN_PTNR2_AUTH_SEQ_ID ;
+ extern cpstr CIFTAG_CONN_PDBX_PTNR2_PDB_INS_CODE ;
+ extern cpstr CIFTAG_CONN_PTNR1_SYMMETRY ;
+ extern cpstr CIFTAG_CONN_PTNR2_SYMMETRY ;
+ extern cpstr CIFTAG_CONN_NAME ;
+
+} // namespace mmdb
+
+#endif
+
diff --git a/mmdb2/mmdb_coormngr.cpp b/mmdb2/mmdb_coormngr.cpp
new file mode 100644
index 0000000..0ab4fbf
--- /dev/null
+++ b/mmdb2/mmdb_coormngr.cpp
@@ -0,0 +1,4347 @@
+// $Id: mmdb_coormngr.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 14.07.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : mmdb_coormngr <implementation>
+// ~~~~~~~~~
+// Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::Brick ( space brick )
+// ~~~~~~~~~ mmdb::CoorManager ( MMDB atom coordinate manager )
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include <math.h>
+#include <string.h>
+
+#include "mmdb_coormngr.h"
+#include "mmdb_math_linalg.h"
+#include "mmdb_tables.h"
+
+namespace mmdb {
+
+ // ========================== Brick =============================
+
+ Brick::Brick() {
+ InitBrick();
+ }
+
+ Brick::~Brick() {
+ Clear();
+ }
+
+ void Brick::InitBrick() {
+ atom = NULL;
+ id = NULL;
+ nAtoms = 0;
+ nAllocAtoms = 0;
+ }
+
+ void Brick::Clear() {
+ if (atom) delete[] atom;
+ FreeVectorMemory ( id,0 );
+ atom = NULL;
+ nAtoms = 0;
+ nAllocAtoms = 0;
+ }
+
+ void Brick::AddAtom ( PAtom A, int atomid ) {
+ int i;
+ PPAtom atom1;
+ ivector id1;
+ if (nAtoms>=nAllocAtoms) {
+ nAllocAtoms = nAtoms+10;
+ atom1 = new PAtom[nAllocAtoms];
+ GetVectorMemory ( id1,nAllocAtoms,0 );
+ for (i=0;i<nAtoms;i++) {
+ atom1[i] = atom[i];
+ id1 [i] = id [i];
+ }
+ for (i=nAtoms;i<nAllocAtoms;i++) {
+ atom1[i] = NULL;
+ id1 [i] = -1;
+ }
+ if (atom) delete[] atom;
+ FreeVectorMemory ( id,0 );
+ atom = atom1;
+ id = id1;
+ }
+ atom[nAtoms] = A;
+ id [nAtoms] = atomid;
+ nAtoms++;
+ }
+
+
+ // =========================== mbrick =============================
+
+ MBrick::MBrick ( int nStructures ) {
+ InitMBrick ( nStructures );
+ }
+
+ MBrick::~MBrick() {
+ Clear();
+ }
+
+ void MBrick::InitMBrick ( int nStructures ) {
+ int i;
+ nStruct = nStructures;
+ atom = new PPAtom[nStruct];
+ id = new ivector[nStruct];
+ GetVectorMemory ( nAtoms,nStruct,0 );
+ GetVectorMemory ( nAlloAtoms,nStruct,0 );
+ for (i=0;i<nStruct;i++) {
+ atom [i] = NULL;
+ id [i] = NULL;
+ nAtoms [i] = 0;
+ nAlloAtoms[i] = 0;
+ }
+ }
+
+ void MBrick::Clear() {
+ int i;
+ if (atom) {
+ for (i=0;i<nStruct;i++)
+ if (atom[i]) delete[] atom[i];
+ delete[] atom;
+ atom = NULL;
+ }
+ FreeMatrixMemory ( id,nStruct,0,0 );
+ FreeVectorMemory ( nAtoms,0 );
+ FreeVectorMemory ( nAlloAtoms,0 );
+ nStruct = 0;
+ }
+
+ void MBrick::AddAtom ( PAtom A, int structNo, int atomid ) {
+ int i,natoms,nalloc;
+ PPAtom atom0,atom1;
+ ivector id0,id1;
+ natoms = nAtoms [structNo];
+ nalloc = nAlloAtoms[structNo];
+ atom0 = atom [structNo];
+ id0 = id [structNo];
+ if (natoms>=nalloc) {
+ nalloc = natoms+10;
+ atom1 = new PAtom[nalloc];
+ GetVectorMemory ( id1,nalloc,0 );
+ for (i=0;i<natoms;i++) {
+ atom1[i] = atom0[i];
+ id1 [i] = id0 [i];
+ }
+ for (i=natoms;i<nalloc;i++) {
+ atom1[i] = NULL;
+ id1 [i] = -1;
+ }
+ if (atom0) delete[] atom0;
+ FreeVectorMemory ( id0,0 );
+ atom[structNo] = atom1;
+ id [structNo] = id1;
+ nAlloAtoms[structNo] = nalloc;
+ atom0 = atom1;
+ id0 = id1;
+ }
+ atom0 [natoms] = A;
+ id0 [natoms] = atomid;
+ nAtoms[structNo] = natoms+1;
+ }
+
+
+
+ // ==================== GenSym ========================
+
+ GenSym::GenSym() : SymOps() {
+ InitGenSym();
+ }
+
+ GenSym::GenSym ( io::RPStream Object ) : SymOps(Object) {
+ InitGenSym();
+ }
+
+ GenSym::~GenSym() {} // virtual FreeMmeory is called by ~SymOps()
+
+ void GenSym::InitGenSym() {
+ chID1 = NULL;
+ chID2 = NULL;
+ nChains = NULL;
+ nOpAlloc = 0;
+ }
+
+ void GenSym::FreeMemory() {
+ int i;
+ for (i=0;i<nOpAlloc;i++) {
+ if (chID1[i]) delete[] chID1[i];
+ if (chID2[i]) delete[] chID2[i];
+ }
+ if (chID1) delete[] chID1;
+ if (chID2) delete[] chID2;
+ FreeVectorMemory ( nChains,0 );
+ nOpAlloc = 0;
+ SymOps::FreeMemory();
+ }
+
+ int GenSym::AddSymOp ( cpstr XYZOperation ) {
+ int RC,i;
+ PChainID * ch1ID;
+ PChainID * ch2ID;
+ ivector nChains1;
+
+ RC = SymOps::AddSymOp ( XYZOperation );
+ if (Nops>nOpAlloc) {
+ ch1ID = new PChainID[Nops];
+ ch2ID = new PChainID[Nops];
+ GetVectorMemory ( nChains1,Nops,0 );
+ for (i=0;i<nOpAlloc;i++) {
+ ch1ID[i] = chID1[i];
+ ch2ID[i] = chID2[i];
+ nChains1[i] = nChains[i];
+ }
+ for (i=nOpAlloc;i<Nops;i++) {
+ ch1ID[i] = NULL;
+ ch2ID[i] = NULL;
+ nChains1[i] = 0;
+ }
+ if (chID1) delete[] chID1;
+ if (chID2) delete[] chID2;
+ FreeVectorMemory ( nChains,0 );
+ chID1 = ch1ID;
+ chID2 = ch2ID;
+ nChains = nChains1;
+ nOpAlloc = Nops;
+ }
+ return RC;
+ }
+
+ int GenSym::AddRenChain ( int Nop, const ChainID ch1,
+ const ChainID ch2 ) {
+ int i;
+ PChainID c1,c2;
+ if ((0<=Nop) && (Nop<Nops)) {
+ c1 = new ChainID[nChains[Nop]+1];
+ c2 = new ChainID[nChains[Nop]+1];
+ for (i=0;i<nChains[Nop];i++) {
+ strcpy ( c1[i],chID1[Nop][i] );
+ strcpy ( c2[i],chID2[Nop][i] );
+ }
+ strcpy ( c1[nChains[Nop]],ch1 );
+ strcpy ( c2[nChains[Nop]],ch2 );
+ if (chID1[Nop]) delete[] chID1[Nop];
+ if (chID2[Nop]) delete[] chID2[Nop];
+ chID1[Nop] = c1;
+ chID2[Nop] = c2;
+ nChains[Nop]++;
+ return SYMOP_Ok;
+ } else
+ return SYMOP_NoSymOps;
+ }
+
+ void GenSym::Copy ( PSymOps GenSym ) {
+ int i,j;
+ SymOps::Copy ( GenSym );
+ if (Nops>0) {
+ nOpAlloc = Nops;
+ chID1 = new PChainID[Nops];
+ chID2 = new PChainID[Nops];
+ GetVectorMemory ( nChains,Nops,0 );
+ for (i=0;i<Nops;i++) {
+ nChains[i] = PGenSym(GenSym)->nChains[i];
+ if (nChains[i]<=0) {
+ chID1[i] = NULL;
+ chID2[i] = NULL;
+ } else {
+ chID1[i] = new ChainID[nChains[i]];
+ chID2[i] = new ChainID[nChains[i]];
+ for (j=0;j<nChains[i];j++) {
+ strcpy ( chID1[i][j],PGenSym(GenSym)->chID1[i][j] );
+ strcpy ( chID2[i][j],PGenSym(GenSym)->chID2[i][j] );
+ }
+ }
+ }
+ }
+ }
+
+ void GenSym::write ( io::RFile f ) {
+ int i,j;
+ byte Version=1;
+ f.WriteByte ( &Version );
+ SymOps::write ( f );
+ f.WriteInt ( &nOpAlloc );
+ for (i=0;i<nOpAlloc;i++) {
+ f.WriteInt ( &(nChains[i]) );
+ for (j=0;j<nChains[i];j++) {
+ f.WriteTerLine ( chID1[i][j],false );
+ f.WriteTerLine ( chID2[i][j],false );
+ }
+ }
+ }
+
+ void GenSym::read ( io::RFile f ) {
+ int i,j;
+ byte Version;
+ f.ReadByte ( &Version );
+ SymOps::read ( f );
+ f.ReadInt ( &nOpAlloc );
+ if (nOpAlloc>0) {
+ chID1 = new PChainID[nOpAlloc];
+ chID2 = new PChainID[nOpAlloc];
+ GetVectorMemory ( nChains,nOpAlloc,0 );
+ for (i=0;i<nOpAlloc;i++) {
+ f.ReadInt ( &(nChains[i]) );
+ if (nChains[i]>0) {
+ chID1[i] = new ChainID[nChains[i]];
+ chID2[i] = new ChainID[nChains[i]];
+ for (j=0;j<nChains[i];j++) {
+ f.ReadTerLine ( chID1[i][j],false );
+ f.ReadTerLine ( chID2[i][j],false );
+ }
+ } else {
+ chID1[i] = NULL;
+ chID2[i] = NULL;
+ }
+ }
+ }
+ }
+
+
+ MakeStreamFunctions(GenSym)
+
+
+
+ // ======================= ContactIndex ==========================
+
+ void Contact::Copy ( RContact c ) {
+ id1 = c.id1;
+ id2 = c.id2;
+ group = c.group;
+ dist = c.dist;
+ }
+
+ void Contact::Swap ( RContact c ) {
+ int ib;
+ long lb;
+ realtype rb;
+ ib = id1; id1 = c.id1; c.id1 = ib;
+ ib = id2; id2 = c.id2; c.id2 = ib;
+ lb = group; group = c.group; c.group = lb;
+ rb = dist; dist = c.dist; c.dist = rb;
+ }
+
+ DefineClass(ContactIndex)
+
+ class ContactIndex {
+
+ friend class SelManager;
+
+ public :
+
+ ContactIndex ( PContact contact,
+ int maxlen,
+ int ncontacts,
+ int max_alloc );
+ ~ContactIndex();
+
+ void AddContact ( int id1, int id2, realtype dist, int group );
+ void GetIndex ( RPContact contact, int & ncontacts );
+
+ protected :
+
+ PContact contact_index; // contact index
+ int max_index; // if <=0 then dynamical index
+ // otherwise fixed by max_index
+ int n_contacts; // number of contacts
+ int alloc_index; // physical length of contact_index
+ // when dynamical
+ int alloc_max; // physical limit on allocation
+
+ };
+
+
+ ContactIndex::ContactIndex ( PContact contact,
+ int maxlen,
+ int ncontacts,
+ int max_alloc ) {
+ contact_index = contact;
+ max_index = maxlen;
+ if (!contact_index) n_contacts = 0;
+ else n_contacts = IMax(0,ncontacts);
+ alloc_index = n_contacts;
+ alloc_max = n_contacts + max_alloc;
+ }
+
+ ContactIndex::~ContactIndex() {
+ if (contact_index) delete[] contact_index;
+ contact_index = NULL;
+ n_contacts = 0;
+ alloc_index = 0;
+ }
+
+ void ContactIndex::AddContact ( int id1, int id2, realtype dist,
+ int group ) {
+ PContact cont1;
+ int i;
+
+ if ((alloc_max<=0) || (n_contacts<alloc_max)) {
+ if (max_index>0) {
+ if (n_contacts<max_index) {
+ contact_index[n_contacts].id1 = id1;
+ contact_index[n_contacts].id2 = id2;
+ contact_index[n_contacts].dist = dist;
+ contact_index[n_contacts].group = group;
+ }
+ } else {
+ if (n_contacts>=alloc_index) {
+ alloc_index = n_contacts+IMax(alloc_index/4+10,10);
+ if ((alloc_max>0) && (alloc_index>alloc_max))
+ alloc_index = alloc_max;
+ cont1 = new Contact[alloc_index];
+ for (i=0;i<n_contacts;i++)
+ cont1[i].Copy ( contact_index[i] );
+ if (contact_index) delete[] contact_index;
+ contact_index = cont1;
+ }
+ contact_index[n_contacts].id1 = id1;
+ contact_index[n_contacts].id2 = id2;
+ contact_index[n_contacts].dist = dist;
+ contact_index[n_contacts].group = group;
+ }
+ n_contacts++;
+ }
+ }
+
+ void ContactIndex::GetIndex ( RPContact contact, int & ncontacts ) {
+ contact = contact_index;
+ ncontacts = n_contacts;
+ contact_index = NULL;
+ n_contacts = 0;
+ alloc_index = 0;
+ }
+
+
+ // ======================== MContact =============================
+
+ MContact::MContact ( int nStructures ) {
+ int i;
+ nStruct = nStructures;
+ if (nStruct>0) {
+ atom = new PPAtom[nStruct];
+ id = new ivector[nStruct];
+ GetVectorMemory ( nAtoms,nStruct,0 );
+ GetVectorMemory ( nAlloc,nStruct,0 );
+ for (i=0;i<nStruct;i++) {
+ atom [i] = NULL;
+ id [i] = NULL;
+ nAtoms[i] = 0;
+ nAlloc[i] = 0;
+ }
+ } else {
+ atom = NULL;
+ nAtoms = NULL;
+ nAlloc = NULL;
+ }
+ }
+
+ MContact::~MContact() {
+ int i;
+ if (atom) {
+ for (i=0;i<nStruct;i++)
+ if (atom[i]) delete[] atom[i];
+ delete[] atom;
+ atom = NULL;
+ }
+ FreeMatrixMemory ( id,nStruct,0,0 );
+ FreeVectorMemory ( nAtoms,0 );
+ FreeVectorMemory ( nAlloc,0 );
+ nStruct = 0;
+ }
+
+ void MContact::AddContact ( PAtom A, int structNo, int atomid ) {
+ PPAtom A1,A2;
+ ivector id1,id2;
+ int nat,nal,i;
+ A1 = atom [structNo];
+ id1 = id [structNo];
+ nat = nAtoms[structNo];
+ nal = nAlloc[structNo];
+ if (nat>=nal) {
+ nal = nat+10;
+ A2 = new PAtom[nal];
+ GetVectorMemory ( id2,nal,0 );
+ for (i=0;i<nat;i++) {
+ A2 [i] = A1 [i];
+ id2[i] = id1[i];
+ }
+ for (i=nat;i<nal;i++) {
+ A2 [i] = NULL;
+ id2[i] = 0;
+ }
+ if (A1) delete[] A1;
+ FreeVectorMemory ( id1,0 );
+ atom[structNo] = A2;
+ id [structNo] = id2;
+ A1 = A2;
+ id1 = id2;
+ nAlloc[structNo] = nal;
+ }
+ A1 [nat] = A;
+ id1[nat] = atomid;
+ nAtoms[structNo] = nat+1;
+ }
+
+
+ void DeleteMContacts ( PPMContact & mcontact, int nContacts ) {
+ int i;
+ if (mcontact) {
+ for (i=0;i<nContacts;i++)
+ if (mcontact[i]) delete mcontact[i];
+ delete[] mcontact;
+ mcontact = NULL;
+ }
+ }
+
+
+ // ==================== CoorManager =====================
+
+ CoorManager::CoorManager() : Root() {
+ InitMMDBCoorManager();
+ }
+
+ CoorManager::CoorManager ( io::RPStream Object ) : Root(Object) {
+ InitMMDBCoorManager();
+ }
+
+ CoorManager::~CoorManager() {
+ RemoveBricks ();
+ RemoveMBricks();
+ }
+
+ void CoorManager::ResetManager() {
+ Root::ResetManager();
+ RemoveBricks ();
+ RemoveMBricks ();
+ InitMMDBCoorManager();
+ }
+
+ void CoorManager::InitMMDBCoorManager() {
+
+ CoorIDCode = CID_Ok;
+
+ brick_size = 6.0; // angstroms
+ xbrick_0 = 0.0;
+ ybrick_0 = 0.0;
+ zbrick_0 = 0.0;
+ nbrick_x = 0;
+ nbrick_y = 0;
+ nbrick_z = 0;
+ brick = NULL;
+
+ mbrick_size = 6.0; // angstroms
+ xmbrick_0 = 0.0;
+ ymbrick_0 = 0.0;
+ zmbrick_0 = 0.0;
+ nmbrick_x = 0;
+ nmbrick_y = 0;
+ nmbrick_z = 0;
+ mbrick = NULL;
+
+ }
+
+
+ int CoorManager::SetDefaultCoorID ( cpstr CID ) {
+ return DefPath.SetPath ( CID );
+ }
+
+ PModel CoorManager::GetFirstDefinedModel() {
+ PModel mdl;
+ int i;
+ mdl = NULL;
+ for (i=0;(i<nModels) && (!mdl);i++)
+ mdl = model[i];
+ return mdl;
+ }
+
+ int CoorManager::GetFirstModelNum() {
+ PModel mdl;
+ int i;
+ mdl = NULL;
+ for (i=0;(i<nModels) && (!mdl);i++)
+ mdl = model[i];
+ if (mdl) return mdl->GetSerNum();
+ return 1;
+ }
+
+
+ PModel CoorManager::GetModel ( int modelNo ) {
+ if ((modelNo>=1) && (modelNo<=nModels))
+ return model[modelNo-1];
+ else return NULL;
+ }
+
+ PModel CoorManager::GetModel ( cpstr CID ) {
+ int modno,sn,rc;
+ ChainID chname;
+ InsCode ic;
+ ResName resname;
+ AtomName aname;
+ Element elname;
+ AltLoc aloc;
+
+ CoorIDCode = CID_Ok;
+ rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
+ aname,elname,aloc,&DefPath );
+ if ((rc<0) || (rc & APATH_WC_ModelNo)) {
+ CoorIDCode = CID_WrongPath;
+ return NULL;
+ }
+
+ if ((modno>=1) && (modno<=nModels))
+ return model[modno-1];
+ else return NULL;
+
+ }
+
+ void CoorManager::GetModelTable ( PPModel & modelTable,
+ int & NumberOfModels ) {
+ NumberOfModels = nModels;
+ modelTable = model;
+ }
+
+ int CoorManager::DeleteModel ( int modelNo ) {
+ if ((modelNo>=1) && (modelNo<=nModels)) {
+ if (model[modelNo-1]) {
+ Exclude = false;
+ delete model[modelNo-1];
+ model[modelNo-1] = NULL;
+ Exclude = true;
+ return 1;
+ }
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteModel ( cpstr CID ) {
+ int modno,sn,rc;
+ ChainID chname;
+ InsCode ic;
+ ResName resname;
+ AtomName aname;
+ Element elname;
+ AltLoc aloc;
+
+ CoorIDCode = CID_Ok;
+ rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
+ aname,elname,aloc,&DefPath );
+ if ((rc<0) || (rc & APATH_WC_ModelNo)) {
+ CoorIDCode = CID_WrongPath;
+ return 0;
+ }
+
+ if ((modno>=1) && (modno<=nModels)) {
+ if (model[modno-1]) {
+ Exclude = false;
+ delete model[modno-1];
+ model[modno-1] = NULL;
+ Exclude = true;
+ return 1;
+ }
+ }
+
+ return 0;
+
+ }
+
+
+ int CoorManager::DeleteSolvent() {
+ int i,k;
+ Exclude = false;
+ k = 0;
+ for (i=0;i<nModels;i++)
+ if (model[i]) {
+ k += model[i]->DeleteSolvent();
+ model[i]->TrimChainTable();
+ if (model[i]->nChains<=0) {
+ delete model[i];
+ model[i] = NULL;
+ }
+ }
+ Exclude = true;
+ return k;
+ }
+
+
+ // ---------------- Adding/Inserting models ---------------
+
+ int CoorManager::AddModel ( PModel mdl ) {
+ PPModel model1;
+ int i,nnat,nat1;
+
+ for (i=0;i<nModels;i++)
+ if (model[i]==mdl) return -i;
+
+ nnat = mdl->GetNumberOfAtoms ( true );
+ AddAtomArray ( nnat ); // get space for new atoms
+
+ if (mdl->GetCoordHierarchy()) {
+ SwitchModel ( nModels+1 ); // get one more model at the end
+ nat1 = nAtoms;
+ model[nModels-1]->_copy ( mdl,atom,nat1 );
+ model[nModels-1]->serNum = nModels;
+ nAtoms = nat1;
+ } else {
+ model1 = new PModel[nModels+1];
+ for (i=0;i<nModels;i++)
+ model1[i] = model[i];
+ if (model) delete[] model;
+ model = model1;
+ model[nModels] = mdl;
+ model[nModels]->SetMMDBManager ( PManager(this),nModels+1 );
+ model[nModels]->CheckInAtoms();
+ nModels++;
+ }
+
+ return nModels;
+
+ }
+
+ int CoorManager::InsModel ( PModel mdl, int modelNo ) {
+ AddModel ( mdl );
+ RotateModels ( modelNo,nModels,1 );
+ return nModels;
+ }
+
+ void CoorManager::RotateModels ( int modelNo1, int modelNo2,
+ int rotdir ) {
+ PModel mdl;
+ PPAtom A;
+ int m1,m2,i11,i12,i21,i22,nat,i,k;
+
+ m1 = IMax ( 0,modelNo1-1 );
+ m2 = IMin ( nModels,modelNo2) - 1;
+ if (m1>m2) ISwap ( m1,m2 );
+
+ if (m1!=m2) {
+
+ if (model[m1] && model[m2]) {
+ model[m1]->GetAIndexRange ( i11,i12 );
+ model[m2]->GetAIndexRange ( i21,i22 );
+ if ((i11<i12) && (i21<i22) && (i12<i22)) {
+ i11--; i12--;
+ i21--; i22--;
+ if (rotdir<0) {
+ // rotate anticlockwise
+ nat = i12-i11+1;
+ A = new PAtom[nat];
+ k = 0;
+ for (i=i11;i<=i12;i++)
+ A[k++] = atom[i];
+ k = i11;
+ for (i=i12+1;i<=i22;i++) {
+ atom[k] = atom[i];
+ if (atom[k]) atom[k]->index = k+1;
+ k++;
+ }
+ for (i=0;i<nat;i++) {
+ atom[k] = A[i];
+ if (atom[k]) atom[k]->index = k+1;
+ k++;
+ }
+ } else {
+ // rotate anticlockwise
+ nat = i22-i21+1;
+ A = new PAtom[nat];
+ k = 0;
+ for (i=i21;i<=i22;i++)
+ A[k++] = atom[i];
+ k = i22;
+ for (i=i21-1;i>=i11;i--) {
+ atom[k] = atom[i];
+ if (atom[k]) atom[k]->index = k+1;
+ k--;
+ }
+ for (i=nat-1;i>=0;i--) {
+ atom[k] = A[i];
+ if (atom[k]) atom[k]->index = k+1;
+ k--;
+ }
+ }
+ delete[] A;
+ }
+ }
+
+ if (rotdir<0) {
+ // rotate anticlockwise
+ mdl = model[m1];
+ for (i=m1;i<m2;i++) {
+ model[i] = model[i+1];
+ model[i]->serNum = i+1;
+ }
+ model[m2] = mdl;
+ model[m2]->serNum = m2+1;
+ } else {
+ // rotate clockwise
+ mdl = model[m2];
+ for (i=m2;i>m1;i--) {
+ model[i] = model[i-1];
+ model[i]->serNum = i+1;
+ }
+ model[m1] = mdl;
+ model[m1]->serNum = m1+1;
+ }
+
+ }
+
+ }
+
+
+ void CoorManager::SwapModels ( int modelNo1, int modelNo2 ) {
+ PModel mdl;
+ PPAtom A;
+ int m1,m2,i11,i12,i21,i22,i,k,n;
+
+ n = 0; // tp depress "uninitialized" warning
+
+ m1 = IMax ( 0,modelNo1-1 );
+ m2 = IMin ( nModels,modelNo2) - 1;
+ if (m1>m2) ISwap ( m1,m2 );
+
+ if (m1!=m2) {
+
+ if (model[m1])
+ model[m1]->GetAIndexRange ( i11,i12 );
+ else {
+ n = m1;
+ while ((!model[n]) && (n<m2)) n++;
+ if (n<m2) {
+ model[n]->GetAIndexRange ( i11,i12 );
+ i12 = i11-1;
+ } else
+ n = -1;
+ }
+
+ if (n>=0) {
+ if (model[m2])
+ model[m2]->GetAIndexRange ( i21,i22 );
+ else {
+ n = m2;
+ while ((!model[n]) && (m1<n)) n--;
+ if (m1<n) {
+ model[n]->GetAIndexRange ( i21,i22 );
+ i22 = i21-1;
+ } else
+ n = -1;
+ }
+ }
+
+ if (n>=0) {
+
+ i11--; i12--;
+ i21--; i22--;
+
+ A = new PAtom[atmLen];
+ k = 0;
+
+ for (i=0 ;i<i11 ;i++) A[k++] = atom[i];
+ for (i=i21 ;i<=i22 ;i++) A[k++] = atom[i];
+ for (i=i12+1 ;i<i21 ;i++) A[k++] = atom[i];
+ for (i=i11 ;i<=i12 ;i++) A[k++] = atom[i];
+
+ for (i=0 ;i<nAtoms;i++) if (A[i]) A[i]->index = i+1;
+ for (i=nAtoms;i<atmLen;i++) A[i] = NULL;
+
+ if (atom) delete[] atom;
+ atom = A;
+
+ }
+
+ mdl = model[m2];
+ model[m2] = model[m1];
+ model[m1] = mdl;
+
+ model[m1]->serNum = m1+1;
+ model[m2]->serNum = m2+1;
+
+ }
+
+ }
+
+
+ PChain CoorManager::GetChain ( int modelNo, const ChainID chainID ) {
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->GetChain ( chainID );
+ }
+ return NULL;
+ }
+
+ PChain CoorManager::GetChain ( int modelNo, int chainNo ) {
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->GetChain ( chainNo );
+ }
+ return NULL;
+ }
+
+ PChain CoorManager::GetChain ( cpstr CID ) {
+ int modno,sn,rc;
+ ChainID chname;
+ InsCode ic;
+ ResName resname;
+ AtomName aname;
+ Element elname;
+ AltLoc aloc;
+
+ CoorIDCode = CID_Ok;
+ rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
+ aname,elname,aloc,&DefPath );
+ if ((rc<0) || (rc & (APATH_WC_ModelNo | APATH_WC_ChainID))) {
+ CoorIDCode = CID_WrongPath;
+ return NULL;
+ }
+ return GetChain ( modno,chname );
+
+ }
+
+ void CoorManager::GetChainTable ( int modelNo,
+ PPChain & chainTable,
+ int & NumberOfChains ) {
+ chainTable = NULL;
+ NumberOfChains = 0;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1]) {
+ chainTable = model[modelNo-1]->chain;
+ NumberOfChains = model[modelNo-1]->nChains;
+ }
+ }
+ }
+
+ void CoorManager::GetChainTable ( cpstr CID,
+ PPChain & chainTable,
+ int & NumberOfChains ) {
+ int modno,sn,rc;
+ ChainID chname;
+ InsCode ic;
+ ResName resname;
+ AtomName aname;
+ Element elname;
+ AltLoc aloc;
+
+ chainTable = NULL;
+ NumberOfChains = 0;
+ CoorIDCode = CID_Ok;
+
+ rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
+ aname,elname,aloc,&DefPath );
+ if ((rc<0) || (rc & APATH_WC_ModelNo)) {
+ CoorIDCode = CID_WrongPath;
+ return;
+ }
+
+ if ((0<modno) && (modno<=nModels)) {
+ if (model[modno-1]) {
+ chainTable = model[modno-1]->chain;
+ NumberOfChains = model[modno-1]->nChains;
+ }
+ }
+ }
+
+
+ int CoorManager::DeleteChain ( int modelNo, const ChainID chID ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteChain ( chID );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteChain ( int modelNo, int chainNo ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteChain ( chainNo );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAllChains ( int modelNo ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAllChains();
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAllChains() {
+ int i,k;
+ k = 0;
+ for (i=0;i<nModels;i++)
+ if (model[i]) k += model[i]->DeleteAllChains();
+ return k;
+ }
+
+ int CoorManager::AddChain ( int modelNo, PChain chain ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->AddChain ( chain );
+ }
+ return 0;
+ }
+
+
+ PResidue CoorManager::GetResidue ( int modelNo,
+ const ChainID chainID,
+ int seqNo,
+ const InsCode insCode ) {
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->GetResidue ( chainID,seqNo,insCode );
+ }
+ return NULL;
+ }
+
+ PResidue CoorManager::GetResidue ( int modelNo, int chainNo,
+ int seqNo,
+ const InsCode insCode ) {
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->GetResidue ( chainNo,seqNo,insCode );
+ }
+ return NULL;
+ }
+
+ PResidue CoorManager::GetResidue ( int modelNo,
+ const ChainID chainID,
+ int resNo ) {
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->GetResidue ( chainID,resNo );
+ }
+ return NULL;
+ }
+
+ PResidue CoorManager::GetResidue ( int modelNo, int chainNo,
+ int resNo ) {
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->GetResidue ( chainNo,resNo );
+ }
+ return NULL;
+ }
+
+ PResidue CoorManager::GetResidue ( cpstr CID ) {
+ int modno,sn,rc;
+ ChainID chname;
+ InsCode ic;
+ ResName resname;
+ AtomName aname;
+ Element elname;
+ AltLoc aloc;
+
+ CoorIDCode = CID_Ok;
+ rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
+ aname,elname,aloc,&DefPath );
+ if ((rc<0) || (rc & (APATH_WC_ModelNo | APATH_WC_ChainID |
+ APATH_WC_SeqNum | APATH_WC_InsCode))) {
+ CoorIDCode = CID_WrongPath;
+ return NULL;
+ }
+ return GetResidue ( modno,chname,sn,ic );
+
+ }
+
+
+ int CoorManager::GetResidueNo ( int modelNo,
+ const ChainID chainID,
+ int seqNo,
+ const InsCode insCode ) {
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->GetResidueNo ( chainID,seqNo,insCode );
+ }
+ return -3;
+ }
+
+ int CoorManager::GetResidueNo ( int modelNo, int chainNo,
+ int seqNo,
+ const InsCode insCode ) {
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->GetResidueNo ( chainNo,seqNo,insCode );
+ }
+ return -3;
+ }
+
+ void CoorManager::GetResidueTable ( PPResidue & resTable,
+ int & NumberOfResidues ) {
+ // resTable has to be NULL or it will be reallocated. The
+ // application is responsible for deallocating the resTable (but not
+ // of its residues!). This does not apply to other GetResidueTable
+ // functions.
+ PPChain chain;
+ PPResidue res;
+ int i,j,k,n,nChains,nResidues;
+
+ if (resTable) {
+ delete[] resTable;
+ resTable = NULL;
+ }
+
+ NumberOfResidues = 0;
+ for (i=0;i<nModels;i++)
+ if (model[i]) {
+ model[i]->GetChainTable ( chain,nChains );
+ for (j=0;j<model[i]->nChains;j++)
+ if (chain[j]) {
+ chain[j]->GetResidueTable ( res,nResidues );
+ NumberOfResidues += nResidues;
+ }
+ }
+
+ if (NumberOfResidues>0) {
+ resTable = new PResidue[NumberOfResidues];
+ k = 0;
+ for (i=0;i<nModels;i++)
+ if (model[i]) {
+ model[i]->GetChainTable ( chain,nChains );
+ for (j=0;j<model[i]->nChains;j++)
+ if (chain[j]) {
+ chain[j]->GetResidueTable ( res,nResidues );
+ for (n=0;n<nResidues;n++)
+ if (res[n]) resTable[k++] = res[n];
+ }
+ }
+ NumberOfResidues = k;
+ }
+
+ }
+
+ void CoorManager::GetResidueTable ( int modelNo,
+ const ChainID chainID,
+ PPResidue & resTable,
+ int & NumberOfResidues ) {
+ PChain chain;
+ resTable = NULL;
+ NumberOfResidues = 0;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1]) {
+ chain = model[modelNo-1]->GetChain ( chainID );
+ if (chain) {
+ resTable = chain->residue;
+ NumberOfResidues = chain->nResidues;
+ }
+ }
+ }
+ }
+
+ void CoorManager::GetResidueTable ( int modelNo, int chainNo,
+ PPResidue & resTable,
+ int & NumberOfResidues ) {
+ PChain chain;
+ resTable = NULL;
+ NumberOfResidues = 0;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1]) {
+ chain = model[modelNo-1]->GetChain ( chainNo );
+ if (chain) {
+ resTable = chain->residue;
+ NumberOfResidues = chain->nResidues;
+ }
+ }
+ }
+ }
+
+ void CoorManager::GetResidueTable ( cpstr CID,
+ PPResidue & resTable,
+ int & NumberOfResidues ) {
+ int modno,sn,rc;
+ ChainID chname;
+ InsCode ic;
+ ResName resname;
+ AtomName aname;
+ Element elname;
+ AltLoc aloc;
+ PChain chain;
+
+ resTable = NULL;
+ NumberOfResidues = 0;
+ CoorIDCode = CID_Ok;
+
+ rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
+ aname,elname,aloc,&DefPath );
+ if ((rc<0) || (rc & (APATH_WC_ModelNo | APATH_WC_ChainID))) {
+ CoorIDCode = CID_WrongPath;
+ return;
+ }
+
+ if ((0<modno) && (modno<=nModels)) {
+ if (model[modno-1]) {
+ chain = model[modno-1]->GetChain ( chname );
+ if (chain) {
+ resTable = chain->residue;
+ NumberOfResidues = chain->nResidues;
+ }
+ }
+ }
+
+ }
+
+
+ int CoorManager::DeleteResidue ( int modelNo,
+ const ChainID chainID,
+ int seqNo,
+ const InsCode insCode ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteResidue ( chainID,seqNo,insCode );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteResidue ( int modelNo,
+ const ChainID chainID,
+ int resNo ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteResidue ( chainID,resNo );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteResidue ( int modelNo, int chainNo,
+ int seqNo,
+ const InsCode insCode ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteResidue ( chainNo,seqNo,insCode );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteResidue ( int modelNo, int chainNo,
+ int resNo ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteResidue ( chainNo,resNo );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAllResidues ( int modelNo,
+ const ChainID chainID ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAllResidues ( chainID );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAllResidues ( int modelNo, int chainNo ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAllResidues ( chainNo );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAllResidues ( int modelNo ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAllResidues();
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAllResidues() {
+ int i,k;
+ k = 0;
+ for (i=0;i<nModels;i++)
+ if (model[i]) k += model[i]->DeleteAllResidues();
+ return k;
+ }
+
+ int CoorManager::AddResidue ( int modelNo, const ChainID chainID,
+ PResidue res ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->AddResidue ( chainID,res );
+ }
+ return 0;
+ }
+
+ int CoorManager::AddResidue ( int modelNo, int chainNo,
+ PResidue res ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->AddResidue ( chainNo,res );
+ }
+ return 0;
+ }
+
+
+
+ int CoorManager::GetNumberOfChains ( int modelNo ) {
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->nChains;
+ }
+ return 0;
+ }
+
+ int CoorManager::GetNumberOfChains ( cpstr CID ) {
+ int modno,sn,rc;
+ ChainID chname;
+ InsCode ic;
+ ResName resname;
+ AtomName aname;
+ Element elname;
+ AltLoc aloc;
+
+ CoorIDCode = CID_Ok;
+ rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
+ aname,elname,aloc,&DefPath );
+ if ((rc<0) || (rc & APATH_WC_ModelNo)) {
+ CoorIDCode = CID_WrongPath;
+ return 0;
+ }
+
+ if ((0<modno) && (modno<=nModels)) {
+ if (model[modno-1])
+ return model[modno-1]->nChains;
+ }
+
+ return 0;
+
+ }
+
+ int CoorManager::GetNumberOfResidues ( int modelNo,
+ const ChainID chainID ) {
+ PChain chain;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1]) {
+ chain = model[modelNo-1]->GetChain ( chainID );
+ if (chain) return chain->nResidues;
+ }
+ }
+ return 0;
+ }
+
+ int CoorManager::GetNumberOfResidues ( int modelNo, int chainNo ) {
+ PChain chain;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1]) {
+ if ((0<=chainNo) && (chainNo<model[modelNo-1]->nChains)) {
+ chain = model[modelNo-1]->chain[chainNo];
+ if (chain) return chain->nResidues;
+ }
+ }
+ }
+ return 0;
+ }
+
+ int CoorManager::GetNumberOfResidues ( cpstr CID ) {
+ int modno,sn,rc;
+ ChainID chname;
+ InsCode ic;
+ ResName resname;
+ AtomName aname;
+ Element elname;
+ AltLoc aloc;
+ PChain chain;
+
+ CoorIDCode = CID_Ok;
+ rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
+ aname,elname,aloc,&DefPath );
+ if ((rc<0) || (rc & (APATH_WC_ModelNo | APATH_WC_ChainID))) {
+ CoorIDCode = CID_WrongPath;
+ return 0;
+ }
+
+ if ((0<modno) && (modno<=nModels)) {
+ if (model[modno-1]) {
+ chain = model[modno-1]->GetChain ( chname );
+ if (chain) return chain->nResidues;
+ }
+ }
+
+ return 0;
+
+ }
+
+
+ int CoorManager::GetNumberOfAtoms ( int modelNo,
+ const ChainID chainID,
+ int seqNo,
+ const InsCode insCode ) {
+ PChain chain;
+ PResidue res;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1]) {
+ chain = model[modelNo-1]->GetChain ( chainID );
+ if (chain) {
+ res = chain->GetResidue ( seqNo,insCode );
+ if (res) return res->nAtoms;
+ }
+ }
+ }
+ return 0;
+ }
+
+ int CoorManager::GetNumberOfAtoms ( int modelNo, int chainNo,
+ int seqNo,
+ const InsCode insCode ) {
+ PChain chain;
+ PResidue res;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1]) {
+ if ((0<=chainNo) && (chainNo<model[modelNo-1]->nChains)) {
+ chain = model[modelNo-1]->chain[chainNo];
+ if (chain) {
+ res = chain->GetResidue ( seqNo,insCode );
+ if (res) return res->nAtoms;
+ }
+ }
+ }
+ }
+ return 0;
+ }
+
+ int CoorManager::GetNumberOfAtoms ( int modelNo,
+ const ChainID chainID,
+ int resNo ) {
+ PChain chain;
+ PResidue res;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1]) {
+ chain = model[modelNo-1]->GetChain ( chainID );
+ if (chain) {
+ if ((0<=resNo) && (resNo<chain->nResidues)) {
+ res = chain->residue[resNo];
+ if (res) return res->nAtoms;
+ }
+ }
+ }
+ }
+ return 0;
+ }
+
+ int CoorManager::GetNumberOfAtoms ( int modelNo, int chainNo,
+ int resNo ) {
+ PChain chain;
+ PResidue res;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1]) {
+ if ((0<=chainNo) && (chainNo<model[modelNo-1]->nChains)) {
+ chain = model[modelNo-1]->chain[chainNo];
+ if (chain) {
+ if ((0<=resNo) && (resNo<chain->nResidues)) {
+ res = chain->residue[resNo];
+ if (res) return res->nAtoms;
+ }
+ }
+ }
+ }
+ }
+ return 0;
+ }
+
+ int CoorManager::GetNumberOfAtoms ( cpstr CID ) {
+ // returns number of atoms in residues identified by CID
+ int modno,sn,rc;
+ ChainID chname;
+ InsCode ic;
+ ResName resname;
+ AtomName aname;
+ Element elname;
+ AltLoc aloc;
+ PChain chain;
+ PResidue res;
+
+ CoorIDCode = CID_Ok;
+ rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
+ aname,elname,aloc,&DefPath );
+ if ((rc<0) || (rc & (APATH_WC_ModelNo | APATH_WC_ChainID |
+ APATH_WC_SeqNum | APATH_WC_InsCode))) {
+ CoorIDCode = CID_WrongPath;
+ return 0;
+ }
+
+ if ((0<modno) && (modno<=nModels)) {
+ if (model[modno-1]) {
+ chain = model[modno-1]->GetChain ( chname );
+ if (chain) {
+ res = chain->GetResidue ( sn,ic );
+ if (res) return res->nAtoms;
+ }
+ }
+ }
+
+ return 0;
+
+ }
+
+
+ // -------------------- Extracting atoms -----------------------
+
+ PAtom CoorManager::GetAtom (
+ int modelNo, // model serial number 1...
+ const ChainID chID, // chain ID
+ int seqNo, // residue sequence number
+ const InsCode insCode, // residue insertion code
+ const AtomName aname, // atom name
+ const Element elmnt, // chemical element code or '*'
+ const AltLoc aloc // alternate location indicator
+ ) {
+ PModel mdl;
+ PChain chn;
+ PResidue res;
+ PAtom atm;
+
+ if ((1<=modelNo) && (modelNo<=nModels))
+ mdl = model[modelNo-1];
+ else mdl = NULL;
+ if (!mdl) {
+ CoorIDCode = CID_NoModel;
+ return NULL;
+ }
+
+ chn = mdl->GetChain ( chID );
+ if (!chn) {
+ CoorIDCode = CID_NoChain;
+ return NULL;
+ }
+
+ res = chn->GetResidue ( seqNo,insCode );
+ if (!res) {
+ CoorIDCode = CID_NoResidue;
+ return NULL;
+ }
+
+ atm = res->GetAtom ( aname,elmnt,aloc );
+ if (!atm) CoorIDCode = CID_NoAtom;
+ else CoorIDCode = CID_Ok;
+
+ return atm;
+
+ }
+
+ PAtom CoorManager::GetAtom (
+ int modelNo, // model serial number 1...
+ const ChainID chID, // chain ID
+ int seqNo, // residue sequence number
+ const InsCode insCode, // residue insertion code
+ int atomNo // atom number 0..
+ ) {
+ PModel mdl;
+ PChain chn;
+ PResidue res;
+ PAtom atm;
+
+ if ((1<=modelNo) && (modelNo<=nModels))
+ mdl = model[modelNo-1];
+ else mdl = NULL;
+ if (!mdl) {
+ CoorIDCode = CID_NoModel;
+ return NULL;
+ }
+
+ chn = mdl->GetChain ( chID );
+ if (!chn) {
+ CoorIDCode = CID_NoChain;
+ return NULL;
+ }
+
+ res = chn->GetResidue ( seqNo,insCode );
+ if (!res) {
+ CoorIDCode = CID_NoResidue;
+ return NULL;
+ }
+
+ if ((0<=atomNo) && (atomNo<res->nAtoms))
+ atm = res->atom[atomNo];
+ else atm = NULL;
+ if (!atm) CoorIDCode = CID_NoAtom;
+ else CoorIDCode = CID_Ok;
+
+ return atm;
+
+ }
+
+ PAtom CoorManager::GetAtom (
+ int modelNo, // model serial number 1...
+ const ChainID chID, // chain ID
+ int resNo, // residue number 0..
+ const AtomName aname, // atom name
+ const Element elmnt, // chemical element code or '*'
+ const AltLoc aloc // alternate location indicator
+ ) {
+ PModel mdl;
+ PChain chn;
+ PResidue res;
+ PAtom atm;
+
+ if ((1<=modelNo) && (modelNo<=nModels))
+ mdl = model[modelNo-1];
+ else mdl = NULL;
+ if (!mdl) {
+ CoorIDCode = CID_NoModel;
+ return NULL;
+ }
+
+ chn = mdl->GetChain ( chID );
+ if (!chn) {
+ CoorIDCode = CID_NoChain;
+ return NULL;
+ }
+
+ if ((0<=resNo) && (resNo<chn->nResidues))
+ res = chn->residue[resNo];
+ else res = NULL;
+ if (!res) {
+ CoorIDCode = CID_NoResidue;
+ return NULL;
+ }
+
+ atm = res->GetAtom ( aname,elmnt,aloc );
+ if (!atm) CoorIDCode = CID_NoAtom;
+ else CoorIDCode = CID_Ok;
+
+ return atm;
+
+ }
+
+ PAtom CoorManager::GetAtom (
+ int modelNo, // model serial number 1...
+ const ChainID chID, // chain ID
+ int resNo, // residue number 0..
+ int atomNo // atom number 0..
+ ) {
+ PModel mdl;
+ PChain chn;
+ PResidue res;
+ PAtom atm;
+
+ if ((1<=modelNo) && (modelNo<=nModels))
+ mdl = model[modelNo-1];
+ else mdl = NULL;
+ if (!mdl) {
+ CoorIDCode = CID_NoModel;
+ return NULL;
+ }
+
+ chn = mdl->GetChain ( chID );
+ if (!chn) {
+ CoorIDCode = CID_NoChain;
+ return NULL;
+ }
+
+ if ((0<=resNo) && (resNo<chn->nResidues))
+ res = chn->residue[resNo];
+ else res = NULL;
+ if (!res) {
+ CoorIDCode = CID_NoResidue;
+ return NULL;
+ }
+
+ if ((0<=atomNo) && (atomNo<res->nAtoms))
+ atm = res->atom[atomNo];
+ else atm = NULL;
+ if (!atm) CoorIDCode = CID_NoAtom;
+ else CoorIDCode = CID_Ok;
+
+ return atm;
+
+ }
+
+ PAtom CoorManager::GetAtom (
+ int modelNo, // model serial number 1...
+ int chNo, // chain number 0..
+ int seqNo, // residue sequence number
+ const InsCode insCode, // residue insertion code
+ const AtomName aname, // atom name
+ const Element elmnt, // chemical element code or '*'
+ const AltLoc aloc // alternate location indicator
+ ) {
+ PModel mdl;
+ PChain chn;
+ PResidue res;
+ PAtom atm;
+
+ if ((1<=modelNo) && (modelNo<=nModels))
+ mdl = model[modelNo-1];
+ else mdl = NULL;
+ if (!mdl) {
+ CoorIDCode = CID_NoModel;
+ return NULL;
+ }
+
+ if ((0<=chNo) && (chNo<mdl->nChains))
+ chn = mdl->chain[chNo];
+ else chn = NULL;
+ if (!chn) {
+ CoorIDCode = CID_NoChain;
+ return NULL;
+ }
+
+ res = chn->GetResidue ( seqNo,insCode );
+ if (!res) {
+ CoorIDCode = CID_NoResidue;
+ return NULL;
+ }
+
+ atm = res->GetAtom ( aname,elmnt,aloc );
+ if (!atm) CoorIDCode = CID_NoAtom;
+ else CoorIDCode = CID_Ok;
+
+ return atm;
+
+ }
+
+ PAtom CoorManager::GetAtom (
+ int modelNo, // model serial number 1...
+ int chNo, // chain number 0...
+ int seqNo, // residue sequence number
+ const InsCode insCode, // residue insertion code
+ int atomNo // atom number 0...
+ ) {
+ PModel mdl;
+ PChain chn;
+ PResidue res;
+ PAtom atm;
+
+ if ((1<=modelNo) && (modelNo<=nModels))
+ mdl = model[modelNo-1];
+ else mdl = NULL;
+ if (!mdl) {
+ CoorIDCode = CID_NoModel;
+ return NULL;
+ }
+
+ if ((0<=chNo) && (chNo<mdl->nChains))
+ chn = mdl->chain[chNo];
+ else chn = NULL;
+ if (!chn) {
+ CoorIDCode = CID_NoChain;
+ return NULL;
+ }
+
+ res = chn->GetResidue ( seqNo,insCode );
+ if (!res) {
+ CoorIDCode = CID_NoResidue;
+ return NULL;
+ }
+
+ if ((0<=atomNo) && (atomNo<res->nAtoms))
+ atm = res->atom[atomNo];
+ else atm = NULL;
+ if (!atm) CoorIDCode = CID_NoAtom;
+ else CoorIDCode = CID_Ok;
+
+ return atm;
+
+ }
+
+ PAtom CoorManager::GetAtom (
+ int modelNo, // model serial number 1...
+ int chNo, // chain number 0...
+ int resNo, // residue number 0...
+ const AtomName aname, // atom name
+ const Element elmnt, // chemical element code or '*'
+ const AltLoc aloc // alternate location indicator
+ ) {
+ PModel mdl;
+ PChain chn;
+ PResidue res;
+ PAtom atm;
+
+ if ((1<=modelNo) && (modelNo<=nModels))
+ mdl = model[modelNo-1];
+ else mdl = NULL;
+ if (!mdl) {
+ CoorIDCode = CID_NoModel;
+ return NULL;
+ }
+
+ if ((0<=chNo) && (chNo<mdl->nChains))
+ chn = mdl->chain[chNo];
+ else chn = NULL;
+ if (!chn) {
+ CoorIDCode = CID_NoChain;
+ return NULL;
+ }
+
+ if ((0<=resNo) && (resNo<chn->nResidues))
+ res = chn->residue[resNo];
+ else res = NULL;
+ if (!res) {
+ CoorIDCode = CID_NoResidue;
+ return NULL;
+ }
+
+ atm = res->GetAtom ( aname,elmnt,aloc );
+ if (!atm) CoorIDCode = CID_NoAtom;
+ else CoorIDCode = CID_Ok;
+
+ return atm;
+
+ }
+
+ PAtom CoorManager::GetAtom (
+ int modelNo, // model serial number 1...
+ int chNo, // chain number 0...
+ int resNo, // residue number 0...
+ int atomNo // atom number 0...
+ ) {
+ PModel mdl;
+ PChain chn;
+ PResidue res;
+ PAtom atm;
+
+ if ((1<=modelNo) && (modelNo<=nModels))
+ mdl = model[modelNo-1];
+ else mdl = NULL;
+ if (!mdl) {
+ CoorIDCode = CID_NoModel;
+ return NULL;
+ }
+
+ if ((0<=chNo) && (chNo<mdl->nChains))
+ chn = mdl->chain[chNo];
+ else chn = NULL;
+ if (!chn) {
+ CoorIDCode = CID_NoChain;
+ return NULL;
+ }
+
+ if ((0<=resNo) && (resNo<chn->nResidues))
+ res = chn->residue[resNo];
+ else res = NULL;
+ if (!res) {
+ CoorIDCode = CID_NoResidue;
+ return NULL;
+ }
+
+ if ((0<=atomNo) && (atomNo<res->nAtoms))
+ atm = res->atom[atomNo];
+ else atm = NULL;
+ if (!atm) CoorIDCode = CID_NoAtom;
+ else CoorIDCode = CID_Ok;
+
+ return atm;
+
+ }
+
+
+ PAtom CoorManager::GetAtom ( cpstr CID ) {
+ int modno,sn,rc;
+ ChainID chname;
+ InsCode ic;
+ ResName resname;
+ AtomName aname;
+ Element elname;
+ AltLoc aloc;
+
+ CoorIDCode = CID_Ok;
+ rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
+ aname,elname,aloc,&DefPath );
+ if ((rc<0) || (rc & APATH_Incomplete)) {
+ CoorIDCode = CID_WrongPath;
+ return NULL;
+ }
+
+ return GetAtom ( modno,chname,sn,ic,aname,elname,aloc );
+
+ }
+
+
+ void CoorManager::GetAtomTable ( PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ atomTable = atom;
+ NumberOfAtoms = nAtoms;
+ }
+
+ void CoorManager::GetAtomTable ( int modelNo,
+ const ChainID chainID,
+ int seqNo,
+ const InsCode insCode,
+ PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1]) {
+ res = model[modelNo-1]->GetResidue ( chainID,seqNo,insCode );
+ if (res) {
+ atomTable = res->atom;
+ NumberOfAtoms = res->nAtoms;
+ }
+ }
+ }
+ }
+
+ void CoorManager::GetAtomTable ( int modelNo,
+ int chainNo,
+ int seqNo,
+ const InsCode insCode,
+ PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1]) {
+ res = model[modelNo-1]->GetResidue ( chainNo,seqNo,insCode );
+ if (res) {
+ atomTable = res->atom;
+ NumberOfAtoms = res->nAtoms;
+ }
+ }
+ }
+ }
+
+ void CoorManager::GetAtomTable ( int modelNo,
+ const ChainID chainID,
+ int resNo,
+ PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1]) {
+ res = model[modelNo-1]->GetResidue ( chainID,resNo );
+ if (res) {
+ atomTable = res->atom;
+ NumberOfAtoms = res->nAtoms;
+ }
+ }
+ }
+ }
+
+ void CoorManager::GetAtomTable ( int modelNo, int chainNo,
+ int resNo, PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1]) {
+ res = model[modelNo-1]->GetResidue ( chainNo,resNo );
+ if (res) {
+ atomTable = res->atom;
+ NumberOfAtoms = res->nAtoms;
+ }
+ }
+ }
+ }
+
+ void CoorManager::GetAtomTable ( cpstr CID,
+ PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ int modno,sn,rc;
+ ChainID chname;
+ InsCode ic;
+ ResName resname;
+ AtomName aname;
+ Element elname;
+ AltLoc aloc;
+ PResidue res;
+
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+
+ CoorIDCode = CID_Ok;
+ rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
+ aname,elname,aloc,&DefPath );
+ if ((rc<0) || (rc & (APATH_WC_ModelNo | APATH_WC_ChainID |
+ APATH_WC_SeqNum | APATH_WC_InsCode))) {
+ CoorIDCode = CID_WrongPath;
+ return;
+ }
+
+ res = GetResidue ( modno,chname,sn,ic );
+ if (res) {
+ atomTable = res->atom;
+ NumberOfAtoms = res->nAtoms;
+ }
+
+ }
+
+
+ void CoorManager::GetAtomTable1 ( PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ int i,j;
+ if (atomTable) delete[] atomTable;
+ if (nAtoms>0) {
+ atomTable = new PAtom[nAtoms];
+ j = 0;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (!atom[i]->Ter)
+ atomTable[j++] = atom[i];
+ }
+ NumberOfAtoms = j;
+ } else {
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ }
+ }
+
+ void CoorManager::GetAtomTable1 ( int modelNo,
+ const ChainID chainID,
+ int seqNo,
+ const InsCode insCode,
+ PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ res = NULL;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ res = model[modelNo-1]->GetResidue ( chainID,seqNo,insCode );
+ }
+ if (res)
+ res->GetAtomTable1 ( atomTable,NumberOfAtoms );
+ else {
+ if (atomTable) delete[] atomTable;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ }
+ }
+
+ void CoorManager::GetAtomTable1 ( int modelNo,
+ int chainNo,
+ int seqNo,
+ const InsCode insCode,
+ PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ res = NULL;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ res = model[modelNo-1]->GetResidue ( chainNo,seqNo,insCode );
+ }
+ if (res)
+ res->GetAtomTable1 ( atomTable,NumberOfAtoms );
+ else {
+ if (atomTable) delete[] atomTable;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ }
+ }
+
+ void CoorManager::GetAtomTable1 ( int modelNo,
+ const ChainID chainID,
+ int resNo,
+ PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ res = NULL;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ res = model[modelNo-1]->GetResidue ( chainID,resNo );
+ }
+ if (res)
+ res->GetAtomTable1 ( atomTable,NumberOfAtoms );
+ else {
+ if (atomTable) delete[] atomTable;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ }
+ }
+
+ void CoorManager::GetAtomTable1 ( int modelNo, int chainNo,
+ int resNo,
+ PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ res = NULL;
+ if ((0<modelNo) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ res = model[modelNo-1]->GetResidue ( chainNo,resNo );
+ }
+ if (res)
+ res->GetAtomTable1 ( atomTable,NumberOfAtoms );
+ else {
+ if (atomTable) delete[] atomTable;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ }
+ }
+
+ void CoorManager::GetAtomTable1 ( cpstr CID, PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ int modno,sn,rc;
+ ChainID chname;
+ InsCode ic;
+ ResName resname;
+ AtomName aname;
+ Element elname;
+ AltLoc aloc;
+ PResidue res;
+
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+
+ CoorIDCode = CID_Ok;
+ rc = ParseAtomPath ( CID,modno,chname,sn,ic,resname,
+ aname,elname,aloc,&DefPath );
+ if ((rc<0) || (rc & (APATH_WC_ModelNo | APATH_WC_ChainID |
+ APATH_WC_SeqNum | APATH_WC_InsCode))) {
+ CoorIDCode = CID_WrongPath;
+ return;
+ }
+
+ res = GetResidue ( modno,chname,sn,ic );
+ if (res)
+ res->GetAtomTable1 ( atomTable,NumberOfAtoms );
+ else {
+ if (atomTable) delete[] atomTable;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ }
+
+ }
+
+
+
+ int CoorManager::DeleteAtom ( int modelNo,
+ const ChainID chID,
+ int seqNo,
+ const InsCode insCode,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAtom ( chID,seqNo,insCode,
+ aname,elmnt,aloc );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAtom ( int modelNo,
+ const ChainID chID,
+ int seqNo,
+ const InsCode insCode,
+ int atomNo ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAtom ( chID,seqNo,insCode,atomNo );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAtom ( int modelNo,
+ const ChainID chID,
+ int resNo,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAtom ( chID,resNo,
+ aname,elmnt,aloc );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAtom ( int modelNo,
+ const ChainID chID,
+ int resNo,
+ int atomNo ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAtom ( chID,resNo,atomNo );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAtom ( int modelNo, int chNo, int seqNo,
+ const InsCode insCode,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAtom ( chNo,seqNo,insCode,
+ aname,elmnt,aloc );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAtom ( int modelNo, int chNo, int seqNo,
+ const InsCode insCode, int atomNo ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAtom ( chNo,seqNo,insCode,atomNo );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAtom ( int modelNo, int chNo, int resNo,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAtom ( chNo,resNo,
+ aname,elmnt,aloc );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAtom ( int modelNo, int chNo, int resNo,
+ int atomNo ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAtom ( chNo,resNo,atomNo );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAllAtoms ( int modelNo,
+ const ChainID chID,
+ int seqNo,
+ const InsCode insCode ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAllAtoms ( chID,seqNo,insCode );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAllAtoms ( int modelNo, const ChainID chID,
+ int resNo ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAllAtoms ( chID,resNo );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAllAtoms ( int modelNo, const ChainID chID ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAllAtoms ( chID );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAllAtoms ( int modelNo, int chNo, int seqNo,
+ const InsCode insCode ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAllAtoms ( chNo,seqNo,insCode );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAllAtoms ( int modelNo, int chNo,
+ int resNo ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAllAtoms ( chNo,resNo );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAllAtoms ( int modelNo, int chNo ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAllAtoms ( chNo );
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAllAtoms ( int modelNo ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->DeleteAllAtoms();
+ }
+ return 0;
+ }
+
+ int CoorManager::DeleteAllAtoms() {
+ int i,k;
+ k = 0;
+ for (i=0;i<nModels;i++)
+ if (model[i]) k += model[i]->DeleteAllAtoms();
+ return k;
+ }
+
+
+ /*
+ int CoorManager::DeleteAltLocs() {
+ // This function leaves only alternative location with maximal
+ // occupancy, if those are equal or unspecified, the one with
+ // "least" alternative location indicator.
+ // The function returns the number of deleted atoms and optimizes
+ // the atom index.
+ ChainID chID;
+ ResName rName;
+ InsCode iCode;
+ AtomName aname;
+ AltLoc aLoc,aL;
+ realtype occupancy,occ;
+ int seqNum;
+ int i,j,k,i1,i2,n;
+
+ k = 0;
+ n = 0;
+ i = 0;
+ while (i<nAtoms) {
+
+ if (atom[i]) {
+ seqNum = atom[i]->GetSeqNum ();
+ occupancy = atom[i]->GetOccupancy();
+ strcpy ( chID ,atom[i]->GetChainID() );
+ strcpy ( rName,atom[i]->GetResName() );
+ strcpy ( iCode,atom[i]->GetInsCode() );
+ strcpy ( aname,atom[i]->name );
+ strcpy ( aLoc ,atom[i]->altLoc );
+ j = i+1;
+ i1 = -1;
+ i2 = i;
+ while (j<nAtoms)
+ if (atom[j]) {
+ if ((atom[j]->GetSeqNum()==seqNum) &&
+ (!strcmp(atom[j]->name,aname)) &&
+ (!strcmp(atom[j]->GetInsCode(),iCode)) &&
+ (!strcmp(atom[j]->GetResName(),rName)) &&
+ (!strcmp(atom[j]->GetChainID(),chID ))) {
+ occ = atom[j]->GetOccupancy();
+ if (occ>occupancy) {
+ occupancy = occ;
+ i1 = j;
+ }
+ if (aLoc[0]) {
+ strcpy ( aL,atom[j]->altLoc );
+ if (!aL[0]) {
+ aLoc[0] = char(0);
+ i2 = j;
+ } else if (strcmp(aL,aLoc)<0) {
+ strcpy ( aLoc,aL );
+ i2 = j;
+ }
+ }
+ j++;
+ } else
+ break;
+ } else
+ j++;
+ if (i1<0) {
+ if (atom[i]->WhatIsSet & ASET_Occupancy) i1 = i;
+ else i1 = i2;
+ }
+ while (i<j) {
+ if (atom[i]) {
+ if (i!=i1) {
+ delete atom[i];
+ atom[i] = NULL;
+ n++;
+ } else {
+ if (k<i) {
+ atom[k] = atom[i];
+ atom[k]->index = k+1;
+ }
+ k++;
+ }
+ }
+ i++;
+ }
+
+ } else
+ i++;
+
+ }
+
+ nAtoms = k;
+ return n;
+
+ }
+ */
+
+ int CoorManager::DeleteAltLocs() {
+ // This function leaves only alternative location with maximal
+ // occupancy, if those are equal or unspecified, the one with
+ // "least" alternative location indicator.
+ // The function returns the number of deleted atoms. All tables
+ // remain untrimmed, so that explicit trimming or calling
+ // FinishStructEdit() at some point is required.
+ int i,n;
+
+ n = 0;
+ for (i=0;i<nModels;i++)
+ if (model[i]) n += model[i]->DeleteAltLocs();
+
+ return n;
+
+ }
+
+ int CoorManager::AddAtom ( int modelNo,
+ const ChainID chID,
+ int seqNo,
+ const InsCode insCode,
+ PAtom atom ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->AddAtom ( chID,seqNo,insCode,atom );
+ }
+ return 0;
+ }
+
+ int CoorManager::AddAtom ( int modelNo, const ChainID chID,
+ int resNo, PAtom atom ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->AddAtom ( chID,resNo,atom );
+ }
+ return 0;
+ }
+
+ int CoorManager::AddAtom ( int modelNo, int chNo,
+ int seqNo, const InsCode insCode,
+ PAtom atom ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->AddAtom ( chNo,seqNo,insCode,atom );
+ }
+ return 0;
+ }
+
+ int CoorManager::AddAtom ( int modelNo, int chNo,
+ int resNo, PAtom atom ) {
+ if ((modelNo>0) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->AddAtom ( chNo,resNo,atom );
+ }
+ return 0;
+ }
+
+
+ void CoorManager::RemoveBricks() {
+ int i,j,k;
+ if (brick) {
+ for (i=0;i<nbrick_x;i++)
+ if (brick[i]) {
+ for (j=0;j<nbrick_y;j++)
+ if (brick[i][j]) {
+ for (k=0;k<nbrick_z;k++)
+ if (brick[i][j][k]) delete brick[i][j][k];
+ delete[] brick[i][j];
+ }
+ delete[] brick[i];
+ }
+ delete[] brick;
+ }
+ brick = NULL;
+ nbrick_x = 0;
+ nbrick_y = 0;
+ nbrick_z = 0;
+ }
+
+ void CoorManager::GetBrickCoor ( PAtom A,
+ int & nx, int & ny, int & nz ) {
+ nx = (int)floor((A->x-xbrick_0)/brick_size);
+ ny = (int)floor((A->y-ybrick_0)/brick_size);
+ nz = (int)floor((A->z-zbrick_0)/brick_size);
+ if ((ny<0) || (nz<0) || (nx>=nbrick_x) ||
+ (ny>=nbrick_y) || (nz>=nbrick_z)) nx = -1;
+ }
+
+ void CoorManager::GetBrickCoor ( realtype x, realtype y,
+ realtype z, int & nx,
+ int & ny, int & nz ) {
+ nx = (int)floor((x-xbrick_0)/brick_size);
+ ny = (int)floor((y-ybrick_0)/brick_size);
+ nz = (int)floor((z-zbrick_0)/brick_size);
+ if ((ny<0) || (nz<0) || (nx>=nbrick_x) ||
+ (ny>=nbrick_y) || (nz>=nbrick_z)) nx = -1;
+ }
+
+ void CoorManager::GetBrickDimension (
+ int & nxmax, int & nymax, int & nzmax ) {
+ if (!brick) {
+ nxmax = 0; nymax = 0; nzmax = 0;
+ } else {
+ nxmax = nbrick_x;
+ nymax = nbrick_y;
+ nzmax = nbrick_z;
+ }
+ }
+
+ PBrick CoorManager::GetBrick ( int nx, int ny, int nz ) {
+ if (!brick) return NULL;
+ if ((nx>=0) && (nx<nbrick_x) &&
+ (ny>=0) && (ny<nbrick_y) &&
+ (nz>=0) && (nz<nbrick_z)) {
+ if (!brick[nx]) return NULL;
+ if (!brick[nx][ny]) return NULL;
+ return brick[nx][ny][nz];
+ }
+ return NULL;
+ }
+
+ void CoorManager::MakeBricks ( PPAtom atmvec, int avlen,
+ realtype Margin,
+ realtype BrickSize ) {
+ // Makes bricking for atoms contained in vector atmvec of length
+ // avlen, with brick size BrickSize (in angstroms). The previous
+ // bricking, if there was any, is removed.
+ int i,j, nx,ny,nz, alen;
+ realtype x1,x2, y1,y2, z1,z2, dx,dy,dz;
+ PPAtom A;
+
+ RemoveBricks();
+
+ brick_size = BrickSize;
+
+ if (atmvec) {
+ A = atmvec;
+ alen = avlen;
+ } else {
+ A = atom;
+ alen = nAtoms;
+ }
+
+ if (alen>0) {
+ // find the range of coordinates
+ x1 = MaxReal;
+ x2 = -x1;
+ y1 = MaxReal;
+ y2 = -y1;
+ z1 = MaxReal;
+ z2 = -z1;
+ for (i=0;i<alen;i++)
+ if (A[i]) {
+ if ((!A[i]->Ter) && (A[i]->WhatIsSet & ASET_Coordinates)) {
+ if (A[i]->x<x1) x1 = A[i]->x;
+ if (A[i]->x>x2) x2 = A[i]->x;
+ if (A[i]->y<y1) y1 = A[i]->y;
+ if (A[i]->y>y2) y2 = A[i]->y;
+ if (A[i]->z<z1) z1 = A[i]->z;
+ if (A[i]->z>z2) z2 = A[i]->z;
+ }
+ }
+ if (x1<MaxReal) {
+ x1 -= Margin; x2 += Margin;
+ y1 -= Margin; y2 += Margin;
+ z1 -= Margin; z2 += Margin;
+ dx = x2-x1; nbrick_x = mround(dx/brick_size+0.0001)+1;
+ dy = y2-y1; nbrick_y = mround(dy/brick_size+0.0001)+1;
+ dz = z2-z1; nbrick_z = mround(dz/brick_size+0.0001)+1;
+ xbrick_0 = x1 - (nbrick_x*brick_size-dx)/2.0;
+ ybrick_0 = y1 - (nbrick_y*brick_size-dy)/2.0;
+ zbrick_0 = z1 - (nbrick_z*brick_size-dz)/2.0;
+ for (i=0;i<alen;i++)
+ if (A[i]) {
+ if ((!A[i]->Ter) && (A[i]->WhatIsSet & ASET_Coordinates)) {
+ GetBrickCoor ( A[i],nx,ny,nz );
+ if (nx>=0) {
+ if (!brick) {
+ brick = new PPPBrick[nbrick_x];
+ for (j=0;j<nbrick_x;j++)
+ brick[j] = NULL;
+ }
+ if (!brick[nx]) {
+ brick[nx] = new PPBrick[nbrick_y];
+ for (j=0;j<nbrick_y;j++)
+ brick[nx][j] = NULL;
+ }
+ if (!brick[nx][ny]) {
+ brick[nx][ny] = new PBrick[nbrick_z];
+ for (j=0;j<nbrick_z;j++)
+ brick[nx][ny][j] = NULL;
+ }
+ if (!brick[nx][ny][nz])
+ brick[nx][ny][nz] = new Brick();
+ brick[nx][ny][nz]->AddAtom ( A[i],i );
+ } else
+ printf ( " error in "
+ "CoorManager::MakeBricks!!!\n" );
+ }
+ }
+ }
+ }
+
+ }
+
+
+ void CoorManager::RemoveMBricks() {
+ int i,j,k;
+ if (mbrick) {
+ for (i=0;i<nmbrick_x;i++)
+ if (mbrick[i]) {
+ for (j=0;j<nmbrick_y;j++)
+ if (mbrick[i][j]) {
+ for (k=0;k<nmbrick_z;k++)
+ if (mbrick[i][j][k]) delete mbrick[i][j][k];
+ delete[] mbrick[i][j];
+ }
+ delete[] mbrick[i];
+ }
+ delete[] mbrick;
+ }
+ mbrick = NULL;
+ nmbrick_x = 0;
+ nmbrick_y = 0;
+ nmbrick_z = 0;
+ }
+
+ void CoorManager::GetMBrickCoor ( PAtom A,
+ int & nx, int & ny, int & nz ) {
+ nx = (int)floor((A->x-xmbrick_0)/mbrick_size);
+ ny = (int)floor((A->y-ymbrick_0)/mbrick_size);
+ nz = (int)floor((A->z-zmbrick_0)/mbrick_size);
+ if ((ny<0) || (nz<0) || (nx>=nmbrick_x) ||
+ (ny>=nmbrick_y) || (nz>=nmbrick_z)) nx = -nx-1;
+ }
+
+ void CoorManager::GetMBrickCoor (
+ realtype x, realtype y, realtype z,
+ int & nx, int & ny, int & nz ) {
+ nx = (int)floor((x-xmbrick_0)/mbrick_size);
+ ny = (int)floor((y-ymbrick_0)/mbrick_size);
+ nz = (int)floor((z-zmbrick_0)/mbrick_size);
+ if ((ny<0) || (nz<0) || (nx>=nmbrick_x) ||
+ (ny>=nmbrick_y) || (nz>=nmbrick_z)) nx = -nx-1;
+ }
+
+ void CoorManager::GetMBrickDimension (
+ int & nxmax, int & nymax, int & nzmax ) {
+ if (!brick) {
+ nxmax = 0; nymax = 0; nzmax = 0;
+ } else {
+ nxmax = nmbrick_x;
+ nymax = nmbrick_y;
+ nzmax = nmbrick_z;
+ }
+ }
+
+ PMBrick CoorManager::GetMBrick ( int nx, int ny, int nz ) {
+ if (!mbrick) return NULL;
+ if ((nx>=0) && (nx<nmbrick_x) &&
+ (ny>=0) && (ny<nmbrick_y) &&
+ (nz>=0) && (nz<nmbrick_z)) {
+ if (!mbrick[nx]) return NULL;
+ if (!mbrick[nx][ny]) return NULL;
+ return mbrick[nx][ny][nz];
+ }
+ return NULL;
+ }
+
+ void CoorManager::MakeMBricks ( PPAtom * atmvec, ivector avlen,
+ int nStructures, realtype Margin,
+ realtype BrickSize ) {
+ // Makes bricking for atoms contained in vectors atmvec with lengths
+ // given in avlen, with brick size BrickSize (in angstroms).
+ // The previous bricking, if there was any, is removed.
+ int i,j,k, nx,ny,nz;
+ realtype x1,x2, y1,y2, z1,z2, dx,dy,dz;
+ PAtom A;
+
+ RemoveMBricks();
+
+ mbrick_size = BrickSize;
+
+ // find the range of coordinates
+ x1 = MaxReal;
+ x2 = -x1;
+ y1 = MaxReal;
+ y2 = -y1;
+ z1 = MaxReal;
+ z2 = -z1;
+ for (i=0;i<nStructures;i++)
+ for (j=0;j<avlen[i];j++) {
+ A = atmvec[i][j];
+ if (A) {
+ if ((!A->Ter) && (A->WhatIsSet & ASET_Coordinates)) {
+ if (A->x<x1) x1 = A->x;
+ if (A->x>x2) x2 = A->x;
+ if (A->y<y1) y1 = A->y;
+ if (A->y>y2) y2 = A->y;
+ if (A->z<z1) z1 = A->z;
+ if (A->z>z2) z2 = A->z;
+ }
+ }
+ }
+ if (x1<MaxReal) {
+ x1 -= Margin; x2 += Margin;
+ y1 -= Margin; y2 += Margin;
+ z1 -= Margin; z2 += Margin;
+ dx = x2-x1; nmbrick_x = mround(dx/mbrick_size+0.0001)+1;
+ dy = y2-y1; nmbrick_y = mround(dy/mbrick_size+0.0001)+1;
+ dz = z2-z1; nmbrick_z = mround(dz/mbrick_size+0.0001)+1;
+ xmbrick_0 = x1 - (nmbrick_x*mbrick_size-dx)/2.0;
+ ymbrick_0 = y1 - (nmbrick_y*mbrick_size-dy)/2.0;
+ zmbrick_0 = z1 - (nmbrick_z*mbrick_size-dz)/2.0;
+ /*
+ mbrick = new PPPMBrick[nmbrick_x];
+ for (i=0;i<nmbrick_x;i++) {
+ mbrick[i] = new PPMBrick[nmbrick_y];
+ for (j=0;j<nmbrick_y;j++) {
+ mbrick[i][j] = new PMBrick[nmbrick_z];
+ for (k=0;k<nmbrick_z;k++)
+ mbrick[i][j][k] = new mbrick(nStructures);
+ }
+ }
+ */
+ for (i=0;i<nStructures;i++)
+ for (j=0;j<avlen[i];j++) {
+ A = atmvec[i][j];
+ if (A) {
+ if ((!A->Ter) && (A->WhatIsSet & ASET_Coordinates)) {
+ GetMBrickCoor ( A,nx,ny,nz );
+ if (nx>=0) {
+ if (!mbrick) {
+ mbrick = new PPPMBrick[nmbrick_x];
+ for (k=0;k<nmbrick_x;k++)
+ mbrick[k] = NULL;
+ }
+ if (!mbrick[nx]) {
+ mbrick[nx] = new PPMBrick[nmbrick_y];
+ for (k=0;k<nmbrick_y;k++)
+ mbrick[nx][k] = NULL;
+ }
+ if (!mbrick[nx][ny]) {
+ mbrick[nx][ny] = new PMBrick[nmbrick_z];
+ for (k=0;k<nmbrick_z;k++)
+ mbrick[nx][ny][k] = NULL;
+ }
+ if (!mbrick[nx][ny][nz])
+ mbrick[nx][ny][nz] = new MBrick(nStructures);
+ mbrick[nx][ny][nz]->AddAtom ( A,i,j );
+ } else
+ printf ( " error in "
+ "CoorManager::MakeMBricks!!!\n" );
+ }
+ }
+ }
+ }
+
+ }
+
+
+ int CoorManager::GenerateSymMates ( PGenSym genSym ) {
+ //
+ // The function generates symmetry mates according to symmetry
+ // operations found in GenSym. Results of first symmetry operation
+ // (number 0) always replaces the existing set of atoms, others
+ // are added as additional sets.
+ // If GenSym is set to NULL, the function generates all
+ // symmetry mates for the unit cell taking the symmetry information
+ // from cryst.SymOps.
+ // The newly generated chains are added to each model. These
+ // chains have many-character chain names, composed as 'x_n',
+ // where 'x' is the original name and 'n' is a unique number, which
+ // coincides with the symmetry operation (order) number; number '_0'
+ // (for the very first symmetry operatyion) is missing. Another
+ // side effect is the disorder in atoms' serial numbers.
+ // The hierarchy should therefore be cleaned after
+ // generating the symmetry mates. An appropriate way to do
+ // that is to issue the following call:
+ //
+ // PDBCleanup ( PDBCLEAN_TER | PDBCLEAN_ALTCODE_STRONG |
+ // PDBCLEAN_CHAIN_STRONG | PDBCLEAN_SERIAL );
+ //
+ PPCoorManager Mate;
+ int i,j,k,n,nMates,nMates1,nAtoms1;
+ PPAtom Atom1;
+ PPModel Model1;
+
+ if (genSym) nMates = genSym->GetNofSymOps();
+ else nMates = cryst.GetNumberOfSymOps();
+ if (nMates<=0) return GSM_NoSymOps;
+
+ if (!cryst.areMatrices()) return GSM_NoTransfMatrices;
+ if (!cryst.isCellParameters()) return GSM_NoCell;
+
+ nMates1 = nMates-1;
+ if (nMates1>0) {
+
+ // Generate symmetry mates in parallel hierarchies
+ Mate = new PCoorManager[nMates1];
+ for (i=0;i<nMates1;i++) {
+ Mate[i] = new CoorManager();
+ Mate[i]->Copy ( this );
+ Mate[i]->ApplySymTransform ( i+1,genSym );
+ }
+
+ // apply 1st symmetry operation:
+ if (genSym) ApplySymTransform ( 0,genSym );
+
+ // Gather all symmetry mates in 'this' hierarchy
+ nAtoms1 = nMates*nAtoms; // new number of atoms
+ Atom1 = new PAtom[nAtoms1]; // new array of atoms
+
+ if (nModels>0) Model1 = new PModel[nModels]; // new array of
+ else Model1 = NULL; // models
+
+ k = 0; // index of collected atoms
+ for (i=0;i<nModels;i++)
+ if (model[i]) {
+ Model1[i] = newModel();
+ Model1[i]->SetMMDBManager ( PManager(this),i+1 );
+ for (j=0;j<model[i]->nChains;j++)
+ Model1[i]->MoveChain ( model[i]->chain[j],atom,Atom1,k,0 );
+ for (n=0;n<nMates1;n++)
+ for (j=0;j<model[i]->nChains;j++)
+ Model1[i]->MoveChain ( Mate[n]->model[i]->chain[j],
+ Mate[n]->atom,Atom1,k,n+1 );
+ } else
+ Model1[i] = NULL;
+
+ if (model) delete[] model;
+ model = Model1;
+
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) delete atom[i]; // should never happen
+ if (atom) delete[] atom;
+ atom = Atom1;
+ atmLen = nAtoms1; // length of Atom array
+ nAtoms = k;
+
+ // Dispose parallel hierarchies
+ for (i=0;i<nMates1;i++)
+ delete Mate[i];
+ delete[] Mate;
+
+ } else {
+ // just apply the only symmetry operation:
+ if (genSym) ApplySymTransform ( 0,genSym );
+ }
+
+ return GSM_Ok;
+
+ }
+
+ void CoorManager::ApplyTransform ( mat44 & TMatrix ) {
+ // simply transforms all coordinates by multiplying with matrix TMatrix
+ int i;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (!atom[i]->Ter) atom[i]->Transform ( TMatrix );
+ }
+ }
+
+ void CoorManager::ApplySymTransform ( int SymOpNo, PGenSym genSym ) {
+ // This procedure applies the symmetry operation number SymOpNo
+ // (starting from 0 on) and renames chains as specified in
+ // GenSym.
+ // The chains don't have to be renamed. The number of chains
+ // to be renamed is obtained as GenSym->nChains[SymOpNo], their
+ // old names - as GenSym->chID1[SymOpNo][j], and their new names
+ // - as GenSym->chID2[SymOpNo][j], 0<=j<GenSym->nChains[SymOpNo].
+ mat44 tmat;
+ int i,j,k,nChn;
+ PPChain chain;
+ if (cryst.GetTMatrix(tmat,SymOpNo,0,0,0,PSymOps(genSym))
+ ==SYMOP_Ok) {
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (!atom[i]->Ter) atom[i]->Transform ( tmat );
+ }
+ if (genSym)
+ for (i=0;i<nModels;i++)
+ if (model[i]) {
+ model[i]->GetChainTable ( chain,nChn );
+ for (j=0;j<genSym->nChains[SymOpNo];j++)
+ for (k=0;k<nChn;k++)
+ if (!strcmp(chain[k]->chainID,genSym->chID1[SymOpNo][j]))
+ chain[k]->SetChainID ( genSym->chID2[SymOpNo][j] );
+ }
+ }
+ }
+
+
+ void GetEulerRotMatrix ( mat33 & erm,
+ realtype alpha,
+ realtype beta,
+ realtype gamma ) {
+ // Calculates the Euler rotation matrix for rotation:
+ // 1) about z-axis by angle alpha (0..2*Pi)
+ // 2) about new y-axis by angle beta (0..Pi)
+ // 3) about new z-axis by angle gamma (0..2*Pi)
+ realtype ca,cb,cg, sa,sb,sg;
+
+ ca = cos(alpha);
+ sa = sin(alpha);
+ cb = cos(beta);
+ sb = sin(beta);
+ cg = cos(gamma);
+ sg = sin(gamma);
+
+ erm[0][0] = ca*cb*cg - sa*sg;
+ erm[0][1] = cb*cg*sa + ca*sg;
+ erm[0][2] = -cg*sb;
+
+ erm[1][0] = -cg*sa - ca*cb*sg;
+ erm[1][1] = ca*cg - cb*sa*sg;
+ erm[1][2] = sb*sg;
+
+ erm[2][0] = ca*sb;
+ erm[2][1] = sa*sb;
+ erm[2][2] = cb;
+
+ }
+
+
+
+ void GetEulerTMatrix ( mat44 & erm,
+ realtype alpha,
+ realtype beta,
+ realtype gamma,
+ realtype x0,
+ realtype y0,
+ realtype z0 ) {
+ // Calculates the Euler rotation-translation matrix for rotation:
+ // 1) about z-axis by angle alpha
+ // 2) about new y-axis by angle beta
+ // 3) about new z-axis by angle gamma
+ // Point (x0,y0,z0) is the center of rotation.
+ mat33 m;
+
+ m[0][0] = 1.0;
+ GetEulerRotMatrix ( m,alpha,beta,gamma );
+
+ erm[0][0] = m[0][0]; erm[0][1] = m[0][1]; erm[0][2] = m[0][2];
+ erm[1][0] = m[1][0]; erm[1][1] = m[1][1]; erm[1][2] = m[1][2];
+ erm[2][0] = m[2][0]; erm[2][1] = m[2][1]; erm[2][2] = m[2][2];
+ erm[3][0] = 0.0; erm[3][1] = 0.0; erm[3][2] = 0.0;
+
+ erm[3][3] = 1.0;
+
+ erm[0][3] = x0 - m[0][0]*x0 - m[0][1]*y0 - m[0][2]*z0;
+ erm[1][3] = y0 - m[1][0]*x0 - m[1][1]*y0 - m[1][2]*z0;
+ erm[2][3] = z0 - m[2][0]*x0 - m[2][1]*y0 - m[2][2]*z0;
+
+ }
+
+
+ void EulerRotation ( PPAtom A,
+ int nA,
+ realtype alpha,
+ realtype beta,
+ realtype gamma,
+ realtype x0,
+ realtype y0,
+ realtype z0 ) {
+ // Euler rotation: 1) about z-axis by angle alpha
+ // 2) about new y-axis by angle beta
+ // 3) about new z-axis by angle gamma
+ // Point (x0,y0,z0) is the center of rotation.
+ mat33 m;
+ realtype x,y,z;
+ int i;
+
+ m[0][0] = 1.0;
+ GetEulerRotMatrix ( m,alpha,beta,gamma );
+
+ for (i=0;i<nA;i++)
+ if (A[i]) {
+ if ((!A[i]->Ter) && (A[i]->WhatIsSet & ASET_Coordinates)) {
+ x = A[i]->x - x0;
+ y = A[i]->y - y0;
+ z = A[i]->z - z0;
+ A[i]->x = m[0][0]*x + m[0][1]*y + m[0][2]*z + x0;
+ A[i]->y = m[1][0]*x + m[1][1]*y + m[1][2]*z + y0;
+ A[i]->z = m[2][0]*x + m[2][1]*y + m[2][2]*z + z0;
+ }
+ }
+
+ }
+
+
+ void GetVecRotMatrix ( mat33 & vrm,
+ realtype alpha,
+ realtype vx,
+ realtype vy,
+ realtype vz ) {
+ // Calculates the rotation matrix for rotation by angle alpha about
+ // arbitrary vector directed as (vx,vy,vz) = (vx2-vx1,vy2-vy1,vz2-vz1).
+ realtype ca,sa, rx,ry,rz, vl;
+
+ ca = cos(alpha);
+ sa = sin(alpha);
+
+ vl = sqrt ( vx*vx + vy*vy + vz*vz );
+ if (vl<=0.0) return;
+ rx = vx/vl;
+ ry = vy/vl;
+ rz = vz/vl;
+
+ vrm[0][0] = rx*rx*(1.0-ca) + ca;
+ vrm[0][1] = rx*ry*(1.0-ca) - rz*sa;
+ vrm[0][2] = rx*rz*(1.0-ca) + ry*sa;
+
+ vrm[1][0] = ry*rx*(1.0-ca) + rz*sa;
+ vrm[1][1] = ry*ry*(1.0-ca) + ca;
+ vrm[1][2] = ry*rz*(1.0-ca) - rx*sa;
+
+ vrm[2][0] = rz*rx*(1.0-ca) - ry*sa;
+ vrm[2][1] = rz*ry*(1.0-ca) + rx*sa;
+ vrm[2][2] = rz*rz*(1.0-ca) + ca;
+
+ }
+
+
+ void GetRotParameters ( mat33 & vrm,
+ realtype & alpha,
+ realtype & vx,
+ realtype & vy,
+ realtype & vz ) {
+ // Given the rotation matrix vrm, GetRotParameters(..)
+ // returns the rotation angle alpha and the normalized
+ // rotation axis vector (vx,vy,vz).
+ // The rotation angle and vector are determined up to
+ // their sign (however correlated, so that being substituted
+ // into GetVecRotMatrix(..) they yield the same rotation
+ // matrix).
+ // The function does not check for vrm to be a valid
+ // rotation matrix.
+ realtype ca,sa,vl;
+ ca = (vrm[0][0]+vrm[1][1]+vrm[2][2]-1.0)/2.0;
+ if (ca<-1.0) ca = -1.0; // does not work if rotation
+ if (ca>1.0) ca = 1.0; // matrix is correct
+ sa = sqrt(1.0-ca*ca);
+ if (sa>0.0) {
+ alpha = acos(ca);
+ // coefficient of 2 is corrected by normalization below
+ vx = (vrm[2][1]-vrm[1][2])/sa;
+ vy = (vrm[0][2]-vrm[2][0])/sa;
+ vz = (vrm[1][0]-vrm[0][1])/sa;
+ // the following code is formally redundant if rotation
+ // matrix is correct, however it eliminates the round-offs
+ vl = sqrt(vx*vx+vy*vy+vz*vz);
+ vx /= vl;
+ vy /= vl;
+ vz /= vl;
+ } else {
+ // zero rotation, arbitrary axis would do
+ alpha = 0.0;
+ vx = 1.0;
+ vy = 0.0;
+ vz = 0.0;
+ }
+ }
+
+
+ void GetVecTMatrix ( mat44 & vrm,
+ realtype alpha,
+ realtype vx,
+ realtype vy,
+ realtype vz,
+ realtype x0,
+ realtype y0,
+ realtype z0 ) {
+ // Calculates the rotation-translation matrix for rotation by angle
+ // alpha about arbitrary vector directed as (vx,vy,vz) =
+ // (vx2-vx1,vy2-vy1,vz2-vz1). Point (x0,y0,z0) is the center of
+ // rotation -- actually a point belonging to the rotation axis.
+ mat33 m;
+
+ GetVecRotMatrix ( m,alpha,vx,vy,vz );
+
+ vrm[0][0] = m[0][0]; vrm[0][1] = m[0][1]; vrm[0][2] = m[0][2];
+ vrm[1][0] = m[1][0]; vrm[1][1] = m[1][1]; vrm[1][2] = m[1][2];
+ vrm[2][0] = m[2][0]; vrm[2][1] = m[2][1]; vrm[2][2] = m[2][2];
+ vrm[3][0] = 0.0; vrm[3][1] = 0.0; vrm[3][2] = 0.0;
+
+ vrm[3][3] = 1.0;
+
+ vrm[0][3] = x0 - m[0][0]*x0 - m[0][1]*y0 - m[0][2]*z0;
+ vrm[1][3] = y0 - m[1][0]*x0 - m[1][1]*y0 - m[1][2]*z0;
+ vrm[2][3] = z0 - m[2][0]*x0 - m[2][1]*y0 - m[2][2]*z0;
+
+ }
+
+
+ void VectorRotation ( PPAtom A,
+ int nA,
+ realtype alpha,
+ realtype vx,
+ realtype vy,
+ realtype vz,
+ realtype x0,
+ realtype y0,
+ realtype z0 ) {
+ // Vector rotation is rotation by angle alpha about arbitrary
+ // vector directed as (vx,vy,vz) = (vx2-vx1,vy2-vy1,vz2-vz1).
+ // Point (x0,y0,z0) is the center of rotation -- actually
+ // a point belonging to the rotation axis.
+ mat33 m;
+ realtype x,y,z;
+ int i;
+
+ GetVecRotMatrix ( m, alpha,vx,vy,vz );
+
+ for (i=0;i<nA;i++)
+ if (A[i]) {
+ if ((!A[i]->Ter) && (A[i]->WhatIsSet & ASET_Coordinates)) {
+ x = A[i]->x - x0;
+ y = A[i]->y - y0;
+ z = A[i]->z - z0;
+ A[i]->x = m[0][0]*x + m[0][1]*y + m[0][2]*z + x0;
+ A[i]->y = m[1][0]*x + m[1][1]*y + m[1][2]*z + y0;
+ A[i]->z = m[2][0]*x + m[2][1]*y + m[2][2]*z + z0;
+ }
+ }
+
+ }
+
+
+ void GetMassCenter ( PPAtom A, int nA,
+ realtype & xmc, realtype & ymc,
+ realtype & zmc ) {
+ realtype w,mass;
+ int i,k;
+
+ xmc = 0.0;
+ ymc = 0.0;
+ zmc = 0.0;
+ mass = 0.0;
+
+ for (i=0;i<nA;i++)
+ if (A[i]) {
+ if ((!A[i]->Ter) && (A[i]->WhatIsSet & ASET_Coordinates)) {
+ k = getElementNo ( A[i]->element );
+ if (k>=0) w = MolecWeight[k];
+ else w = 1.0;
+ xmc += w*A[i]->x;
+ ymc += w*A[i]->y;
+ zmc += w*A[i]->z;
+ mass += w;
+ }
+ }
+
+ if (mass>0.0) {
+ xmc /= mass;
+ ymc /= mass;
+ zmc /= mass;
+ }
+
+ }
+
+ int CoorManager::BringToUnitCell() {
+ // brings all chains into 0th unit cell
+ PChain chain;
+ PPAtom atom;
+ realtype x0,y0,z0, x,y,z, xf,yf,zf, sx,sy,sz;
+ realtype dx,dy,dz, d,d0;
+ int nAtoms;
+ int i,j,k,n,m,nt, ic,jc,kc, is,js,ks;
+
+ if (!cryst.areMatrices()) return -1;
+
+ is = 0; // this is only
+ js = 0; // to depress
+ ks = 0; // "uninitialized" worning
+
+ cryst.Frac2Orth ( 0.5,0.5,0.5, x0,y0,z0 );
+
+ nt = 0;
+ for (i=0;i<nModels;i++)
+ if (model[i]) {
+ for (j=0;j<model[i]->nChains;j++) {
+ chain = model[i]->chain[j];
+ if (chain) {
+
+ x = 0.0;
+ y = 0.0;
+ z = 0.0;
+ m = 0;
+ for (k=0;k<chain->nResidues;k++)
+ if (chain->residue[k]) {
+ chain->residue[k]->GetAtomTable ( atom,nAtoms );
+ for (n=0;n<nAtoms;n++)
+ if (atom[n]) {
+ if (!atom[n]->Ter) {
+ x += atom[n]->x;
+ y += atom[n]->y;
+ z += atom[n]->z;
+ m++;
+ }
+ }
+ }
+ x /= m;
+ y /= m;
+ z /= m;
+
+ cryst.Orth2Frac ( x,y,z, xf,yf,zf );
+ sx = frac ( xf );
+ sy = frac ( yf );
+ sz = frac ( zf );
+ d0 = MaxReal;
+ for (ic=-3;ic<3;ic++)
+ for (jc=-3;jc<3;jc++)
+ for (kc=-3;kc<3;kc++) {
+ cryst.Frac2Orth ( sx+ic,sy+jc,sz+kc, dx,dy,dz );
+ dx -= x0;
+ dy -= y0;
+ dz -= z0;
+ d = dx*dx + dy*dy + dz*dz;
+ if (d<d0) {
+ d0 = d;
+ is = ic;
+ js = jc;
+ ks = kc;
+ }
+ }
+
+ sx = xf - (sx+is);
+ sy = yf - (sy+js);
+ sz = zf - (sz+ks);
+
+ if ((fabs(sx)>1.0e-10) || (fabs(sy)>1.0e-10)
+ || (fabs(sz)>1.0e-10)) {
+ nt++;
+ for (k=0;k<chain->nResidues;k++)
+ if (chain->residue[k]) {
+ chain->residue[k]->GetAtomTable ( atom,nAtoms );
+ for (n=0;n<nAtoms;n++)
+ if (atom[n]) {
+ if (!atom[n]->Ter) {
+ cryst.Orth2Frac ( atom[n]->x,atom[n]->y,
+ atom[n]->z,
+ xf,yf,zf );
+ cryst.Frac2Orth ( xf-sx,yf-sy,zf-sz,
+ atom[n]->x,atom[n]->y,
+ atom[n]->z );
+ }
+ }
+ }
+ }
+
+ }
+ }
+ }
+
+ return nt; // number of converted chains
+
+ }
+
+
+ bool CoorManager::Frac2Orth (
+ realtype xfrac, realtype yfrac, realtype zfrac,
+ realtype & xorth, realtype & yorth, realtype & zorth ) {
+ return cryst.Frac2Orth ( xfrac,yfrac,zfrac, xorth,yorth,zorth );
+ }
+
+ bool CoorManager::Orth2Frac (
+ realtype xorth, realtype yorth, realtype zorth,
+ realtype & xfrac, realtype & yfrac, realtype & zfrac ) {
+ return cryst.Orth2Frac ( xorth,yorth,zorth, xfrac,yfrac,zfrac );
+ }
+
+
+ bool CoorManager::Frac2Orth ( mat44 & F, mat44 & T ) {
+ return cryst.Frac2Orth ( F,T );
+ }
+
+ bool CoorManager::Orth2Frac ( mat44 & T, mat44 & F ) {
+ return cryst.Orth2Frac ( T,F );
+ }
+
+
+
+ // ------------------------ Contacts -------------------------------
+
+
+ #define CA_CA_Dist2 16.0
+
+ void CoorManager::FindSeqSection ( PAtom atom, int seqDist,
+ int & seq1, int & seq2 ) {
+ PAtom a;
+ PResidue res;
+ PChain chain;
+ realtype x0,y0,z0, x,y,z, dx,dy,dz, d2;
+ int i1;
+ bool B0,B;
+
+ x = 0.0;
+ y = 0.0;
+ z = 0.0;
+ x0 = 0.0;
+ y0 = 0.0;
+ z0 = 0.0;
+
+ res = atom->residue;
+ if ((!res) || (seqDist<=0)) {
+ seq1 = MaxInt4;
+ seq2 = MinInt4;
+ return;
+ }
+
+ chain = res->chain;
+ if (!chain) {
+ seq1 = MaxInt4;
+ seq2 = MinInt4;
+ return;
+ }
+
+ if (seqDist==1) {
+ seq1 = res->index;
+ seq2 = seq1;
+ return;
+ }
+
+ a = res->GetAtom ( pstr("CA"),pstr("C"),NULL );
+ if (a) {
+ x0 = a->x;
+ y0 = a->y;
+ z0 = a->z;
+ B0 = true;
+ } else
+ B0 = false;
+ if (B0) {
+ x = x0;
+ y = y0;
+ z = z0;
+ }
+
+ B = B0;
+ seq2 = res->index;
+ i1 = IMin(chain->nResidues,seq2+seqDist)-1;
+ while (seq2<i1) {
+ seq2++;
+ if (chain->residue[seq2]) {
+ a = chain->residue[seq2]->GetAtom ( pstr("CA"),pstr("C"),NULL );
+ if (a && B) {
+ dx = x-a->x;
+ dy = y-a->y;
+ dz = z-a->z;
+ d2 = dx*dx + dy*dy + dz*dz;
+ if (d2>CA_CA_Dist2) {
+ seq2--;
+ break;
+ }
+ }
+ if (a) {
+ x = a->x;
+ y = a->y;
+ z = a->z;
+ B = true;
+ } else
+ B = false;
+ }
+ }
+
+ if (B0) {
+ x = x0;
+ y = y0;
+ z = z0;
+ }
+ B = B0;
+ seq1 = res->index;
+ i1 = IMax(0,seq1-seqDist+1);
+ while (seq1>i1) {
+ seq1--;
+ if (chain->residue[seq1]) {
+ a = chain->residue[seq1]->GetAtom ( pstr("CA"),pstr("C"),NULL );
+ if (a && B) {
+ dx = x-a->x;
+ dy = y-a->y;
+ dz = z-a->z;
+ d2 = dx*dx + dy*dy + dz*dz;
+ if (d2>CA_CA_Dist2) {
+ seq1++;
+ break;
+ }
+ }
+ if (a) {
+ x = a->x;
+ y = a->y;
+ z = a->z;
+ B = true;
+ } else
+ B = false;
+ }
+ }
+
+ }
+
+
+ bool CoorManager::iContact ( PAtom a1, PAtom a2,
+ int seq1, int seq2,
+ realtype dd, realtype d12,
+ realtype d22, realtype & d2 ) {
+ // seq1..seq2 is forbidden region for residue sequence numbers
+ PResidue res1,res2;
+ PChain chain1,chain2;
+ realtype dx,dy,dz;
+
+ if (a2->Ter) return false;
+
+ dx = fabs(a2->x-a1->x);
+ if (dx<=dd) {
+ dy = fabs(a2->y-a1->y);
+ if (dy<=dd) {
+ dz = fabs(a2->z-a1->z);
+ if (dz<=dd) {
+ d2 = dx*dx + dy*dy + dz*dz;
+ if ((d12<=d2) && (d2<=d22)) {
+ if (seq1<=seq2) {
+ res1 = a1->residue;
+ res2 = a2->residue;
+ if (res1 && res2) {
+ chain1 = res1->chain;
+ chain2 = res2->chain;
+ if (chain1 && chain2) {
+ if (!strcmp(chain1->chainID,chain2->chainID)) {
+ if ((seq1<=res2->index) && (res2->index<=seq2))
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+
+ }
+
+ bool CoorManager::iContact ( realtype x, realtype y,
+ realtype z, PAtom a2,
+ realtype dd, realtype d12,
+ realtype d22, realtype & d2 ) {
+ realtype dx,dy,dz;
+
+ if (a2->Ter) return false;
+
+ dx = fabs(a2->x-x);
+ if (dx<=dd) {
+ dy = fabs(a2->y-y);
+ if (dy<=dd) {
+ dz = fabs(a2->z-z);
+ if (dz<=dd) {
+ d2 = dx*dx + dy*dy + dz*dz;
+ if ((d12<=d2) && (d2<=d22)) return true;
+ }
+ }
+ }
+
+ return false;
+
+ }
+
+
+ void CoorManager::SeekContacts ( PPAtom AIndex,
+ int ilen,
+ int atomNum,
+ realtype dist1,
+ realtype dist2,
+ int seqDist,
+ RPContact contact,
+ int & ncontacts,
+ int maxlen,
+ long group ) {
+ PContactIndex contactIndex;
+ realtype d12,d22,d2;
+ int i,seq1,seq2;
+
+ if (!AIndex) return;
+ if (dist2<dist1) return;
+ if (!AIndex[atomNum]) return;
+ if (AIndex[atomNum]->Ter) return;
+
+ contactIndex = new ContactIndex ( contact,maxlen,ncontacts,ilen );
+
+ FindSeqSection ( AIndex[atomNum],seqDist,seq1,seq2 );
+
+ d12 = dist1*dist1;
+ d22 = dist2*dist2;
+
+ for (i=0;i<ilen;i++)
+ if ((i!=atomNum) && AIndex[i]) {
+ if (iContact(AIndex[atomNum],AIndex[i],seq1,seq2,dist2,
+ d12,d22,d2))
+ contactIndex->AddContact ( atomNum,i,sqrt(d2),group );
+ }
+
+ contactIndex->GetIndex ( contact,ncontacts );
+
+ delete contactIndex;
+
+ }
+
+
+ void CoorManager::SeekContacts ( PAtom A,
+ PPAtom AIndex,
+ int ilen,
+ realtype dist1,
+ realtype dist2,
+ int seqDist,
+ RPContact contact,
+ int & ncontacts,
+ int maxlen,
+ long group
+ ) {
+ PContactIndex contactIndex;
+ realtype d12,d22,d2;
+ int i,seq1,seq2;
+
+ if (!AIndex) return;
+ if (dist2<dist1) return;
+ if (!A) return;
+ if (A->Ter) return;
+
+ contactIndex = new ContactIndex ( contact,maxlen,ncontacts,ilen );
+
+ FindSeqSection ( A,seqDist,seq1,seq2 );
+
+ d12 = dist1*dist1;
+ d22 = dist2*dist2;
+
+ for (i=0;i<ilen;i++)
+ if ((AIndex[i]!=A) && AIndex[i]) {
+ if (iContact(A,AIndex[i],seq1,seq2,dist2,d12,d22,d2))
+ contactIndex->AddContact ( -1,i,sqrt(d2),group );
+ }
+
+ contactIndex->GetIndex ( contact,ncontacts );
+
+ delete contactIndex;
+
+ }
+
+
+ void CoorManager::SeekContacts ( PPAtom AIndex1,
+ int ilen1,
+ PPAtom AIndex2,
+ int ilen2,
+ realtype dist1,
+ realtype dist2,
+ int seqDist,
+ RPContact contact,
+ int & ncontacts,
+ int maxlen,
+ mat44 * TMatrix,
+ long group,
+ int bricking,
+ bool doSqrt
+ ) {
+ // It is Ok to have NULL pointers in AIndex1 and AIndex2
+ PContactIndex contactIndex;
+ PPAtom A1,A2;
+ rvector sx0,sy0,sz0;
+ rvector dx0,dy0,dz0;
+ realtype d12,d22,d2, eps;
+ int l1,l2, i,j, nx,ny,nz, dn;
+ int ix1,ix2, iy1,iy2, iz1,iz2, ix,iy,iz;
+ int seq1,seq2;
+ PBrick B;
+ bool swap,UnitT;
+
+ if ((dist2<dist1) || (!AIndex1) || (!AIndex2)) return;
+
+ contactIndex = new ContactIndex ( contact,maxlen,ncontacts,
+ ilen1*ilen2 );
+
+ sx0 = NULL;
+ sy0 = NULL;
+ sz0 = NULL;
+ dx0 = NULL;
+ dy0 = NULL;
+ dz0 = NULL;
+ UnitT = true;
+ if (TMatrix) {
+ // Transformation matrix is given. Check that that is not
+ // the unit one.
+ eps = 1.0e-6;
+ for (i=0;(i<3) && UnitT;i++)
+ for (j=0;(j<4) && UnitT;j++)
+ if (i==j) UnitT = fabs(1.0-(*TMatrix)[i][j])<eps;
+ else UnitT = fabs((*TMatrix)[i][j])<eps;
+ if (!UnitT) {
+ // A non-unit transformation to AIndex2 is required.
+ // As AIndex1 and AIndex2 may overlap, we have to save
+ // the original AIndex1 coordinates
+ GetVectorMemory ( sx0,ilen1,0 );
+ GetVectorMemory ( sy0,ilen1,0 );
+ GetVectorMemory ( sz0,ilen1,0 );
+ for (i=0;i<ilen1;i++)
+ if (AIndex1[i]) {
+ sx0[i] = AIndex1[i]->x;
+ sy0[i] = AIndex1[i]->y;
+ sz0[i] = AIndex1[i]->z;
+ }
+ // Save original AIndex2 coordinates and modify the index
+ GetVectorMemory ( dx0,ilen2,0 );
+ GetVectorMemory ( dy0,ilen2,0 );
+ GetVectorMemory ( dz0,ilen2,0 );
+ for (i=0;i<ilen2;i++)
+ if (AIndex2[i]) {
+ dx0[i] = AIndex2[i]->x;
+ dy0[i] = AIndex2[i]->y;
+ dz0[i] = AIndex2[i]->z;
+ AIndex2[i]->Transform ( *TMatrix );
+ }
+ }
+ }
+
+ // choose A2 as the largest atom set convenient for
+ // bricking (bricking on larger set is more efficient)
+ if (bricking & BRICK_ON_1) {
+ A1 = AIndex2;
+ A2 = AIndex1;
+ l1 = ilen2;
+ l2 = ilen1;
+ swap = true;
+ } else if (bricking & BRICK_ON_2) {
+ A1 = AIndex1;
+ A2 = AIndex2;
+ l1 = ilen1;
+ l2 = ilen2;
+ swap = false;
+ } else if (ilen1<=ilen2) {
+ A1 = AIndex1;
+ A2 = AIndex2;
+ l1 = ilen1;
+ l2 = ilen2;
+ swap = false;
+ } else {
+ A1 = AIndex2;
+ A2 = AIndex1;
+ l1 = ilen2;
+ l2 = ilen1;
+ swap = true;
+ }
+
+ d12 = dist1*dist1;
+ d22 = dist2*dist2;
+
+ if (((bricking & BRICK_READY)==0) || (!brick))
+ MakeBricks ( A2,l2,dist2*1.5 );
+
+ dn = mround(dist2/brick_size)+1;
+
+ if (brick)
+ for (i=0;i<l1;i++)
+ if (A1[i]) {
+ if (!A1[i]->Ter) {
+ if (UnitT) {
+ // No transformation -- AIndex1 and AIndex2 are unmodified.
+ // Calculate the forbidden sequence region
+ FindSeqSection ( A1[i],seqDist,seq1,seq2 );
+ // And the brick location
+ GetBrickCoor ( A1[i],nx,ny,nz );
+ } else {
+ // AIndex2 and AIndex1 are modified, but the sequence
+ // distance does not apply to physically different chains
+ // (meaning that transformation of A2 effectively makes
+ // a different chain). Use unmodified atom coordinates
+ // of 1st set for calculating the brick location.
+ if (swap) GetBrickCoor ( A1[i],nx,ny,nz ); // A1 is AIndex2
+ else GetBrickCoor ( sx0[i],sy0[i],sz0[i],nx,ny,nz );
+ }
+ if (nx>=0) {
+ ix1 = IMax ( 0,nx-dn );
+ iy1 = IMax ( 0,ny-dn );
+ iz1 = IMax ( 0,nz-dn );
+ ix2 = IMin ( nbrick_x,nx+dn+1 );
+ iy2 = IMin ( nbrick_y,ny+dn+1 );
+ iz2 = IMin ( nbrick_z,nz+dn+1 );
+ if (UnitT) {
+ // AIndex1 unmodified, use it
+ for (ix=ix1;ix<ix2;ix++)
+ if (brick[ix])
+ for (iy=iy1;iy<iy2;iy++)
+ if (brick[ix][iy])
+ for (iz=iz1;iz<iz2;iz++) {
+ B = brick[ix][iy][iz];
+ if (B)
+ for (j=0;j<B->nAtoms;j++)
+ if (B->atom[j]!=A1[i]) {
+ if (iContact(A1[i],B->atom[j],seq1,seq2,
+ dist2,d12,d22,d2)) {
+ if (doSqrt) d2 = sqrt(d2);
+ if (swap) contactIndex->AddContact (
+ B->id[j],i,d2,group );
+ else contactIndex->AddContact (
+ i,B->id[j],d2,group );
+ }
+ }
+ }
+ } else if (swap) {
+ // A1 stands for AIndex2, it is modified and we need to use
+ // the modified coordinates
+ for (ix=ix1;ix<ix2;ix++)
+ if (brick[ix])
+ for (iy=iy1;iy<iy2;iy++)
+ if (brick[ix][iy])
+ for (iz=iz1;iz<iz2;iz++) {
+ B = brick[ix][iy][iz];
+ if (B)
+ for (j=0;j<B->nAtoms;j++)
+ if (iContact(A1[i]->x,A1[i]->y,A1[i]->z,
+ B->atom[j], dist2,d12,d22,d2)) {
+ if (doSqrt) d2 = sqrt(d2);
+ contactIndex->AddContact ( B->id[j],i,d2,group );
+ }
+ }
+ } else {
+ // A1 stands for AIndex1, it may be modified (if AIndex1
+ // and AIndex2 overlap) -- use its unmodified coordinates
+ // instead.
+ for (ix=ix1;ix<ix2;ix++)
+ if (brick[ix])
+ for (iy=iy1;iy<iy2;iy++)
+ if (brick[ix][iy])
+ for (iz=iz1;iz<iz2;iz++) {
+ B = brick[ix][iy][iz];
+ if (B)
+ for (j=0;j<B->nAtoms;j++)
+ if (iContact(sx0[i],sy0[i],sz0[i],
+ B->atom[j],dist2,d12,d22,d2)) {
+ if (doSqrt) d2 = sqrt(d2);
+ contactIndex->AddContact ( i,B->id[j],d2,group );
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ if (!UnitT) {
+ // restore original coordinates
+ for (i=0;i<ilen1;i++)
+ if (AIndex1[i]) {
+ AIndex1[i]->x = sx0[i];
+ AIndex1[i]->y = sy0[i];
+ AIndex1[i]->z = sz0[i];
+ }
+ for (i=0;i<ilen2;i++)
+ if (AIndex2[i]) {
+ AIndex2[i]->x = dx0[i];
+ AIndex2[i]->y = dy0[i];
+ AIndex2[i]->z = dz0[i];
+ }
+ FreeVectorMemory ( sx0,0 );
+ FreeVectorMemory ( sy0,0 );
+ FreeVectorMemory ( sz0,0 );
+ FreeVectorMemory ( dx0,0 );
+ FreeVectorMemory ( dy0,0 );
+ FreeVectorMemory ( dz0,0 );
+ }
+
+ contactIndex->GetIndex ( contact,ncontacts );
+
+ delete contactIndex;
+
+ }
+
+
+ void CoorManager::SeekContacts ( PPAtom AIndex1,
+ int ilen1,
+ PPAtom AIndex2,
+ int ilen2,
+ realtype contDist,
+ PContact contact,
+ int & ncontacts,
+ int bricking
+ ) {
+ // Simplified optimized for speed version:
+ // - no NULL pointers and Ters in AIndex1 and AIndex2
+ // - no checks for identity atoms in AIndex1 and AIndex2
+ // - contact must be pre-allocated with at least ilen1*ilen2 elements
+ // - contact returns square distances
+ // - ncontacts is always reset
+ PPAtom A1,A2;
+ realtype contDist2, dx,dy,dz, d2;
+ int l1,l2, i,j, nx,ny,nz, dn;
+ int ix1,ix2, iy1,iy2, iz1,iz2, ix,iy,iz;
+ PBrick B;
+ bool swap;
+
+ // choose A2 as the largest atom set convenient for
+ // bricking (bricking on larger set is more efficient)
+ if (bricking & BRICK_ON_1) {
+ A1 = AIndex2;
+ A2 = AIndex1;
+ l1 = ilen2;
+ l2 = ilen1;
+ swap = true;
+ } else if (bricking & BRICK_ON_2) {
+ A1 = AIndex1;
+ A2 = AIndex2;
+ l1 = ilen1;
+ l2 = ilen2;
+ swap = false;
+ } else if (ilen1<=ilen2) {
+ A1 = AIndex1;
+ A2 = AIndex2;
+ l1 = ilen1;
+ l2 = ilen2;
+ swap = false;
+ } else {
+ A1 = AIndex2;
+ A2 = AIndex1;
+ l1 = ilen2;
+ l2 = ilen1;
+ swap = true;
+ }
+
+ contDist2 = contDist*contDist;
+
+ if (((bricking & BRICK_READY)==0) || (!brick))
+ MakeBricks ( A2,l2,contDist*1.5 );
+
+ ncontacts = 0;
+
+ if (!brick) return;
+
+ dn = (int)floor(contDist/brick_size)+1;
+
+ if (swap) {
+
+ for (i=0;i<l1;i++)
+ if (A1[i]) {
+ // Find brick location
+ GetBrickCoor ( A1[i],nx,ny,nz );
+ if (nx>=0) {
+ ix1 = IMax ( 0,nx-dn );
+ iy1 = IMax ( 0,ny-dn );
+ iz1 = IMax ( 0,nz-dn );
+ ix2 = IMin ( nbrick_x,nx+dn+1 );
+ iy2 = IMin ( nbrick_y,ny+dn+1 );
+ iz2 = IMin ( nbrick_z,nz+dn+1 );
+ for (ix=ix1;ix<ix2;ix++)
+ if (brick[ix])
+ for (iy=iy1;iy<iy2;iy++)
+ if (brick[ix][iy])
+ for (iz=iz1;iz<iz2;iz++) {
+ B = brick[ix][iy][iz];
+ if (B)
+ for (j=0;j<B->nAtoms;j++) {
+ dx = A1[i]->x - B->atom[j]->x;
+ dy = A1[i]->y - B->atom[j]->y;
+ dz = A1[i]->z - B->atom[j]->z;
+ d2 = dx*dx + dy*dy + dz*dz;
+ if (d2<=contDist2) {
+ contact[ncontacts].id1 = B->id[j];
+ contact[ncontacts].id2 = i;
+ contact[ncontacts].dist = d2;
+ ncontacts++;
+ }
+ }
+ }
+ }
+ }
+
+ } else {
+
+ for (i=0;i<l1;i++)
+ if (A1[i]) {
+ // Find brick location
+ GetBrickCoor ( A1[i],nx,ny,nz );
+ if (nx>=0) {
+ ix1 = IMax ( 0,nx-dn );
+ iy1 = IMax ( 0,ny-dn );
+ iz1 = IMax ( 0,nz-dn );
+ ix2 = IMin ( nbrick_x,nx+dn+1 );
+ iy2 = IMin ( nbrick_y,ny+dn+1 );
+ iz2 = IMin ( nbrick_z,nz+dn+1 );
+ for (ix=ix1;ix<ix2;ix++)
+ if (brick[ix])
+ for (iy=iy1;iy<iy2;iy++)
+ if (brick[ix][iy])
+ for (iz=iz1;iz<iz2;iz++) {
+ B = brick[ix][iy][iz];
+ if (B)
+ for (j=0;j<B->nAtoms;j++) {
+ dx = A1[i]->x - B->atom[j]->x;
+ dy = A1[i]->y - B->atom[j]->y;
+ dz = A1[i]->z - B->atom[j]->z;
+ d2 = dx*dx + dy*dy + dz*dz;
+ if (d2<=contDist2) {
+ contact[ncontacts].id1 = i;
+ contact[ncontacts].id2 = B->id[j];
+ contact[ncontacts].dist = d2;
+ ncontacts++;
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ }
+
+
+ void CoorManager::SeekContacts ( PPAtom AIndex1,
+ int ilen1,
+ PPAtom * AIndex2,
+ ivector ilen2,
+ int nStructures,
+ realtype dist1,
+ realtype dist2,
+ PPMContact & contact,
+ int bricking
+ ) {
+ // It is Ok to have NULL pointers in AIndex1 and AIndex2
+ PMBrick B;
+ PAtom A;
+ realtype d12,d22,d2;
+ int dn, i,j,k, nx,ny,nz, ix1,iy1,iz1, ix2,iy2,iz2;
+ int ix,iy,iz;
+
+ if (dist2<dist1) return;
+ if ((!AIndex1) || (!AIndex2)) return;
+
+ d12 = dist1*dist1;
+ d22 = dist2*dist2;
+
+ if (((bricking & BRICK_READY)==0) || (!mbrick))
+ MakeMBricks ( AIndex2,ilen2,nStructures,dist2*1.5 );
+
+ contact = new PMContact[ilen1];
+
+ dn = mround(dist2/brick_size)+1;
+
+ if (mbrick)
+ for (i=0;i<ilen1;i++) {
+ A = AIndex1[i];
+ contact[i] = NULL;
+ if (A) {
+ if (!A->Ter) {
+ contact[i] = new MContact(nStructures);
+ contact[i]->contactID = i;
+ // Calculate the brick location
+ GetMBrickCoor ( A,nx,ny,nz );
+ if (nx>=0) {
+ ix1 = IMax ( 0,nx-dn );
+ iy1 = IMax ( 0,ny-dn );
+ iz1 = IMax ( 0,nz-dn );
+ ix2 = IMin ( nmbrick_x,nx+dn+1 );
+ iy2 = IMin ( nmbrick_y,ny+dn+1 );
+ iz2 = IMin ( nmbrick_z,nz+dn+1 );
+ for (ix=ix1;ix<ix2;ix++)
+ if (mbrick[ix])
+ for (iy=iy1;iy<iy2;iy++)
+ if (mbrick[ix][iy])
+ for (iz=iz1;iz<iz2;iz++) {
+ B = mbrick[ix][iy][iz];
+ if (B)
+ for (j=0;j<nStructures;j++)
+ for (k=0;k<B->nAtoms[j];k++)
+ if (B->atom[j][k]!=A) {
+ if (iContact(A,B->atom[j][k],
+ MaxInt4,MinInt4,
+ dist2,d12,d22,d2))
+ contact[i]->AddContact (
+ B->atom[j][k],j,B->id[j][k] );
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ for (i=0;i<ilen1;i++)
+ contact[i] = NULL;
+
+ }
+
+
+
+ DefineClass(QSortContacts)
+
+ class QSortContacts : public QuickSort {
+ public :
+ QSortContacts() : QuickSort() {}
+ int Compare ( int i, int j );
+ void Swap ( int i, int j );
+ void Sort ( PContact contact, int ncontacts, int sortmode );
+ protected :
+ int mode;
+ };
+
+ int QSortContacts::Compare ( int i, int j ) {
+ bool gt,lt;
+ switch (mode) {
+ default :
+ case CNSORT_1INC : gt = (((PContact)data)[i].id1 >
+ ((PContact)data)[j].id1);
+ lt = (((PContact)data)[i].id1 <
+ ((PContact)data)[j].id1);
+ break;
+ case CNSORT_1DEC : gt = (((PContact)data)[j].id1 >
+ ((PContact)data)[i].id1);
+ lt = (((PContact)data)[j].id1 <
+ ((PContact)data)[i].id1);
+ break;
+ case CNSORT_2INC : gt = (((PContact)data)[i].id2 >
+ ((PContact)data)[j].id2);
+ lt = (((PContact)data)[i].id2 <
+ ((PContact)data)[j].id2);
+ break;
+ case CNSORT_2DEC : gt = (((PContact)data)[j].id2 >
+ ((PContact)data)[i].id2);
+ lt = (((PContact)data)[j].id2 <
+ ((PContact)data)[i].id2);
+ break;
+ case CNSORT_DINC : gt = (((PContact)data)[i].dist >
+ ((PContact)data)[j].dist);
+ lt = (((PContact)data)[i].dist <
+ ((PContact)data)[j].dist);
+ break;
+ case CNSORT_DDEC : gt = (((PContact)data)[j].dist >
+ ((PContact)data)[i].dist);
+ lt = (((PContact)data)[j].dist <
+ ((PContact)data)[i].dist);
+ break;
+ }
+ if (gt) return 1;
+ if (lt) return -1;
+ return 0;
+ }
+
+ void QSortContacts::Swap ( int i, int j ) {
+ ((PContact)data)[i].Swap ( ((PContact)data)[j] );
+ }
+
+
+ void QSortContacts::Sort ( PContact contact, int ncontacts,
+ int sortmode ) {
+ mode = sortmode;
+ if (mode!=CNSORT_OFF)
+ QuickSort::Sort ( &(contact[0]),ncontacts );
+ }
+
+
+ void SortContacts ( PContact contact, int ncontacts,
+ CNSORT_DIR sortmode ) {
+ QSortContacts SC;
+ if (sortmode!=CNSORT_OFF)
+ SC.Sort ( contact,ncontacts,sortmode );
+ }
+
+
+ // ------------------- Stream functions ----------------------
+
+ void CoorManager::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ Root::write ( f );
+ f.WriteInt ( &CoorIDCode );
+ f.WriteReal ( &brick_size );
+ f.WriteReal ( &xbrick_0 );
+ f.WriteReal ( &ybrick_0 );
+ f.WriteReal ( &zbrick_0 );
+ f.WriteInt ( &nbrick_x );
+ f.WriteInt ( &nbrick_y );
+ f.WriteInt ( &nbrick_z );
+ }
+
+ void CoorManager::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ Root::read ( f );
+ f.ReadInt ( &CoorIDCode );
+ f.ReadReal ( &brick_size );
+ f.ReadReal ( &xbrick_0 );
+ f.ReadReal ( &ybrick_0 );
+ f.ReadReal ( &zbrick_0 );
+ f.ReadInt ( &nbrick_x );
+ f.ReadInt ( &nbrick_y );
+ f.ReadInt ( &nbrick_z );
+ }
+
+
+ MakeStreamFunctions(CoorManager);
+
+
+
+
+ // ===================================================================
+
+ int SuperposeAtoms ( mat44 & T, PPAtom A1, int nA, PPAtom A2,
+ ivector C ) {
+ realtype xc1,yc1,zc1, xc2,yc2,zc2, det,B;
+ rmatrix A,U,V;
+ rvector W,RV1;
+ vect3 vc1,vc2;
+ int i,j,k,i1,i2,nat;
+
+
+ // 1. Set unit matrix as "default" return
+
+ for (i=0;i<4;i++) {
+ for (j=0;j<4;j++)
+ T[i][j] = 0.0;
+ T[i][i] = 1.0;
+ }
+
+
+ // 2. Calculate mass centers
+
+ xc1 = 0.0;
+ yc1 = 0.0;
+ zc1 = 0.0;
+ xc2 = 0.0;
+ yc2 = 0.0;
+ zc2 = 0.0;
+
+ nat = 0;
+ if (C) {
+
+ for (i1=0;i1<nA;i1++)
+ if (!A1[i1]->Ter) {
+ i2 = C[i1];
+ if (i2>=0) {
+ xc1 += A1[i1]->x;
+ yc1 += A1[i1]->y;
+ zc1 += A1[i1]->z;
+ xc2 += A2[i2]->x;
+ yc2 += A2[i2]->y;
+ zc2 += A2[i2]->z;
+ nat++;
+ }
+ }
+
+ } else {
+
+ for (i=0;i<nA;i++)
+ if ((!A1[i]->Ter) && (!A2[i]->Ter)) {
+ xc1 += A1[i]->x;
+ yc1 += A1[i]->y;
+ zc1 += A1[i]->z;
+ xc2 += A2[i]->x;
+ yc2 += A2[i]->y;
+ zc2 += A2[i]->z;
+ nat++;
+ }
+
+ }
+
+ if (nat>1) {
+ xc1 /= nat;
+ yc1 /= nat;
+ zc1 /= nat;
+ xc2 /= nat;
+ yc2 /= nat;
+ zc2 /= nat;
+ } else if (nat>0) {
+ T[0][3] = xc2 - xc1;
+ T[1][3] = yc2 - yc1;
+ T[2][3] = zc2 - zc1;
+ return SPOSEAT_Ok;
+ } else
+ return SPOSEAT_NoAtoms;
+
+
+ // 3. Calculate the correlation matrix
+
+ GetMatrixMemory ( A,3,3,1,1 );
+
+ for (i=1;i<=3;i++)
+ for (j=1;j<=3;j++)
+ A[i][j] = 0.0;
+
+ if (C) {
+
+ for (i1=0;i1<nA;i1++)
+ if (!A1[i1]->Ter) {
+ i2 = C[i1];
+ if (i2>=0) {
+ vc1[0] = A1[i1]->x - xc1;
+ vc1[1] = A1[i1]->y - yc1;
+ vc1[2] = A1[i1]->z - zc1;
+ vc2[0] = A2[i2]->x - xc2;
+ vc2[1] = A2[i2]->y - yc2;
+ vc2[2] = A2[i2]->z - zc2;
+ for (i=1;i<=3;i++)
+ for (j=1;j<=3;j++)
+ A[i][j] += vc1[j-1]*vc2[i-1];
+ }
+ }
+
+ } else {
+
+ for (k=0;k<nA;k++)
+ if ((!A1[k]->Ter) && (!A2[k]->Ter)) {
+ vc1[0] = A1[k]->x - xc1;
+ vc1[1] = A1[k]->y - yc1;
+ vc1[2] = A1[k]->z - zc1;
+ vc2[0] = A2[k]->x - xc2;
+ vc2[1] = A2[k]->y - yc2;
+ vc2[2] = A2[k]->z - zc2;
+ for (i=1;i<=3;i++)
+ for (j=1;j<=3;j++)
+ A[i][j] += vc1[j-1]*vc2[i-1];
+ }
+
+ }
+
+
+ // 4. Calculate transformation matrix (to be applied to A1)
+
+ det = A[1][1]*A[2][2]*A[3][3] +
+ A[1][2]*A[2][3]*A[3][1] +
+ A[2][1]*A[3][2]*A[1][3] -
+ A[1][3]*A[2][2]*A[3][1] -
+ A[1][1]*A[2][3]*A[3][2] -
+ A[3][3]*A[1][2]*A[2][1];
+
+ // 4.1 SV-decompose the correlation matrix
+
+ GetMatrixMemory ( U ,3,3,1,1 );
+ GetMatrixMemory ( V ,3,3,1,1 );
+ GetVectorMemory ( W ,3,1 );
+ GetVectorMemory ( RV1,3,1 );
+
+ math::SVD ( 3,3,3,A,U,V,W,RV1,true,true,i );
+
+ if (i!=0) {
+ FreeVectorMemory ( RV1,1 );
+ FreeVectorMemory ( W ,1 );
+ FreeMatrixMemory ( V ,3,1,1 );
+ FreeMatrixMemory ( U ,3,1,1 );
+ FreeMatrixMemory ( A ,3,1,1 );
+ return SPOSEAT_SVD_Fail;
+ }
+
+ // 4.2 Check for parasite inversion and fix it if found
+
+ if (det<=0.0) {
+ k = 0;
+ B = MaxReal;
+ for (j=1;j<=3;j++)
+ if (W[j]<B) {
+ B = W[j];
+ k = j;
+ }
+ for (j=1;j<=3;j++)
+ V[j][k] = -V[j][k];
+ }
+
+ // 4.3 Calculate rotational part of T
+
+ for (j=1;j<=3;j++)
+ for (k=1;k<=3;k++) {
+ B = 0.0;
+ for (i=1;i<=3;i++)
+ B += U[j][i]*V[k][i];
+ T[j-1][k-1] = B;
+ }
+
+
+ // 4.4 Add translational part to T
+
+ T[0][3] = xc2 - T[0][0]*xc1 - T[0][1]*yc1 - T[0][2]*zc1;
+ T[1][3] = yc2 - T[1][0]*xc1 - T[1][1]*yc1 - T[1][2]*zc1;
+ T[2][3] = zc2 - T[2][0]*xc1 - T[2][1]*yc1 - T[2][2]*zc1;
+
+
+ // 5. Release memory and quit
+
+ FreeVectorMemory ( RV1,1 );
+ FreeVectorMemory ( W ,1 );
+ FreeMatrixMemory ( V ,3,1,1 );
+ FreeMatrixMemory ( U ,3,1,1 );
+ FreeMatrixMemory ( A ,3,1,1 );
+
+ return SPOSEAT_Ok;
+
+ }
+
+ realtype getPhi ( PPAtom A ) {
+ //
+ // A0 A1 A2 A3
+ // o-----o-----o-----o
+ // |
+ // Phi
+ //
+ // -Pi <= Phi <= +Pi
+ //
+ vect3 U,W,V, a,b,c;
+ realtype Wmag,S,T;
+
+ U[0] = A[0]->x - A[1]->x;
+ U[1] = A[0]->y - A[1]->y;
+ U[2] = A[0]->z - A[1]->z;
+
+ W[0] = A[2]->x - A[1]->x;
+ W[1] = A[2]->y - A[1]->y;
+ W[2] = A[2]->z - A[1]->z;
+
+ V[0] = A[3]->x - A[2]->x;
+ V[1] = A[3]->y - A[2]->y;
+ V[2] = A[3]->z - A[2]->z;
+
+ a[0] = U[1]*W[2] - W[1]*U[2];
+ a[1] = U[2]*W[0] - W[2]*U[0];
+ a[2] = U[0]*W[1] - W[0]*U[1];
+
+ b[0] = V[1]*W[2] - W[1]*V[2];
+ b[1] = V[2]*W[0] - W[2]*V[0];
+ b[2] = V[0]*W[1] - W[0]*V[1];
+
+ c[0] = a[1]*b[2] - b[1]*a[2];
+ c[1] = a[2]*b[0] - b[2]*a[0];
+ c[2] = a[0]*b[1] - b[0]*a[1];
+
+ Wmag = sqrt(W[0]*W[0]+W[1]*W[1]+W[2]*W[2]);
+
+ S = c[0]*W[0] + c[1]*W[1] + c[2]*W[2];
+ T = a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
+ T *= Wmag;
+
+ if ((S==0.0) && (T==0.0)) return NO_TORSION;
+ else return atan2(S,T);
+
+ }
+
+ realtype getPsi ( PPAtom A ) {
+ vect3 v1,v2;
+ realtype l1,l2;
+
+ v1[0] = A[0]->x - A[1]->x;
+ v1[1] = A[0]->y - A[1]->y;
+ v1[2] = A[0]->z - A[1]->z;
+
+ v2[0] = A[2]->x - A[1]->x;
+ v2[1] = A[2]->y - A[1]->y;
+ v2[2] = A[2]->z - A[1]->z;
+
+ l1 = v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2];
+ if (l1==0.0) l1 = 1.0;
+ l2 = v2[0]*v2[0] + v2[1]*v2[1] + v2[2]*v2[2];
+ if (l2==0.0) l2 = 1.0;
+
+ return acos((v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])/sqrt(l1*l2));
+
+ }
+
+ const realtype NO_TORSION = -MaxReal;
+
+
+} // namespace mmdb
diff --git a/mmdb2/mmdb_coormngr.h b/mmdb2/mmdb_coormngr.h
new file mode 100644
index 0000000..c493169
--- /dev/null
+++ b/mmdb2/mmdb_coormngr.h
@@ -0,0 +1,959 @@
+// $Id: mmdb_coormngr.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 14.07.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : mmdb_coormngr <interface>
+// ~~~~~~~~~
+// Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::Brick ( space brick )
+// ~~~~~~~~~ mmdb::CoorManager ( MMDB atom coordinate manager )
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_CoorMngr__
+#define __MMDB_CoorMngr__
+
+#include "mmdb_root.h"
+
+namespace mmdb {
+
+ // =========================== Brick ==============================
+
+ // bricking control
+ enum BRICK_STATE {
+ BRICK_ON_1 = 0x00000001,
+ BRICK_ON_2 = 0x00000002,
+ BRICK_READY = 0x00000004
+ };
+
+ DefineClass(Brick);
+ typedef PPBrick * PPPBrick;
+
+ class Brick {
+
+ public :
+ int nAtoms; // number of atoms hit into brick
+ PPAtom atom; // pointers to atoms
+ ivector id; // atom ids (in present realization, these are
+ // indices of atoms from the bricked array)
+
+ Brick ();
+ ~Brick();
+
+ void Clear ();
+ void AddAtom ( PAtom A, int atomid );
+
+ protected :
+ int nAllocAtoms;
+ void InitBrick();
+
+ };
+
+
+ // =========================== MBrick =============================
+
+ // Bricking multiple structures
+
+ DefineClass(MBrick);
+ typedef PPMBrick * PPPMBrick;
+
+ class MBrick {
+
+ public :
+ ivector nAtoms; // number of atoms in the brick
+ PPAtom *atom; // pointers to atoms
+ imatrix id; // atom ids (in present realization, these are
+ // indices of atoms from the bricked array)
+
+ MBrick ( int nStructures );
+ ~MBrick();
+
+ void Clear ();
+ void AddAtom ( PAtom A, int structNo, int atomid );
+
+ protected :
+ ivector nAlloAtoms;
+ int nStruct;
+ void InitMBrick ( int nStructures );
+
+ };
+
+
+
+ // ==================== GenSym ========================
+
+ DefineClass(GenSym);
+ DefineStreamFunctions(GenSym);
+
+ class GenSym : public SymOps {
+
+ friend class CoorManager;
+
+ public :
+
+ GenSym ();
+ GenSym ( io::RPStream Object );
+ ~GenSym();
+
+ void FreeMemory();
+
+ int AddSymOp ( cpstr XYZOperation );
+ // the number of just added operation may be obtained as
+ // Nop = GenSym::GetNofSymOps()-1 .
+
+ int AddRenChain ( int Nop, const ChainID ch1, const ChainID ch2 );
+
+ void Copy ( PSymOps genSym );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ PChainID * chID1; // pairs of chains to rename from chID1[n][i]
+ PChainID * chID2; // to chID2[n][i] for each operation n<Nops
+ ivector nChains; // number of chains to rename for each oper-n
+
+ void InitGenSym();
+
+ private :
+ int nOpAlloc; // number of allocated operations
+
+ };
+
+
+ // ========================= Contact =============================
+
+ DefineStructure(Contact);
+
+ struct Contact {
+ int id1,id2;
+ long group;
+ realtype dist;
+ void Copy ( RContact c );
+ void Swap ( RContact c );
+ };
+
+
+ // ======================== MContact =============================
+
+ DefineClass(MContact);
+
+ class MContact : public io::Stream {
+
+ public :
+ int nStruct,contactID;
+ ivector nAtoms;
+ PPAtom * atom;
+ imatrix id;
+
+ MContact ( int nStructures );
+ ~MContact();
+
+ void AddContact ( PAtom A, int structNo, int atomid );
+
+ protected:
+ ivector nAlloc;
+
+ };
+
+ extern void DeleteMContacts ( PPMContact & mcontact, int nContacts );
+
+
+ // ====================== CoorManager =========================
+
+ DefineClass(CoorManager);
+ DefineStreamFunctions(CoorManager);
+
+ // ---- Atom extraction return
+ enum CID_RC {
+ CID_Ok = 0,
+ CID_NoModel = 1,
+ CID_NoChain = 2,
+ CID_NoResidue = 3,
+ CID_NoAtom = 4,
+ CID_WrongPath = 5
+ };
+
+ // ---- generate symmetry mates return codes
+ enum GSM_RC {
+ GSM_Ok = 0,
+ GSM_NoSymOps = 1,
+ GSM_NoTransfMatrices = 2,
+ GSM_NoCell = 3
+ };
+
+ class CoorManager : public Root {
+
+ public :
+
+ int CoorIDCode; // last return from atom extraction procedure
+
+ CoorManager ();
+ CoorManager ( io::RPStream Object );
+ ~CoorManager();
+
+
+ // ----------------------------------------------------------
+
+ int SetDefaultCoorID ( cpstr CID );
+
+
+ // ---------------- Bricking ------------------------------
+
+ void RemoveBricks ();
+ bool areBricks () { return (brick!=NULL); }
+ void MakeBricks ( PPAtom atmvec, int avlen,
+ realtype Margin, realtype BrickSize=6.0 );
+ void GetBrickDimension (
+ int & nxmax, int & nymax, int & nzmax );
+ void GetBrickCoor ( PAtom A, int & nx, int & ny, int & nz );
+ void GetBrickCoor ( realtype x, realtype y, realtype z,
+ int & nx, int & ny, int & nz );
+ PBrick GetBrick ( int nx, int ny, int nz );
+
+ void RemoveMBricks ();
+ bool areMBricks () { return (mbrick!=NULL); }
+ void MakeMBricks ( PPAtom * atmvec, ivector avlen,
+ int nStructures, realtype Margin,
+ realtype BrickSize=6.0 );
+ void GetMBrickDimension (
+ int & nxmax, int & nymax, int & nzmax );
+ void GetMBrickCoor ( PAtom A, int & nx, int & ny, int & nz );
+ void GetMBrickCoor ( realtype x, realtype y, realtype z,
+ int & nx, int & ny, int & nz );
+ PMBrick GetMBrick ( int nx, int ny, int nz );
+
+ // ---------------- Extracting models ---------------------
+
+ int GetNumberOfModels () { return nModels; }
+ int GetFirstModelNum ();
+ PModel GetFirstDefinedModel();
+ PModel GetModel ( int modelNo ); // 1<=modelNo<=nModels
+ PModel GetModel ( cpstr CID );
+ void GetModelTable ( PPModel & modTable,
+ int & NumberOfModels );
+
+ // ---------------- Deleting models -----------------------
+
+ int DeleteModel ( cpstr CID );
+ int DeleteModel ( int modelNo ); // 1<=modelNo<=nOfModels
+
+ // ---------------- Adding/Inserting models ---------------
+
+ int AddModel ( PModel mdl );
+ int InsModel ( PModel mdl, int modelNo );
+ void RotateModels ( int modelNo1, int modelNo2, int rotdir );
+ void SwapModels ( int modelNo1, int modelNo2 );
+
+ // ---------------- Extracting chains ---------------------
+
+ int GetNumberOfChains ( int modelNo );
+ int GetNumberOfChains ( cpstr CID );
+ PChain GetChain ( int modelNo, const ChainID chainID );
+ PChain GetChain ( int modelNo, int chainNo );
+ PChain GetChain ( cpstr CID );
+ void GetChainTable ( int modelNo, PPChain & chainTable,
+ int & NumberOfChains );
+ void GetChainTable ( cpstr CID, PPChain & chainTable,
+ int & NumberOfChains );
+
+ // ----------------- Deleting chains ----------------------
+
+ int DeleteChain ( int modelNo, const ChainID chID );
+ int DeleteChain ( int modelNo, int chainNo );
+ int DeleteAllChains ( int modelNo );
+ int DeleteAllChains ();
+
+ // ------------------ Adding chains -----------------------
+
+ int AddChain ( int modelNo, PChain chain );
+
+ // ---------------- Extracting residues -------------------
+
+ int GetNumberOfResidues ( int modelNo, const ChainID chainID );
+ int GetNumberOfResidues ( int modelNo, int chainNo );
+ int GetNumberOfResidues ( cpstr CID );
+ PResidue GetResidue ( int modelNo, const ChainID chainID,
+ int seqNo, const InsCode insCode );
+ PResidue GetResidue ( int modelNo, int chainNo,
+ int seqNo, const InsCode insCode );
+ PResidue GetResidue ( int modelNo, const ChainID chainID,
+ int resNo );
+ PResidue GetResidue ( int modelNo, int chainNo, int resNo );
+ PResidue GetResidue ( cpstr CID );
+ int GetResidueNo ( int modelNo, const ChainID chainID,
+ int seqNo, const InsCode insCode );
+ int GetResidueNo ( int modelNo, int chainNo,
+ int seqNo, const InsCode insCode );
+ void GetResidueTable ( PPResidue & resTable,
+ int & NumberOfResidues );
+ void GetResidueTable ( int modelNo, const ChainID chainID,
+ PPResidue & resTable,
+ int & NumberOfResidues );
+ void GetResidueTable ( int modelNo, int chainNo,
+ PPResidue & resTable,
+ int & NumberOfResidues );
+ void GetResidueTable ( cpstr CID, PPResidue & resTable,
+ int & NumberOfResidues );
+
+
+ // ----------------- Deleting residues -----------------------
+
+ int DeleteResidue ( int modelNo, const ChainID chainID,
+ int seqNo, const InsCode insCode );
+ int DeleteResidue ( int modelNo, const ChainID chainID,
+ int resNo );
+ int DeleteResidue ( int modelNo, int chainNo,
+ int seqNo, const InsCode insCode );
+ int DeleteResidue ( int modelNo, int chainNo, int resNo );
+ int DeleteAllResidues ( int modelNo, const ChainID chainID );
+ int DeleteAllResidues ( int modelNo, int chainNo );
+ int DeleteAllResidues ( int modelNo );
+ int DeleteAllResidues ();
+ int DeleteSolvent ();
+
+ // ------------------- Adding residues -----------------------
+
+ int AddResidue ( int modelNo, const ChainID chainID,
+ PResidue res );
+ int AddResidue ( int modelNo, int chainNo, PResidue res );
+
+ // -------------------- Extracting atoms ----------------------
+
+ int GetNumberOfAtoms () { return nAtoms; }
+ int GetNumberOfAtoms ( int modelNo, const ChainID chainID,
+ int seqNo, const InsCode insCode );
+ int GetNumberOfAtoms ( int modelNo, int chainNo,
+ int seqNo, const InsCode insCode );
+ int GetNumberOfAtoms ( int modelNo, const ChainID chainID,
+ int resNo );
+ int GetNumberOfAtoms ( int modelNo, int chainNo, int resNo );
+ int GetNumberOfAtoms ( cpstr CID );
+
+ PAtom GetAtom (
+ int modelNo, // model serial number 1...
+ const ChainID chID, // chain ID
+ int seqNo, // residue sequence number
+ const InsCode insCode, // residue insertion code
+ const AtomName aname, // atom name
+ const Element elmnt, // chemical element code or '*'
+ const AltLoc aloc // alternate location indicator
+ );
+
+ PAtom GetAtom (
+ int modelNo, // model serial number 1...
+ const ChainID chID, // chain ID
+ int seqNo, // residue sequence number
+ const InsCode insCode, // residue insertion code
+ int atomNo // atom number 0..
+ );
+
+ PAtom GetAtom (
+ int modelNo, // model serial number 1...
+ const ChainID chID, // chain ID
+ int resNo, // residue number 0..
+ const AtomName aname, // atom name
+ const Element elmnt, // chemical element code or '*'
+ const AltLoc aloc // alternate location indicator
+ );
+
+ PAtom GetAtom (
+ int modelNo, // model serial number 1...
+ const ChainID chID, // chain ID
+ int resNo, // residue number 0..
+ int atomNo // atom number 0..
+ );
+
+ PAtom GetAtom (
+ int modelNo, // model serial number 1...
+ int chNo, // chain number 0..
+ int seqNo, // residue sequence number
+ const InsCode insCode, // residue insertion code
+ const AtomName aname, // atom name
+ const Element elmnt, // chemical element code or '*'
+ const AltLoc aloc // alternate location indicator
+ );
+
+ PAtom GetAtom (
+ int modelNo, // model serial number 1...
+ int chNo, // chain number 0...
+ int seqNo, // residue sequence number
+ const InsCode insCode, // residue insertion code
+ int atomNo // atom number 0...
+ );
+
+ PAtom GetAtom (
+ int modelNo, // model serial number 1...
+ int chNo, // chain number 0...
+ int resNo, // residue number 0...
+ const AtomName aname, // atom name
+ const Element elmnt, // chemical element code or '*'
+ const AltLoc aloc // alternate location indicator
+ );
+
+ PAtom GetAtom (
+ int modelNo, // model serial number 1...
+ int chNo, // chain number 0...
+ int resNo, // residue number 0...
+ int atomNo // atom number 0...
+ );
+
+
+ // GetAtom(CID) returns atom answering to the following
+ // CID pattern:
+ // /mdl/chn/seq(res).i/atm[elm]:a
+ // where
+ // mdl - model number (mandatory); at least model #1 is always
+ // present
+ // chn - chain identifier ( mandatory)
+ // seq - residue sequence number (mandatory)
+ // (res) - residue name in round brackets (may be omitted)
+ // .i - insert code after a dot; if '.i' or 'i' is missing
+ // then residue without an insertion code is looked
+ // for
+ // atm - atom name (mandatory)
+ // [elm] - chemical element code in square brackets; it may
+ // be omitted but could be helpful for e.g.
+ // distinguishing C_alpha and CA
+ // :a - alternate location indicator after colon; if
+ // ':a' or 'a' is missing then an atom without
+ // alternate location indicator is looked for.
+ // All spaces are ignored, all identifiers should be in capital
+ // letters (comparisons are case-sensitive).
+ PAtom GetAtom ( cpstr CID );
+
+
+ void GetAtomTable ( PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable ( int modelNo, const ChainID chainID,
+ int seqNo, const InsCode insCode,
+ PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable ( int modelNo, int chainNo,
+ int seqNo, const InsCode insCode,
+ PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable ( int modelNo, const ChainID chainID, int resNo,
+ PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable ( int modelNo, int chainNo, int resNo,
+ PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable ( cpstr CID, PPAtom & atomTable,
+ int & NumberOfAtoms );
+
+
+ // GetAtomTable1(..) returns atom table without TER atoms and
+ // without NULL atom pointers. NumberOfAtoms returns the actual
+ // number of atom pointers in atomTable.
+ // atomTable is allocated within the function. If it was
+ // not set to NULL before calling the function, the function will
+ // attempt to deallocate it first.
+ // The application is responsible for deleting atomTable,
+ // however it must not touch atom pointers, i.e. use simply
+ // "delete atomTable;". Never pass atomTable from GetAtomTable(..)
+ // into this function, unless you set it to NULL before doing that.
+ void GetAtomTable1 ( PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable1 ( int modelNo, const ChainID chainID,
+ int seqNo, const InsCode insCode,
+ PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable1 ( int modelNo, int chainNo,
+ int seqNo, const InsCode insCode,
+ PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable1 ( int modelNo, const ChainID chainID, int resNo,
+ PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable1 ( int modelNo, int chainNo, int resNo,
+ PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable1 ( cpstr CID, PPAtom & atomTable,
+ int & NumberOfAtoms );
+
+
+ // -------------------- Deleting atoms -----------------------
+
+ int DeleteAtom ( int modelNo,
+ const ChainID chID,
+ int seqNo,
+ const InsCode insCode,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc );
+ int DeleteAtom ( int modelNo,
+ const ChainID chID,
+ int seqNo,
+ const InsCode insCode,
+ int atomNo );
+ int DeleteAtom ( int modelNo,
+ const ChainID chID,
+ int resNo,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc );
+ int DeleteAtom ( int modelNo, const ChainID chID,
+ int resNo, int atomNo );
+ int DeleteAtom ( int modelNo, int chNo, int seqNo,
+ const InsCode insCode,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc );
+ int DeleteAtom ( int modelNo, int chNo, int seqNo,
+ const InsCode insCode, int atomNo );
+ int DeleteAtom ( int modelNo, int chNo, int resNo,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc );
+ int DeleteAtom ( int modelNo, int chNo, int resNo, int atomNo );
+
+ int DeleteAllAtoms ( int modelNo, const ChainID chID,
+ int seqNo, const InsCode insCode );
+ int DeleteAllAtoms ( int modelNo, const ChainID chID, int resNo );
+ int DeleteAllAtoms ( int modelNo, const ChainID chID );
+ int DeleteAllAtoms ( int modelNo, int chNo, int seqNo,
+ const InsCode insCode );
+ int DeleteAllAtoms ( int modelNo, int chNo, int resNo );
+ int DeleteAllAtoms ( int modelNo, int chNo );
+ int DeleteAllAtoms ( int modelNo );
+ int DeleteAllAtoms ();
+
+ // This function leaves only alternative location with maximal
+ // occupancy, if those are equal or unspecified, the one with
+ // "least" alternative location indicator.
+ // The function returns the number of deleted atoms and optimizes
+ // the atom index.
+ int DeleteAltLocs ();
+
+
+ // --------------------- Adding atoms ------------------------
+
+ int AddAtom ( int modelNo, const ChainID chID,
+ int seqNo, const InsCode insCode, PAtom atom );
+ int AddAtom ( int modelNo, const ChainID chID, int resNo,
+ PAtom atom );
+ int AddAtom ( int modelNo, int chNo, int seqNo,
+ const InsCode insCode, PAtom atom );
+ int AddAtom ( int modelNo, int chNo, int resNo, PAtom atom );
+
+
+ // -------------------- Transformations -----------------------
+
+ int GenerateSymMates ( PGenSym genSym=NULL );
+ // 1: no Sym operations,
+ // 2: no fract/orth matrices
+ // 3: no cell parameters
+ // 0: Ok
+
+ void ApplyTransform ( mat44 & TMatrix ); // simply transforms all
+ // coordinates by multiplying
+ // with matrix TMatrix
+
+ int BringToUnitCell(); // brings all chains into 0th unit cell
+
+ // Frac2Orth(..) and Orth2Frac(..) transform between fractional
+ // and orthogonal coordinates, if areMatrices() returns true.
+ // If the transformation matrices were not set, the functions just
+ // copy the coordinates. Returns true if the transformation was
+ // done; False return means that transformation matrices were not
+ // calculated
+ bool Frac2Orth (
+ realtype xfrac, realtype yfrac, realtype zfrac,
+ realtype & xorth, realtype & yorth, realtype & zorth );
+ bool Orth2Frac (
+ realtype xorth, realtype yorth, realtype zorth,
+ realtype & xfrac, realtype & yfrac, realtype & zfrac );
+
+
+ // Below, F and T are transformation matrices in fractional and
+ // orthogonal coordinates, respectively.
+ bool Frac2Orth ( mat44 & F, mat44 & T );
+ bool Orth2Frac ( mat44 & T, mat44 & F );
+
+ // ==================== Seeking contacts ======================
+
+ void SeekContacts (
+ PPAtom AIndex, // index of atoms [0..ilen-1]
+ int ilen, // length of index
+ int atomNum, // number of 1st contact atom
+ // in the index. All other atoms
+ // are checked for contact with
+ // 1st atom
+ realtype dist1, // minimal contact distance
+ realtype dist2, // maximal contact distance
+ int seqDist, // the sequence distance to neglect.
+ // If seqDist==0, all atoms are
+ // checked for contact. If
+ // seqDist==1, the atoms belonging
+ // to the same residue as atom
+ // AIndex[atomNum], are neglected.
+ // If seqDist>1, all atoms belonging
+ // to residues closer than
+ // +/-(seqDist-1) around that of
+ // atom AIndex[atomNum], are
+ // neglected. If chain is broken
+ // (has a gap) on section
+ // [-(seqDist-1)..seqDist-1], the
+ // section of neglection is
+ // shortened to that gap.
+ RPContact contact, // indices of contacting atoms
+ // [0..ncontacts-1]. contact[i].id1
+ // is set to atomNum and
+ // contact[i].id2 is set to the
+ // index of 2nd contacting atom
+ // in vector AIndex
+ int & ncontacts, // number of contacts found. If
+ // ncontacts>0 on input, it is
+ // assumed that new contacts that
+ // newly found contacts should be
+ // appended to those already
+ // existing
+ int maxlen=0, // if <=0, then vector contact is
+ // allocated dynamically. If
+ // contact!=NULL, then it is
+ // appended with new contacts.
+ // The application is responsible
+ // for deallocation of contact
+ // after use.
+ // If maxlen>0 then vector contact
+ // is prohibited of dynamical
+ // allocation/deallocation. In this
+ // case, not more than maxlen
+ // contacts will be returned.
+ long group=0 // a contact group ID, which will be
+ // simply stored in contact[i].group
+ // fields. This ID may be useful
+ // if contacts are obtained in
+ // multiple calls of the function
+ );
+
+ void SeekContacts (
+ PAtom A, // 1st atom in contact
+ PPAtom AIndex, // index of atoms [0..ilen-1] to
+ // check for contact with 1st atom
+ int ilen, // length of index
+ realtype dist1, // minimal contact distance
+ realtype dist2, // maximal contact distance
+ int seqDist, // the sequence distance to neglect.
+ // If seqDist==0, all atoms are
+ // checked for contact. If
+ // seqDist==1, the atoms belonging
+ // to the same residue as atom
+ // A, are neglected. If seqDist>1,
+ // all atoms belonging to residues
+ // closer than +/-(seqDist-1) around
+ // that of atom A, are neglected. If
+ // chain is broken (has a gap) on
+ // section
+ // [-(seqDist-1)..seqDist-1], the
+ // section of neglection is
+ // shortened to that gap.
+ RPContact contact, // indices of contacting atoms
+ // [0..ncontacts-1]. contact[i].id1
+ // is set to -1, and contact[i].id2
+ // is set to the index of 2nd
+ // contacting atom in vector AIndex
+ int & ncontacts, // number of contacts found. If
+ // ncontacts>0 on input, it is
+ // assumed that new contacts that
+ // newly found contacts should be
+ // appended those already existing
+ int maxlen=0, // if <=0, then vector contact is
+ // allocated dynamically. If
+ // contact!=NULL, then it is
+ // appended with new contacts.
+ // The application is responsible
+ // for deallocation of contact
+ // after use.
+ // If maxlen>0 then vector contact
+ // is prohibited of dynamical
+ // allocation/deallocation. In this
+ // case, not more than maxlen
+ // contacts will be returned.
+ long group=0 // a contact group ID, which will be
+ // simply stored in contact[i].group
+ // fields. This ID may be useful
+ // if contacts are obtained in
+ // multiple calls of the function
+ );
+
+ void SeekContacts (
+ PPAtom AIndex1, // 1st atom index [0..ilen1-1]
+ int ilen1, // length of 1st index
+ PPAtom AIndex2, // 2nd atom index [0..ilen2-1] to
+ // check for contact with 1st index
+ int ilen2, // length of 2nd index
+ realtype dist1, // minimal contact distance
+ realtype dist2, // maximal contact distance
+ int seqDist, // the sequence distance to
+ // neglect.
+ // If seqDist==0, all atoms are
+ // checked for contact.
+ // If seqDist==1, the atoms
+ // belonging to the same residue
+ // are neglected.
+ // If seqDist>1, all atoms
+ // belonging to residues closer than
+ // +/-(seqDist-1) to each other,
+ // are neglected. If chain is broken
+ // (has a gap) on section
+ // [-(seqDist-1)..seqDist-1], the
+ // section of neglection is
+ // shortened to that gap.
+ RPContact contact, // indices of contacting atoms
+ // [0..ncontacts-1]. contact[i].id1
+ // contains number of atom from 1st
+ // index, and contact[i].id2
+ // contains number of atom from 2nd
+ // index, contacting with the former
+ // one
+ int & ncontacts, // number of contacts found. If
+ // ncontacts>0 on input, it is
+ // assumed that newly found
+ // contacts should be appended to
+ // those already existing
+ int maxlen=0, // if <=0, then vector contact is
+ // allocated dynamically. If
+ // contact!=NULL, then it is
+ // appended with new contacts.
+ // The application is responsible
+ // for deallocation of contact
+ // after use.
+ // If maxlen>0 then vector contact
+ // is prohibited of dynamical
+ // allocation/deallocation. In this
+ // case, not more than maxlen
+ // contacts will be returned.
+ mat44 * TMatrix=NULL, // transformation matrix for 2nd
+ // set of atoms (AIndex2)
+ long group=0, // a contact group ID, which will
+ // be stored in contact[i].group
+ // fields. This ID may be useful
+ // if contacts are obtained in
+ // multiple calls of the function
+ int bricking=0, // bricking control; may be a
+ // combination of BRICK_ON_1 or
+ // BRICK_ON_2 with BRICK_READY
+ bool doSqrt=true // if False, then Contact contains
+ // square distances
+ );
+
+ // Simplified optimized for speed version:
+ // - no NULL pointers and Ters in AIndex1 and AIndex2
+ // - no checks for identity atoms in AIndex1 and AIndex2
+ // - contact must be pre-allocated with at least ilen1*ilen2
+ // elements
+ // - contact returns square distances
+ // - ncontacts is always reset
+ void SeekContacts (
+ PPAtom AIndex1, // 1st atom index [0..ilen1-1]
+ int ilen1, // length of 1st index
+ PPAtom AIndex2, // 2nd atom index [0..ilen2-1] to
+ // check for contact with 1st index
+ int ilen2, // length of 2nd index
+ realtype contDist, // maximal contact distance
+ PContact contact, // indices of contacting atoms
+ // [0..ncontacts-1]. contact[i].id1
+ // contains number of atom from 1st
+ // index, and contact[i].id2
+ // contains number of atom from 2nd
+ // index, contacting with the former
+ // one. Must be pre-allocated
+ int & ncontacts, // number of contacts found
+ int bricking=0 // bricking control; may be a
+ // combination of BRICK_ON_1 or
+ // BRICK_ON_2 with BRICK_READY
+ );
+
+ void SeekContacts (
+ PPAtom AIndex1, // 1st atom index [0..ilen1-1]
+ int ilen1, // length of 1st index
+ PPAtom * AIndex2, // indexes of atoms to be checked
+ // for contact with each atom from
+ // Aindex1; dimension
+ // [0..nStructures-1][0..ilen2[i]-1]
+ ivector ilen2, // lengths of indexes AIndex2
+ int nStructures, // number of indexes AIndex2
+ realtype dist1, // minimal contact distance
+ realtype dist2, // maximal contact distance
+ PPMContact & contact, // resulting contacts, one structure
+ // per each position in AIndex1. If
+ // AIndex1[i] is NULL, contact[i] is
+ // also NULL. "contact" is always
+ // allocated, no re-use or
+ // re-allocation is attempted.
+ int bricking=0 // bricking control; may be
+ // BRICK_READY if AIndex2 does not
+ // change
+ );
+
+ protected :
+
+ // bricks
+ realtype brick_size, xbrick_0,ybrick_0,zbrick_0;
+ int nbrick_x,nbrick_y,nbrick_z;
+ PPPBrick * brick;
+
+ realtype mbrick_size, xmbrick_0,ymbrick_0,zmbrick_0;
+ int nmbrick_x,nmbrick_y,nmbrick_z;
+ PPPMBrick * mbrick;
+
+ // --------------- Stream I/O -----------------------------
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ void InitMMDBCoorManager();
+
+ void ApplySymTransform ( int SymMatrixNo, PGenSym genSym=NULL );
+
+ void ResetManager ();
+
+ void FindSeqSection ( PAtom atom, int seqDist,
+ int & seq1, int & seq2 );
+ bool iContact ( PAtom a1, PAtom a2,
+ int seq1, int seq2,
+ realtype dd, realtype d12,
+ realtype d22, realtype & d2 );
+ bool iContact ( realtype x, realtype y,
+ realtype z, PAtom a2,
+ realtype dd, realtype d12,
+ realtype d22, realtype & d2 );
+
+ };
+
+
+
+ // ===================================================================
+
+
+
+ // GetEulerRotMatrix(..) calculates the Euler rotation matrix
+ // for rotation:
+ // 1) about z-axis by angle alpha
+ // 2) about new y-axis by angle beta
+ // 3) about new z-axis by angle gamma
+ extern void GetEulerRotMatrix ( mat33 & erm, realtype alpha,
+ realtype beta, realtype gamma );
+
+ // GetEulerTMatrix(..) calculates the Euler rotation-translation
+ // matrix for rotation:
+ // 1) about z-axis by angle alpha
+ // 2) about new y-axis by angle beta
+ // 3) about new z-axis by angle gamma
+ // Point (x0,y0,z0) is the center of rotation.
+ extern void GetEulerTMatrix ( mat44 & erm, realtype alpha,
+ realtype beta, realtype gamma,
+ realtype x0, realtype y0, realtype z0 );
+
+ // Euler rotation: 1) about z-axis by angle alpha
+ // 2) about new y-axis by angle beta
+ // 3) about new z-axis by angle gamma
+ // Point (x0,y0,z0) is the center of rotation.
+ extern void EulerRotation ( PPAtom A, int nA,
+ realtype alpha, realtype beta, realtype gamma,
+ realtype x0, realtype y0, realtype z0 );
+
+ // GetVecRotMatrix(..) calculates the rotation matrix for
+ // rotation by angle alpha about arbitrary vector directed
+ // as (vx,vy,vz) = (vx2-vx1,vy2-vy1,vz2-vz1).
+ extern void GetVecRotMatrix ( mat33 & vrm, realtype alpha,
+ realtype vx, realtype vy, realtype vz );
+
+
+ // Given the rotation matrix vrm, GetRotParameters(..)
+ // returns the rotation angle alpha and the normalized
+ // rotation axis vector (vx,vy,vz).
+ // The rotation angle and vector are determined up to
+ // their sign (however correlated, so that being substituted
+ // into GetVecRotMatrix(..) they yield the same rotation
+ // matrix).
+ // The function does not check for vrm to be a valid
+ // rotation matrix.
+ extern void GetRotParameters ( mat33 & vrm, realtype & alpha,
+ realtype & vx, realtype & vy, realtype & vz );
+
+
+ // GetVecTMatrix(..) calculates the rotation-translation matrix
+ // for rotation by angle alpha about arbitrary vector directed as
+ // (vx,vy,vz) = (vx2-vx1,vy2-vy1,vz2-vz1). Point (x0,y0,z0) is
+ // the center of rotation -- actually a point belonging to the
+ // rotation axis.
+ extern void GetVecTMatrix ( mat44 & vrm, realtype alpha,
+ realtype vx, realtype vy, realtype vz,
+ realtype x0, realtype y0, realtype z0 );
+
+ // Vector rotation is rotation by angle alpha about arbitrary
+ // vector directed as (vx,vy,vz) = (vx2-vx1,vy2-vy1,vz2-vz1).
+ // Point (x0,y0,z0) is the center of rotation -- actually
+ // a point belonging to the rotation axis.
+ extern void VectorRotation ( PPAtom A, int nA, realtype alpha,
+ realtype vx, realtype vy, realtype vz,
+ realtype x0, realtype y0, realtype z0 );
+
+ extern void GetMassCenter ( PPAtom A, int nA,
+ realtype & xmc, realtype & ymc, realtype & zmc );
+
+
+ enum SPOSEAT_RC {
+ SPOSEAT_Ok = 0,
+ SPOSEAT_NoAtoms = 1,
+ SPOSEAT_SVD_Fail = 2
+ };
+
+ // Given two sets of atoms, A1 and A2, SuperposeAtoms(...) calculates
+ // the rotational-translational matrix T such that |T*A1 - A2| is
+ // minimal in least-square terms.
+ // If vector C is not given (default), all nA atoms of set A1 are
+ // considered as corresponding to nA first atoms of set A2,
+ // A1[i] <-> A2[i], 0<=i<nA .
+ // If vector C is given, then the correspondence of atoms is
+ // established as A1[i] <-> A2[C[i]] only for those i that C[i]>=0.
+ // The default option (C==NULL) is thus identical to C[i]==i, 0<=i<nA.
+ // Upon normal completion, the procedure returns SPOSEAT_Ok.
+
+ extern int SuperposeAtoms ( mat44 & T, PPAtom A1, int nA, PPAtom A2,
+ ivector C=NULL );
+
+ enum CNSORT_DIR {
+ CNSORT_OFF = 0,
+ CNSORT_1INC = 1,
+ CNSORT_1DEC = 2,
+ CNSORT_2INC = 3,
+ CNSORT_2DEC = 4,
+ CNSORT_DINC = 5,
+ CNSORT_DDEC = 6
+ };
+
+ extern void SortContacts ( PContact contact, int ncontacts,
+ CNSORT_DIR sortmode );
+
+
+ extern const realtype NO_TORSION;
+
+ extern realtype getPhi ( PPAtom A ); // A[0] - A[3] used
+ extern realtype getPsi ( PPAtom A ); // A[0] - A[2] used
+
+} // namespace mmdb
+
+#endif
+
diff --git a/mmdb2/mmdb_cryst.cpp b/mmdb2/mmdb_cryst.cpp
new file mode 100644
index 0000000..5ad924c
--- /dev/null
+++ b/mmdb2/mmdb_cryst.cpp
@@ -0,0 +1,2312 @@
+// $Id: mmdb_cryst.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 21.11.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_Cryst <implementation>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::CrystContainer ( container for cryst. data )
+// ~~~~~~~~~ mmdb::NCSMatrix ( non-cryst. symm. matrix class )
+// mmdb::TVect ( translation vector class )
+// mmdb::Cryst ( MMDB cryst. section class )
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "mmdb_cryst.h"
+#include "mmdb_defs.h"
+#include "mmdb_cifdefs.h"
+
+namespace mmdb {
+
+ // ============== CrystContainer ====================
+
+ PContainerClass CrystContainer::MakeContainerClass ( int ClassID ) {
+ switch (ClassID) {
+ default :
+ case ClassID_Template :
+ return ClassContainer::MakeContainerClass(ClassID);
+ case ClassID_NCSMatrix : return new NCSMatrix();
+ case ClassID_TVect : return new TVect ();
+ }
+ }
+
+ ERROR_CODE CrystContainer::AddMTRIXLine ( cpstr S ) {
+ int i;
+ ERROR_CODE RC;
+ RC = Error_NCSM_WrongSerial;
+ for (i=0;i<length;i++) {
+ RC = PNCSMatrix(Container[i])->ConvertPDBASCII(S);
+ if (RC==0) break;
+ if (RC!=Error_NCSM_WrongSerial) break;
+ }
+ return RC;
+ }
+
+ MakeStreamFunctions(CrystContainer)
+
+
+ // ================ NCSMatrix ===================
+
+ NCSMatrix::NCSMatrix() : ContainerClass() {
+ Init();
+ }
+
+ NCSMatrix::NCSMatrix ( cpstr S ) : ContainerClass() {
+ Init();
+ ConvertPDBASCII ( S );
+ }
+
+ NCSMatrix::NCSMatrix ( io::RPStream Object )
+ : ContainerClass(Object) {
+ Init();
+ }
+
+ NCSMatrix::~NCSMatrix() {}
+
+ void NCSMatrix::Init() {
+ int i,j;
+ serNum = -1;
+ iGiven = -1;
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++)
+ m[i][j] = 0.0;
+ m[i][i] = 1.0;
+ v[i] = 0.0;
+ }
+ WhatIsSet = 0; // nothing is set
+ }
+
+ bool NCSMatrix::PDBASCIIDump1 ( io::RFile f ) {
+ // makes the ASCII PDB MATRIXn lines if all
+ // of them were set.
+ char S[100];
+ int i,j;
+
+ if ((WhatIsSet & NCSMSET_All)==NCSMSET_All)
+ for (i=0;i<3;i++) {
+ sprintf ( S,"MTRIX%1i %3i",i+1,serNum );
+ PadSpaces ( S,80 );
+ for (j=0;j<3;j++)
+ PutRealF ( &(S[10+j*10]),m[i][j],10,6 );
+ PutRealF ( &(S[45]),v[i],10,5 );
+ if (iGiven) S[59] = '1';
+ f.WriteLine ( S );
+ }
+
+ return true; // container should use this virtual
+
+ }
+
+ ERROR_CODE NCSMatrix::ConvertPDBASCII ( cpstr S ) {
+ realtype m0,m1,m2,v0;
+ int sN,iG;
+
+ if (!(GetInteger(sN,&(S[7]) ,3 ) &&
+ GetReal (m0,&(S[10]),10) &&
+ GetReal (m1,&(S[20]),10) &&
+ GetReal (m2,&(S[30]),10) &&
+ GetReal (v0,&(S[45]),10)))
+ return Error_NCSM_Unrecognized;
+
+ if (S[59]=='1') iG = 1;
+ else iG = 0;
+
+ if (WhatIsSet & NCSMSET_All) {
+ if (sN!=serNum) return Error_NCSM_WrongSerial;
+ if (iG!=iGiven) return Error_NCSM_UnmatchIG;
+ }
+
+ if (!strncmp(S,"MTRIX1",6)) {
+
+ if (WhatIsSet & NCSMSET_Matrix1) return Error_NCSM_AlreadySet;
+ serNum = sN;
+ iGiven = iG;
+ m[0][0] = m0;
+ m[0][1] = m1;
+ m[0][2] = m2;
+ v[0] = v0;
+ WhatIsSet |= NCSMSET_Matrix1;
+
+ } else if (!strncmp(S,"MTRIX2",6)) {
+
+ if (WhatIsSet & NCSMSET_Matrix2) return Error_NCSM_AlreadySet;
+ serNum = sN;
+ iGiven = iG;
+ m[1][0] = m0;
+ m[1][1] = m1;
+ m[1][2] = m2;
+ v[1] = v0;
+ WhatIsSet |= NCSMSET_Matrix2;
+
+ } else if (!strncmp(S,"MTRIX3",6)) {
+
+ if (WhatIsSet & NCSMSET_Matrix3) return Error_NCSM_AlreadySet;
+ serNum = sN;
+ iGiven = iG;
+ m[2][0] = m0;
+ m[2][1] = m1;
+ m[2][2] = m2;
+ v[2] = v0;
+ WhatIsSet |= NCSMSET_Matrix3;
+
+ } else
+ return Error_WrongSection;
+
+ return Error_NoError;
+
+ }
+
+ void NCSMatrix::MakeCIF ( mmcif::PData CIF, int N ) {
+ mmcif::PLoop Loop;
+ int RC;
+ RC = CIF->AddLoop ( CIFCAT_STRUCT_NCS_OPER,Loop );
+ if ((RC!=mmcif::CIFRC_Ok) || (N==0)) {
+ // the category was (re)created, provide tags
+ Loop->AddLoopTag ( CIFTAG_ID );
+ Loop->AddLoopTag ( CIFTAG_MATRIX11 );
+ Loop->AddLoopTag ( CIFTAG_MATRIX12 );
+ Loop->AddLoopTag ( CIFTAG_MATRIX13 );
+ Loop->AddLoopTag ( CIFTAG_VECTOR1 );
+ Loop->AddLoopTag ( CIFTAG_MATRIX21 );
+ Loop->AddLoopTag ( CIFTAG_MATRIX22 );
+ Loop->AddLoopTag ( CIFTAG_MATRIX23 );
+ Loop->AddLoopTag ( CIFTAG_VECTOR2 );
+ Loop->AddLoopTag ( CIFTAG_MATRIX31 );
+ Loop->AddLoopTag ( CIFTAG_MATRIX32 );
+ Loop->AddLoopTag ( CIFTAG_MATRIX33 );
+ Loop->AddLoopTag ( CIFTAG_VECTOR3 );
+ Loop->AddLoopTag ( CIFTAG_CODE );
+ }
+ Loop->AddInteger ( serNum );
+ if (WhatIsSet & NCSMSET_Matrix1) {
+ Loop->AddReal ( m[0][0] );
+ Loop->AddReal ( m[0][1] );
+ Loop->AddReal ( m[0][2] );
+ Loop->AddReal ( v[0] );
+ } else {
+ Loop->AddString ( NULL );
+ Loop->AddString ( NULL );
+ Loop->AddString ( NULL );
+ Loop->AddString ( NULL );
+ }
+ if (WhatIsSet & NCSMSET_Matrix2) {
+ Loop->AddReal ( m[1][0] );
+ Loop->AddReal ( m[1][1] );
+ Loop->AddReal ( m[1][2] );
+ Loop->AddReal ( v[1] );
+ } else {
+ Loop->AddString ( NULL );
+ Loop->AddString ( NULL );
+ Loop->AddString ( NULL );
+ Loop->AddString ( NULL );
+ }
+ if (WhatIsSet & NCSMSET_Matrix3) {
+ Loop->AddReal ( m[2][0] );
+ Loop->AddReal ( m[2][1] );
+ Loop->AddReal ( m[2][2] );
+ Loop->AddReal ( v[2] );
+ } else {
+ Loop->AddString ( NULL );
+ Loop->AddString ( NULL );
+ Loop->AddString ( NULL );
+ Loop->AddString ( NULL );
+ }
+ if (iGiven==1) Loop->AddString ( pstr("generated") );
+ else Loop->AddNoData ( mmcif::CIF_NODATA_DOT );
+ }
+
+ ERROR_CODE NCSMatrix::GetCIF ( mmcif::PData CIF, int & n ) {
+ mmcif::PLoop Loop;
+ char Code[100];
+ ERROR_CODE rc;
+
+ Loop = CIF->GetLoop ( CIFCAT_STRUCT_NCS_OPER );
+ if (!Loop) {
+ n = -1; // signal to finish processing of this structure
+ return Error_EmptyCIF;
+ }
+
+ if (n>=Loop->GetLoopLength()) {
+ n = -1;
+ return Error_EmptyCIF;
+ }
+
+ WhatIsSet = 0;
+ rc = CIFGetInteger ( serNum,Loop,CIFTAG_ID,n );
+ if (rc!=Error_NoError) return rc;
+ if (CIFGetString(Code,Loop,CIFTAG_CODE,n,sizeof(Code),
+ pstr("")))
+ iGiven = MinInt4;
+ else if (!strcasecmp(Code,"generated"))
+ iGiven = 1;
+ else
+ iGiven = MinInt4;
+
+
+ rc = CIFGetReal ( m[0][0],Loop,CIFTAG_MATRIX11,n );
+ if (rc!=Error_NoError) return rc;
+ rc = CIFGetReal ( m[0][1],Loop,CIFTAG_MATRIX12,n );
+ if (rc!=Error_NoError) return rc;
+ rc = CIFGetReal ( m[0][2],Loop,CIFTAG_MATRIX13,n );
+ if (rc!=Error_NoError) return rc;
+ rc = CIFGetReal ( v[0] ,Loop,CIFTAG_VECTOR1 ,n );
+ if (rc!=Error_NoError) return rc;
+ WhatIsSet |= NCSMSET_Matrix1;
+
+ rc = CIFGetReal ( m[1][0],Loop,CIFTAG_MATRIX21,n );
+ if (rc!=Error_NoError) return rc;
+ rc = CIFGetReal ( m[1][1],Loop,CIFTAG_MATRIX22,n );
+ if (rc!=Error_NoError) return rc;
+ rc = CIFGetReal ( m[1][2],Loop,CIFTAG_MATRIX23,n );
+ if (rc!=Error_NoError) return rc;
+ rc = CIFGetReal ( v[1] ,Loop,CIFTAG_VECTOR2 ,n );
+ if (rc!=Error_NoError) return rc;
+ WhatIsSet |= NCSMSET_Matrix2;
+
+ rc = CIFGetReal ( m[2][0],Loop,CIFTAG_MATRIX31,n );
+ if (rc!=Error_NoError) return rc;
+ rc = CIFGetReal ( m[2][1],Loop,CIFTAG_MATRIX32,n );
+ if (rc!=Error_NoError) return rc;
+ rc = CIFGetReal ( m[2][2],Loop,CIFTAG_MATRIX33,n );
+ if (rc!=Error_NoError) return rc;
+ rc = CIFGetReal ( v[2] ,Loop,CIFTAG_VECTOR3 ,n );
+ if (rc!=Error_NoError) return rc;
+ WhatIsSet |= NCSMSET_Matrix3;
+
+ n++;
+
+ return Error_NoError;
+
+ }
+
+ void NCSMatrix::SetNCSMatrix ( int serialNum,
+ mat33 & ncs_m, vect3 & ncs_v,
+ int i_Given ) {
+ int i,j;
+ serNum = serialNum;
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++)
+ m[i][j] = ncs_m[i][j];
+ v[i] = ncs_v[i];
+ }
+ iGiven = i_Given;
+ WhatIsSet |= NCSMSET_All;
+ }
+
+ void NCSMatrix::Copy ( PContainerClass NCSMatrix ) {
+ int i,j;
+
+ serNum = PNCSMatrix(NCSMatrix)->serNum;
+ iGiven = PNCSMatrix(NCSMatrix)->iGiven;
+
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++)
+ m[i][j] = PNCSMatrix(NCSMatrix)->m[i][j];
+ v[i] = PNCSMatrix(NCSMatrix)->v[i];
+ }
+
+ WhatIsSet = PNCSMatrix(NCSMatrix)->WhatIsSet;
+
+ }
+
+ void NCSMatrix::write ( io::RFile f ) {
+ int i,j;
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &serNum );
+ f.WriteInt ( &iGiven );
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++)
+ f.WriteReal ( &(m[i][j]) );
+ f.WriteReal ( &(v[i]) );
+ }
+ f.WriteWord ( &WhatIsSet );
+ }
+
+ void NCSMatrix::read ( io::RFile f ) {
+ int i,j;
+ byte Version;
+ f.ReadByte ( &Version );
+ f.ReadInt ( &serNum );
+ f.ReadInt ( &iGiven );
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++)
+ f.ReadReal ( &(m[i][j]) );
+ f.ReadReal ( &(v[i]) );
+ }
+ f.ReadWord ( &WhatIsSet );
+ }
+
+ MakeStreamFunctions(NCSMatrix)
+
+
+
+ // ================ TVect ===================
+
+ TVect::TVect() : ContainerClass() {
+ Init();
+ }
+
+ TVect::TVect ( cpstr S ) : ContainerClass() {
+ Init();
+ ConvertPDBASCII ( S );
+ }
+
+ TVect::TVect ( io::RPStream Object ) : ContainerClass(Object) {
+ Init();
+ }
+
+ TVect::~TVect() {
+ if (comment) delete[] comment;
+ }
+
+ void TVect::Init() {
+ serNum = -1;
+ t[0] = 0.0;
+ t[1] = 0.0;
+ t[2] = 0.0;
+ comment = NULL;
+ }
+
+ void TVect::PDBASCIIDump ( pstr S, int N ) {
+ UNUSED_ARGUMENT(N);
+ // makes the ASCII PDB TVECT line number N
+ sprintf ( S,"TVECT %3i",serNum );
+ PadSpaces ( S,80 );
+ PutRealF ( &(S[10]),t[0],10,5 );
+ PutRealF ( &(S[20]),t[1],10,5 );
+ PutRealF ( &(S[30]),t[2],10,5 );
+ if (comment)
+ strncpy ( &(S[40]),comment,IMin(30,strlen(comment)) );
+ }
+
+ ERROR_CODE TVect::ConvertPDBASCII ( cpstr S ) {
+ GetInteger ( serNum ,&(S[7]) ,3 );
+ GetReal ( t[0] ,&(S[10]),10 );
+ GetReal ( t[1] ,&(S[20]),10 );
+ GetReal ( t[2] ,&(S[30]),10 );
+ CreateCopy ( comment,&(S[40]) );
+ return Error_NoError;
+
+ }
+
+ void TVect::MakeCIF ( mmcif::PData CIF, int N ) {
+ mmcif::PLoop Loop;
+ int RC;
+ RC = CIF->AddLoop ( CIFCAT_DATABASE_PDB_TVECT,Loop );
+ if ((RC!=mmcif::CIFRC_Ok) || (N==0)) {
+ // the category was (re)created, provide tags
+ Loop->AddLoopTag ( CIFTAG_ID );
+ Loop->AddLoopTag ( CIFTAG_VECTOR1 );
+ Loop->AddLoopTag ( CIFTAG_VECTOR2 );
+ Loop->AddLoopTag ( CIFTAG_VECTOR3 );
+ Loop->AddLoopTag ( CIFTAG_DETAILS );
+ }
+ Loop->AddInteger ( serNum );
+ Loop->AddReal ( t[0] );
+ Loop->AddReal ( t[1] );
+ Loop->AddReal ( t[2] );
+ Loop->AddString ( comment );
+ }
+
+ ERROR_CODE TVect::GetCIF ( mmcif::PData CIF, int & n ) {
+ mmcif::PLoop Loop;
+ ERROR_CODE rc;
+
+ Loop = CIF->GetLoop ( CIFCAT_DATABASE_PDB_TVECT );
+ if (!Loop) {
+ n = -1; // signal to finish processing of this structure
+ return Error_EmptyCIF;
+ }
+
+ if (n>=Loop->GetLoopLength()) {
+ n = -1;
+ return Error_EmptyCIF;
+ }
+
+ rc = CIFGetInteger(serNum,Loop,CIFTAG_ID,n );
+ if (rc!=Error_NoError) return rc;
+ rc = CIFGetReal(t[0],Loop,CIFTAG_VECTOR1,n );
+ if (rc!=Error_NoError) return rc;
+ rc = CIFGetReal(t[1],Loop,CIFTAG_VECTOR2,n );
+ if (rc!=Error_NoError) return rc;
+ rc = CIFGetReal(t[2],Loop,CIFTAG_VECTOR3,n );
+ if (rc!=Error_NoError) return rc;
+ Loop->GetString ( comment,CIFTAG_DETAILS,n,true );
+
+ n++;
+
+ return Error_NoError;
+
+ }
+
+
+ void TVect::Copy ( PContainerClass TVect ) {
+ int i;
+ serNum = PTVect(TVect)->serNum;
+ for (i=0;i<3;i++)
+ t[i] = PTVect(TVect)->t[i];
+ CreateCopy ( comment,PTVect(TVect)->comment );
+ }
+
+ void TVect::write ( io::RFile f ) {
+ int i;
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &serNum );
+ for (i=0;i<3;i++)
+ f.WriteReal ( &(t[i]) );
+ f.CreateWrite ( comment );
+ }
+
+ void TVect::read ( io::RFile f ) {
+ int i;
+ byte Version;
+ f.ReadByte ( &Version );
+ f.ReadInt ( &serNum );
+ for (i=0;i<3;i++)
+ f.ReadReal ( &(t[i]) );
+ f.CreateRead ( comment );
+ }
+
+ MakeStreamFunctions(TVect)
+
+
+
+ // ===================== Cryst =======================
+
+ Cryst::Cryst() : io::Stream() {
+ Init ( true );
+ }
+
+ Cryst::Cryst ( io::RPStream Object ) : io::Stream(Object) {
+ Init ( true );
+ }
+
+ void Cryst::Init ( bool fullInit ) {
+ int i,j,k;
+
+ WhatIsSet = 0; // nothing is set
+ a = 1.0;
+ b = 1.0;
+ c = 1.0;
+ alpha = 90.0;
+ beta = 90.0;
+ gamma = 90.0;
+ strcpy ( spaceGroup ,"" );
+ strcpy ( spaceGroupFix,"" );
+ Z = 1;
+ CellCheck = CCHK_NoCell;
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++) {
+ o[i][j] = 0.0;
+ s[i][j] = 0.0;
+ for (k=0;k<6;k++)
+ RR[k][i][j] = 0.0;
+ }
+ o[i][i] = 1.0;
+ s[i][i] = 1.0;
+ t[i] = 0.0;
+ u[i] = 0.0;
+ for (k=0;k<6;k++)
+ RR[k][i][i] = 1.0;
+ }
+ for (i=0;i<4;i++) {
+ for (j=0;j<4;j++) {
+ RO [i][j] = 0.0;
+ RF [i][j] = 0.0;
+ ROU[i][j] = 0.0;
+ RFU[i][j] = 0.0;
+ }
+ RO [i][i] = 1.0;
+ RF [i][i] = 1.0;
+ ROU[i][i] = 1.0;
+ RFU[i][i] = 1.0;
+ }
+ Vol = 0.0;
+ VolChk = 0.0;
+ VolErr = 0.0;
+ as = 1.0;
+ bs = 1.0;
+ cs = 1.0;
+ alphas = 90.0;
+ betas = 90.0;
+ gammas = 90.0;
+
+ for (k=0;k<6;k++)
+ AC[k] = 0.0;
+
+ NCode = 0;
+
+ if (fullInit) {
+ syminfo_lib = NULL;
+ ignoreScalei = false; // flag to ignore SCALEi cards
+ processSG = true; // flag to process space group at file read
+ fixSpaceGroup = true; // flag to fix space group at file read
+ }
+
+ }
+
+ Cryst::~Cryst() {
+ FreeMemory();
+ if (syminfo_lib) delete[] syminfo_lib;
+ }
+
+ void Cryst::FreeMemory() {
+ ncsMatrix.FreeContainer();
+ tVect .FreeContainer();
+ symOps .FreeMemory ();
+ }
+
+ void Cryst::Reset() {
+ FreeMemory();
+ Init ( false );
+ }
+
+ cpstr rhombohedral[] = {
+ cpstr("R 3" ),
+ cpstr("R 3" ),
+ cpstr("R 3 2"),
+ cpstr("R 3 2")
+ };
+
+ cpstr short_mono[] = {
+ cpstr("P 2" ),
+ cpstr("P 21"),
+ cpstr("C 2" ),
+ cpstr("A 2" ),
+ cpstr("B 2" ),
+ cpstr("I 2" )
+ };
+
+ cpstr special[] = {
+ cpstr("A1" ),
+ cpstr("Hall: P 1 (-x,-1/2*y+1/2*z,1/2*y+1/2*z)" ),
+ cpstr("C1211" ),
+ cpstr("Hall: C 2y (x+1/4,y+1/4,z)" ),
+ cpstr("C21" ),
+ cpstr("Hall: C 2y (x+1/4,y+1/4,z)" ),
+ cpstr("I1211" ),
+ cpstr("Hall: C 2y (x+1/4,y+1/4,-x+z-1/4)" ),
+ cpstr("I21" ),
+ cpstr("Hall: C 2y (x+1/4,y+1/4,-x+z-1/4)" ),
+ cpstr("P21212A"),
+ cpstr("Hall: P 2 2ab (x+1/4,y+1/4,z)" ),
+ cpstr("F422" ),
+ cpstr("Hall: I 4 2 (1/2*x+1/2*y,-1/2*x+1/2*y,z)" ),
+ cpstr("C4212" ),
+ cpstr("Hall: P 4 2 (1/2*x+1/2*y-1/4,-1/2*x+1/2*y-1/4,z)")
+ };
+
+
+
+ int Cryst::FixSpaceGroup() {
+ // This function attempts to clean up the Brookhaven mess in space
+ // group naming, by checking the space group symbol with cell
+ // parameters. Returns:
+ //
+ // 0 - space group symbol is correct, spaceGroupFix receives
+ // a copy of spaceGroup
+ // 1 - space group symbol does not agree with cell parameters,
+ // and fixed successfully. spaceGroupFix receives
+ // the appropriate space group symbol
+ // -1 - space group symbol does not agree with cell parameters,
+ // however fix is not possible. spaceGroupFix receives
+ // a copy of spaceGroup
+ // -2 - any checks are not possible because cell parameters
+ // are not found, spaceGroupFix receives a copy of
+ // spaceGroup
+ //
+ realtype eps,m1,m2;
+ SymGroup s;
+ int i,k;
+ char c;
+
+ strcpy ( spaceGroupFix,spaceGroup );
+
+ if ((WhatIsSet & CSET_CellParams)!=CSET_CellParams) return -2;
+
+ eps = 0.01;
+
+ k = -1;
+ for (i=0;(i<4) && (k<0);i++)
+ if (!strcmp(spaceGroup,rhombohedral[i])) k = i;
+
+ if (k>=0) {
+ c = 'N';
+ if ((fabs(a-b)<=eps) && (fabs(alpha-90.0)<=eps) &&
+ (fabs(beta-90.0)<=eps) && (fabs(gamma-120.0)<=eps))
+ c = 'H';
+ else {
+ m1 = (a+b+c)/3.0;
+ m2 = (alpha+beta+gamma)/3.0;
+ if ((fabs(a-m1)<=eps) && (fabs(b-m1)<=eps) &&
+ (fabs(c-m1)<=eps) &&
+ (fabs(alpha-m2)<=eps) && (fabs(beta-m2)<=eps) &&
+ (fabs(gamma-m2)<=eps))
+ c = 'R';
+ }
+ if (c!=spaceGroup[0]) {
+ if (c!='N') {
+ spaceGroupFix[0] = c;
+ return 1;
+ }
+ return -1;
+ }
+ return 0;
+ }
+
+ for (i=0;(i<6) && (k<0);i++)
+ if (!strcmp(spaceGroup,short_mono[i])) k = i;
+
+ if (k>=0) {
+ if ((fabs(alpha-90.0)<=eps) && (fabs(gamma-90.0)<=eps)) {
+ if (spaceGroup[0]=='B') return -1;
+ sprintf ( spaceGroupFix,"%c 1 %s 1",spaceGroup[0],
+ &(spaceGroup[2]) );
+ return 1;
+ }
+ if ((fabs(alpha-90.0)<=eps) && (fabs(beta-90.0)<=eps)) {
+ if (spaceGroup[0]=='C') return -1;
+ sprintf ( spaceGroupFix,"%c 1 1 %s",spaceGroup[0],
+ &(spaceGroup[2]) );
+ return 1;
+ }
+ return -1;
+ }
+
+ i = 0;
+ k = 0;
+ while (spaceGroup[i]) {
+ if (spaceGroup[i]!=' ') s[k++] = spaceGroup[i];
+ i++;
+ }
+ s[k] = char(0);
+
+ k = -1;
+ for (i=0;(i<16) && (k<0);i+=2)
+ if (!strcmp(s,special[i])) k = i;
+
+ if (k>=0) {
+ strcpy ( spaceGroupFix,special[k+1] );
+ return 1;
+ }
+
+ return 0;
+
+ }
+
+ ERROR_CODE Cryst::ConvertPDBString ( pstr PDBString ) {
+ // Interprets the ASCII PDB line and fills the corresponding fields.
+ // Returns zero if the line was converted, otherwise returns a
+ // non-negative value of Error_XXXX.
+ // PDBString must be not shorter than 81 characters.
+ PNCSMatrix ncsMtx;
+ PTVect tV;
+ ERROR_CODE RC;
+
+ // pad input line with spaces, if necessary
+ PadSpaces ( PDBString,80 );
+
+ if (!strncmp(PDBString,"CRYST",5)) {
+ // Here we check for "CRYST" and not for "CRYST1" keyword.
+ // As seems, people tend to not differentiating them.
+ if (GetReal(a,&(PDBString[6]) ,9) &&
+ GetReal(b,&(PDBString[15]),9) &&
+ GetReal(c,&(PDBString[24]),9))
+ WhatIsSet |= CSET_CellParams1;
+
+ if (GetReal(alpha,&(PDBString[33]),7) &&
+ GetReal(beta ,&(PDBString[40]),7) &&
+ GetReal(gamma,&(PDBString[47]),7))
+ WhatIsSet |= CSET_CellParams2;
+
+ GetString ( spaceGroup,&(PDBString[55]),11 );
+ CutSpaces ( spaceGroup,SCUTKEY_BEGEND );
+ if (fixSpaceGroup) FixSpaceGroup();
+ else strcpy ( spaceGroupFix,spaceGroup );
+ if (spaceGroupFix[0] && processSG) {
+ if (symOps.SetGroup(spaceGroupFix,syminfo_lib)==SYMOP_Ok)
+ WhatIsSet |= CSET_SpaceGroup;
+ }
+
+ if (GetInteger(Z,&(PDBString[66]),4))
+ WhatIsSet |= CSET_ZValue;
+
+ WhatIsSet &= 0xFBFF;
+
+ if ((a*b*c*alpha*beta*gamma==0.0) ||
+ ((a==1.0) && (b==1.0) && (c==1.0) &&
+ (alpha==90.0) && (beta==90.0) && (gamma==90.0) &&
+ (!strcmp(spaceGroup,"P 1")))) {
+ WhatIsSet &= ~(CSET_CellParams1 | CSET_CellParams2 |
+ CSET_SpaceGroup);
+ WhatIsSet |= CSET_DummyCell;
+ }
+
+ } else if (!strncmp(PDBString,"ORIGX1",6)) {
+
+ if (GetReal(o[0][0],&(PDBString[10]),10) &&
+ GetReal(o[0][1],&(PDBString[20]),10) &&
+ GetReal(o[0][2],&(PDBString[30]),10) &&
+ GetReal(t[0] ,&(PDBString[45]),10))
+ WhatIsSet |= CSET_OrigMatrix1;
+
+ } else if (!strncmp(PDBString,"ORIGX2",6)) {
+
+ if (GetReal(o[1][0],&(PDBString[10]),10) &&
+ GetReal(o[1][1],&(PDBString[20]),10) &&
+ GetReal(o[1][2],&(PDBString[30]),10) &&
+ GetReal(t[1] ,&(PDBString[45]),10))
+ WhatIsSet |= CSET_OrigMatrix2;
+
+ } else if (!strncmp(PDBString,"ORIGX3",6)) {
+
+ if (GetReal(o[2][0],&(PDBString[10]),10) &&
+ GetReal(o[2][1],&(PDBString[20]),10) &&
+ GetReal(o[2][2],&(PDBString[30]),10) &&
+ GetReal(t[2] ,&(PDBString[45]),10))
+ WhatIsSet |= CSET_OrigMatrix3;
+
+ } else if (!strncmp(PDBString,"SCALE1",6)) {
+
+ if (GetReal(s[0][0],&(PDBString[10]),10) &&
+ GetReal(s[0][1],&(PDBString[20]),10) &&
+ GetReal(s[0][2],&(PDBString[30]),10) &&
+ GetReal(u[0] ,&(PDBString[45]),10))
+ WhatIsSet |= CSET_ScaleMatrix1;
+ WhatIsSet &= 0xFBFF;
+ CellCheck |= CCHK_Unchecked;
+
+ } else if (!strncmp(PDBString,"SCALE2",6)) {
+
+ if (GetReal(s[1][0],&(PDBString[10]),10) &&
+ GetReal(s[1][1],&(PDBString[20]),10) &&
+ GetReal(s[1][2],&(PDBString[30]),10) &&
+ GetReal(u[1] ,&(PDBString[45]),10))
+ WhatIsSet |= CSET_ScaleMatrix2;
+ WhatIsSet &= 0xFBFF;
+ CellCheck |= CCHK_Unchecked;
+
+ } else if (!strncmp(PDBString,"SCALE3",6)) {
+
+ if (GetReal(s[2][0],&(PDBString[10]),10) &&
+ GetReal(s[2][1],&(PDBString[20]),10) &&
+ GetReal(s[2][2],&(PDBString[30]),10) &&
+ GetReal(u[2] ,&(PDBString[45]),10))
+ WhatIsSet |= CSET_ScaleMatrix3;
+ WhatIsSet &= 0xFBFF;
+ CellCheck |= CCHK_Unchecked;
+
+ } else if (!strncmp(PDBString,"MTRIX",5)) {
+
+ RC = ncsMatrix.AddMTRIXLine ( PDBString );
+ if (RC==Error_NCSM_WrongSerial) {
+ ncsMtx = new NCSMatrix();
+ RC = ncsMtx->ConvertPDBASCII ( PDBString );
+ if (RC==0) ncsMatrix.AddData ( ncsMtx );
+ else delete ncsMtx;
+ }
+ return RC;
+
+ } else if (!strncmp(PDBString,"TVECT ",6)) {
+
+ tV = new TVect();
+ RC = tV->ConvertPDBASCII(PDBString);
+ if (RC==0) tVect.AddData ( tV );
+ else delete tV;
+ return RC;
+
+ } else
+ return Error_WrongSection;
+
+ return Error_NoError;
+
+ }
+
+ void Cryst::PDBASCIIDump ( io::RFile f ) {
+ int i,j;
+ char S[100];
+
+ if (WhatIsSet & (CSET_CrystCard | CSET_DummyCell)) {
+ strcpy ( S,"CRYST1" );
+ PadSpaces ( S,80 );
+ if (WhatIsSet & CSET_CellParams1) {
+ PutRealF ( &(S[6 ]),a,9,3 );
+ PutRealF ( &(S[15]),b,9,3 );
+ PutRealF ( &(S[24]),c,9,3 );
+ }
+ if (WhatIsSet & CSET_CellParams2) {
+ PutRealF ( &(S[33]),alpha,7,2 );
+ PutRealF ( &(S[40]),beta ,7,2 );
+ PutRealF ( &(S[47]),gamma,7,2 );
+ }
+ if ((WhatIsSet & CSET_SpaceGroup) || (spaceGroup[0]))
+ strncpy ( &(S[55]),spaceGroup,IMin(11,strlen(spaceGroup)) );
+ if (WhatIsSet & CSET_ZValue)
+ PutInteger ( &(S[66]),Z,4 );
+ f.WriteLine ( S );
+ }
+
+ if ((WhatIsSet & CSET_OrigMatrix)==CSET_OrigMatrix)
+ for (i=0;i<3;i++) {
+ sprintf ( S,"ORIGX%1i",i+1);
+ PadSpaces ( S,80 );
+ for (j=0;j<3;j++)
+ PutRealF ( &(S[10+j*10]),o[i][j],10,6 );
+ PutRealF ( &(S[45]),t[i],10,5 );
+ f.WriteLine ( S );
+ }
+
+ if ((WhatIsSet & CSET_ScaleMatrix)==CSET_ScaleMatrix)
+ for (i=0;i<3;i++) {
+ sprintf ( S,"SCALE%1i",i+1);
+ PadSpaces ( S,80 );
+ for (j=0;j<3;j++)
+ PutRealF ( &(S[10+j*10]),s[i][j],10,6 );
+ PutRealF ( &(S[45]),u[i],10,5 );
+ f.WriteLine ( S );
+ }
+
+ ncsMatrix.PDBASCIIDump ( f );
+ tVect .PDBASCIIDump ( f );
+
+ }
+
+
+ ERROR_CODE Cryst::GetCIF ( mmcif::PData CIF ) {
+ mmcif::PStruct cifStruct;
+ ERROR_CODE RC;
+
+ WhatIsSet = 0;
+
+ cifStruct = CIF->GetStructure ( CIFCAT_CELL );
+
+ if (cifStruct) {
+
+ RC = CIFGetReal ( a,cifStruct,CIFTAG_LENGTH_A );
+ if (RC==Error_NoError)
+ RC = CIFGetReal ( b,cifStruct,CIFTAG_LENGTH_B );
+ if (RC==Error_NoError)
+ RC = CIFGetReal ( c,cifStruct,CIFTAG_LENGTH_C );
+ if (RC==Error_UnrecognizedReal) return RC;
+ if (RC==Error_NoError) WhatIsSet |= CSET_CellParams1;
+
+ RC = CIFGetReal ( alpha,cifStruct,CIFTAG_ANGLE_ALPHA );
+ if (RC==Error_NoError)
+ RC = CIFGetReal ( beta,cifStruct,CIFTAG_ANGLE_BETA );
+ if (RC==Error_NoError)
+ RC = CIFGetReal ( gamma,cifStruct,CIFTAG_ANGLE_GAMMA );
+ if (RC==Error_UnrecognizedReal) return RC;
+ if (RC==Error_NoError) WhatIsSet |= CSET_CellParams2;
+
+ RC = CIFGetInteger ( Z,cifStruct,CIFTAG_Z_PDB );
+ if (RC==Error_UnrecognizedReal) return RC;
+ if (RC==Error_NoError) WhatIsSet |= CSET_ZValue;
+
+ }
+
+ cifStruct = CIF->GetStructure ( CIFCAT_SYMMETRY );
+ if (cifStruct) {
+ CIFGetString ( spaceGroup,cifStruct,CIFTAG_SPACE_GROUP_NAME_H_M,
+ sizeof(spaceGroup),pstr("") );
+ CutSpaces ( spaceGroup,SCUTKEY_BEGEND );
+ if (fixSpaceGroup) FixSpaceGroup();
+ else strcpy ( spaceGroupFix,spaceGroup );
+ /*
+ if (fixSpaceGroup) {
+ if (!strcasecmp(spaceGroup,"P 21"))
+ strcpy ( spaceGroup,"P 1 21 1" );
+ else if (!strcasecmp(spaceGroup,"C 2"))
+ strcpy ( spaceGroup,"C 1 2 1" );
+ }
+ */
+ if (spaceGroupFix[0] && processSG) {
+ if (symOps.SetGroup(spaceGroupFix,syminfo_lib)==SYMOP_Ok)
+ WhatIsSet |= CSET_SpaceGroup;
+ }
+ }
+
+ if ((a*b*c*alpha*beta*gamma==0.0) ||
+ ((a==1.0) && (b==1.0) && (c==1.0) &&
+ (alpha==90.0) && (beta==90.0) && (gamma==90.0) &&
+ (!strcmp(spaceGroup,"P 1")))) {
+ WhatIsSet &= ~(CSET_CellParams1 | CSET_CellParams2 |
+ CSET_SpaceGroup);
+ WhatIsSet |= CSET_DummyCell;
+ }
+
+ cifStruct = CIF->GetStructure ( CIFCAT_DATABASE_PDB_MATRIX );
+ if (cifStruct) {
+ RC = CIFGetReal ( o[0][0],cifStruct,CIFTAG_ORIGX11 );
+ if (RC==Error_NoError)
+ RC = CIFGetReal ( o[0][1],cifStruct,CIFTAG_ORIGX12 );
+ if (RC==Error_NoError)
+ RC = CIFGetReal ( o[0][2],cifStruct,CIFTAG_ORIGX13 );
+ if (RC==Error_NoError)
+ RC = CIFGetReal ( o[1][0],cifStruct,CIFTAG_ORIGX21 );
+ if (RC==Error_NoError)
+ RC = CIFGetReal ( o[1][1],cifStruct,CIFTAG_ORIGX22 );
+ if (RC==Error_NoError)
+ RC = CIFGetReal ( o[1][2],cifStruct,CIFTAG_ORIGX23 );
+ if (RC==Error_NoError)
+ RC = CIFGetReal ( o[2][0],cifStruct,CIFTAG_ORIGX31 );
+ if (RC==Error_NoError)
+ RC = CIFGetReal ( o[2][1],cifStruct,CIFTAG_ORIGX32 );
+ if (RC==Error_NoError)
+ RC = CIFGetReal ( o[2][2],cifStruct,CIFTAG_ORIGX33 );
+ if (RC==Error_NoError)
+ RC = CIFGetReal ( t[0],cifStruct,CIFTAG_ORIGX_VECTOR1 );
+ if (RC==Error_NoError)
+ RC = CIFGetReal ( t[1],cifStruct,CIFTAG_ORIGX_VECTOR2 );
+ if (RC==Error_NoError)
+ RC = CIFGetReal ( t[2],cifStruct,CIFTAG_ORIGX_VECTOR3 );
+ if (RC!=Error_NoError) return RC;
+ WhatIsSet |= CSET_OrigMatrix;
+ }
+
+ cifStruct = CIF->GetStructure ( CIFCAT_ATOM_SITES );
+ if (cifStruct) {
+ RC = CIFGetReal ( s[0][0],cifStruct,CIFTAG_FRACT_TRANSF_MATRIX11 );
+ if (RC==Error_NoError)
+ RC = CIFGetReal(s[0][1],cifStruct,CIFTAG_FRACT_TRANSF_MATRIX12);
+ if (RC==Error_NoError)
+ RC = CIFGetReal(s[0][2],cifStruct,CIFTAG_FRACT_TRANSF_MATRIX13);
+ if (RC==Error_NoError)
+ RC = CIFGetReal(s[1][0],cifStruct,CIFTAG_FRACT_TRANSF_MATRIX21);
+ if (RC==Error_NoError)
+ RC = CIFGetReal(s[1][1],cifStruct,CIFTAG_FRACT_TRANSF_MATRIX22);
+ if (RC==Error_NoError)
+ RC = CIFGetReal(s[1][2],cifStruct,CIFTAG_FRACT_TRANSF_MATRIX23);
+ if (RC==Error_NoError)
+ RC = CIFGetReal(s[2][0],cifStruct,CIFTAG_FRACT_TRANSF_MATRIX31);
+ if (RC==Error_NoError)
+ RC = CIFGetReal(s[2][1],cifStruct,CIFTAG_FRACT_TRANSF_MATRIX32);
+ if (RC==Error_NoError)
+ RC = CIFGetReal(s[2][2],cifStruct,CIFTAG_FRACT_TRANSF_MATRIX33);
+ if (RC==Error_NoError)
+ RC = CIFGetReal(u[0] ,cifStruct,CIFTAG_FRACT_TRANSF_VECTOR1 );
+ if (RC==Error_NoError)
+ RC = CIFGetReal(u[1] ,cifStruct,CIFTAG_FRACT_TRANSF_VECTOR2 );
+ if (RC==Error_NoError)
+ RC = CIFGetReal(u[2] ,cifStruct,CIFTAG_FRACT_TRANSF_VECTOR3 );
+ if (RC!=Error_NoError) return RC;
+ WhatIsSet |= CSET_ScaleMatrix;
+ }
+
+ RC = ncsMatrix.GetCIF(CIF,ClassID_NCSMatrix);
+ if (RC!=Error_NoError) return RC;
+
+ RC = tVect.GetCIF(CIF,ClassID_TVect);
+ return RC;
+
+ }
+
+ void Cryst::MakeCIF ( mmcif::PData CIF ) {
+ mmcif::PStruct cifStruct;
+ char S[200];
+
+ if (WhatIsSet & (CSET_CellParams1 | CSET_DummyCell)) {
+ CIF->AddStructure ( CIFCAT_CELL,cifStruct );
+ cifStruct->PutReal ( a,CIFTAG_LENGTH_A,8 );
+ cifStruct->PutReal ( b,CIFTAG_LENGTH_B,8 );
+ cifStruct->PutReal ( c,CIFTAG_LENGTH_C,8 );
+ }
+
+ if (WhatIsSet & (CSET_CellParams2 | CSET_DummyCell)) {
+ CIF->AddStructure ( CIFCAT_CELL,cifStruct );
+ cifStruct->PutReal ( alpha,CIFTAG_ANGLE_ALPHA,8 );
+ cifStruct->PutReal ( beta ,CIFTAG_ANGLE_BETA, 8 );
+ cifStruct->PutReal ( gamma,CIFTAG_ANGLE_GAMMA,8 );
+ }
+
+ if ((WhatIsSet & (CSET_SpaceGroup | CSET_DummyCell)) ||
+ (spaceGroup[0]))
+ CIF->PutString ( strcpy_cs(S,spaceGroup),CIFCAT_SYMMETRY,
+ CIFTAG_SPACE_GROUP_NAME_H_M );
+
+ if (WhatIsSet & (CSET_ZValue | CSET_DummyCell))
+ CIF->PutInteger ( Z,CIFCAT_CELL,CIFTAG_Z_PDB );
+
+
+ if ((WhatIsSet & CSET_OrigMatrix)==CSET_OrigMatrix) {
+ CIF->AddStructure ( CIFCAT_DATABASE_PDB_MATRIX,cifStruct );
+ cifStruct->PutReal ( o[0][0],CIFTAG_ORIGX11 ,8 );
+ cifStruct->PutReal ( o[0][1],CIFTAG_ORIGX12 ,8 );
+ cifStruct->PutReal ( o[0][2],CIFTAG_ORIGX13 ,8 );
+ cifStruct->PutReal ( o[1][0],CIFTAG_ORIGX21 ,8 );
+ cifStruct->PutReal ( o[1][1],CIFTAG_ORIGX22 ,8 );
+ cifStruct->PutReal ( o[1][2],CIFTAG_ORIGX23 ,8 );
+ cifStruct->PutReal ( o[2][0],CIFTAG_ORIGX31 ,8 );
+ cifStruct->PutReal ( o[2][1],CIFTAG_ORIGX32 ,8 );
+ cifStruct->PutReal ( o[2][2],CIFTAG_ORIGX33 ,8 );
+ cifStruct->PutReal ( t[0] ,CIFTAG_ORIGX_VECTOR1,8 );
+ cifStruct->PutReal ( t[1] ,CIFTAG_ORIGX_VECTOR2,8 );
+ cifStruct->PutReal ( t[2] ,CIFTAG_ORIGX_VECTOR3,8 );
+ }
+
+ if ((WhatIsSet & CSET_ScaleMatrix)==CSET_ScaleMatrix) {
+ CIF->AddStructure ( CIFCAT_ATOM_SITES,cifStruct );
+ cifStruct->PutReal ( s[0][0],CIFTAG_FRACT_TRANSF_MATRIX11,8 );
+ cifStruct->PutReal ( s[0][1],CIFTAG_FRACT_TRANSF_MATRIX12,8 );
+ cifStruct->PutReal ( s[0][2],CIFTAG_FRACT_TRANSF_MATRIX13,8 );
+ cifStruct->PutReal ( s[1][0],CIFTAG_FRACT_TRANSF_MATRIX21,8 );
+ cifStruct->PutReal ( s[1][1],CIFTAG_FRACT_TRANSF_MATRIX22,8 );
+ cifStruct->PutReal ( s[1][2],CIFTAG_FRACT_TRANSF_MATRIX23,8 );
+ cifStruct->PutReal ( s[2][0],CIFTAG_FRACT_TRANSF_MATRIX31,8 );
+ cifStruct->PutReal ( s[2][1],CIFTAG_FRACT_TRANSF_MATRIX32,8 );
+ cifStruct->PutReal ( s[2][2],CIFTAG_FRACT_TRANSF_MATRIX33,8 );
+ cifStruct->PutReal ( u[0] ,CIFTAG_FRACT_TRANSF_VECTOR1 ,8 );
+ cifStruct->PutReal ( u[1] ,CIFTAG_FRACT_TRANSF_VECTOR2 ,8 );
+ cifStruct->PutReal ( u[2] ,CIFTAG_FRACT_TRANSF_VECTOR3 ,8 );
+ }
+
+ ncsMatrix.MakeCIF ( CIF );
+ tVect .MakeCIF ( CIF );
+
+ }
+
+
+
+ cpstr OrthCode[6] = {
+ cpstr("A/X0, C*/Z0"), // (standard brookhaven)
+ cpstr("B/X0, A*/Z0"),
+ cpstr("C/X0, B*/Z0"),
+ cpstr("HEX A+B/X0, C*/Z0"),
+ cpstr("A*/X0, C/Z0 (rollett)"),
+ cpstr("A/X0, B*/Y0")
+ };
+
+ cpstr getOrthCodeName ( int NCode ) {
+ if ((NCode>0) && (NCode<=6)) return OrthCode[NCode-1];
+ return cpstr("CUSTOM");
+ }
+
+ void Cryst::CalcCoordTransforms() {
+ realtype rChk1,rChk2,Fac;
+ int i,j,k;
+
+ WhatIsSet &= ~CSET_Transforms; // clear the flag
+
+ if ((WhatIsSet & CSET_CellParams)==CSET_CellParams) {
+ // The 'cryst1' card was supplied. Calculate
+ // standard orthogonalizations.
+
+ CalcOrthMatrices();
+ if (NCode<0) NCode = 0;
+
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++)
+ RO[i][j] = RR[NCode][i][j];
+ RO[i][3] = 0.0;
+ RO[3][i] = 0.0;
+ }
+ RO[3][3] = 1.0;
+ Mat4Inverse ( RO,RF );
+
+ WhatIsSet |= CSET_Transforms;
+
+ if (ignoreScalei)
+ CellCheck = CCHK_Ok;
+ else if ((WhatIsSet & CSET_ScaleMatrix)==CSET_ScaleMatrix) {
+ // All 'scalei' cards were supplied. Calculate
+ // rotation and translation matrices and check
+ // if they are in consistence with the cell.
+
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++)
+ RF[i][j] = s[i][j];
+ RF[i][3] = u[i];
+ RF[3][i] = 0.0;
+ }
+ RF[3][3] = 1.0;
+ Mat4Inverse ( RF,RO );
+
+ // Find orthogonalisation type
+ VolChk = RO[0][0]*(RO[1][1]*RO[2][2] - RO[1][2]*RO[2][1]) +
+ RO[0][1]*(RO[1][2]*RO[2][0] - RO[1][0]*RO[2][2]) +
+ RO[0][2]*(RO[1][0]*RO[2][1] - RO[1][1]*RO[2][0]);
+
+ CellCheck = CCHK_Ok;
+ if (Vol>0.0) {
+ VolErr = fabs(VolChk-Vol)/Vol;
+ if (VolErr>0.02) CellCheck |= CCHK_Error;
+ else if (VolErr>0.1) CellCheck |= CCHK_Disagreement;
+ } else
+ CellCheck |= CCHK_NoCell;
+
+ // try to find NCode
+ NCode = -1;
+ for (k=0;(k<6) && (NCode<0);k++) {
+ NCode = k;
+ for (i=0;i<3;i++)
+ for (j=0;j<3;j++) {
+ rChk1 = RO[i][j] + RR[k][i][j];
+ rChk2 = RO[i][j] - RR[k][i][j];
+ if (fabs(rChk1)>=0.1) {
+ if (fabs(rChk2/rChk1)>0.01)
+ NCode = -1;
+ }
+ }
+ }
+
+ // Correct inaccuracy of SCALEi input due to FORMAT,
+ // replace RF,RO with RR[NCode][][] if possible.
+
+ if (NCode>=0) {
+ for (i=0;i<3;i++)
+ for (j=0;j<3;j++)
+ RO[i][j] = RR[NCode][i][j];
+ Mat4Inverse ( RO,RF );
+ } else
+ CellCheck |= CCHK_NoOrthCode;
+
+ if ((u[0]!=0.0) || (u[1]!=0.0) || (u[2]!=0.0))
+ CellCheck |= CCHK_Translations;
+
+ }
+
+ // Generate ROU and RFU for AnisoU stuff
+ RFU[3][3] = 1.0;
+ for (i=0;i<3;i++) {
+ Fac = sqrt(RF[i][0]*RF[i][0] + RF[i][1]*RF[i][1] +
+ RF[i][2]*RF[i][2]);
+ RFU[i][0] = RF[i][0]/Fac;
+ RFU[i][1] = RF[i][1]/Fac;
+ RFU[i][2] = RF[i][2]/Fac;
+ RFU[i][3] = 0.0;
+ RFU[3][i] = 0.0;
+ }
+ RFU[3][3] = 1.0;
+ Mat4Inverse ( RFU,ROU );
+
+ } else
+ CellCheck |= CCHK_NoCell;
+
+ }
+
+
+ void Cryst::RWBROOKReadPrintout() {
+ int i,j;
+
+ if ((WhatIsSet & CSET_CellParams)==CSET_CellParams) {
+ printf ( " MATRICES DERIVED FROM CRYST1"
+ " CARD IN COORDINATE FILE\n\n\n"
+ " RF "
+ " RO\n\n" );
+ for (i=0;i<4;i++) {
+ printf ( " " );
+ for (j=0;j<4;j++)
+ printf ( "%8.3f",RF[i][j] );
+ printf ( " " );
+ for (j=0;j<4;j++)
+ printf ( "%8.3f",RO[i][j] );
+ printf ( "\n" );
+ }
+ printf ( "\n" );
+ } else
+ printf ( "\n $WARNING: NO CRYST CARDS READ$\n" );
+
+ if ((WhatIsSet & CSET_ScaleMatrix)!=CSET_ScaleMatrix)
+ printf ( "\n $WARNING: NO SCALE CARDS READ$\n" );
+
+ }
+
+
+ void Cryst::CalcOrthMatrices() {
+ // Calculates matrices for standard orthogonalizations
+ // and the cell volume.
+ // The matrices are stored in array RR
+ realtype Conv,Alph,Bet,Gamm,Sum,V;
+ realtype sinA,cosA,sinB,cosB,sinG,cosG;
+ realtype sinAS,cosAS,sinBS,cosBS,sinGS,cosGS;
+ int i,j,k;
+
+ if ((WhatIsSet & CSET_CellParams)!=CSET_CellParams) return;
+
+ Conv = Pi/180.0;
+
+ Alph = alpha*Conv;
+ Bet = beta *Conv;
+ Gamm = gamma*Conv;
+
+ Sum = (Alph+Bet+Gamm)*0.5;
+
+ V = sqrt(sin(Sum-Alph)*sin(Sum-Bet)*sin(Sum-Gamm)*sin(Sum));
+
+ Vol = 2.0*a*b*c*V;
+
+ // Precaution measure for erratic use of the library
+ if ((fabs(Alph)<1.0e-6) || (fabs(Bet)<1.0e-6) ||
+ (fabs(Gamm)<1.0e-6)) {
+ as = 0.0;
+ bs = 0.0;
+ cs = 0.0;
+ alphas = 0.0;
+ betas = 0.0;
+ gammas = 0.0;
+ for (k=0;k<6;k++) {
+ AC[k] = 0.0;
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++)
+ RR[k][i][j] = 0.0;
+ RR[k][i][i] = 1.0;
+ }
+ }
+ return;
+ }
+
+ sinA = sin(Alph);
+ cosA = cos(Alph);
+ sinB = sin(Bet);
+ cosB = cos(Bet);
+ sinG = sin(Gamm);
+ cosG = cos(Gamm);
+
+ cosAS = (cosG*cosB-cosA) / (sinB*sinG);
+ sinAS = sqrt(1.0-cosAS*cosAS);
+ cosBS = (cosA*cosG-cosB) / (sinA*sinG);
+ sinBS = sqrt(1.0-cosBS*cosBS);
+ cosGS = (cosA*cosB-cosG) / (sinA*sinB);
+ sinGS = sqrt(1.0-cosGS*cosGS);
+
+ as = b*c*sinA/Vol;
+ bs = c*a*sinB/Vol;
+ cs = a*b*sinG/Vol;
+ alphas = atan2(sinAS,cosAS)/Conv;
+ betas = atan2(sinBS,cosBS)/Conv;
+ gammas = atan2(sinGS,cosGS)/Conv;
+
+ // ---- Set useful things for calculating dstar
+
+ AC[0] = as*as;
+ AC[1] = bs*bs;
+ AC[2] = cs*cs;
+ AC[3] = 2.0*bs*cs*cosAS;
+ AC[4] = 2.0*cs*as*cosBS;
+ AC[5] = 2.0*as*bs*cosGS;
+
+ // ---- Zero matrices
+
+ for (k=0;k<6;k++)
+ for (i=0;i<3;i++)
+ for (j=0;j<3;j++)
+ RR[k][i][j] = 0.0;
+
+ // ---- Calculate matrices
+
+ // ---- XO along a Zo along c*
+
+ RR[0][0][0] = a;
+ RR[0][0][1] = b*cosG;
+ RR[0][0][2] = c*cosB;
+ RR[0][1][1] = b*sinG;
+ RR[0][1][2] = -c*sinB*cosAS;
+ RR[0][2][2] = c*sinB*sinAS;
+
+ // ---- XO along b Zo along a*
+
+ RR[1][0][0] = a*cosG;
+ RR[1][0][1] = b;
+ RR[1][0][2] = c*cosA;
+ RR[1][1][0] = -a*sinG*cosBS;
+ RR[1][1][2] = c*sinA;
+ RR[1][2][0] = a*sinG*sinBS;
+
+ // ---- XO along c Zo along b*
+
+ RR[2][0][0] = a*cosB;
+ RR[2][0][1] = b*cosA;
+ RR[2][0][2] = c;
+ RR[2][1][0] = a*sinB;
+ RR[2][1][1] = -b*sinA*cosGS;
+ RR[2][2][1] = b*sinA*sinGS;
+
+ // ---- trigonal only - XO along a+b YO alon a-b Zo along c*
+
+ RR[3][0][0] = a/2.0;
+ RR[3][0][1] = a/2.0;
+ RR[3][1][0] = -a*sinG;
+ RR[3][1][1] = a*sinG;
+ RR[3][2][2] = c;
+
+ // ---- XO along a*, ZO along c
+
+ RR[4][0][0] = a*sinB*sinGS;
+ RR[4][1][0] = -a*sinB*cosGS;
+ RR[4][1][1] = b*sinA;
+ RR[4][2][0] = a*cosB;
+ RR[4][2][1] = b*cosA;
+ RR[4][2][2] = c;
+
+ // ---- Grr*! to Gerard Bricogne - his setting for P1 in SKEW.
+ // XO along a, Y0 along b*
+
+ RR[5][0][0] = a;
+ RR[5][0][1] = b*cosG;
+ RR[5][0][2] = c*cosB;
+ RR[5][1][1] = b*sinG*sinAS;
+ RR[5][2][1] = -b*sinG*cosAS;
+ RR[5][2][2] = c*sinB;
+
+ }
+
+
+ bool Cryst::areMatrices() {
+ // returns true if the orthogonal-to-fractional and
+ // fractional-to-orthogonal matrices are defined
+ return (WhatIsSet & CSET_Transforms)!=0x0000;
+ }
+
+
+ bool Cryst::Frac2Orth (
+ realtype x, realtype y, realtype z,
+ realtype & xx, realtype & yy, realtype & zz ) {
+ if (areMatrices()) {
+ xx = RO[0][0]*x + RO[0][1]*y + RO[0][2]*z + RO[0][3];
+ yy = RO[1][0]*x + RO[1][1]*y + RO[1][2]*z + RO[1][3];
+ zz = RO[2][0]*x + RO[2][1]*y + RO[2][2]*z + RO[2][3];
+ return true;
+ } else {
+ xx = x;
+ yy = y;
+ zz = z;
+ return false;
+ }
+ }
+
+ bool Cryst::Orth2Frac (
+ realtype x, realtype y, realtype z,
+ realtype & xx, realtype & yy, realtype & zz ) {
+ if (areMatrices()) {
+ xx = RF[0][0]*x + RF[0][1]*y + RF[0][2]*z + RF[0][3];
+ yy = RF[1][0]*x + RF[1][1]*y + RF[1][2]*z + RF[1][3];
+ zz = RF[2][0]*x + RF[2][1]*y + RF[2][2]*z + RF[2][3];
+ return true;
+ } else {
+ xx = x;
+ yy = y;
+ zz = z;
+ return false;
+ }
+ }
+
+
+ bool Cryst::Frac2Orth ( mat44 & F, mat44 & T ) {
+ mat44 A;
+ if (areMatrices()) {
+ Mat4Mult ( A,F,RF );
+ Mat4Mult ( T,RO,A );
+ return true;
+ } else {
+ Mat4Init ( T );
+ return false;
+ }
+ }
+
+
+ bool Cryst::Orth2Frac ( mat44 & T, mat44 & F ) {
+ mat44 A;
+ if (areMatrices()) {
+ Mat4Mult ( A,T,RO );
+ Mat4Mult ( F,RF,A );
+ return true;
+ } else {
+ Mat4Init ( F );
+ return false;
+ }
+ }
+
+
+ int Cryst::GetNumberOfSymOps() {
+ return symOps.GetNofSymOps();
+ }
+
+ pstr Cryst::GetSymOp ( int Nop ) {
+ return symOps.GetSymOp ( Nop );
+ }
+
+
+ int Cryst::GetTMatrix ( mat44 & TMatrix, int Nop,
+ int cellshift_a, int cellshift_b,
+ int cellshift_c, PSymOps symOpers ) {
+ //
+ // GetTMatrix(..) calculates and returns the coordinate transformation
+ // matrix, which converts orthogonal coordinates according to the
+ // symmetry operation Nop and places them into unit cell shifted by
+ // cellshift_a a's, cellshift_b b's and cellshift_c c's.
+ //
+ // Return 0 means everything's fine,
+ // 1 there's no symmetry operation Nop defined
+ // 2 fractionalizing/orthogonalizing matrices were not
+ // calculated
+ // 3 cell parameters were not set up.
+ //
+ mat44 fm;
+ int i,j,k;
+
+ if (cellshift_a<=-MaxInt4) {
+ k = GetFractMatrix ( fm,Nop,0,0,0,symOpers );
+ fm[0][3] = frac(fm[0][3]);
+ fm[1][3] = frac(fm[1][3]);
+ fm[2][3] = frac(fm[2][3]);
+ } else
+ k = GetFractMatrix ( fm,Nop,cellshift_a,cellshift_b,cellshift_c,
+ symOpers );
+
+ if (k) {
+ Mat4Init ( TMatrix );
+ return k;
+ }
+
+ // transformation back to orthogonal coordinates
+ for (i=0;i<3;i++) {
+ for (j=0;j<4;j++) {
+ TMatrix[i][j] = 0.0;
+ for (k=0;k<3;k++)
+ TMatrix[i][j] += RO[i][k]*fm[k][j];
+ }
+ TMatrix[i][3] += RO[i][3];
+ }
+
+ TMatrix[3][0] = 0.0;
+ TMatrix[3][1] = 0.0;
+ TMatrix[3][2] = 0.0;
+ TMatrix[3][3] = 1.0;
+
+ return 0;
+
+ }
+
+
+ int Cryst::GetUCTMatrix ( mat44 & TMatrix, int Nop,
+ realtype x, realtype y, realtype z,
+ int cellshift_a, int cellshift_b,
+ int cellshift_c, PSymOps symOpers ) {
+ //
+ // GetUCTMatrix(..) calculates and returns the coordinate
+ // transformation matrix, which converts orthogonal coordinates
+ // according to the symmetry operation Nop. Translation part of
+ // the matrix is being chosen such that point (x,y,z) has least
+ // distance to the center of primary (333) unit cell, and then
+ // it is shifted by cellshift_a a's, cellshift_b b's and
+ // cellshift_c c's.
+ //
+ // Return 0 means everything's fine,
+ // 1 there's no symmetry operation Nop defined
+ // 2 fractionalizing/orthogonalizing matrices were not
+ // calculated
+ // 3 cell parameters were not set up.
+ //
+ mat44 fm,tm;
+ vect3 ft;
+ realtype x0,y0,z0, dx,dy,dz, d,d0;
+ int i,j,k, ic,jc,kc;
+
+ k = GetFractMatrix ( fm,Nop,0,0,0,symOpers );
+ if (k) {
+ Mat4Init ( TMatrix );
+ return k;
+ }
+
+ fm[0][3] = frac(fm[0][3]) + cellshift_a;
+ fm[1][3] = frac(fm[1][3]) + cellshift_b;
+ fm[2][3] = frac(fm[2][3]) + cellshift_c;
+
+ Frac2Orth ( cellshift_a+0.5,cellshift_b+0.5,cellshift_c+0.5,
+ x0,y0,z0 );
+
+ // transformation back to orthogonal coordinates
+
+ for (i=0;i<3;i++)
+ for (j=0;j<3;j++) {
+ tm[i][j] = 0.0;
+ for (k=0;k<3;k++)
+ tm[i][j] += RO[i][k]*fm[k][j];
+ }
+ tm[3][0] = 0.0;
+ tm[3][1] = 0.0;
+ tm[3][2] = 0.0;
+ tm[3][3] = 1.0;
+
+ d0 = MaxReal;
+ for (ic=-3;ic<3;ic++)
+ for (jc=-3;jc<3;jc++)
+ for (kc=-3;kc<3;kc++) {
+ ft[0] = fm[0][3] + ic;
+ ft[1] = fm[1][3] + jc;
+ ft[2] = fm[2][3] + kc;
+ for (i=0;i<3;i++) {
+ tm[i][3] = 0.0;
+ for (k=0;k<3;k++)
+ tm[i][3] += RO[i][k]*ft[k];
+ tm[i][3] += RO[i][3];
+ }
+ dx = tm[0][0]*x + tm[0][1]*y + tm[0][2]*z + tm[0][3] - x0;
+ dy = tm[1][0]*x + tm[1][1]*y + tm[1][2]*z + tm[1][3] - y0;
+ dz = tm[2][0]*x + tm[2][1]*y + tm[2][2]*z + tm[2][3] - z0;
+ d = dx*dx + dy*dy + dz*dz;
+ if (d<d0) {
+ d0 = d;
+ Mat4Copy ( tm,TMatrix );
+ }
+ }
+
+ return 0;
+
+ }
+
+
+ int Cryst::GetFractMatrix ( mat44 & TMatrix, int Nop,
+ int cellshift_a, int cellshift_b,
+ int cellshift_c,
+ PSymOps symOpers ) {
+ //
+ // GetFractMatrix(..) calculates and returns the coordinate
+ // transformation matrix, which converts fractional coordinates
+ // according to the symmetry operation Nop and places them into
+ // unit cell shifted by cellshift_a a's, cellshift_b b's and
+ // cellshift_c c's.
+ //
+ // Return 0 means everything's fine,
+ // 1 there's no symmetry operation Nop defined
+ // 2 fractionalizing/orthogonalizing matrices were not
+ // calculated
+ // 3 cell parameters were not set up.
+ //
+ mat44 tm;
+ int i,j,k;
+
+ k = 0;
+ if (symOpers) k = symOpers->GetTMatrix ( tm,Nop );
+ else k = symOps.GetTMatrix ( tm,Nop );
+ if (!k) {
+ if (!areMatrices()) k = 2;
+ if (!isCellParameters()) k = 3;
+ } else
+ k = 1;
+
+ if (k) {
+ Mat4Init ( TMatrix );
+ return k;
+ }
+
+ // transformation to fractional coordinates + symmetry operation
+ for (i=0;i<3;i++) {
+ for (j=0;j<4;j++) {
+ TMatrix[i][j] = 0.0;
+ for (k=0;k<3;k++)
+ TMatrix[i][j] += tm[i][k]*RF[k][j];
+ }
+ TMatrix[i][3] += tm[i][3]; // symmetry operation shift
+ }
+
+ // cell shift
+ TMatrix[0][3] += cellshift_a;
+ TMatrix[1][3] += cellshift_b;
+ TMatrix[2][3] += cellshift_c;
+
+ TMatrix[3][0] = 0.0;
+ TMatrix[3][1] = 0.0;
+ TMatrix[3][2] = 0.0;
+ TMatrix[3][3] = 1.0;
+
+ return 0;
+
+ }
+
+ int Cryst::GetSymOpMatrix ( mat44 & TMatrix, int Nop ) {
+ //
+ // GetSymOpMatrix(..) returns the transformation matrix for
+ // Nop-th symmetry operator in the space group
+ //
+ // Return 0 means everything's fine,
+ // 1 there's no symmetry operation Nop defined
+ // 2 fractionalizing/orthogonalizing matrices were not
+ // calculated
+ // 3 cell parameters were not set up.
+ //
+ return symOps.GetTMatrix ( TMatrix,Nop );
+ }
+
+
+ bool Cryst::Cryst2Orth ( rvector U ) {
+ mat33 A,AT,Tmp,TmpMat;
+ realtype BB;
+ int i,j,k;
+
+ if (areMatrices()) {
+
+ Tmp[0][0] = U[0];
+ Tmp[1][1] = U[1];
+ Tmp[2][2] = U[2];
+ Tmp[0][1] = U[3];
+ Tmp[1][0] = U[3];
+ Tmp[0][2] = U[4];
+ Tmp[2][0] = U[4];
+ Tmp[1][2] = U[5];
+ Tmp[2][1] = U[5];
+
+ for (i=0;i<3;i++)
+ for (j=0;j<3;j++) {
+ A [j][i] = ROU[j][i];
+ AT[i][j] = ROU[j][i];
+ }
+
+ // TmpMat = Tmp*AT
+ for (i=0;i<3;i++)
+ for (j=0;j<3;j++) {
+ BB = 0.0;
+ for (k=0;k<3;k++)
+ BB += Tmp[i][k]*AT[k][j];
+ TmpMat[i][j] = BB;
+ }
+
+ // Tmp = A*TmpMat
+ for (i=0;i<3;i++)
+ for (j=0;j<3;j++) {
+ BB = 0.0;
+ for (k=0;k<3;k++)
+ BB += A[i][k]*TmpMat[k][j];
+ Tmp[i][j] = BB;
+ }
+
+ U[0] = Tmp[0][0];
+ U[1] = Tmp[1][1];
+ U[2] = Tmp[2][2];
+ U[3] = Tmp[0][1];
+ U[4] = Tmp[0][2];
+ U[5] = Tmp[1][2];
+
+ return true;
+
+ }
+
+ return false;
+
+ }
+
+
+ bool Cryst::Orth2Cryst ( rvector U ) {
+ mat33 A,AT,Tmp,TmpMat;
+ realtype BB;
+ int i,j,k;
+
+ if (areMatrices()) {
+
+ Tmp[0][0] = U[0];
+ Tmp[1][1] = U[1];
+ Tmp[2][2] = U[2];
+ Tmp[0][1] = U[3];
+ Tmp[1][0] = U[3];
+ Tmp[0][2] = U[4];
+ Tmp[2][0] = U[4];
+ Tmp[1][2] = U[5];
+ Tmp[2][1] = U[5];
+
+ for (i=0;i<3;i++)
+ for (j=0;j<3;j++) {
+ A [j][i] = RFU[j][i];
+ AT[i][j] = RFU[j][i];
+ }
+
+ // TmpMat = Tmp*AT
+ for (i=0;i<3;i++)
+ for (j=0;j<3;j++) {
+ BB = 0.0;
+ for (k=0;k<3;k++)
+ BB += Tmp[i][k]*AT[k][j];
+ TmpMat[i][j] = BB;
+ }
+
+ // Tmp = A*TmpMat
+ for (i=0;i<3;i++)
+ for (j=0;j<3;j++) {
+ BB = 0.0;
+ for (k=0;k<3;k++)
+ BB += A[i][k]*TmpMat[k][j];
+ Tmp[i][j] = BB;
+ }
+
+ U[0] = Tmp[0][0];
+ U[1] = Tmp[1][1];
+ U[2] = Tmp[2][2];
+ U[3] = Tmp[0][1];
+ U[4] = Tmp[0][2];
+ U[5] = Tmp[1][2];
+
+ return true;
+
+ }
+
+ return false;
+
+ }
+
+
+ void Cryst::SetCell ( realtype cell_a,
+ realtype cell_b,
+ realtype cell_c,
+ realtype cell_alpha,
+ realtype cell_beta,
+ realtype cell_gamma,
+ int OrthCode ) {
+ // this function should be used for changing the cell parameters
+ int i,j;
+
+ if ((cell_a>0.0) && (cell_b>0.0) && (cell_c>0.0) &&
+ (cell_alpha!=0.0) && (cell_beta!=0.0) && (cell_gamma!=0.0)) {
+
+ if (OrthCode>0) NCode = OrthCode-1;
+ else NCode = 0;
+
+ a = cell_a;
+ b = cell_b;
+ c = cell_c;
+ alpha = cell_alpha;
+ beta = cell_beta;
+ gamma = cell_gamma;
+
+ WhatIsSet |= CSET_CellParams;
+
+ // calculate matrices
+
+ for (i=0;i<4;i++) {
+ for (j=0;j<4;j++) {
+ RO [i][j] = 0.0;
+ RF [i][j] = 0.0;
+ ROU[i][j] = 0.0;
+ RFU[i][j] = 0.0;
+ }
+ RO [i][i] = 1.0;
+ RF [i][i] = 1.0;
+ ROU[i][i] = 1.0;
+ RFU[i][i] = 1.0;
+ }
+
+ CalcCoordTransforms();
+
+ if (!(CellCheck & CCHK_NoOrthCode)) {
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++)
+ RO[i][j] = RR[NCode][i][j];
+ RO[i][3] = 0.0;
+ RO[3][i] = 0.0;
+ }
+ RO[3][3] = 1.0;
+ Mat4Inverse ( RO,RF );
+ }
+
+ WhatIsSet |= CSET_Transforms;
+
+ } else
+
+ WhatIsSet &= ~(CSET_CellParams | CSET_Transforms);
+
+ }
+
+ void Cryst::SetSyminfoLib ( cpstr syminfoLib ) {
+ CreateCopy ( syminfo_lib,syminfoLib );
+ }
+
+ pstr Cryst::GetSyminfoLib() {
+ return syminfo_lib;
+ }
+
+ int Cryst::SetSpaceGroup ( cpstr spGroup ) {
+ // This function does not attempt to fix the space group
+ int RC,l;
+ RC = SYMOP_UnknownSpaceGroup;
+ WhatIsSet &= ~CSET_SpaceGroup;
+ if (spGroup) {
+ if (spGroup[0]) {
+ l = IMin ( strlen(spGroup),sizeof(spaceGroup)-1 );
+ strcpy_ncss ( spaceGroup,spGroup,l );
+ strcpy ( spaceGroupFix,spaceGroup );
+ if (spaceGroup[0]) {
+ RC = symOps.SetGroup ( spaceGroup,syminfo_lib );
+ // RC = SymOps.SetGroup ( spGroup,syminfo_lib );
+ // strncpy ( spaceGroup,spGroup,l );
+ // spaceGroup[l] = char(0);
+ if (RC==SYMOP_Ok) WhatIsSet |= CSET_SpaceGroup;
+ }
+ }
+ }
+ return RC;
+ }
+
+
+ void Cryst::PutCell ( realtype cell_a,
+ realtype cell_b,
+ realtype cell_c,
+ realtype cell_alpha,
+ realtype cell_beta,
+ realtype cell_gamma,
+ int OrthCode ) {
+ // this function should be used for setting the cell parameters
+ int i,j;
+
+ if ((cell_a!=0.0) || (OrthCode>0)) {
+ a = cell_a;
+ b = cell_b;
+ c = cell_c;
+ alpha = cell_alpha;
+ beta = cell_beta;
+ gamma = cell_gamma;
+ WhatIsSet |= CSET_CellParams;
+ }
+
+ if (OrthCode>0) {
+
+ // calculate matrices
+
+ NCode = OrthCode-1;
+ CalcOrthMatrices();
+
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++)
+ RO[i][j] = RR[NCode][i][j];
+ RO[i][3] = 0.0;
+ RO[3][i] = 0.0;
+ }
+ RO[3][3] = 1.0;
+
+ Mat4Inverse ( RO,RF );
+
+ WhatIsSet |= CSET_Transforms;
+
+ } else
+ WhatIsSet &= ~CSET_Transforms;
+
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++)
+ s[i][j] = RF[i][j];
+ u[i] = RF[i][3];
+ }
+
+ WhatIsSet |= CSET_ScaleMatrix;
+
+ }
+
+
+ bool Cryst::isScaleMatrix() {
+ return ((WhatIsSet & CSET_ScaleMatrix)==CSET_ScaleMatrix);
+ }
+
+ bool Cryst::isCellParameters() {
+ return ((WhatIsSet & CSET_CellParams)==CSET_CellParams);
+ }
+
+ bool Cryst::isNCSMatrix() {
+ return (ncsMatrix.Length()>0);
+ }
+
+ int Cryst::GetNumberOfNCSMatrices() {
+ return ncsMatrix.Length();
+ }
+
+ int Cryst::GetNumberOfNCSMates() {
+ // Returns the number of NCS mates not given in the file (iGiven==0)
+ int i,l,iG;
+ PNCSMatrix NCSM;
+ iG = 0;
+ l = ncsMatrix.Length();
+ for (i=0;i<l;i++) {
+ NCSM = PNCSMatrix(ncsMatrix.GetContainerClass(i));
+ if (NCSM) {
+ if (!NCSM->iGiven) iG++;
+ }
+ }
+ return iG;
+ }
+
+ bool Cryst::GetNCSMatrix ( int NCSMatrixNo,
+ mat33 & ncs_m, vect3 & ncs_v ) {
+ int i,j;
+ PNCSMatrix NCSM;
+ NCSM = PNCSMatrix(ncsMatrix.GetContainerClass(NCSMatrixNo));
+ if (NCSM) {
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++)
+ ncs_m[i][j] = NCSM->m[i][j];
+ ncs_v[i] = NCSM->v[i];
+ }
+ return true;
+ }
+ return false;
+ }
+
+ bool Cryst::GetNCSMatrix ( int NCSMatrixNo,
+ mat44 & ncs_m, int & iGiven ) {
+ int i,j;
+ PNCSMatrix NCSM;
+ NCSM = PNCSMatrix(ncsMatrix.GetContainerClass(NCSMatrixNo));
+ if (NCSM) {
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++)
+ ncs_m[i][j] = NCSM->m[i][j];
+ ncs_m[i][3] = NCSM->v[i];
+ }
+ ncs_m[3][0] = 0.0;
+ ncs_m[3][1] = 0.0;
+ ncs_m[3][2] = 0.0;
+ ncs_m[3][3] = 1.0;
+ iGiven = NCSM->iGiven;
+ return true;
+ } else {
+ for (i=0;i<4;i++) {
+ for (j=0;j<4;j++)
+ ncs_m[i][j] = 0.0;
+ ncs_m[i][i] = 1.0;
+ }
+ return false;
+ }
+ }
+
+ int Cryst::AddNCSMatrix ( mat33 & ncs_m, vect3 & ncs_v,
+ int iGiven ) {
+ PNCSMatrix ncsMtx;
+ ncsMtx = new NCSMatrix();
+ ncsMtx->SetNCSMatrix ( ncsMatrix.Length()+1,ncs_m,ncs_v,iGiven );
+ ncsMatrix.AddData ( ncsMtx );
+ return ncsMtx->serNum;
+ }
+
+ void Cryst::GetRCell ( realtype & cell_as,
+ realtype & cell_bs,
+ realtype & cell_cs,
+ realtype & cell_alphas,
+ realtype & cell_betas,
+ realtype & cell_gammas,
+ realtype & vols ) {
+ cell_as = as;
+ cell_bs = bs;
+ cell_cs = cs;
+ cell_alphas = alphas;
+ cell_betas = betas;
+ cell_gammas = gammas;
+ if (Vol!=0.0) vols = 1.0/Vol;
+ else vols = 0.0;
+ }
+
+ void Cryst::GetCell ( realtype & cell_a,
+ realtype & cell_b,
+ realtype & cell_c,
+ realtype & cell_alpha,
+ realtype & cell_beta,
+ realtype & cell_gamma,
+ realtype & vol ) {
+ if (WhatIsSet & CSET_CellParams) {
+ cell_a = a;
+ cell_b = b;
+ cell_c = c;
+ cell_alpha = alpha;
+ cell_beta = beta;
+ cell_gamma = gamma;
+ vol = Vol;
+ } else {
+ cell_a = 0.0;
+ cell_b = 0.0;
+ cell_c = 0.0;
+ cell_alpha = 0.0;
+ cell_beta = 0.0;
+ cell_gamma = 0.0;
+ vol = 0.0;
+ }
+ }
+
+ pstr Cryst::GetSpaceGroup() {
+ if (WhatIsSet & CSET_SpaceGroup) return spaceGroup;
+ else return NULL;
+ }
+
+ pstr Cryst::GetSpaceGroupFix() {
+ if (WhatIsSet & CSET_SpaceGroup) return spaceGroupFix;
+ else return NULL;
+ }
+
+
+ void Cryst::Copy ( PCryst Cryst ) {
+ int i,j,k;
+
+ if (Cryst) {
+
+ a = Cryst->a;
+ b = Cryst->b;
+ c = Cryst->c;
+ alpha = Cryst->alpha;
+ beta = Cryst->beta;
+ gamma = Cryst->gamma;
+
+ for (i=0;i<4;i++)
+ for (j=0;j<4;j++) {
+ RO [i][j] = Cryst->RO [i][j];
+ RF [i][j] = Cryst->RF [i][j];
+ ROU[i][j] = Cryst->ROU[i][j];
+ RFU[i][j] = Cryst->RFU[i][j];
+ }
+
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++) {
+ o[i][j] = Cryst->o[i][j];
+ s[i][j] = Cryst->s[i][j];
+ for (k=0;k<6;k++)
+ RR[k][i][j] = Cryst->RR[k][i][j];
+ }
+ t[i] = Cryst->t[i];
+ u[i] = Cryst->u[i];
+ }
+
+ Vol = Cryst->Vol;
+ NCode = Cryst->NCode;
+ Z = Cryst->Z;
+ CellCheck = Cryst->CellCheck;
+ WhatIsSet = Cryst->WhatIsSet;
+ strcpy ( spaceGroup ,Cryst->spaceGroup );
+ strcpy ( spaceGroupFix,Cryst->spaceGroupFix );
+
+ ncsMatrix.Copy ( &(Cryst->ncsMatrix) );
+ tVect .Copy ( &(Cryst->tVect) );
+ symOps .Copy ( &(Cryst->symOps) );
+
+ as = Cryst->as;
+ bs = Cryst->bs;
+ cs = Cryst->cs;
+ alphas = Cryst->alphas;
+ betas = Cryst->betas;
+ gammas = Cryst->betas;
+ VolChk = Cryst->VolChk;
+ VolErr = Cryst->VolErr;
+
+ for (k=0;k<6;k++)
+ AC[k] = Cryst->AC[k];
+
+ } else {
+
+ ncsMatrix.FreeContainer();
+ tVect .FreeContainer();
+ WhatIsSet = 0;
+
+ }
+
+ }
+
+
+ void Cryst::write ( io::RFile f ) {
+ int i,j,k;
+ byte Version=3;
+
+ f.WriteByte ( &Version );
+ f.WriteWord ( &WhatIsSet );
+ f.WriteReal ( &a );
+ f.WriteReal ( &b );
+ f.WriteReal ( &c );
+ f.WriteReal ( &alpha );
+ f.WriteReal ( &beta );
+ f.WriteReal ( &gamma );
+ f.WriteWord ( &CellCheck );
+ f.WriteBool ( &ignoreScalei );
+ for (i=0;i<4;i++)
+ for (j=0;j<4;j++) {
+ f.WriteReal ( &(RO [i][j]) );
+ f.WriteReal ( &(RF [i][j]) );
+ f.WriteReal ( &(ROU[i][j]) );
+ f.WriteReal ( &(RFU[i][j]) );
+ }
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++) {
+ f.WriteReal ( &(o[i][j]) );
+ f.WriteReal ( &(s[i][j]) );
+ for (k=0;k<6;k++)
+ f.WriteReal ( &(RR[k][i][j]) );
+ }
+ f.WriteReal ( &(t[i]) );
+ f.WriteReal ( &(u[i]) );
+ }
+ f.WriteReal ( &Vol );
+ f.WriteReal ( &VolChk );
+ f.WriteReal ( &VolErr );
+ f.WriteInt ( &NCode );
+ f.WriteInt ( &Z );
+ f.WriteTerLine ( spaceGroup ,false );
+ f.WriteTerLine ( spaceGroupFix,false );
+
+ for (i=0;i<6;i++)
+ f.WriteReal ( &(AC[6]) );
+ f.WriteReal ( &as );
+ f.WriteReal ( &bs );
+ f.WriteReal ( &cs );
+ f.WriteReal ( &alphas );
+ f.WriteReal ( &betas );
+ f.WriteReal ( &gammas );
+
+ ncsMatrix.write ( f );
+ tVect .write ( f );
+ symOps .write ( f );
+
+ }
+
+ void Cryst::read ( io::RFile f ) {
+ int i,j,k;
+ byte Version;
+
+ f.ReadByte ( &Version );
+ f.ReadWord ( &WhatIsSet );
+ f.ReadReal ( &a );
+ f.ReadReal ( &b );
+ f.ReadReal ( &c );
+ f.ReadReal ( &alpha );
+ f.ReadReal ( &beta );
+ f.ReadReal ( &gamma );
+ f.ReadWord ( &CellCheck );
+ if (Version>2)
+ f.ReadBool ( &ignoreScalei );
+ else ignoreScalei = false;
+ for (i=0;i<4;i++)
+ for (j=0;j<4;j++) {
+ f.ReadReal ( &(RO [i][j]) );
+ f.ReadReal ( &(RF [i][j]) );
+ f.ReadReal ( &(ROU[i][j]) );
+ f.ReadReal ( &(RFU[i][j]) );
+ }
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++) {
+ f.ReadReal ( &(o[i][j]) );
+ f.ReadReal ( &(s[i][j]) );
+ for (k=0;k<6;k++)
+ f.ReadReal ( &(RR[k][i][j]) );
+ }
+ f.ReadReal ( &(t[i]) );
+ f.ReadReal ( &(u[i]) );
+ }
+ f.ReadReal ( &Vol );
+ f.ReadReal ( &VolChk );
+ f.ReadReal ( &VolErr );
+ f.ReadInt ( &NCode );
+ f.ReadInt ( &Z );
+ f.ReadTerLine ( spaceGroup,false );
+ if (Version>1)
+ f.ReadTerLine ( spaceGroupFix,false );
+ else strcpy ( spaceGroupFix,spaceGroup );
+
+ for (i=0;i<6;i++)
+ f.ReadReal ( &(AC[6]) );
+ f.ReadReal ( &as );
+ f.ReadReal ( &bs );
+ f.ReadReal ( &cs );
+ f.ReadReal ( &alphas );
+ f.ReadReal ( &betas );
+ f.ReadReal ( &gammas );
+
+ ncsMatrix.read ( f );
+ tVect .read ( f );
+ symOps .read ( f );
+
+ }
+
+ MakeStreamFunctions(Cryst)
+
+
+ // ===================================================================
+
+
+ void TestCryst() {
+ // reads from 'in.cryst', writes into
+ // 'out.cryst' and 'abin.cryst'
+ io::File f;
+ char S[81];
+ PCryst cryst;
+
+ cryst = new Cryst();
+
+ f.assign ( pstr("in.cryst"),true );
+ if (f.reset()) {
+ while (!f.FileEnd()) {
+ f.ReadLine ( S,sizeof(S) );
+ cryst->ConvertPDBString ( S );
+ }
+ f.shut();
+ } else {
+ printf ( " Can't open input file 'in.chain' \n" );
+ delete cryst;
+ return;
+ }
+
+ f.assign ( pstr("out.cryst"),true );
+ if (f.rewrite()) {
+ cryst->PDBASCIIDump ( f );
+ f.shut();
+ } else {
+ printf ( " Can't open output file 'out.cryst' \n" );
+ delete cryst;
+ return;
+ }
+
+
+ f.assign ( pstr("mmdb.cryst.bin"),false );
+ if (f.rewrite()) {
+ cryst->write ( f );
+ f.shut();
+ } else {
+ printf ( " Can't open binary cryst file for writing.\n" );
+ delete cryst;
+ return;
+ }
+
+ delete cryst;
+ printf ( " Cryst deleted.\n" );
+
+ cryst = new Cryst();
+ if (f.reset()) {
+ cryst->read ( f );
+ f.shut();
+ } else {
+ printf ( " Can't open binary cryst file for reading.\n" );
+ delete cryst;
+ return;
+ }
+
+ f.assign ( pstr("abin.cryst"),true );
+ if (f.rewrite()) {
+ cryst->PDBASCIIDump ( f );
+ f.shut();
+ } else
+ printf ( " Can't open output file 'abin.cryst' \n" );
+
+ delete cryst;
+
+ }
+
+} // namespace mmdb
diff --git a/mmdb2/mmdb_cryst.h b/mmdb2/mmdb_cryst.h
new file mode 100644
index 0000000..4ca4150
--- /dev/null
+++ b/mmdb2/mmdb_cryst.h
@@ -0,0 +1,458 @@
+// $Id: mmdb_cryst.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_Cryst <interface>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::CrystContainer ( container for cryst. data )
+// ~~~~~~~~~ mmdb::NCSMatrix ( non-cryst. symm. matrix class )
+// mmdb::TVect ( translation vector class )
+// mmdb::Cryst ( MMDB cryst. section class )
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_Cryst__
+#define __MMDB_Cryst__
+
+#include "mmdb_io_stream.h"
+#include "mmdb_symop.h"
+#include "mmdb_defs.h"
+#include "mmdb_utils.h"
+
+namespace mmdb {
+
+ // ==================== CrystContainer ======================
+
+ DefineClass(CrystContainer);
+ DefineStreamFunctions(CrystContainer);
+
+ class CrystContainer : public ClassContainer {
+
+ public :
+
+ CrystContainer () : ClassContainer() {}
+ CrystContainer ( io::RPStream Object )
+ : ClassContainer ( Object ) {}
+ ~CrystContainer() {}
+
+ PContainerClass MakeContainerClass ( int ClassID );
+
+ ERROR_CODE AddMTRIXLine ( cpstr S );
+
+ };
+
+
+ // ================== NCSMatrix ========================
+
+ enum NCSM_SET {
+ NCSMSET_Matrix1 = 0x00000001,
+ NCSMSET_Matrix2 = 0x00000002,
+ NCSMSET_Matrix3 = 0x00000004,
+ NCSMSET_All = 0x00000007
+ };
+
+ DefineClass(NCSMatrix);
+ DefineStreamFunctions(NCSMatrix);
+
+ class NCSMatrix : public ContainerClass {
+
+ friend class Cryst;
+
+ public :
+
+ int serNum; // serial number
+ mat33 m; // non-crystallographic symmetry matrix
+ vect3 v; // translational part of ncs matrix
+ int iGiven; // iGiven flag (see PDB format)
+
+ NCSMatrix ();
+ NCSMatrix ( cpstr S );
+ NCSMatrix ( io::RPStream Object );
+ ~NCSMatrix();
+
+ bool PDBASCIIDump1 ( io::RFile f );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ void MakeCIF ( mmcif::PData CIF, int N );
+ ERROR_CODE GetCIF ( mmcif::PData CIF, int & n );
+ CLASS_ID GetClassID () { return ClassID_NCSMatrix; }
+
+ void SetNCSMatrix ( int serialNum,
+ mat33 & ncs_m, vect3 & ncs_v,
+ int i_Given );
+
+ void Copy ( PContainerClass NCSMatrix );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+ word WhatIsSet; // mask field
+ // 0x0001 MTRIX1 was converted
+ // 0x0002 MTRIX2 was converted
+ // 0x0004 MTRIX3 was converted
+
+ void Init();
+
+ };
+
+
+ // ================== TVect ========================
+
+ DefineClass(TVect);
+ DefineStreamFunctions(TVect);
+
+ class TVect : public ContainerClass {
+
+ public :
+
+ int serNum; // serial number
+ vect3 t; // translation vector
+ pstr comment; // comment
+
+ TVect ();
+ TVect ( cpstr S );
+ TVect ( io::RPStream Object );
+ ~TVect();
+
+ void PDBASCIIDump ( pstr S, int N );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ void MakeCIF ( mmcif::PData CIF, int N );
+ ERROR_CODE GetCIF ( mmcif::PData CIF, int & n );
+ CLASS_ID GetClassID () { return ClassID_TVect; }
+
+ void Copy ( PContainerClass TVect );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void Init();
+
+ };
+
+
+ // ================= Cryst =======================
+
+ DefineClass(Cryst);
+ DefineStreamFunctions(Cryst);
+
+ // constants for the CellCheck field
+ enum CELL_CHECK {
+ CCHK_Ok = 0x00000000,
+ CCHK_NoCell = 0x00000001,
+ CCHK_Error = 0x00000002,
+ CCHK_Disagreement = 0x00000004,
+ CCHK_NoOrthCode = 0x00000008,
+ CCHK_Translations = 0x00000010,
+ CCHK_Unchecked = 0x00001000
+ };
+
+ // constants for the WhatIsSet field
+ enum CELL_SET {
+ CSET_CellParams1 = 0x00000001,
+ CSET_CellParams2 = 0x00000002,
+ CSET_CellParams = 0x00000003,
+ CSET_SpaceGroup = 0x00000004,
+ CSET_ZValue = 0x00000008,
+ CSET_CrystCard = 0x0000000F,
+ CSET_OrigMatrix1 = 0x00000010,
+ CSET_OrigMatrix2 = 0x00000020,
+ CSET_OrigMatrix3 = 0x00000040,
+ CSET_OrigMatrix = 0x00000070,
+ CSET_ScaleMatrix1 = 0x00000080,
+ CSET_ScaleMatrix2 = 0x00000100,
+ CSET_ScaleMatrix3 = 0x00000200,
+ CSET_ScaleMatrix = 0x00000380,
+ CSET_Transforms = 0x00000400,
+ CSET_DummyCell = 0x00001000
+ };
+
+ extern cpstr OrthCode[6];
+
+ class Cryst : public io::Stream {
+
+ friend class Channel;
+
+ public :
+ realtype a,b,c; // cell parameters
+ realtype alpha,beta,gamma; // cell parameters
+ mat44 RO,RF; // orthogonal-fractional recalculation
+ // matrices
+ mat44 ROU,RFU; // ort-frac recalc matrices for
+ // anisotr. t-fac
+ mat633 RR; // standard orthogonalizations
+ realtype Vol; // cell volume
+ int NCode; // code of orthogonalization matrix
+ SymGroup spaceGroup; // group of space symmetry as read
+ // from file
+ SymGroup spaceGroupFix; // actually used space group
+ int Z; // Z-value
+
+ mat33 o; // orthogonal transformation matrix
+ vect3 t; // translation orthogonal vector
+ mat33 s; // scale matrix
+ vect3 u; // translation part of the scale matrix
+
+ word CellCheck; // 0x0000 - Ok
+ // 0x0001 - no cell stored
+ // 0x0002 - some error in cell volume
+ // 0x0004 - disagreement between
+ // cell and PDB
+ // 0x0008 - no orth code derived
+ // 0x0010 - translations also specified
+ // 0x1000 - the check was not done
+ word WhatIsSet; // indicator of the fields set
+ bool ignoreScalei; // flag to ignore SCALEi cards
+ bool processSG; // flag to process space group at file
+ // read
+ bool fixSpaceGroup; // flag to fix space group at file read
+
+ Cryst ();
+ Cryst ( io::RPStream Object );
+ ~Cryst();
+
+ void FreeMemory();
+ void Reset ();
+
+ // ConvertPDBString(..) interprets an ASCII PDB line and fills
+ // the corresponding data fields. It returns zero if the line was
+ // successfully converted, otherwise returns a non-negative value
+ // of Error_XXXX.
+ // PDBString must be not shorter than 81 characters.
+ ERROR_CODE ConvertPDBString ( pstr PDBString );
+
+ // RWBROOKReadPrintout() may be invoked after reading PDB file
+ // for simulating the old RWBROOK messages and warnings
+ void RWBROOKReadPrintout();
+
+ void SetCell ( realtype cell_a,
+ realtype cell_b,
+ realtype cell_c,
+ realtype cell_alpha,
+ realtype cell_beta,
+ realtype cell_gamma,
+ int OrthCode );
+ void PutCell ( realtype cell_a,
+ realtype cell_b,
+ realtype cell_c,
+ realtype cell_alpha,
+ realtype cell_beta,
+ realtype cell_gamma,
+ int OrthCode );
+
+ void GetCell ( realtype & cell_a,
+ realtype & cell_b,
+ realtype & cell_c,
+ realtype & cell_alpha,
+ realtype & cell_beta,
+ realtype & cell_gamma,
+ realtype & vol );
+
+ void GetRCell ( realtype & cell_as,
+ realtype & cell_bs,
+ realtype & cell_cs,
+ realtype & cell_alphas,
+ realtype & cell_betas,
+ realtype & cell_gammas,
+ realtype & vols );
+
+ void SetSyminfoLib ( cpstr syminfoLib );
+ pstr GetSyminfoLib ();
+
+ int SetSpaceGroup ( cpstr spGroup );
+ pstr GetSpaceGroup ();
+ pstr GetSpaceGroupFix();
+
+ // CalcCoordTransforms() should be called once after all data
+ // relevant to the crystallographic information, are read and
+ // converted. Field CellCheck will then have bits set if there
+ // are errors, e.g. bit CCHK_NoCell means that the coordinate
+ // transformations cannot be performed.
+ void CalcCoordTransforms();
+
+ // A PDB ASCII dump
+ void PDBASCIIDump ( io::RFile f );
+
+ ERROR_CODE GetCIF ( mmcif::PData CIF );
+ void MakeCIF ( mmcif::PData CIF );
+
+ bool areMatrices(); // returns True if the orthogonal-to-
+ // fractional and fractional-to-orthogonal
+ // matrices are defined
+
+ // Frac2Orth(..) and Orth2Frac(..) transform between fractional
+ // and orthogonal coordinates, if areMatrices() returns True.
+ // If the transformation matrices were not set, the functions just
+ // copy the coordinates. Returns True if the transformation was
+ // done; False return means that transformation matrices were not
+ // calculated
+ bool Frac2Orth (
+ realtype x, realtype y, realtype z,
+ realtype & xx, realtype & yy, realtype & zz );
+ bool Orth2Frac (
+ realtype x, realtype y, realtype z,
+ realtype & xx, realtype & yy, realtype & zz );
+
+ // Below, F and T are transformation matrices in fractional and
+ // orthogonal coordinates, respectively.
+ bool Frac2Orth ( mat44 & F, mat44 & T );
+ bool Orth2Frac ( mat44 & T, mat44 & F );
+
+
+ // Cryst2Orth(..) and Orth2Cryst(..) transform between fractional
+ // and orthogonal anisotropic temperature factors, if areMatrices()
+ // returns True. If the transformation matrices were not set, the
+ // functions leave the factors unchanged.
+ // Vector U is composed as follows:
+ // U[0]=u11 U[1]=u22 U[2]=u33
+ // U[3]=u12 U[4]=u13 U[5]=u23
+ // Returns True if the transformation was done; False retuen
+ // means that transformation matrices were not calculated
+ bool Cryst2Orth ( rvector U );
+ bool Orth2Cryst ( rvector U );
+
+ void CalcOrthMatrices(); // calculates RR, AC, cella's and Vol
+
+ bool isNCSMatrix ();
+ bool isScaleMatrix ();
+ bool isCellParameters();
+
+ int GetNumberOfSymOps();
+ pstr GetSymOp ( int Nop );
+
+ int GetNumberOfNCSMatrices();
+ int GetNumberOfNCSMates (); // Returns the number of
+ // NCS mates not given in
+ // the file (iGiven==0)
+
+ bool GetNCSMatrix ( int NCSMatrixNo, mat33 & ncs_m,
+ vect3 & ncs_v );
+ bool GetNCSMatrix ( int NCSMatrixNo, mat44 & ncs_m,
+ int & iGiven ); // no=0..N-1
+ int AddNCSMatrix ( mat33 & ncs_m, vect3 & ncs_v, int iGiven );
+
+ // GetTMatrix(..) calculates and returns the coordinate
+ // transformation matrix, which converts orthogonal coordinates
+ // according to the symmetry operation number Nop and places
+ // them into unit cell shifted by cellshift_a a's, cellshift_b
+ // b's and cellshift_c c's.
+ //
+ // Return 0 means everything's fine,
+ // 1 there's no symmetry operation Nop defined
+ // 2 fractionalizing/orthogonalizing matrices were not
+ // calculated
+ // 3 cell parameters were not set up.
+ int GetTMatrix ( mat44 & TMatrix, int Nop,
+ int cellshift_a, int cellshift_b,
+ int cellshift_c, PSymOps symOpers=NULL );
+
+ // GetUCTMatrix(..) calculates and returns the coordinate
+ // transformation matrix, which converts orthogonal coordinates
+ // according to the symmetry operation Nop. Translation part
+ // of the matrix is being chosen such that point (x,y,z) has
+ // least distance to the center of primary (333) unit cell,
+ // and then it is shifted by cellshift_a a's, cellshift_b b's
+ // and cellshift_c c's.
+ //
+ // Return 0 means everything's fine,
+ // 1 there's no symmetry operation Nop defined
+ // 2 fractionalizing/orthogonalizing matrices were not
+ // calculated
+ // 3 cell parameters were not set up.
+ //
+ int GetUCTMatrix ( mat44 & TMatrix, int Nop,
+ realtype x, realtype y, realtype z,
+ int cellshift_a, int cellshift_b,
+ int cellshift_c, PSymOps symOpers=NULL );
+
+ // GetFractMatrix(..) calculates and returns the coordinate
+ // transformation matrix, which converts fractional coordinates
+ // according to the symmetry operation number Nop and places them
+ // into unit cell shifted by cellshift_a a's, cellshift_b b's and
+ // cellshift_c c's.
+ //
+ // Return 0 means everything's fine,
+ // 1 there's no symmetry operation Nop defined
+ // 2 fractionalizing/orthogonalizing matrices were not
+ // calculated
+ // 3 cell parameters were not set up.
+ int GetFractMatrix ( mat44 & TMatrix, int Nop,
+ int cellshift_a, int cellshift_b,
+ int cellshift_c, PSymOps symOpers=NULL );
+
+ // GetSymOpMatrix(..) returns the transformation matrix for
+ // Nop-th symmetry operator in the space group
+ //
+ // Return 0 means everything's fine,
+ // 1 there's no symmetry operation Nop defined
+ // 2 fractionalizing/orthogonalizing matrices were not
+ // calculated
+ // 3 cell parameters were not set up.
+ //
+ int GetSymOpMatrix ( mat44 & TMatrix, int Nop );
+
+ void Copy ( PCryst Cryst );
+
+ void write ( io::RFile f ); // writes header to PDB binary file
+ void read ( io::RFile f ); // reads header from PDB binary file
+
+ protected :
+
+ CrystContainer ncsMatrix; // non-cryst. symm. matrices
+ CrystContainer tVect; // translation vectors
+
+ realtype as,bs,cs; // calculated 'cell parameters'
+ realtype alphas,betas,gammas; // calculated 'cell parameters'
+ realtype AC[6];
+ realtype VolChk,VolErr;
+
+ pstr syminfo_lib; // path to syminfo.lib
+ SymOps symOps; // symmetry operations
+
+ void Init ( bool fullInit );
+ int FixSpaceGroup();
+
+ };
+
+ extern cpstr getOrthCodeName ( int NCode );
+
+} // namespace mmdb
+
+/*
+extern void TestCryst(); // reads from 'in.cryst', writes into
+ // 'out.cryst' and 'abin.cryst'
+*/
+
+
+#endif
+
diff --git a/mmdb2/mmdb_defs.h b/mmdb2/mmdb_defs.h
new file mode 100644
index 0000000..da06dac
--- /dev/null
+++ b/mmdb2/mmdb_defs.h
@@ -0,0 +1,271 @@
+// $Id: mmdb_defs.h,v 1.27 2012/01/26 17:52:20 ekr Exp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2008.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 10.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDBF_Defs <interface>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+//
+// Definition of types, constants and important classes.
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_Defs__
+#define __MMDB_Defs__
+
+#include "mmdb_mattype.h"
+
+namespace mmdb {
+
+ enum MMDB_VERSION {
+ MAJOR_VERSION = 2, //!< MMDB major version
+ MINOR_VERSION = 0, //!< MMDB minor version
+ MICRO_VERSION = 1 //!< MMDB micro version
+ };
+
+ // ======================= types =================================
+
+ typedef char IDCode [16]; //!< ID code of PDB entry
+ typedef IDCode * PIDCode; //!< pointer to ID code
+ typedef PIDCode & RPIDCode; //!< ref. to pointer to ID code
+ typedef char Date [12]; //!< date DD-MMM-YYYY
+ typedef char RecName [7]; //!< name of PDB record
+
+ typedef char ChainID [10]; //!< chain ID
+ typedef ChainID * PChainID; //!< pointer to chain ID
+ typedef char InsCode [10]; //!< insertion code
+ typedef char DBName [10]; //!< sequence database name
+ typedef char DBAcCode[20]; //!< seq. database accession code
+ typedef DBAcCode * PDBAcCode; //!< pointer to seq. db acc code
+ typedef char DBIdCode[20]; //!< seq. database ident-n code
+ typedef DBIdCode * PDBIdCode; //!< pointer to DBIdCode
+ typedef char ResName [20]; //!< residue name
+ typedef ResName * PResName; //!< pointer to residue name
+ typedef PResName * PPResName; //!< ptr to vector of residue names
+ typedef char HelixID [20]; //!< helix ID
+ typedef char StrandID[20]; //!< strand ID
+ typedef char SheetID [20]; //!< sheet ID
+ typedef char TurnID [20]; //!< turn ID
+ typedef char LinkRID [20]; //!< Refmac link ID
+
+ typedef char SymGroup[100]; //!< group of space symmetry
+ typedef realtype vect3 [3]; //!< vector of 3 real numbers
+ typedef vect3 * pvect3; //!< ptr to vector 3
+ typedef pvect3 & rpvect3; //!< ref to ptr to vector 3
+ typedef realtype vect4 [4]; //!< vector of 4 real numbers
+ typedef vect3 mat33 [3]; //!< matrix 3x3 of real numbers
+
+ typedef vect4 mat44 [4]; //!< matrix 4x4 of real numbers
+ typedef mat44 * pmat44; //!< ptr to matrix 4x4
+ typedef mat44 & rmat44; //!< ref to matrix 4x4
+ typedef pmat44 * ppmat44; //!< ptr to ptr to matrix 4x4
+ typedef pmat44 & rpmat44; //!< ref to ptr to matrix 4x4
+ typedef mat33 mat633 [6]; //!< matrix 6x3x3 of real numbers
+
+ typedef char AtomName[20]; //!< name of the atom
+ typedef AtomName * PAtomName; //!< pointer to atom name
+ typedef char AltLoc [20]; //!< alternate location indicator
+ typedef AltLoc * PAltLoc; //!< pointer to alt loc indicator
+ typedef char SegID [20]; //!< segment identifier
+ typedef char Element [10]; //!< chemical element name
+ typedef Element * PElement; //!< ptr to chemical element name
+ typedef char EnergyType[10]; //!< energy type name
+ typedef EnergyType * PEnergyType; //!< pointer to energy type name
+
+ // do not forget update this when change the above typedefs:
+ typedef char maxMMDBName[40];
+
+
+ // ===================== constants ===============================
+
+ // ANY_RES should be used in selection functions for specifying
+ // "any residue" to select. Defined in mmdb_selmngr.cpp
+ extern const int ANY_RES;
+
+ // PRNK_XXXXX are the print keys. PRNK_Silent supresses all print
+ // inside mmdb_xxxx unless specifically ordered or catastrophic.
+ // PRNK_SimRWBROOK instructs mmdb to issue, whenever possible and
+ // necessary, printouts and warnings of RWBROOK (fortran) package.
+ enum PRINT_KEY {
+ PRNK_Silent = 0,
+ PRNK_SimRWBROOK = 1
+ };
+
+ // Error_XXXX may be returned by XX::ConvertPDBString() and GetCIF(..)
+ // functions.
+ // Error_WrongSection is returned if the string passed into function
+ // does not belong to the corresponding PDB section.
+
+
+ enum ERROR_CODE {
+
+ Error_EmptyCIF =-1, //!< used as signal at reading CIF files
+
+ Error_NoError = 0,
+ Error_Ok = 0,
+ Error_WrongSection = 1,
+ Error_WrongChainID = 2,
+ Error_WrongEntryID = 3,
+
+ // Error_SEQRES_serNum is returned by CSeqRes::ConvertPDBASCII() if
+ // serial numbers of SEQRES records do not increment by 1
+ Error_SEQRES_serNum = 4,
+
+ // Error_SEQRES_numRes is returned by CSeqRes::ConvertPDBASCII() if
+ // SEQRES records show different number of residues
+ Error_SEQRES_numRes = 5,
+
+ // Error_SEQRES_extraRes is returned by CSeqRes::ConvertPDBASCII() if
+ // SEQRES contains more residues than specified
+ Error_SEQRES_extraRes = 6,
+
+ Error_NCSM_Unrecognized = 7,
+ Error_NCSM_AlreadySet = 8,
+ Error_NCSM_WrongSerial = 9,
+ Error_NCSM_UnmatchIG = 10,
+
+ Error_ATOM_Unrecognized = 11,
+ Error_ATOM_AlreadySet = 12,
+ Error_ATOM_NoResidue = 13,
+ Error_ATOM_Unmatch = 14,
+
+ Error_CantOpenFile = 15,
+ Error_UnrecognizedInteger = 16,
+ Error_WrongModelNo = 17,
+ Error_DuplicatedModel = 18,
+ Error_NoModel = 19,
+ Error_ForeignFile = 20,
+ Error_WrongEdition = 21,
+
+ // CIF specific
+ Error_NotACIFFile = 22,
+ Error_NoData = 23,
+ Error_NoLoop = 24,
+ Error_NoStruct = 25,
+ Error_UnrecognCIFItems = 26,
+ Error_MissingCIFField = 27,
+ Error_EmptyCIFLoop = 28,
+ Error_EmptyCIFStruct = 29,
+ Error_UnexpEndOfCIF = 30,
+ Error_MissgCIFLoopField = 31,
+ Error_NotACIFStructure = 32,
+ Error_NotACIFLoop = 33,
+ Error_UnrecognizedReal = 34,
+
+ Error_NoSheetID = 35,
+ Error_WrongSheetID = 36,
+ Error_WrongStrandNo = 37,
+
+ // Error_WrongNumberOfStrands may be issued when reading
+ // sheet data from CIF
+ Error_WrongNumberOfStrands = 38,
+
+ // Error_WrongSheetOrder may be issued when reading
+ // sheet data from CIF
+ Error_WrongSheetOrder = 39,
+
+ // Error_HBondInconsistency may be issued when reading
+ // sheet data from CIF
+ Error_HBondInconsistency = 40,
+
+ // Error_EmptyResidueName is issued when PDB ATOM record
+ // does not have a residue name
+ Error_EmptyResidueName = 41,
+
+ // Error_DuplicateSeqNum is issued when PDB ATOM records
+ // show the sequence number and insertion code assigned
+ // to more than one residue name
+ Error_DuplicateSeqNum = 42,
+
+ // Error_NoLogicalName may be returned by file i/o functions
+ // if the specified environmental variable for file name
+ // is not found.
+ Error_NoLogicalName = 43,
+
+ // Error_EmptyFile may be returned at reading non-existing
+ // coordinate files
+ Error_EmptyFile = 44,
+
+ Error_Unknown = 45,
+
+ // Error_CIF_EmptyRow is the event of encountering
+ // an empty row in _atom_site loop. It is handled
+ // internally and has no effect on API
+ Error_CIF_EmptyRow = 99999,
+
+ Error_GeneralError1 = 10000
+
+ };
+
+ // ClassID_XXXX are used by container classes for proper
+ // creating containered classes when reading from binary file.
+
+ enum CLASS_ID {
+ ClassID_Template ,
+ ClassID_String ,
+ ClassID_ObsLine ,
+ ClassID_TitleLine ,
+ ClassID_CAVEAT ,
+ ClassID_Compound ,
+ ClassID_Source ,
+ ClassID_ExpData ,
+ ClassID_MdlType ,
+ ClassID_Author ,
+ ClassID_RevData ,
+ ClassID_Supersede ,
+ ClassID_Journal ,
+ ClassID_Remark ,
+ ClassID_DBReference,
+ ClassID_SeqAdv ,
+ ClassID_ModRes ,
+ ClassID_Het ,
+ ClassID_NCSMatrix ,
+ ClassID_TVect ,
+ ClassID_Helix ,
+ ClassID_Turn ,
+ ClassID_Link ,
+ ClassID_LinkR ,
+ ClassID_CisPep
+ };
+
+
+ // ===================== classes ===============================
+
+ DefineClass(Atom);
+ DefineClass(Residue);
+ DefineClass(Chain);
+ DefineClass(Model);
+ DefineClass(Manager);
+
+} // namespace mmdb
+
+#endif
+
diff --git a/mmdb/mmdb_ficif.cpp b/mmdb2/mmdb_ficif.cpp
old mode 100755
new mode 100644
similarity index 93%
rename from mmdb/mmdb_ficif.cpp
rename to mmdb2/mmdb_ficif.cpp
index d57c94a..e7892d5
--- a/mmdb/mmdb_ficif.cpp
+++ b/mmdb2/mmdb_ficif.cpp
@@ -6,13 +6,13 @@
//
// Copyright (C) Eugene Krissinel 2000-2008.
//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
// of the license to address the requirements of UK law.
//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
//
// This program is distributed in the hope that it will be useful,
@@ -29,27 +29,22 @@
// **** Module : MMDB_FICIF <implementation>
// ~~~~~~~~~
// **** Project : MacroMolecular Data Base (MMDB)
-// ~~~~~~~~~
-// **** Classes :
-// ~~~~~~~~~
+// ~~~~~~~~~
+// **** Classes :
+// ~~~~~~~~~
//
// (C) E. Krissinel 2000-2008
//
// =================================================================
//
-#ifndef __MMDB_MMCIF__
-#include "mmdb_mmcif.h"
-#endif
-
-#ifndef __MMDB_FICIF__
+#include "mmdb_mmcif_.h"
#include "mmdb_ficif.h"
-#endif
// ==================================================================
-PCMMCIFData mmCIFData = NULL;
+mmcif::PData mmCIFData = NULL;
FORTRAN_SUBR ( MMDB_FCIF_INIT, mmdb_fcif_init,(),(),() ) {
@@ -90,14 +85,14 @@ FORTRAN_SUBR ( MMDB_FCIF_CREATE, mmdb_fcif_create,
char S[500];
if (mmCIFData) delete mmCIFData;
- mmCIFData = new CMMCIFData ( makeString(S,sizeof(S),
+ mmCIFData = new mmcif::Data ( makeString(S,sizeof(S),
FTN_STR(DataName),FTN_LEN(DataName)) );
}
void MMDB_CCIF_Create ( pstr DataName ) {
if (mmCIFData) delete mmCIFData;
- mmCIFData = new CMMCIFData ( DataName );
+ mmCIFData = new mmcif::Data ( DataName );
}
@@ -107,13 +102,13 @@ FORTRAN_SUBR ( MMDB_FCIF_WRITE, mmdb_fcif_write,
int * iRet, // return code
int FileName_len // fortran-hidden length of FileName
), ( // lengths-in-structure list
- fpstr FileName, int *iRet
+ fpstr FileName, int *iRet
), ( // lengths-follow list
- fpstr FileName, int FileName_len, int * iRet
+ fpstr FileName, int FileName_len, int * iRet
) ) {
pstr S;
- if (!mmCIFData)
+ if (!mmCIFData)
*iRet = -1000;
else {
S = new char[FTN_LEN(FileName)+10];
@@ -182,7 +177,7 @@ FORTRAN_SUBR ( MMDB_FCIF_PUTDOT, mmdb_fcif_putdot,
char CN[200],TN[200];
if (!mmCIFData)
*iRet = -1000;
- else *iRet = mmCIFData->PutNoData ( CIF_NODATA_DOT,
+ else *iRet = mmCIFData->PutNoData ( mmcif::CIF_NODATA_DOT,
makeString(CN,sizeof(CN),
FTN_STR(CatName),FTN_LEN(CatName)),
makeString(TN,sizeof(TN),
@@ -192,7 +187,7 @@ char CN[200],TN[200];
int MMDB_CCIF_PutDot ( pstr CatName, pstr Tag ) {
if (!mmCIFData) return -1000;
- else return mmCIFData->PutNoData ( CIF_NODATA_DOT,
+ else return mmCIFData->PutNoData ( mmcif::CIF_NODATA_DOT,
CatName,Tag );
}
@@ -214,7 +209,7 @@ FORTRAN_SUBR ( MMDB_FCIF_PUTQUESTION, mmdb_fcif_putquestion,
char CN[200],TN[200];
if (!mmCIFData)
*iRet = -1000;
- else *iRet = mmCIFData->PutNoData ( CIF_NODATA_QUESTION,
+ else *iRet = mmCIFData->PutNoData ( mmcif::CIF_NODATA_QUESTION,
makeString(CN,sizeof(CN),
FTN_STR(CatName),FTN_LEN(CatName)),
makeString(TN,sizeof(TN),
@@ -223,8 +218,10 @@ char CN[200],TN[200];
int MMDB_CCIF_PutQuestion ( pstr CatName, pstr Tag ) {
- if (!mmCIFData) return -1000;
- else return mmCIFData->PutNoData ( CIF_NODATA_QUESTION,
+ if (!mmCIFData)
+ return -1000;
+ else
+ return mmCIFData->PutNoData ( mmcif::CIF_NODATA_QUESTION,
CatName,Tag );
}
@@ -241,7 +238,7 @@ FORTRAN_SUBR ( MMDB_FCIF_PUTSTRING, mmdb_fcif_putstring,
), ( // lengths-in-structure list
fpstr Data, fpstr CatName, fpstr Tag, int * iRet
), ( // lengths-follow list
- fpstr Data, int Data_len,
+ fpstr Data, int Data_len,
fpstr CatName, int CatName_len,
fpstr Tag, int Tag_len,
int * iRet
@@ -254,7 +251,7 @@ pstr S;
else {
S = new char[FTN_LEN(Data)+10];
*iRet = mmCIFData->PutString ( makeString(S,FTN_LEN(Data)+5,
- FTN_STR(Data),FTN_LEN(Data)),
+ FTN_STR(Data),FTN_LEN(Data)),
makeString(CN,sizeof(CN),
FTN_STR(CatName),FTN_LEN(CatName)),
makeString(TN,sizeof(TN),
@@ -281,7 +278,7 @@ FORTRAN_SUBR ( MMDB_FCIF_PUTREAL, mmdb_fcif_putreal,
), ( // lengths-in-structure list
apireal * V, fpstr CatName, fpstr Tag, int * iRet
), ( // lengths-follow list
- apireal * V,
+ apireal * V,
fpstr CatName, int CatName_len,
fpstr Tag, int Tag_len,
int * iRet
@@ -315,7 +312,7 @@ FORTRAN_SUBR ( MMDB_FCIF_PUTINTEGER, mmdb_fcif_putinteger,
), ( // lengths-in-structure list
int * I, fpstr CatName, fpstr Tag, int * iRet
), ( // lengths-follow list
- int * I,
+ int * I,
fpstr CatName, int CatName_len,
fpstr Tag, int Tag_len,
int * iRet
@@ -355,7 +352,7 @@ FORTRAN_SUBR ( MMDB_FCIF_PUTLOOPDOT, mmdb_fcif_putloopdot,
char CN[200],TN[200];
if (!mmCIFData)
*iRet = -1000;
- else *iRet = mmCIFData->PutLoopNoData ( CIF_NODATA_DOT,
+ else *iRet = mmCIFData->PutLoopNoData ( mmcif::CIF_NODATA_DOT,
makeString(CN,sizeof(CN),
FTN_STR(CatName),FTN_LEN(CatName)),
makeString(TN,sizeof(TN),
@@ -364,8 +361,10 @@ char CN[200],TN[200];
int MMDB_CCIF_PutLoopDot ( pstr CatName, pstr Tag, int nrow ) {
- if (!mmCIFData) return -1000;
- else return mmCIFData->PutLoopNoData ( CIF_NODATA_DOT,
+ if (!mmCIFData)
+ return -1000;
+ else
+ return mmCIFData->PutLoopNoData ( mmcif::CIF_NODATA_DOT,
CatName,Tag,nrow );
}
@@ -388,7 +387,7 @@ FORTRAN_SUBR ( MMDB_FCIF_PUTLOOPQUESTION, mmdb_fcif_putloopquestion,
char CN[200],TN[200];
if (!mmCIFData)
*iRet = -1000;
- else *iRet = mmCIFData->PutLoopNoData ( CIF_NODATA_QUESTION,
+ else *iRet = mmCIFData->PutLoopNoData ( mmcif::CIF_NODATA_QUESTION,
makeString(CN,sizeof(CN),
FTN_STR(CatName),FTN_LEN(CatName)),
makeString(TN,sizeof(TN),
@@ -396,9 +395,11 @@ char CN[200],TN[200];
}
int MMDB_CCIF_PutLoopQuestion ( pstr CatName, pstr Tag, int nrow ) {
- if (!mmCIFData) return -1000;
- else return mmCIFData->PutLoopNoData ( CIF_NODATA_QUESTION,
- CatName,Tag,nrow );
+ if (!mmCIFData)
+ return -1000;
+ else
+ return mmCIFData->PutLoopNoData ( mmcif::CIF_NODATA_QUESTION,
+ CatName,Tag,nrow );
}
@@ -416,7 +417,7 @@ FORTRAN_SUBR ( MMDB_FCIF_PUTLOOPSTRING, mmdb_fcif_putloopstring,
fpstr Data, fpstr CatName, fpstr Tag,
int * nrow, int * iRet
), ( // lengths-follow list
- fpstr Data, int Data_len,
+ fpstr Data, int Data_len,
fpstr CatName, int CatName_len,
fpstr Tag, int Tag_len,
int * nrow, int * iRet
@@ -429,7 +430,7 @@ pstr S;
else {
S = new char[FTN_LEN(Data)+10];
*iRet = mmCIFData->PutLoopString ( makeString(S,FTN_LEN(Data)+5,
- FTN_STR(Data),FTN_LEN(Data)),
+ FTN_STR(Data),FTN_LEN(Data)),
makeString(CN,sizeof(CN),
FTN_STR(CatName),FTN_LEN(CatName)),
makeString(TN,sizeof(TN),
@@ -459,7 +460,7 @@ FORTRAN_SUBR ( MMDB_FCIF_PUTLOOPREAL, mmdb_fcif_putloopreal,
apireal * V, fpstr CatName, fpstr Tag,
int * nrow, int * iRet
), ( // lengths-follow list
- apireal * V,
+ apireal * V,
fpstr CatName, int CatName_len,
fpstr Tag, int Tag_len,
int * nrow, int * iRet
@@ -495,7 +496,7 @@ FORTRAN_SUBR ( MMDB_FCIF_PUTLOOPINTEGER, mmdb_fcif_putloopinteger,
int * I, fpstr CatName, fpstr Tag,
int * nrow, int * iRet
), ( // lengths-follow list
- int * I,
+ int * I,
fpstr CatName, int CatName_len,
fpstr Tag, int Tag_len,
int * nrow, int * iRet
diff --git a/mmdb/mmdb_ficif.h b/mmdb2/mmdb_ficif.h
old mode 100755
new mode 100644
similarity index 96%
rename from mmdb/mmdb_ficif.h
rename to mmdb2/mmdb_ficif.h
index 5a015f2..7347f38
--- a/mmdb/mmdb_ficif.h
+++ b/mmdb2/mmdb_ficif.h
@@ -1,4 +1,4 @@
-// $Id: mmdb_ficif.h,v 1.19 2012/01/26 17:52:20 ekr Exp $
+// $Id: mmdb_ficif.h $
// =================================================================
//
// CCP4 Coordinate Library: support of coordinate-related
@@ -6,13 +6,13 @@
//
// Copyright (C) Eugene Krissinel 2000-2008.
//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
// of the license to address the requirements of UK law.
//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
//
// This program is distributed in the hope that it will be useful,
@@ -22,7 +22,7 @@
//
// =================================================================
//
-// 15.12.02 <-- Date of Last Modification.
+// 12.09.13 <-- Date of Last Modification.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// -----------------------------------------------------------------
//
@@ -30,10 +30,10 @@
// ~~~~~~~~~
// **** Project : MacroMolecular Data Base (MMDB)
// ~~~~~~~~~
-// **** Classes :
-// ~~~~~~~~~
+// **** Classes :
+// ~~~~~~~~~
//
-// (C) E. Krissinel 2000-2008
+// (C) E. Krissinel 2000-2013
//
// =================================================================
//
@@ -41,13 +41,10 @@
#ifndef __MMDB_FICIF__
#define __MMDB_FICIF__
+#include "mmdb_machine_.h"
-#ifndef __Machine__
-#include "machine_.h"
-#endif
-
-
-
+using namespace mmdb;
+using namespace mmdb::machine;
// ==================== FORTRAN INTERFACE ========================
@@ -71,9 +68,9 @@ FORTRAN_SUBR ( MMDB_FCIF_WRITE, mmdb_fcif_write,
int * iRet, // return code
int FileName_len // fortran-hidden length of FileName
), ( // lengths-in-structure list
- fpstr FileName, int *iRet
+ fpstr FileName, int *iRet
), ( // lengths-follow list
- fpstr FileName, int FileName_len, int * iRet
+ fpstr FileName, int FileName_len, int * iRet
) );
FORTRAN_SUBR ( MMDB_FCIF_PUTDATE, mmdb_fcif_putdate,
@@ -133,7 +130,7 @@ FORTRAN_SUBR ( MMDB_FCIF_PUTSTRING, mmdb_fcif_putstring,
), ( // lengths-in-structure list
fpstr Data, fpstr CatName, fpstr Tag, int * iRet
), ( // lengths-follow list
- fpstr Data, int Data_len,
+ fpstr Data, int Data_len,
fpstr CatName, int CatName_len,
fpstr Tag, int Tag_len,
int * iRet
@@ -150,11 +147,11 @@ FORTRAN_SUBR ( MMDB_FCIF_PUTREAL, mmdb_fcif_putreal,
), ( // lengths-in-structure list
apireal * V, fpstr CatName, fpstr Tag, int * iRet
), ( // lengths-follow list
- apireal * V,
+ apireal * V,
fpstr CatName, int CatName_len,
fpstr Tag, int Tag_len,
int * iRet
- ) );
+ ) );
FORTRAN_SUBR ( MMDB_FCIF_PUTINTEGER, mmdb_fcif_putinteger,
( // lengths-at-end list
@@ -167,7 +164,7 @@ FORTRAN_SUBR ( MMDB_FCIF_PUTINTEGER, mmdb_fcif_putinteger,
), ( // lengths-in-structure list
int * I, fpstr CatName, fpstr Tag, int * iRet
), ( // lengths-follow list
- int * I,
+ int * I,
fpstr CatName, int CatName_len,
fpstr Tag, int Tag_len,
int * iRet
@@ -219,7 +216,7 @@ FORTRAN_SUBR ( MMDB_FCIF_PUTLOOPSTRING, mmdb_fcif_putloopstring,
fpstr Data, fpstr CatName, fpstr Tag,
int * nrow, int * iRet
), ( // lengths-follow list
- fpstr Data, int Data_len,
+ fpstr Data, int Data_len,
fpstr CatName, int CatName_len,
fpstr Tag, int Tag_len,
int * nrow, int * iRet
@@ -238,7 +235,7 @@ FORTRAN_SUBR ( MMDB_FCIF_PUTLOOPREAL, mmdb_fcif_putloopreal,
apireal * V, fpstr CatName, fpstr Tag,
int * nrow, int * iRet
), ( // lengths-follow list
- apireal * V,
+ apireal * V,
fpstr CatName, int CatName_len,
fpstr Tag, int Tag_len,
int * nrow, int * iRet
@@ -257,7 +254,7 @@ FORTRAN_SUBR ( MMDB_FCIF_PUTLOOPINTEGER, mmdb_fcif_putloopinteger,
int * I, fpstr CatName, fpstr Tag,
int * nrow, int * iRet
), ( // lengths-follow list
- int * I,
+ int * I,
fpstr CatName, int CatName_len,
fpstr Tag, int Tag_len,
int * nrow, int * iRet
diff --git a/mmdb2/mmdb_io_file.cpp b/mmdb2/mmdb_io_file.cpp
new file mode 100644
index 0000000..606bdf2
--- /dev/null
+++ b/mmdb2/mmdb_io_file.cpp
@@ -0,0 +1,1873 @@
+// $Id: file_.cpp,v 1.29 2012/01/26 17:52:19 ekr Exp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2008.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 29.01.10 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : mmdb_io_file <implementation>
+// ~~~~~~~~~
+// **** Classes : mmdb::io::File - file I/O Support.
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef _WIN32
+# include <windows.h>
+# define sleep Sleep
+#else
+# ifndef __UNISTD_H
+# include <unistd.h>
+# endif
+#endif
+
+#include "mmdb_io_file.h"
+
+
+// _WIN32_NEWLINE should be raised when compilinig on Windows in
+// order to enforce Windows' line endings when writing text in
+// files opened for *binary* output. Otherwise, writing text lines
+// in binary files will results in UNIX line endings. Line endings
+// in files, opened for output in text mode, will be always
+// platform-specific.
+
+#ifdef _WIN32_NEWLINE
+// for DOS/WINDOWS machines:
+#define NEWLINE "\r\n"
+#else
+// for UNIX machines:
+#define NEWLINE "\n"
+#endif
+
+namespace mmdb {
+
+ namespace io {
+
+#ifdef _WIN32
+ const char _dir_sep_c = '\\';
+ cpstr _dir_sep = "\\";
+#else
+ const char _dir_sep_c = '/';
+ cpstr _dir_sep = "/";
+#endif
+
+ // =================== Auxilary Functions =========================
+
+ cpstr GetFPath ( pstr FilePath, SYSKEY syskey ) {
+ pstr P;
+
+ if (syskey==syskey_unix)
+ P = strrchr(FilePath,'/');
+ else if (syskey==syskey_win)
+ P = strrchr(FilePath,'\\');
+ else if (syskey==syskey_all) {
+ P = strrchr(FilePath,'/');
+ if (!P) P = strrchr(FilePath,'\\');
+ } else
+ P = NULL;
+
+ if (P) {
+ P = P + 1;
+ *P = char(0);
+ } else
+ FilePath[0] = char(0);
+
+ return FilePath;
+
+ }
+
+ cpstr GetFName ( cpstr FilePath, SYSKEY syskey ) {
+ pstr P;
+ if (syskey==syskey_unix)
+ P = strrchr(FilePath,'/');
+ else if (syskey==syskey_win)
+ P = strrchr(FilePath,'\\');
+ else if (syskey==syskey_all) {
+ P = strrchr(FilePath,'/');
+ if (!P) P = strrchr(FilePath,'\\');
+ } else
+ P = NULL;
+ if (!P) return FilePath;
+ else return P + 1;
+ }
+
+ cpstr GetFExt ( cpstr FilePath ) {
+ pstr P;
+ P = strchr ( GetFName(FilePath),'.');
+ if (!P) return &(FilePath[strlen(FilePath)]);
+ else return P;
+ }
+
+ cpstr ChangeExt ( pstr FilePath, cpstr newExt, SYSKEY syskey ) {
+ int i;
+ i = strlen(FilePath)-1;
+ if (syskey==syskey_unix)
+ while ((i>0) && (FilePath[i]!='.') && (FilePath[i]!='/')) i--;
+ else if (syskey==syskey_win)
+ while ((i>0) && (FilePath[i]!='.') && (FilePath[i]!='\\')) i--;
+ else if (syskey==syskey_all)
+ while ((i>0) && (FilePath[i]!='.') &&
+ (FilePath[i]!='/') && (FilePath[i]!='\\')) i--;
+ if (FilePath[i]=='.') {
+ FilePath[i+1] = char(0);
+ strcat ( FilePath,newExt );
+ } else {
+ strcat ( FilePath,"." );
+ strcat ( FilePath,newExt );
+ }
+ return FilePath;
+ }
+
+ bool FileExists ( cpstr FileName, PFile f ) {
+ PFile g;
+ bool B;
+ if (FileName) {
+ if (!f) g = new File();
+ else g = f;
+ g->assign ( FileName );
+ B = g->exists();
+ if (!f) delete g;
+ return B;
+ } else
+ return false;
+ }
+
+
+ // ======================== File Class ========================
+
+ #define ARCH_NONE 0
+ #define ARCH_GZIP 1
+ #define ARCH_COMPRESS 2
+ #define ARCH_ENFORCE 3
+
+ File::File ( word BufSize ) {
+ Buf_Size = BufSize;
+ BufLen = 0;
+ BufInc = 1;
+ EofFile = false;
+ hFile = NULL;
+ FName = NULL;
+ BufCnt = 0;
+ IOBuf = NULL;
+ IOSuccess = true;
+ TextMode = false;
+ UniBin = false;
+ StdIO = false;
+ gzipIO = ARCH_NONE;
+ memIO = false;
+ }
+
+ File::~File() {
+ shut ();
+ FreeBuffer();
+ }
+
+ void File::FreeBuffer () {
+ if (IOBuf) {
+ if (!memIO) delete[] IOBuf;
+ IOBuf = NULL;
+ }
+ if (FName) {
+ delete[] FName;
+ FName = NULL;
+ }
+ }
+
+ void File::assign ( cpstr FileName, bool Text, bool UniB,
+ GZ_MODE gzMode ) {
+ pstr p;
+
+ shut();
+
+ FreeBuffer();
+
+ CreateCopy ( FName,FileName );
+ StdIO = (!strcmp(FName,"stdin" )) ||
+ (!strcmp(FName,"stdout")) ||
+ (!strcmp(FName,"stderr"));
+
+ if (StdIO) TextMode = true;
+ else TextMode = Text;
+
+ UniBin = UniB;
+
+ gzipMode = gzMode;
+ gzipIO = ARCH_NONE;
+ if ((gzipMode==GZM_ENFORCE) || (gzipMode==GZM_ENFORCE_GZIP))
+ gzipIO = ARCH_GZIP;
+ else if (gzipMode==GZM_ENFORCE_COMPRESS)
+ gzipIO = ARCH_COMPRESS;
+ else if (gzipMode==GZM_CHECK) {
+ p = strrchr ( FName,'.' );
+ if (p) {
+ if (!strcmp(p,".gz")) gzipIO = ARCH_GZIP;
+ else if (!strcmp(p,".Z")) gzipIO = ARCH_COMPRESS;
+ }
+ }
+
+ memIO = false;
+
+ }
+
+
+ void File::assign ( word poolSize, word sizeInc, pstr filePool ) {
+
+ shut ();
+ FreeBuffer();
+
+ IOBuf = (pstr)filePool;
+ BufLen = poolSize;
+ FLength = poolSize;
+ BufInc = sizeInc;
+ BufCnt = 0;
+
+ memIO = true;
+ gzipMode = GZM_NONE;
+ gzipIO = ARCH_NONE;
+
+ }
+
+ void File::GetFilePool ( pstr & filePool, word & fileSize ) {
+ if (memIO) {
+ filePool = IOBuf;
+ fileSize = FLength;
+ IOBuf = NULL;
+ BufLen = 0;
+ BufCnt = 0;
+ FLength = 0;
+ } else {
+ filePool = NULL;
+ fileSize = 0;
+ }
+ }
+
+ static pstr gzip_path = pstr("gzip ");
+ static pstr ungzip_path = pstr("gzip -dc ");
+ static pstr compress_path = pstr("compress ");
+ static pstr uncompress_path = pstr("uncompress -c ");
+
+ void SetGZIPPath ( pstr gzipPath, pstr ungzipPath ) {
+ if (!gzipPath) gzip_path = pstr("gzip ");
+ else gzip_path = gzipPath;
+ if (!ungzipPath) ungzip_path = pstr("gzip -d ");
+ else ungzip_path = ungzipPath;
+ }
+
+ void SetCompressPath ( pstr compressPath, pstr uncompressPath ) {
+ if (!compressPath) compress_path = pstr("compress ");
+ else compress_path = compressPath;
+ if (!uncompressPath) uncompress_path = pstr("uncompress -c ");
+ else uncompress_path = uncompressPath;
+ }
+
+
+ bool File::reset ( bool ReadOnly, int retry ) {
+ #ifndef _MSC_VER
+ pstr p;
+ int i;
+ #endif
+
+ if (memIO) {
+
+ shut();
+ if (!IOBuf) return false;
+ BufCnt = 0;
+ IOSuccess = true;
+
+ } else {
+
+ if (!FName) return false;
+ shut();
+ BufLen = 0;
+ BufCnt = 0;
+
+ if (!strcmp(FName,"stdin")) {
+
+ hFile = stdin;
+ StdIO = true;
+ TextMode = true;
+ FLength = 1;
+ EofFile = false;
+ IOSuccess = true;
+
+ } else {
+
+ StdIO = false;
+ if (gzipIO==ARCH_GZIP) {
+ #ifndef _MSC_VER
+ p = NULL;
+ CreateConcat ( p,ungzip_path,FName );
+ for (i=0;(i<=retry) && (!hFile);i++) {
+ if (i>0) sleep ( 1 );
+ hFile = popen ( p,"r" );
+ }
+ if (p) delete[] p;
+ #endif
+
+ } else if (gzipIO==ARCH_COMPRESS) {
+ #ifndef _MSC_VER
+ p = NULL;
+ CreateConcat ( p,uncompress_path,FName );
+ for (i=0;(i<=retry) && (!hFile);i++) {
+ if (i>0) sleep ( 1 );
+ hFile = popen ( p,"r" );
+ }
+ if (p) delete[] p;
+ #endif
+
+ } else {
+
+ #ifndef _MSC_VER
+ for (i=0;(i<=retry) && (!hFile);i++) {
+ if (i>0) sleep ( 1 );
+ if (TextMode) {
+ if (ReadOnly) hFile = fopen ( FName,"rt" );
+ else hFile = fopen ( FName,"r+t" );
+ } else {
+ if (ReadOnly) hFile = fopen ( FName,"rb" );
+ else hFile = fopen ( FName,"r+b" );
+ }
+ }
+ #endif
+
+ }
+
+ if (hFile) {
+ if (gzipIO==ARCH_NONE) {
+ fseek ( hFile,0L,SEEK_END );
+ FLength = ftell ( hFile );
+ fseek ( hFile,0L,SEEK_SET );
+ EofFile = (FLength<=0);
+ } else {
+ FLength = 1;
+ EofFile = false;
+ }
+ IOSuccess = true;
+ } else {
+ EofFile = true;
+ IOSuccess = false;
+ }
+
+ }
+
+ }
+
+ return IOSuccess;
+
+ }
+
+ bool File::rewrite() {
+ #ifndef _MSC_VER
+ pstr p;
+ #endif
+
+ if (memIO) {
+
+ shut();
+ FreeBuffer();
+ IOBuf = new char[BufLen];
+ BufCnt = 0;
+ FLength = 0;
+ IOSuccess = true;;
+
+ } else {
+
+ if (!FName) return false;
+ shut();
+ BufLen = 0;
+ BufCnt = 0;
+
+ if (gzipIO==ARCH_GZIP) {
+ #ifndef _MSC_VER
+ p = NULL;
+ CreateConcat ( p,gzip_path,pstr(" > "),FName );
+ hFile = popen ( p,"w" );
+ if (p) delete[] p;
+ #else
+ hFile = NULL;
+ #endif
+ StdIO = false;
+ } else if (gzipIO==ARCH_COMPRESS) {
+ #ifndef _MSC_VER
+ p = NULL;
+ CreateConcat ( p,compress_path,pstr(" > "),FName );
+ hFile = popen ( p,"w" );
+ if (p) delete[] p;
+ #else
+ hFile = NULL;
+ #endif
+ StdIO = false;
+ } else if (!TextMode) {
+ hFile = fopen ( FName,"w+b" );
+ StdIO = false;
+ } else if (!strcmp(FName,"stdout")) {
+ hFile = stdout;
+ StdIO = true;
+ } else if (!strcmp(FName,"stderr")) {
+ hFile = stderr;
+ StdIO = true;
+ } else {
+ hFile = fopen ( FName,"w+t" );
+ StdIO = false;
+ }
+
+ FLength = 0;
+ IOSuccess = (hFile!=NULL);
+
+ }
+
+ return IOSuccess;
+
+ }
+
+
+ bool File::append() {
+ #ifndef _MSC_VER
+ pstr p;
+ #endif
+
+ if (memIO) {
+
+ if (!IOBuf) {
+ IOBuf = new char[BufLen];
+ BufCnt = 0;
+ }
+ FLength = BufCnt;
+ IOSuccess = true;
+
+ } else {
+
+ if (!FName) return false;
+
+ shut();
+ BufLen = 0;
+ BufCnt = 0;
+ if (gzipIO==ARCH_GZIP) {
+ #ifndef _MSC_VER
+ p = NULL;
+ CreateConcat ( p,gzip_path,pstr(" >> "),FName );
+ hFile = popen ( p,"w" );
+ if (p) delete[] p;
+ #else
+ hFile = NULL;
+ #endif
+ StdIO = false;
+ } else if (gzipIO==ARCH_COMPRESS) {
+ #ifndef _MSC_VER
+ p = NULL;
+ CreateConcat ( p,compress_path,pstr(" >> "),FName );
+ hFile = popen ( p,"w" );
+ if (p) delete[] p;
+ #else
+ hFile = NULL;
+ #endif
+ StdIO = false;
+ } else if (!TextMode) {
+ hFile = fopen ( FName,"ab" );
+ StdIO = false;
+ } else if (!strcmp(FName,"stdout")) {
+ hFile = stdout;
+ StdIO = true;
+ } else if (!strcmp(FName,"stderr")) {
+ hFile = stderr;
+ StdIO = true;
+ } else {
+ hFile = fopen ( FName,"at" );
+ StdIO = false;
+ }
+
+ FLength = 0;
+ IOSuccess = hFile!=NULL;
+
+ }
+
+ return IOSuccess;
+
+ }
+
+ bool File::erase() {
+ if (!FName) return false;
+ shut();
+ if (!StdIO) {
+ BufLen = 0;
+ BufCnt = 0;
+ if (FName)
+ IOSuccess = (remove(FName)==0);
+ FLength = 0;
+ } else
+ IOSuccess = true;
+ return IOSuccess;
+ }
+
+ bool File::exists() {
+
+ if (memIO) {
+
+ IOSuccess = (IOBuf!=NULL);
+
+ } else {
+
+ if (!FName) return false;
+ shut();
+ if (!StdIO) {
+ hFile = fopen ( FName,"r" );
+ IOSuccess = (hFile!=NULL);
+ BufLen = 0;
+ BufCnt = 0;
+ FLength = 0;
+ if (hFile) fclose ( hFile );
+ } else
+ IOSuccess = true;
+ hFile = NULL;
+ }
+
+ return IOSuccess;
+
+ }
+
+ bool File::parse ( cpstr FileName ) {
+ UNUSED_ARGUMENT(FileName);
+ return true;
+ }
+
+ bool File::rename ( cpstr NewFileName ) {
+ if (!FName) return false;
+ shut();
+ if (!StdIO)
+ IOSuccess = (::rename(FName,NewFileName)==0);
+ if (IOSuccess) assign ( NewFileName,TextMode,UniBin,gzipMode );
+ return IOSuccess;
+ }
+
+ long File::Position() {
+ // do not use on text files
+
+ if (memIO) return BufCnt;
+
+ if (hFile==NULL) return 0L;
+ return ftell ( hFile );
+
+ }
+
+ bool File::seek ( long Position ) {
+ // do not use on text files
+ if (memIO) {
+ if (Position<=(long)BufLen) {
+ BufCnt = Position;
+ IOSuccess = true;
+ } else
+ IOSuccess = false;
+ return IOSuccess;
+ } else if (hFile==NULL)
+ return false;
+ else if (!StdIO) {
+ IOSuccess = fseek(hFile,Position,SEEK_SET)==0;
+ return IOSuccess;
+ } else
+ return true;
+ }
+
+ bool File::FileEnd() {
+
+ if (memIO) return ((long)BufCnt>=FLength);
+
+ if (TextMode) {
+ if (EofFile || ((!hFile) && (!StdIO)))
+ return true;
+ if (feof(hFile)==0)
+ return false;
+ return true;
+ }
+
+ return EofFile && (BufLen==0);
+
+ }
+
+ void File::flush () {
+
+ if (hFile!=NULL) {
+ if (!StdIO) {
+ #ifndef _MSC_VER
+ if (gzipIO==ARCH_NONE)
+ fflush ( hFile );
+ #else
+ fflush ( hFile );
+ #endif
+ }
+ }
+ }
+
+ void File::shut () {
+
+ if (hFile!=NULL) {
+ if (!StdIO) {
+ #ifndef _MSC_VER
+ if (gzipIO!=ARCH_NONE) pclose ( hFile );
+ else fclose ( hFile );
+ #else
+ fclose ( hFile );
+ #endif
+ }
+ hFile = NULL;
+ }
+
+ }
+
+ bool File::isOpen() {
+ if (memIO) return (IOBuf!=NULL);
+ return (hFile!=NULL);
+ }
+
+ word File::ReadLine ( pstr Line, word MaxLen ) {
+ word LCnt;
+ int Done;
+ bool HSuccess = IOSuccess;
+
+ if (memIO) {
+
+ LCnt = 0;
+ while (((long)BufCnt<FLength) &&
+ (LCnt<MaxLen-1) &&
+ (IOBuf[BufCnt]!='\r') &&
+ (IOBuf[BufCnt]!='\n') )
+ Line[LCnt++] = IOBuf[BufCnt++];
+ Line[LCnt] = char(0);
+
+ while (((long)BufCnt<FLength) &&
+ (IOBuf[BufCnt]!='\r') &&
+ (IOBuf[BufCnt]!='\n') )
+ BufCnt++;
+
+ if ((long)BufCnt<FLength) {
+ if (IOBuf[BufCnt]=='\r') {
+ BufCnt++;
+ if ((long)BufCnt<FLength) {
+ if (IOBuf[BufCnt]=='\n') BufCnt++;
+ }
+ } else if (IOBuf[BufCnt]=='\n') {
+ BufCnt++;
+ if ((long)BufCnt<FLength) {
+ if (IOBuf[BufCnt]=='\r') BufCnt++;
+ }
+ }
+ }
+
+ return LCnt;
+
+ } else {
+
+ if ((!hFile) && (!StdIO)) {
+ Line[0] = char(0);
+ EofFile = true;
+ BufLen = 0;
+ IOSuccess = false;
+ return 0;
+ }
+ if (TextMode) {
+ Line[0] = char(0);
+ if (fgets(Line,MaxLen,hFile)) {
+ LCnt = strlen(Line);
+ while (LCnt>0) {
+ if ((Line[LCnt-1]!='\n') &&
+ (Line[LCnt-1]!='\r')) break;
+ Line[LCnt-1] = char(0);
+ LCnt--;
+ }
+ } else
+ LCnt = 0;
+ return LCnt;
+ } else {
+ if (IOBuf==NULL) {
+ IOBuf = new char[Buf_Size];
+ BufLen = ReadFile ( IOBuf,Buf_Size );
+ IOSuccess = HSuccess;
+ BufCnt = 0;
+ }
+ LCnt = 0;
+ do {
+ while ((BufCnt<BufLen) &&
+ (LCnt<MaxLen-1) &&
+ (IOBuf[BufCnt]!='\r') &&
+ (IOBuf[BufCnt]!='\n') )
+ Line[LCnt++] = IOBuf[BufCnt++];
+ if (BufCnt>=BufLen) {
+ HSuccess = IOSuccess;
+ BufLen = ReadFile ( IOBuf,Buf_Size );
+ IOSuccess = HSuccess;
+ BufCnt = 0;
+ }
+ if (IOBuf[BufCnt]=='\r') Done = 1;
+ else if (IOBuf[BufCnt]=='\n') Done = 2;
+ else Done = 0;
+ if (Done) BufCnt++;
+ if (BufCnt>=BufLen) {
+ HSuccess = IOSuccess;
+ BufLen = ReadFile ( IOBuf,Buf_Size );
+ IOSuccess = HSuccess;
+ BufCnt = 0;
+ }
+ if (BufLen>0) {
+ if (((Done==2) && (IOBuf[BufCnt]=='\r')) ||
+ ((Done==1) && (IOBuf[BufCnt]=='\n')))
+ BufCnt++;
+ }
+ } while ((!Done) && (LCnt<MaxLen-1) && (BufLen>0));
+ Line[LCnt] = char(0);
+ return LCnt;
+ }
+
+ }
+
+ }
+
+ word File::ReadNonBlankLine ( pstr S, word MaxLen ) {
+ word i,j;
+ do {
+ j = ReadLine ( S,MaxLen );
+ i = 0;
+ while ((i<j) && (S[i]==' ')) i++;
+ } while ((i>=j) && (!FileEnd()));
+ if (i>=j) {
+ S[0] = char(0);
+ j = 0;
+ }
+ return j;
+ }
+
+
+ bool File::WriteLine ( cpstr Line ) {
+ if ((!memIO) && TextMode) {
+ if (hFile==NULL) return false;
+ fputs ( Line,hFile );
+ // return (fputs(NEWLINE,hFile)>=0);
+ return (fputs("\n",hFile)>=0);
+ } else {
+ if (WriteFile(Line,strlen(Line)))
+ return WriteFile ( (void *)NEWLINE,strlen(NEWLINE) );
+ else return false;
+ }
+ }
+
+ bool File::Write ( cpstr Line ) {
+ if ((!memIO) && TextMode) {
+ if (hFile==NULL) return false;
+ return (fputs(Line,hFile)>=0);
+ } else
+ return WriteFile(Line,strlen(Line));
+ }
+
+ bool File::Write ( realtype V, int length ) {
+ char N[50];
+ sprintf ( N,"%-.*g",length,V );
+ if ((!memIO) && TextMode) {
+ if (hFile==NULL) return false;
+ return (fputs(N,hFile)>=0);
+ } else
+ return WriteFile(N,strlen(N));
+ }
+
+ bool File::Write ( int iV, int length ) {
+ char N[50];
+ sprintf ( N,"%*i",length,iV );
+ if ((!memIO) && TextMode) {
+ if (hFile==NULL) return false;
+ return (fputs(N,hFile)>=0);
+ } else
+ return WriteFile(N,strlen(N));
+ }
+
+ bool File::LF() {
+ if ((!memIO) && TextMode) {
+ if (hFile==NULL) return false;
+ // return (fputs(NEWLINE,hFile)>=0);
+ return (fputs("\n",hFile)>=0);
+ } else
+ return WriteFile ( (void *)NEWLINE,strlen(NEWLINE) );
+ }
+
+ bool File::WriteDataLine ( realtype X, realtype Y, int length ) {
+ Write ( pstr(" ") );
+ Write ( X,length );
+ Write ( pstr(" ") );
+ Write ( Y,length );
+ return LF();
+ }
+
+ bool File::WriteParameter ( cpstr S, realtype X,
+ int ParColumn, int length ) {
+ int l=strlen(S);
+ if ((!memIO) && TextMode) {
+ fputs ( S,hFile );
+ while (l<ParColumn) {
+ fputs ( " ",hFile );
+ l++;
+ }
+ } else {
+ WriteFile ( S,l );
+ while (l<ParColumn) {
+ WriteFile ( (void *)" ",1 );
+ l++;
+ }
+ }
+ Write ( X,length );
+ return LF();
+ }
+
+ bool File::WriteParameters ( cpstr S, int n_X, rvector X,
+ int ParColumn, int length ) {
+ int i;
+ int l=strlen(S);
+ if ((!memIO) && TextMode) {
+ fputs ( S,hFile );
+ while (l<ParColumn) {
+ fputs ( " ",hFile );
+ l++;
+ }
+ } else {
+ WriteFile ( S,l );
+ while (l<ParColumn) {
+ WriteFile ( (void *)" ",1 );
+ l++;
+ }
+ }
+ for (i=0;i<n_X;i++) {
+ Write ( X[i],length );
+ if (i!=n_X-1) WriteFile ( (void *)", ",2 );
+ }
+ return LF();
+ }
+
+ bool File::ReadParameter ( pstr S, realtype & X,
+ int ParColumn ) {
+ ReadLine ( S );
+ if ((int)strlen(S)>ParColumn) {
+ // X = atof ( &(S[ParColumn]) );
+ X = GetNumber ( &(S[ParColumn]) );
+ return true;
+ } else {
+ X = 0.0;
+ return false;
+ }
+ }
+
+ bool File::ReadParameters ( pstr S, int & n_X, rvector X,
+ int MaxLen, int ParColumn ) {
+ pstr S1,S2;
+ ReadLine ( S,MaxLen );
+ if ((int)strlen(S)>ParColumn) {
+ n_X = 0;
+ S2 = &(S[ParColumn]);
+ S1 = S2;
+ while (*S1!=char(0)) {
+ if (*S1==',') *S1 = ' ';
+ S1++;
+ }
+ while (*S2!=char(0)) {
+ S1 = S2;
+ X[n_X] = strtod ( S1,&S2 );
+ n_X++;
+ while ((*S2!=char(0)) && (*S2==' ')) S2++;
+ }
+ return true;
+ } else {
+ n_X = 0;
+ X[0] = 0.0;
+ return false;
+ }
+ }
+
+ bool File::ReadParameter ( pstr S, int & X,
+ int ParColumn ) {
+ realtype V;
+ if (ReadParameter(S,V,ParColumn)) {
+ X = mround(V);
+ return true;
+ } else {
+ X = 0;
+ return false;
+ }
+ }
+
+ bool File::CreateWrite ( cpstr Line ) {
+ wordUniBin wUB;
+ word i;
+ if (UniBin) {
+ if (Line) {
+ i = strlen(Line)+1;
+ word2UniBin ( i,wUB );
+ if (WriteFile(wUB,sizeof(wordUniBin)))
+ return WriteFile ( Line,i );
+ else return false;
+ } else {
+ i = 0;
+ word2UniBin ( i,wUB );
+ return WriteFile ( wUB,sizeof(wordUniBin) );
+ }
+ } else {
+ if (Line) {
+ i = strlen(Line)+1;
+ if (WriteFile(&i,sizeof(i)))
+ return WriteFile ( Line,i );
+ else return false;
+ } else {
+ i = 0;
+ return WriteFile ( &i,sizeof(i) );
+ }
+ }
+ }
+
+ #define _max_dyn_string_len 1073741824
+
+ word File::CreateRead ( pstr & Line ) {
+ wordUniBin wUB;
+ word i;
+ //unsigned short int i;
+ if (Line) {
+ delete[] Line;
+ Line = NULL;
+ }
+ if (UniBin) {
+ ReadFile ( wUB,sizeof(wordUniBin) );
+ UniBin2word ( wUB,i );
+ } else
+ ReadFile ( &i,sizeof(i) );
+ if ((i>0) && (i<_max_dyn_string_len)) {
+ Line = new char[i];
+ ReadFile ( Line,i );
+ }
+ return i;
+ }
+
+ bool File::WriteTerLine ( cpstr Line, bool longLine ) {
+ wordUniBin wUB;
+ word ll;
+ byte sl;
+ bool B;
+ if (Line) ll = strlen(Line);
+ else ll = 0;
+ if (!longLine) {
+ sl = byte(ll);
+ B = WriteFile ( &sl,sizeof(sl) );
+ } else if (UniBin) {
+ word2UniBin ( ll,wUB );
+ B = WriteFile ( wUB,sizeof(wordUniBin) );
+ } else
+ B = WriteFile ( &ll,sizeof(ll) );
+ if (B && (ll>0)) B = WriteFile ( Line,ll );
+ return B;
+ }
+
+ word File::ReadTerLine ( pstr Line, bool longLine ) {
+ wordUniBin wUB;
+ word ll;
+ byte sl;
+ if (!longLine) {
+ ReadFile ( &sl,sizeof(sl) );
+ ll = sl;
+ } else if (UniBin) {
+ ReadFile ( wUB,sizeof(wordUniBin) );
+ UniBin2word ( wUB,ll );
+ } else
+ ReadFile ( &ll,sizeof(ll) );
+ if (ll>0) ReadFile ( Line,ll );
+ Line[ll] = char(0);
+ return ll+1;
+ }
+
+ word File::ReadFile ( void * Buffer, word Count ) {
+ word Cnt;
+ if (memIO) {
+ Cnt = WMin(Count,FLength-BufCnt);
+ if (Cnt>0) {
+ memcpy ( Buffer,&(IOBuf[BufCnt]),Cnt );
+ BufCnt += Cnt;
+ }
+ IOSuccess = (Cnt==Count);
+ EofFile = ((Cnt<Count) || ((long)BufCnt>=FLength));
+ return Cnt;
+ } else if (hFile) {
+ Cnt = (word)fread ( Buffer,1,Count,hFile );
+ EofFile = (Cnt<Count) ||
+ ((gzipIO==ARCH_NONE) && (Position()==FLength));
+ IOSuccess = (Cnt==Count);
+ return Cnt;
+ } else
+ return 0;
+ }
+
+ bool File::WriteFile ( const void * Buffer, word Count ) {
+ pstr IOB;
+ word Cnt;
+ long Pos;
+
+ if (memIO) {
+
+ Cnt = BufCnt + Count;
+ if (Cnt>BufLen) {
+ Cnt += BufInc;
+ IOB = new char[Cnt];
+ if (IOBuf) {
+ memcpy ( IOB,IOBuf,BufCnt );
+ delete[] IOBuf;
+ }
+ IOBuf = IOB;
+ BufLen = Cnt;
+ }
+ memcpy ( &(IOBuf[BufCnt]),Buffer,Count );
+ BufCnt += Count;
+ FLength = BufCnt;
+ IOSuccess = true;
+
+ } else {
+
+ if (hFile==NULL) return false;
+ Cnt = (word)fwrite ( Buffer,1,Count,hFile );
+ Pos = Position();
+ if (Pos>FLength) FLength = Pos;
+ IOSuccess = Cnt==Count;
+
+ }
+
+ return IOSuccess;
+
+ }
+
+ bool File::WriteReal ( realtype * V ) {
+ realUniBin rUB;
+ if (UniBin) {
+ real2UniBin ( *V,rUB );
+ return WriteFile ( rUB,sizeof(realUniBin) );
+ } else
+ return WriteFile ( V,sizeof(realtype) );
+ }
+
+ bool File::WriteFloat ( realtype * V ) {
+ floatUniBin fUB;
+ float fV;
+ if (UniBin) {
+ float2UniBin ( *V,fUB );
+ return WriteFile ( fUB,sizeof(floatUniBin) );
+ } else {
+ fV = (float)*V;
+ return WriteFile ( &fV,sizeof(float) );
+ }
+ }
+
+ bool File::WriteInt ( int * I ) {
+ intUniBin iUB;
+ if (UniBin) {
+ int2UniBin ( *I,iUB );
+ return WriteFile ( iUB,sizeof(intUniBin) );
+ } else
+ return WriteFile ( I,sizeof(int) );
+ }
+
+ bool File::WriteShort ( short * S ) {
+ shortUniBin sUB;
+ if (UniBin) {
+ short2UniBin ( *S,sUB );
+ return WriteFile ( sUB,sizeof(shortUniBin) );
+ } else
+ return WriteFile ( S,sizeof(short) );
+ }
+
+ bool File::WriteLong ( long * L ) {
+ longUniBin lUB;
+ if (UniBin) {
+ long2UniBin ( *L,lUB );
+ return WriteFile ( lUB,sizeof(longUniBin) );
+ } else
+ return WriteFile ( L,sizeof(long) );
+ }
+
+ bool File::WriteBool ( bool * B ) {
+ intUniBin iUB;
+ int k;
+ if (UniBin) {
+ if (*B) k = 1;
+ else k = 0;
+ int2UniBin ( k,iUB );
+ return WriteFile ( iUB,sizeof(intUniBin) );
+ } else
+ return WriteFile ( B,sizeof(bool) );
+ }
+
+ bool File::WriteByte ( byte * B ) {
+ return WriteFile ( B,sizeof(byte) );
+ }
+
+ bool File::WriteWord ( word * W ) {
+ wordUniBin wUB;
+ if (UniBin) {
+ word2UniBin ( *W,wUB );
+ return WriteFile ( wUB,sizeof(wordUniBin) );
+ } else
+ return WriteFile ( W,sizeof(word) );
+ }
+
+ bool File::ReadReal ( realtype * V ) {
+ realUniBin rUB;
+ if (UniBin) {
+ if (ReadFile(rUB,sizeof(realUniBin))==sizeof(realUniBin)) {
+ UniBin2real ( rUB,*V );
+ return true;
+ } else
+ return false;
+ } else
+ return ( ReadFile(V,sizeof(realtype))==sizeof(realtype) );
+ }
+
+ bool File::ReadFloat ( realtype * V ) {
+ floatUniBin fUB;
+ float fV;
+ if (UniBin) {
+ if (ReadFile(fUB,sizeof(floatUniBin))==sizeof(floatUniBin)) {
+ UniBin2float ( fUB,*V );
+ return true;
+ }
+ } else if (ReadFile(&fV,sizeof(float))==sizeof(float)) {
+ *V = fV;
+ return true;
+ }
+ return false;
+ }
+
+ bool File::ReadInt ( int * I ) {
+ intUniBin iUB;
+ if (UniBin) {
+ if (ReadFile(iUB,sizeof(intUniBin))==sizeof(intUniBin)) {
+ UniBin2int ( iUB,*I );
+ return true;
+ } else
+ return false;
+ } else
+ return ( ReadFile(I,sizeof(int))==sizeof(int) );
+ }
+
+ bool File::ReadShort ( short * S ) {
+ shortUniBin sUB;
+ if (UniBin) {
+ if (ReadFile(sUB,sizeof(shortUniBin))==sizeof(shortUniBin)) {
+ UniBin2short ( sUB,*S );
+ return true;
+ } else
+ return false;
+ } else
+ return ( ReadFile(S,sizeof(short))==sizeof(short) );
+ }
+
+ bool File::ReadLong ( long * L ) {
+ longUniBin lUB;
+ if (UniBin) {
+ if (ReadFile(lUB,sizeof(longUniBin))==sizeof(longUniBin)) {
+ UniBin2long ( lUB,*L );
+ return true;
+ } else
+ return false;
+ } else
+ return ( ReadFile(L,sizeof(long))==sizeof(long) );
+ }
+
+ bool File::ReadBool ( bool * B ) {
+ intUniBin iUB;
+ int k;
+ if (UniBin) {
+ if (ReadFile(iUB,sizeof(intUniBin))==sizeof(intUniBin)) {
+ UniBin2int ( iUB,k );
+ *B = (k!=0);
+ return true;
+ } else
+ return false;
+ } else
+ return ( ReadFile(B,sizeof(bool))==sizeof(bool) );
+ }
+
+ bool File::ReadByte ( byte * B ) {
+ return ( ReadFile(B,sizeof(byte))==sizeof(byte) );
+ }
+
+ bool File::ReadWord ( word * W ) {
+ wordUniBin wUB;
+ if (UniBin) {
+ if (ReadFile(wUB,sizeof(wordUniBin))==sizeof(wordUniBin)) {
+ UniBin2word ( wUB,*W );
+ return true;
+ } else
+ return false;
+ } else
+ return ( ReadFile(W,sizeof(word))==sizeof(word) );
+ }
+
+ bool File::AddReal ( realtype * V ) {
+ realtype x;
+ if (ReadReal(&x)) {
+ *V += x;
+ return true;
+ }
+ return false;
+ }
+
+ bool File::AddFloat ( realtype * V ) {
+ realtype x;
+ if (ReadFloat(&x)) {
+ *V += x;
+ return true;
+ }
+ return false;
+ }
+
+
+ bool File::AddInt ( int * I ) {
+ int k;
+ if (ReadInt(&k)) {
+ *I += k;
+ return true;
+ }
+ return false;
+ }
+
+ bool File::AddShort ( short * S ) {
+ short k;
+ if (ReadShort(&k)) {
+ *S += k;
+ return true;
+ }
+ return false;
+ }
+
+ bool File::AddLong ( long * L ) {
+ long k;
+ if (ReadLong(&k)) {
+ *L += k;
+ return true;
+ }
+ return false;
+ }
+
+ bool File::AddByte ( byte * B ) {
+ byte k;
+ if (ReadByte(&k)) {
+ *B += k;
+ return true;
+ }
+ return false;
+ }
+
+ bool File::AddWord ( word * W ) {
+ word k;
+ if (ReadWord(&k)) {
+ *W += k;
+ return true;
+ }
+ return false;
+ }
+
+ bool File::WriteVector ( rvector V, int len, int Shift ) {
+ intUniBin iUB;
+ realUniBin rUB;
+ int i;
+ int l = len;
+ if (V==NULL) l = 0;
+ if (UniBin) {
+ int2UniBin ( l,iUB );
+ WriteFile ( iUB,sizeof(intUniBin) );
+ for (i=0;i<len;i++) {
+ real2UniBin ( V[Shift+i],rUB );
+ WriteFile ( rUB,sizeof(realUniBin) );
+ }
+ } else {
+ WriteFile ( &l,sizeof(l) );
+ if (l>0) WriteFile ( &(V[Shift]),sizeof(realtype)*l );
+ }
+ return IOSuccess;
+ }
+
+ bool File::WriteVector ( ivector iV, int len, int Shift ) {
+ intUniBin iUB;
+ int i;
+ int l = len;
+ if (iV==NULL) l = 0;
+ if (UniBin) {
+ int2UniBin ( l,iUB );
+ WriteFile ( iUB,sizeof(intUniBin) );
+ for (i=0;i<len;i++) {
+ int2UniBin ( iV[Shift+i],iUB );
+ WriteFile ( iUB,sizeof(intUniBin) );
+ }
+ } else {
+ WriteFile ( &l,sizeof(l) );
+ if (l>0) WriteFile ( &(iV[Shift]),sizeof(int)*l );
+ }
+ return IOSuccess;
+ }
+
+ bool File::WriteVector ( lvector lV, int len, int Shift ) {
+ intUniBin iUB;
+ longUniBin lUB;
+ int i;
+ int l = len;
+ if (lV==NULL) l = 0;
+ if (UniBin) {
+ int2UniBin ( l,iUB );
+ WriteFile ( iUB,sizeof(intUniBin) );
+ for (i=0;i<len;i++) {
+ long2UniBin ( lV[Shift+i],lUB );
+ WriteFile ( lUB,sizeof(longUniBin) );
+ }
+ } else {
+ WriteFile ( &l,sizeof(l) );
+ if (l>0) WriteFile ( &(lV[Shift]),sizeof(long)*l );
+ }
+ return IOSuccess;
+ }
+
+ bool File::WriteVector ( bvector B, int len, int Shift ) {
+ intUniBin iUB;
+ int l = len;
+ if (B==NULL) l = 0;
+ if (UniBin) {
+ int2UniBin ( l,iUB );
+ WriteFile ( iUB,sizeof(intUniBin) );
+ } else
+ WriteFile ( &l,sizeof(l) );
+ if (l>0) WriteFile ( &(B[Shift]),sizeof(byte)*l );
+ return IOSuccess;
+ }
+
+ bool File::ReadVector ( rvector V, int maxlen, int Shift ) {
+ intUniBin iUB;
+ realUniBin rUB;
+ int i,l,ll;
+ realtype B;
+ if (UniBin) {
+ ReadFile ( iUB,sizeof(intUniBin) );
+ UniBin2int ( iUB,l );
+ if (IOSuccess && (l>0)) {
+ ll = IMin(l,maxlen);
+ if (V)
+ for (i=0;i<=ll;i++) {
+ ReadFile ( rUB,sizeof(realUniBin) );
+ UniBin2real ( rUB,V[Shift+i] );
+ }
+ for (i=ll+1;i<=l;i++)
+ ReadFile ( rUB,sizeof(realUniBin) );
+ }
+ } else {
+ ReadFile ( &l,sizeof(l) );
+ if (IOSuccess && (l>0)) {
+ ll = IMin(l,maxlen);
+ if (V) ReadFile ( &(V[Shift]),sizeof(realtype)*ll );
+ for (i=ll+1;i<=l;i++) ReadFile ( &B,sizeof(B) );
+ }
+ }
+ return IOSuccess;
+ }
+
+ bool File::ReadVector ( ivector iV, int maxlen, int Shift ) {
+ intUniBin iUB;
+ int i,l,ll,iB;
+ if (UniBin) {
+ ReadFile ( iUB,sizeof(intUniBin) );
+ UniBin2int ( iUB,l );
+ if (IOSuccess && (l>0)) {
+ ll = IMin(l,maxlen);
+ if (iV)
+ for (i=0;i<=ll;i++) {
+ ReadFile ( iUB,sizeof(intUniBin) );
+ UniBin2int ( iUB,iV[Shift+i] );
+ }
+ for (i=ll+1;i<=l;i++)
+ ReadFile ( iUB,sizeof(intUniBin) );
+ }
+ } else {
+ ReadFile ( &l,sizeof(l) );
+ if (IOSuccess && (l>0)) {
+ ll = IMin(l,maxlen);
+ if (iV) ReadFile ( &(iV[Shift]),sizeof(int)*ll );
+ for (i=ll+1;i<=l;i++) ReadFile ( &iB,sizeof(iB) );
+ }
+ }
+ return IOSuccess;
+ }
+
+ bool File::ReadVector ( lvector lV, int maxlen, int Shift ) {
+ intUniBin iUB;
+ longUniBin lUB;
+ int i,l,ll;
+ long lB;
+ if (UniBin) {
+ ReadFile ( iUB,sizeof(intUniBin) );
+ UniBin2int ( iUB,l );
+ if (IOSuccess && (l>0)) {
+ ll = IMin(l,maxlen);
+ if (lV)
+ for (i=0;i<=ll;i++) {
+ ReadFile ( lUB,sizeof(longUniBin) );
+ UniBin2long ( lUB,lV[Shift+i] );
+ }
+ for (i=ll+1;i<=l;i++)
+ ReadFile ( lUB,sizeof(longUniBin) );
+ }
+ } else {
+ ReadFile ( &l,sizeof(l) );
+ if (IOSuccess && (l>0)) {
+ ll = IMin(l,maxlen);
+ if (lV) ReadFile ( &(lV[Shift]),sizeof(long)*ll );
+ for (i=ll+1;i<=l;i++) ReadFile ( &lB,sizeof(lB) );
+ }
+ }
+ return IOSuccess;
+ }
+
+ bool File::ReadVector ( bvector B, int maxlen, int Shift ) {
+ intUniBin iUB;
+ int i,l,ll;
+ byte t;
+ if (UniBin) {
+ ReadFile ( iUB,sizeof(intUniBin) );
+ UniBin2int ( iUB,l );
+ } else
+ ReadFile ( &l,sizeof(l) );
+ if (IOSuccess && (l>0)) {
+ ll = IMin(l,maxlen);
+ if (B) ReadFile ( &(B[Shift]),sizeof(byte)*ll );
+ for (i=ll+1;i<=l;i++) ReadFile ( &t,sizeof(t) );
+ }
+ return IOSuccess;
+ }
+
+ bool File::CreateReadVector ( rvector & V, int & len,
+ int Shift ) {
+ intUniBin iUB;
+ realUniBin rUB;
+ int i;
+ realtype B;
+ FreeVectorMemory ( V,Shift );
+ if (UniBin) {
+ ReadFile ( iUB,sizeof(intUniBin) );
+ UniBin2int ( iUB,len );
+ if (IOSuccess && (len>0)) {
+ GetVectorMemory ( V,len,Shift );
+ if (V)
+ for (i=0;i<len;i++) {
+ ReadFile ( rUB,sizeof(realUniBin) );
+ UniBin2real ( rUB,V[Shift+i] );
+ }
+ else for (i=0;i<len;i++)
+ ReadFile ( rUB,sizeof(realUniBin) );
+ }
+ } else {
+ ReadFile ( &len,sizeof(len) );
+ if (IOSuccess && (len>0)) {
+ GetVectorMemory ( V,len,Shift );
+ if (V) ReadFile ( &(V[Shift]),sizeof(realtype)*len );
+ else for (i=0;i<len;i++)
+ ReadFile ( &B,sizeof(B) );
+ }
+ }
+ return IOSuccess;
+ }
+
+ bool File::CreateReadVector ( rvector & V, int Shift ) {
+ int len;
+ return CreateReadVector ( V,len,Shift );
+ }
+
+ bool File::CreateReadVector ( ivector & iV, int & len,
+ int Shift ) {
+ intUniBin iUB;
+ int i,iB;
+ FreeVectorMemory ( iV,Shift );
+ if (UniBin) {
+ ReadFile ( iUB,sizeof(intUniBin) );
+ UniBin2int ( iUB,len );
+ if (IOSuccess && (len>0)) {
+ GetVectorMemory ( iV,len,Shift );
+ if (iV)
+ for (i=0;i<len;i++) {
+ ReadFile ( iUB,sizeof(intUniBin) );
+ UniBin2int ( iUB,iV[Shift+i] );
+ }
+ else for (i=0;i<len;i++)
+ ReadFile ( iUB,sizeof(intUniBin) );
+ }
+ } else {
+ ReadFile ( &len,sizeof(len) );
+ if (IOSuccess && (len>0)) {
+ GetVectorMemory ( iV,len,Shift );
+ if (iV) ReadFile ( &(iV[Shift]),sizeof(int)*len );
+ else for (i=0;i<len;i++)
+ ReadFile ( &iB,sizeof(iB) );
+ }
+ }
+ return IOSuccess;
+ }
+
+ bool File::CreateReadVector ( ivector & iV, int Shift ) {
+ int len;
+ return CreateReadVector ( iV,len,Shift );
+ }
+
+ bool File::CreateReadVector ( lvector & lV, int & len,
+ int Shift ) {
+ intUniBin iUB;
+ longUniBin lUB;
+ int i;
+ long lB;
+ FreeVectorMemory ( lV,Shift );
+ if (UniBin) {
+ ReadFile ( iUB,sizeof(intUniBin) );
+ UniBin2int ( iUB,len );
+ if (IOSuccess && (len>0)) {
+ GetVectorMemory ( lV,len,Shift );
+ if (lV)
+ for (i=0;i<len;i++) {
+ ReadFile ( lUB,sizeof(intUniBin) );
+ UniBin2long ( lUB,lV[Shift+i] );
+ }
+ else for (i=0;i<len;i++)
+ ReadFile ( lUB,sizeof(longUniBin) );
+ }
+ } else {
+ ReadFile ( &len,sizeof(len) );
+ if (IOSuccess && (len>0)) {
+ GetVectorMemory ( lV,len,Shift );
+ if (lV) ReadFile ( &(lV[Shift]),sizeof(long)*len );
+ else for (i=0;i<len;i++)
+ ReadFile ( &lB,sizeof(lB) );
+ }
+ }
+ return IOSuccess;
+ }
+
+ bool File::CreateReadVector ( lvector & lV, int Shift ) {
+ int len;
+ return CreateReadVector ( lV,len,Shift );
+ }
+
+
+ bool File::CreateReadVector ( bvector & B, int & len,
+ int Shift ) {
+ intUniBin iUB;
+ int i;
+ byte t;
+ FreeVectorMemory ( B,Shift );
+ if (UniBin) {
+ ReadFile ( iUB,sizeof(intUniBin) );
+ UniBin2int ( iUB,len );
+ } else
+ ReadFile ( &len,sizeof(len) );
+ if (IOSuccess && (len>0)) {
+ GetVectorMemory ( B,len,Shift );
+ if (B) ReadFile ( &(B[Shift]),sizeof(byte)*len );
+ else for (i=0;i<len;i++)
+ ReadFile ( &t,sizeof(t) );
+ }
+ return IOSuccess;
+ }
+
+ bool File::CreateReadVector ( bvector & B, int Shift ) {
+ int len;
+ return CreateReadVector ( B,len,Shift );
+ }
+
+
+ bool File::WriteMatrix ( rmatrix & A, int N, int M,
+ int ShiftN, int ShiftM ) {
+ intUniBin iUB;
+ realUniBin rUB;
+ int i,j;
+ if (UniBin) {
+ if (!A) {
+ i = 0;
+ int2UniBin ( i,iUB );
+ WriteFile ( iUB,sizeof(intUniBin) );
+ } else {
+ int2UniBin ( N,iUB );
+ WriteFile ( iUB,sizeof(intUniBin) );
+ int2UniBin ( M,iUB );
+ WriteFile ( iUB,sizeof(intUniBin) );
+ for (i=0;i<N;i++)
+ for (j=0;j<M;j++) {
+ real2UniBin ( A[ShiftN+i][ShiftM+j],rUB );
+ WriteFile ( rUB,sizeof(realUniBin) );
+ }
+ }
+ } else if (!A) {
+ i = 0;
+ WriteFile ( &i,sizeof(i) );
+ } else {
+ WriteFile ( &N,sizeof(N) );
+ WriteFile ( &M,sizeof(M) );
+ for (i=0;i<N;i++)
+ WriteFile ( &(A[ShiftN][ShiftM]),sizeof(realtype)*M );
+ }
+ return IOSuccess;
+ }
+
+ bool File::CreateReadMatrix ( rmatrix & A, int ShiftN,
+ int ShiftM ) {
+ int N,M;
+ return CreateReadMatrix ( A,N,M,ShiftN,ShiftM );
+ }
+
+ bool File::CreateReadMatrix ( rmatrix & A, int & N, int & M,
+ int ShiftN, int ShiftM ) {
+ intUniBin iUB;
+ realUniBin rUB;
+ int i,j;
+ FreeMatrixMemory ( A,N,ShiftN,ShiftM );
+ if (UniBin) {
+ ReadFile ( iUB,sizeof(intUniBin) );
+ UniBin2int ( iUB,N );
+ if (IOSuccess && (N>0)) {
+ ReadFile ( iUB,sizeof(intUniBin) );
+ UniBin2int ( iUB,M );
+ if (IOSuccess && (M>0)) {
+ GetMatrixMemory ( A,N,M,ShiftN,ShiftM );
+ for (i=0;i<N;i++)
+ for (j=0;j<M;j++) {
+ ReadFile ( rUB,sizeof(realUniBin) );
+ UniBin2real ( rUB,A[ShiftN+i][ShiftM+j] );
+ }
+ }
+ }
+ } else {
+ ReadFile ( &N,sizeof(N) );
+ if (N>0) {
+ ReadFile ( &M,sizeof(M) );
+ if (M>0) {
+ GetMatrixMemory ( A,N,M,ShiftN,ShiftM );
+ for (i=0;i<N;i++)
+ ReadFile ( &(A[ShiftN][ShiftM]),sizeof(realtype)*M );
+ }
+ }
+ }
+ return IOSuccess;
+ }
+
+
+ bool File::WriteColumns ( rvector X, rvector Y, rvector Z,
+ int len, int Shift, int MLength ) {
+ // WriteColumns writes data stored in X, Y and Z in the form
+ // of columns, adding a blank line in the end. If Z (or Z and Y)
+ // are set to NULL, then only X and Y (or only X) are written.
+ // Shift corresponds to the begining of arrays' enumeration
+ // X[Shift..Shift+len-1].
+ int i,l;
+ l = Shift+len;
+ for (i=Shift;i<l;i++) {
+ Write ( pstr(" ") );
+ Write ( X[i],MLength );
+ if (Y) {
+ Write ( pstr(", ") );
+ Write ( Y[i],MLength );
+ }
+ if (Z) {
+ Write ( pstr(", ") );
+ Write ( Z[i],MLength );
+ }
+ LF();
+ }
+ return LF();
+ }
+
+ bool File::WriteColumns ( rvector X, rvector Y,
+ int len, int Shift, int MLength ) {
+ return WriteColumns ( X,Y,NULL,len,Shift,MLength );
+ }
+
+ int File::ReadColumns ( int maxlen, rvector X, rvector Y, rvector Z,
+ int xCol, int yCol, int zCol, int Shift ) {
+ // ReadColumns reads data stored by WriteColumns. X, Y, and Z must
+ // be allocated prior to call.
+ // xCol, yCol and zCol specify the order number of columns
+ // (starting from 0) to be read into X, Y and Z, correspondingly.
+ // If zCol (or zCol and yCol) < 0 then Z (or Z and Y) are not read.
+ // Shift corresponds to the begining of arrays' enumeration
+ // X[Shift..Shift+len-1].
+ // Returns number of lines read.
+ int DataLen;
+ char S[1025];
+ DataLen = maxlen;
+ _ReadColumns ( DataLen,S,sizeof(S),X,Y,Z,xCol,yCol,zCol,Shift );
+ return DataLen;
+ }
+
+ int File::ReadColumns ( int maxlen, rvector X, rvector Y,
+ int xCol, int yCol, int Shift ) {
+ return ReadColumns ( maxlen,X,Y,NULL,xCol,yCol,-1,Shift );
+ }
+
+
+ int File::CreateReadColumns ( rvector & X, rvector & Y, rvector & Z,
+ int xCol, int yCol, int zCol,
+ int Shift ) {
+ // ReadColumns reads data stored by WriteColumns. X, Y, and Z
+ // must be set to NULL prior to call. They will be allocated
+ // within the procedure.
+ // xCol, yCol and zCol specify the order number of columns
+ // (starting from 0) to be read into X, Y and Z, correspondingly.
+ // If zCol (or zCol and yCol) < 0 then Z (or Z and Y) are not read.
+ // Shift corresponds to the begining of arrays' enumeration
+ // X[Shift..Shift+len-1].
+ // Returns number of lines read, errors are reported by ErrorCode().
+ int i,j,DataLen;
+ char S[1025];
+ bool Ok;
+ DataLen = 0;
+ ErrCode = 0;
+ if (!FileEnd()) {
+ i = 0;
+ j = 1;
+ // the loop terminates at first blank line
+ while ((i<j) && (!FileEnd())) {
+ j = ReadLine ( S,sizeof(S) );
+ i = 0;
+ // check for blank line
+ while ((i<j) && (S[i]==' ')) i++;
+ DataLen++;
+ }
+ if (i>=j) DataLen--;
+ if (DataLen>0) {
+ Ok = GetVectorMemory(X,DataLen,Shift);
+ if (Ok && (yCol>=0))
+ Ok = Ok && GetVectorMemory(Y,DataLen,Shift);
+ if (Ok && (zCol>=0))
+ Ok = Ok && GetVectorMemory(Z,DataLen,Shift);
+ if (Ok) {
+ reset();
+ _ReadColumns ( DataLen,S,sizeof(S),X,Y,Z,xCol,yCol,
+ zCol,Shift );
+ } else ErrCode = FileError_NoMemory;
+ } else ErrCode = FileError_NoDataFound;
+ } else ErrCode = FileError_NoDataFound;
+ return DataLen;
+ }
+
+ int File::CreateReadColumns ( rvector & X, rvector & Y,
+ int xCol, int yCol, int Shift ) {
+ return CreateReadColumns ( X,Y,X,xCol,yCol,-1,Shift );
+ }
+
+ void File::_ReadColumns ( int & DLen, pstr S, int SLen,
+ rvector X, rvector Y, rvector Z,
+ int xCol, int yCol, int zCol,
+ int Shift ) {
+ int i,is,j,k,m,n,cmax;
+ char SV[256];
+ realtype Res;
+ ErrCode = 0;
+ i = 0;
+ cmax = IMax(zCol,IMax(xCol,yCol));
+ while ((i<DLen) && (ErrCode==0)) {
+ k = ReadLine ( S,SLen );
+ RemoveDelimiters(S,k);
+ j = 0;
+ m = -1;
+ n = 0;
+ while ((m<cmax) && (ErrCode==0)) {
+ do {
+ PickOutNumber ( S,SV,k,j );
+ if ((m<0) && (SV[0]==char(0)) && (j>=k)) {
+ DLen = i;
+ return;
+ }
+ m++;
+ } while ((m!=xCol) && (m!=yCol) && (m!=zCol));
+ if (SV[0]==char(0)) {
+ if (n>0) ErrCode = FileError_NoColumn;
+ else ErrCode = FileError_ShortData;
+ } else {
+ Res = GetNumber ( SV );
+ if (ErrCode==0) {
+ is = i+Shift;
+ if (m==xCol) X[is] = Res;
+ else if (m==yCol) Y[is] = Res;
+ else Z[is] = Res;
+ n++;
+ }
+ }
+ }
+ if ((ErrCode==0) && (n<2)) ErrCode = FileError_NoColumn;
+ i++;
+ }
+ if ((ErrCode==FileError_ShortData) && (i>1)) {
+ ErrCode = 0;
+ DLen = i-1;
+ }
+ if (ErrCode!=0) ErrCode = FileError_BadData;
+ }
+
+ void RemoveDelimiters ( pstr S, int SLen ) {
+ int j;
+ for (j=0;j<SLen;j++)
+ if ((S[j]==',') || (S[j]==';') ||
+ (S[j]==':') || (S[j]==char(9)))
+ S[j] = ' ';
+ }
+
+ void PickOutNumber ( cpstr S, pstr SV, int SLen, int & j ) {
+ int l;
+ l = 0;
+ while ((j<SLen) && (S[j]==' ')) j++;
+ if ((S[j]=='+') || (S[j]=='-')) SV[l++] = S[j++];
+ if (S[j]=='.') SV[l++] = '0';
+ while ((j<SLen) && (S[j]!=' ')) SV[l++] = S[j++];
+ SV[l] = char(0);
+ }
+
+ realtype File::GetNumber ( cpstr S ) {
+ char * endptr;
+ realtype V;
+ V = strtod ( S,&endptr );
+ if ((*endptr!=' ') && (*endptr))
+ ErrCode = FileError_BadData;
+ return V;
+ }
+
+ cpstr FileError ( int ErrCode ) {
+ switch (ErrCode) {
+ case 0 : return "Ok";
+ case FileError_NoMemory : return "Insufficient memory";
+ case FileError_NoDataFound : return "No data found";
+ case FileError_NoColumn : return "No column structure";
+ case FileError_BadData : return "Incorrect data format";
+ case FileError_WrongMemoryAllocation
+ : return "Wrong Memory Allocation";
+ default : return "Unknown I/O error";
+ }
+ }
+
+ }
+
+}
diff --git a/mmdb2/mmdb_io_file.h b/mmdb2/mmdb_io_file.h
new file mode 100644
index 0000000..726666e
--- /dev/null
+++ b/mmdb2/mmdb_io_file.h
@@ -0,0 +1,301 @@
+// $Id: mmdb_io_file.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2008.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 11.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : file_ <interface>
+// ~~~~~~~~~
+// **** Classes : mmdb::io::File - file I/O Support.
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_IO_File__
+#define __MMDB_IO_File__
+
+#include <stdio.h>
+
+#include "mmdb_mattype.h"
+
+namespace mmdb {
+
+ namespace io {
+
+ // ======================== File Class ========================
+
+ enum GZ_MODE {
+ GZM_NONE = 0,
+ GZM_CHECK = 1,
+ GZM_ENFORCE = 2,
+ GZM_ENFORCE_GZIP = 2,
+ GZM_ENFORCE_COMPRESS = 3
+ };
+
+ enum FILE_ERROR {
+ FileError_NoMemory = 110,
+ FileError_ShortData = 111,
+ FileError_NoDataFound = 112,
+ FileError_NoColumn = 113,
+ FileError_BadData = 114,
+ FileError_WrongMemoryAllocation = 115
+ };
+
+ enum SYSKEY {
+ syskey_unix = 1,
+ syskey_win = 2,
+ syskey_all = 3
+ };
+
+ extern const char _dir_sep_c;
+ extern cpstr _dir_sep;
+
+ // =================== Auxilary Functions ========================
+
+
+ extern cpstr GetFPath ( pstr FilePath, SYSKEY syskey=syskey_unix );
+ extern cpstr GetFName ( cpstr FilePath, SYSKEY syskey=syskey_unix );
+ extern cpstr GetFExt ( cpstr FilePath );
+ extern cpstr ChangeExt ( pstr FilePath, cpstr newExt,
+ SYSKEY syskey=syskey_unix );
+ extern cpstr FileError ( int ErrCode );
+ extern void RemoveDelimiters ( pstr S, int SLen );
+ extern void PickOutNumber ( cpstr S, pstr SV, int SLen, int & j );
+
+
+ // ========================== File ===============================
+
+ DefineClass(File);
+
+ class File {
+
+ public :
+
+ File ( word BufSize=4096 );
+ virtual ~File();
+
+ // ---- control functions
+ // FileName allows for "stdin", "stdout" and "stderr" as
+ // for standard UNIX streams.
+ void assign ( cpstr FileName,
+ bool Text=false,
+ bool UniB=false,
+ GZ_MODE gzMode=GZM_NONE );
+ // assign for memory IO
+ void assign ( word poolSize, word sizeInc, pstr filePool );
+ void GetFilePool ( pstr & filePool, word & fileSize );
+
+ inline cpstr FileName() { return FName; }
+ bool reset ( bool ReadOnly=false, int retry=0 );
+ // = true if opened, each retry 1 sec sleep
+ bool erase (); // = true if erased
+ bool exists (); // = true if exists
+ bool parse ( cpstr FileName ); // true if filled
+ bool rename ( cpstr NewFileName ); // true if renamed
+ bool rewrite (); // = true if opened
+ bool append (); // = true if opened
+ bool isOpen ();
+ long Position ();
+ inline long FileLength () { return FLength; }
+ bool seek ( long Position );
+ bool FileEnd ();
+ inline bool Success () { return IOSuccess; }
+ inline void SetSuccess() { IOSuccess = true; }
+ void flush ();
+ void shut ();
+
+ // ---- binary I/O
+ word ReadFile ( void * Buffer, word Count );
+ word CreateRead ( pstr & Line );
+ word ReadTerLine ( pstr Line, bool longLine=false );
+ bool WriteFile ( const void * Buffer, word Count );
+ bool CreateWrite ( cpstr Line );
+ bool WriteTerLine ( cpstr Line, bool longLine=false );
+
+ // machine-independent binary I/O
+ bool WriteReal ( realtype * V );
+ bool WriteFloat ( realtype * V );
+ bool WriteInt ( int * I );
+ bool WriteShort ( short * S );
+ bool WriteLong ( long * L );
+ bool WriteBool ( bool * B );
+ bool WriteByte ( byte * B );
+ bool WriteWord ( word * W );
+ bool ReadReal ( realtype * V );
+ bool ReadFloat ( realtype * V );
+ bool ReadInt ( int * I );
+ bool ReadShort ( short * S );
+ bool ReadLong ( long * L );
+ bool ReadBool ( bool * B );
+ bool ReadByte ( byte * B );
+ bool ReadWord ( word * B );
+ bool AddReal ( realtype * V );
+ bool AddFloat ( realtype * V );
+ bool AddInt ( int * I );
+ bool AddShort ( short * S );
+ bool AddLong ( long * L );
+ bool AddByte ( byte * B );
+ bool AddWord ( word * B );
+
+ // complex data binary I/O
+ bool WriteVector ( rvector V, int len, int Shift );
+ bool WriteVector ( ivector iV, int len, int Shift );
+ bool WriteVector ( lvector lV, int len, int Shift );
+ bool WriteVector ( bvector B, int len, int Shift );
+ bool ReadVector ( rvector V, int maxlen, int Shift );
+ bool ReadVector ( ivector iV, int maxlen, int Shift );
+ bool ReadVector ( lvector lV, int maxlen, int Shift );
+ bool ReadVector ( bvector B, int maxlen, int Shift );
+ bool CreateReadVector ( rvector & V, int & len, int Shift );
+ bool CreateReadVector ( ivector & iV, int & len, int Shift );
+ bool CreateReadVector ( lvector & lV, int & len, int Shift );
+ bool CreateReadVector ( bvector & B, int & len, int Shift );
+ bool CreateReadVector ( rvector & V, int Shift );
+ bool CreateReadVector ( ivector & iV, int Shift );
+ bool CreateReadVector ( lvector & lV, int Shift );
+ bool CreateReadVector ( bvector & B, int Shift );
+ bool WriteMatrix ( rmatrix & A, int N, int M,
+ int ShiftN, int ShiftM );
+ bool CreateReadMatrix ( rmatrix & A, int ShiftN, int ShiftM );
+ bool CreateReadMatrix ( rmatrix & A, int & N, int & M,
+ int ShiftN, int ShiftM );
+
+ /// ---- text I/O
+ bool Write ( cpstr Line ); //!< writes without LF
+ bool Write ( realtype V, int length=10 ); //!< w/o LF
+ bool Write ( int iV, int length=5 ); //!< w/o LF
+ bool WriteLine ( cpstr Line ); //!< writes and adds LF
+ bool LF (); //!< just adds LF
+ word ReadLine ( pstr Line, word MaxLen=255 );
+ word ReadNonBlankLine ( pstr S, word MaxLen=255 );
+
+ /// complex data text I/O
+
+ // writes with spaces and adds LF
+ bool WriteDataLine ( realtype X, realtype Y, int length=10 );
+
+ bool WriteParameter ( cpstr S, realtype X, // writes parameter
+ int ParColumn=40, // name S and value X
+ int length=10 ); // at column ParColumn
+ // and adds LF.
+
+ bool WriteParameters ( cpstr S, int n_X, // writes parameter
+ rvector X, // name S and n_X values
+ int ParColumn=40, // X[0..n_X-1] at col
+ int length=10 ); // ParColumn, ads LF.
+
+ bool ReadParameter ( pstr S, realtype & X, // reads parameter
+ int ParColumn=40 ); // name S and val X
+ bool ReadParameter ( pstr S, int & X,
+ int ParColumn=40 );
+
+ bool ReadParameters ( pstr S, int & n_X, // reads parameter
+ rvector X, // name S, counts the
+ int MaxLen=255, // of values n_X and
+ int ParColumn=40 ); // reads X[0..n_X-1].
+ // MaxLen gives sizeof(S)
+
+ // WriteColumns writes data stored in X, Y and Z in the form
+ // of columns, adding a blank line in the end. If Z (or Z and Y)
+ // are set to NULL, then only X and Y (or only X) are written.
+ // Shift corresponds to the begining of arrays' enumeration
+ // X[Shift..Shift+len-1].
+ bool WriteColumns ( rvector X, rvector Y, rvector Z,
+ int len, int Shift, int MLength );
+ bool WriteColumns ( rvector X, rvector Y,
+ int len, int Shift, int MLength );
+
+ // ReadColumns reads data stored by WriteColumns. X, Y, and Z
+ // must be allocated prior to call.
+ // xCol, yCol and zCol specify the order number of columns
+ // (starting from 0) to be read into X, Y and Z, correspondingly.
+ // If zCol (or zCol and yCol) < 0 then Z (or Z and Y) are not read.
+ // Shift corresponds to the begining of arrays' enumeration
+ // X[Shift..Shift+len-1].
+ // Returns number of lines read.
+ int ReadColumns ( int maxlen, rvector X, rvector Y, rvector Z,
+ int xCol, int yCol, int zCol, int Shift );
+ int ReadColumns ( int maxlen, rvector X, rvector Y,
+ int xCol, int yCol, int Shift );
+
+ // CreateReadColumns reads data stored by WriteColumns. X, Y,
+ // and Z must be set to NULL prior to call. They will be allocated
+ // within the procedure.
+ // xCol, yCol and zCol specify the order number of columns
+ // (starting from 0) to be read into X, Y and Z, correspondingly.
+ // If zCol (or zCol and yCol) < 0 then Z (or Z and Y) are not read.
+ // Shift corresponds to the begining of arrays' enumeration
+ // X[Shift..Shift+len-1].
+ // Returns number of lines read, errors are reported by
+ // ErrorCode().
+ int CreateReadColumns ( rvector & X, rvector & Y, rvector & Z,
+ int xCol, int yCol, int zCol, int Shift );
+ int CreateReadColumns ( rvector & X, rvector & Y,
+ int xCol, int yCol, int Shift );
+
+ // ---- miscellaneous
+ realtype GetNumber ( cpstr S );
+ FILE * GetHandle () { return hFile; }
+
+ protected :
+ word Buf_Size;
+ bool TextMode,UniBin;
+ GZ_MODE gzipMode;
+ pstr IOBuf;
+ word BufCnt,BufLen,BufInc;
+ FILE * hFile;
+ bool EofFile;
+ pstr FName;
+ long FLength;
+ bool IOSuccess;
+ int ErrCode;
+
+ void FreeBuffer ();
+ void _ReadColumns ( int & DLen, pstr S, int SLen,
+ rvector X, rvector Y, rvector Z,
+ int xCol, int yCol, int zCol, int Shift );
+
+ private :
+ int gzipIO;
+ bool StdIO,memIO;
+
+ };
+
+
+ extern void SetGZIPPath ( pstr gzipPath, pstr ungzipPath );
+ extern void SetCompressPath ( pstr compressPath, pstr uncompressPath );
+
+ extern bool FileExists ( cpstr FileName, PFile f=NULL );
+
+ }
+
+}
+
+
+#endif
+
diff --git a/mmdb2/mmdb_io_stream.cpp b/mmdb2/mmdb_io_stream.cpp
new file mode 100644
index 0000000..4dbdd46
--- /dev/null
+++ b/mmdb2/mmdb_io_stream.cpp
@@ -0,0 +1,112 @@
+// $Id: mmdb_io_stream.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 11.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : Stream_ <interface>
+// ~~~~~~~~~
+// **** Classes : mmdb::io::Stream ( Basic Stream Class )
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 1995-2013
+//
+// =================================================================
+//
+
+#include "mmdb_io_stream.h"
+
+namespace mmdb {
+
+ namespace io {
+
+ // ========================== CStream ===========================
+
+ // Each streamable class should be derived from Stream
+ // and have constructor Class(PStream & Object), which should
+ // initialize all memory of the class, and virtual functions
+ // read(..) and write(..) (see below). Constructor Class(PStream&)
+ // must not touch the Object variable. This constructor is used
+ // only once just before read(..) function. It is assumed that
+ // read/write functions of Class provide storage/reading of
+ // all vital data. Function read(..) must read data in exactly
+ // the same way as function write(..) stores it.
+ // For using Class in streams, three following functions should
+ // be supplied:
+ //
+ // 1.
+ // void StreamWrite ( RFile f, RPClass Object ) {
+ // StreamWrite ( f,(PStream)PClass );
+ // }
+ //
+ // 2.
+ // PCStream ClassInit ( RPStream Object ) {
+ // return (PStream)(new Class(Object));
+ // }
+ //
+ // 3.
+ // void StreamRead ( RFile f, RPClass Object ) {
+ // StreamRead_ ( f,(PStream)Object,ClassInit );
+ // }
+ //
+ // All these functions are automatically generated by macros
+ // DefineStreamFunctions(CClass) -- in the header -- and
+ // MakeStreamFunctions(CClass) -- in the implementation body.
+ // Then CClass may be streamed in/out using functions #1 and #3.
+ // StreamRead will return NULL for Object if it was not
+ // in the stream. If Object existed before StreamRead(..) but
+ // was not found in the stream, it will be disposed.
+
+ void StreamRead_ ( RFile f, RPStream Object,
+ InitStreamObject Init ) {
+ int i;
+ f.ReadInt ( &i );
+ if (i) {
+ if (!Object)
+ Object = Init(Object); //Object = new CStream ( Object );
+ Object->read ( f );
+ } else {
+ if (Object) delete Object;
+ Object = NULL;
+ }
+ }
+
+ void StreamWrite_ ( RFile f, RPStream Object ) {
+ int i;
+ if (Object) {
+ i = 1;
+ f.WriteInt ( &i );
+ Object->write ( f );
+ } else {
+ i = 0;
+ f.WriteInt ( &i );
+ }
+ }
+
+ MakeStreamFunctions(Stream)
+
+ }
+
+}
diff --git a/mmdb2/mmdb_io_stream.h b/mmdb2/mmdb_io_stream.h
new file mode 100644
index 0000000..689b37f
--- /dev/null
+++ b/mmdb2/mmdb_io_stream.h
@@ -0,0 +1,193 @@
+// $Id: mmdb_io_stream.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2008.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 11.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : Stream <interface>
+// ~~~~~~~~~
+// **** Classes : mmdb::io::Stream ( Basic Stream Class )
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 1995-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_IO_Stream__
+#define __MMDB_IO_Stream__
+
+#include "mmdb_io_file.h"
+
+// *******************************************************************
+
+#ifndef __ClassMacros
+
+# define __ClassMacros
+
+ // A Class definition macros
+# define DefineClass(ClassName) \
+ class ClassName; \
+ typedef ClassName * P##ClassName; \
+ typedef ClassName & R##ClassName; \
+ typedef P##ClassName * PP##ClassName; \
+ typedef P##ClassName & RP##ClassName;
+
+ // A Structure definition macros
+# define DefineStructure(StructureName) \
+ struct StructureName; \
+ typedef StructureName * P##StructureName; \
+ typedef StructureName & R##StructureName; \
+ typedef P##StructureName * PP##StructureName; \
+ typedef P##StructureName & RP##StructureName;
+
+#endif
+
+
+#define DefineStreamFunctions(ClassName) \
+ extern void StreamWrite ( mmdb::io::RFile f, RP##ClassName Object ); \
+ extern void StreamRead ( mmdb::io::RFile f, RP##ClassName Object );
+
+
+#define MakeStreamFunctions(ClassName) \
+ void StreamWrite ( mmdb::io::RFile f, RP##ClassName Object ) { \
+ StreamWrite_ ( f,(mmdb::io::RPStream)Object ); \
+ } \
+ mmdb::io::PStream StreamInit##ClassName ( mmdb::io::RPStream Object ) { \
+ return (mmdb::io::PStream)(new ClassName(Object)); \
+ } \
+ void StreamRead ( mmdb::io::RFile f, RP##ClassName Object ) { \
+ StreamRead_ ( f,(mmdb::io::RPStream)Object,StreamInit##ClassName );\
+ }
+
+#define DefineFactoryFunctions(ClassName) \
+ typedef P##ClassName Make##ClassName(); \
+ typedef Make##ClassName * PMake##ClassName; \
+ typedef P##ClassName StreamMake##ClassName ( mmdb::io::RPStream Object ); \
+ P##ClassName new##ClassName (); \
+ P##ClassName streamNew##ClassName ( mmdb::io::RPStream Object ); \
+ typedef StreamMake##ClassName * PStreamMake##ClassName; \
+ extern void SetMakers##ClassName ( void * defMk, void * streamMk ); \
+ extern void StreamWrite ( mmdb::io::RFile f, RP##ClassName Object ); \
+ extern void StreamRead ( mmdb::io::RFile f, RP##ClassName Object );
+
+
+#define MakeFactoryFunctions(ClassName) \
+ static PMake##ClassName make##ClassName = NULL; \
+ static PStreamMake##ClassName streamMake##ClassName = NULL; \
+ P##ClassName new##ClassName() { \
+ if (make##ClassName) return (*make##ClassName)(); \
+ else return new ClassName(); \
+ } \
+ P##ClassName streamNew##ClassName ( mmdb::io::RPStream Object ) { \
+ if (streamMake##ClassName) \
+ return (*streamMake##ClassName)(Object); \
+ else return new ClassName(Object); \
+ } \
+ void SetMakers##ClassName ( void * defMk, void * streamMk ) { \
+ make##ClassName = PMake##ClassName(defMk); \
+ streamMake##ClassName = PStreamMake##ClassName(streamMk); \
+ } \
+ void StreamWrite ( mmdb::io::RFile f, RP##ClassName Object ) { \
+ StreamWrite_ ( f,(mmdb::io::RPStream)Object ); \
+ } \
+ mmdb::io::PStream StreamInit##ClassName ( mmdb::io::RPStream Object ) { \
+ return (mmdb::io::PStream)(streamNew##ClassName(Object)); \
+ } \
+ void StreamRead ( mmdb::io::RFile f, RP##ClassName Object ) { \
+ StreamRead_ ( f,(mmdb::io::RPStream)Object,StreamInit##ClassName ); \
+ }
+
+namespace mmdb {
+
+ namespace io {
+
+ // ========================== Stream ===========================
+
+ // Each streamable class should be derived from Stream
+ // and have constructor Class(PStream & Object), which should
+ // initialize all memory of the class, and virtual functions
+ // read(..) and write(..) (see below). Constructor Class(PStream&)
+ // must not touch the Object variable. This constructor is used
+ // only once just before the read(..) function. It is assumed that
+ // read(..)/write(..) functions of the Class provide storage/reading
+ // of all vital data. Function read(..) must read data in exactly
+ // the same way as function write(..) stores it.
+ // For using Class in streams, three following functions should
+ // be supplied:
+ //
+ // 1.
+ // void StreamWrite ( File & f, PClass & Object ) {
+ // StreamWrite ( f,(PStream)Object );
+ // }
+ //
+ // 2.
+ // PStream ClassInit ( PStream & Object ) {
+ // return (PStream)(new Class(Object));
+ // }
+ //
+ // 3.
+ // void StreamRead ( File & f, PClass & Object ) {
+ // StreamRead_ ( f,(PStream)Object,ClassInit );
+ // }
+ //
+ // All these functions are automatically generated by macros
+ // DefineStreamFunctions(Class) -- in the header -- and
+ // MakeStreamFunctions(Class) -- in the implementation body. Note
+ // that macro DefineClass(Class) should always be issued for
+ // streamable classes prior to the stream-making macros. Then
+ // Class may be streamed using functions #1 and #3.
+ // StreamRead will return NULL for Object if it was not in
+ // the stream. If Object existed before calling StreamRead(..)
+ // but was not found in the stream, it will be disposed (NULL
+ // assigned).
+
+
+ DefineClass(Stream);
+ DefineStreamFunctions(Stream);
+
+ class Stream {
+ public :
+ Stream () {}
+ Stream ( RPStream ) {}
+ virtual ~Stream () {}
+ virtual void read ( RFile ) {}
+ virtual void write ( RFile ) {}
+ };
+
+
+ typedef PStream InitStreamObject(RPStream Object);
+
+ extern void StreamRead_ ( RFile f, RPStream Object,
+ InitStreamObject Init );
+
+ extern void StreamWrite_ ( RFile f, RPStream Object );
+
+
+ }
+
+}
+
+#endif
diff --git a/mmdb2/mmdb_machine_.cpp b/mmdb2/mmdb_machine_.cpp
new file mode 100644
index 0000000..fb50378
--- /dev/null
+++ b/mmdb2/mmdb_machine_.cpp
@@ -0,0 +1,155 @@
+// $Id: mmdb_machine.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : Machine <interface>
+// ~~~~~~~~~
+// **** Functions : mmdb::machine::GetMachineID - returns ID code
+// ~~~~~~~~~~~ for the machine
+// mmdb::machine::GetMachineName - returns name of
+// the machine
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include "mmdb_machine_.h"
+
+namespace mmdb {
+
+ namespace machine {
+
+#ifdef CALL_LIKE_SUN
+
+ int GetMachineID() {
+ int k = CALL_LIKE_SUN;
+ switch (k) {
+ case 1 : return MACHINE_ALLIANT;
+ case 2 : return MACHINE_CONVEX;
+ case 3 : return MACHINE_ESV;
+ case 4 : return MACHINE_SGI;
+ case 5 : return MACHINE_SOLBOURNE;
+ case 6 : return MACHINE_SOLARIS;
+ case 7 : return MACHINE_ALPHA;
+ case 8 : return MACHINE_F2C_G77;
+ case 9 : return MACHINE_LINUX;
+ default : return MACHINE_UNKNOWN;
+ }
+ }
+
+#elif defined(CALL_LIKE_HPUX)
+
+ int GetMachineID() {
+ int k = CALL_LIKE_HPUX;
+ switch (k) {
+ case 1 : return MACHINE_RS6000;
+ case 2 : return MACHINE_HP9000;
+ default : return MACHINE_UNKNOWN;
+ }
+ }
+
+#elif defined(CALL_LIKE_STARDENT)
+
+ int GetMachineID() {
+ int k = CALL_LIKE_STARDENT;
+ switch (k) {
+ case 1 : return MACHINE_ARDENT;
+ case 2 : return MACHINE_TITAN;
+ case 3 : return MACHINE_STARDENT;
+ default : return MACHINE_UNKNOWN;
+ }
+ }
+
+#elif defined(CALL_LIKE_VMS)
+
+ int GetMachineID() {
+ return MACHINE_VMS;
+ }
+
+#elif defined(CALL_LIKE_MVS)
+
+ int GetMachineID() {
+ return MACHINE_MVS;
+ }
+
+#else
+
+ int GetMachineID() {
+ return MACHINE_UNKNOWN;
+ }
+
+#endif
+
+ static cpstr MCH_SGI = cpstr("Silicon Graphics");
+ static cpstr MCH_RS6000 = cpstr("IBM RS/6000");
+ static cpstr MCH_ALLIANT = cpstr("Alliant");
+ static cpstr MCH_ARDENT = cpstr("Ardent");
+ static cpstr MCH_TITAN = cpstr("Titan");
+ static cpstr MCH_STARDENT = cpstr("Stardent");
+ static cpstr MCH_CONVEX = cpstr("Convex");
+ static cpstr MCH_ESV = cpstr("Evans or Sutherland");
+ static cpstr MCH_HP9000 = cpstr("Hewlett Packard 9000");
+ static cpstr MCH_SOLBOURNE = cpstr("Solbourne");
+ static cpstr MCH_SOLARIS = cpstr("Solaris");
+ static cpstr MCH_ALPHA = cpstr("DEC Alpha");
+ static cpstr MCH_VMS = cpstr("A VMS machine");
+ static cpstr MCH_MVS = cpstr("MS Windows");
+ static cpstr MCH_F2C_G77 = cpstr("SUN compatible");
+ static cpstr MCH_LINUX = cpstr("Linux");
+
+ cpstr GetMachineName ( int MachineID ) {
+ switch (MachineID) {
+ case MACHINE_SGI : return MCH_SGI;
+ case MACHINE_RS6000 : return MCH_RS6000;
+ case MACHINE_ALLIANT : return MCH_ALLIANT;
+ case MACHINE_ARDENT : return MCH_ARDENT;
+ case MACHINE_TITAN : return MCH_TITAN;
+ case MACHINE_STARDENT : return MCH_STARDENT;
+ case MACHINE_CONVEX : return MCH_CONVEX;
+ case MACHINE_ESV : return MCH_ESV;
+ case MACHINE_HP9000 : return MCH_HP9000;
+ case MACHINE_SOLBOURNE : return MCH_SOLBOURNE;
+ case MACHINE_SOLARIS : return MCH_SOLARIS;
+ case MACHINE_ALPHA : return MCH_ALPHA;
+ case MACHINE_VMS : return MCH_VMS;
+ case MACHINE_MVS : return MCH_MVS;
+ case MACHINE_F2C_G77 : return MCH_F2C_G77;
+ case MACHINE_LINUX : return MCH_LINUX;
+ default :
+ case MACHINE_UNKNOWN : return pstr("Unidentified machine");
+ }
+ }
+
+ cpstr GetMachineName() {
+ return GetMachineName ( GetMachineID() );
+ }
+
+
+ }
+
+}
diff --git a/mmdb/machine_.h b/mmdb2/mmdb_machine_.h
old mode 100755
new mode 100644
similarity index 79%
rename from mmdb/machine_.h
rename to mmdb2/mmdb_machine_.h
index e7f812b..6897d06
--- a/mmdb/machine_.h
+++ b/mmdb2/mmdb_machine_.h
@@ -1,18 +1,18 @@
-// $Id: machine_.h,v 1.31 2012/01/26 17:52:19 ekr Exp $
+// $Id: mmdb_machine.h $
// =================================================================
//
// CCP4 Coordinate Library: support of coordinate-related
// functionality in protein crystallography applications.
//
-// Copyright (C) Eugene Krissinel 2000-2008.
+// Copyright (C) Eugene Krissinel 2000-2013.
//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
// of the license to address the requirements of UK law.
//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
//
// This program is distributed in the hope that it will be useful,
@@ -22,26 +22,26 @@
//
// =================================================================
//
-// 08.07.08 <-- Date of Last Modification.
+// 12.09.13 <-- Date of Last Modification.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// -----------------------------------------------------------------
//
-// **** Module : machine_ <interface>
+// **** Module : Machine <interface>
// ~~~~~~~~~
-// **** Functions : GetMachineID - returns ID code for the machine
-// ~~~~~~~~~~~ GetMachineName - returns name of a machine
+// **** Functions : mmdb::machine::GetMachineID - returns ID code
+// ~~~~~~~~~~~ for the machine
+// mmdb::machine::GetMachineName - returns name of
+// the machine
//
-// (C) E. Krissinel 2000-2008
+// (C) E. Krissinel 2000-2013
//
// =================================================================
//
-#ifndef __Machine__
-#define __Machine__
+#ifndef __MMDB_Machine__
+#define __MMDB_Machine__
-#ifndef __MatType__
-#include "mattype_.h"
-#endif
+#include "mmdb_mattype.h"
/*
// Programs written in plain C, should define __PlainC each time
@@ -54,29 +54,34 @@
#endif
*/
+namespace mmdb {
+
+ namespace machine {
-// ================== List of known machines ========================
-#define MACHINE_SGI 1
-#define MACHINE_RS6000 2
-#define MACHINE_ALLIANT 3
-#define MACHINE_ARDENT 4
-#define MACHINE_TITAN 5
-#define MACHINE_STARDENT 6
-#define MACHINE_CONVEX 7
-#define MACHINE_ESV 8
-#define MACHINE_HP9000 9
-#define MACHINE_SOLBOURNE 10
-#define MACHINE_SOLARIS 11
-#define MACHINE_ALPHA 12
-#define MACHINE_VMS 13
-#define MACHINE_MVS 14
-#define MACHINE_F2C_G77 15
-#define MACHINE_LINUX 16
-#define MACHINE_UNKNOWN 100
+ // ================== List of known machines =================
+ enum MACHINE {
+ MACHINE_SGI = 1,
+ MACHINE_RS6000 = 2,
+ MACHINE_ALLIANT = 3,
+ MACHINE_ARDENT = 4,
+ MACHINE_TITAN = 5,
+ MACHINE_STARDENT = 6,
+ MACHINE_CONVEX = 7,
+ MACHINE_ESV = 8,
+ MACHINE_HP9000 = 9,
+ MACHINE_SOLBOURNE = 10,
+ MACHINE_SOLARIS = 11,
+ MACHINE_ALPHA = 12,
+ MACHINE_VMS = 13,
+ MACHINE_MVS = 14,
+ MACHINE_F2C_G77 = 15,
+ MACHINE_LINUX = 16,
+ MACHINE_UNKNOWN = 100
+ };
-// ================ Identification of the machine ===================
+ // ============= Identification of the machine ===============
// IBM Unix RS/6000
#if defined(_AIX) || defined(___AIX)
@@ -103,7 +108,7 @@
# define CALL_LIKE_SUN 3
// Hewlett Packard 9000/750 (RISC) models
-#elif defined(__hpux)
+#elif defined(__hpux)
# define CALL_LIKE_HPUX 2
// Silicon Graphics IRIX systems, Iris'es, Indigo's, Crimson's etc.
@@ -127,13 +132,13 @@
# define CALL_LIKE_VMS 1
// MVS stands for Microsoft Visual Studio
-#elif defined(_MVS)
+#elif defined(_MVS)
# define CALL_LIKE_MVS 1
#elif defined(F2C) || defined(G77)
# define CALL_LIKE_SUN 8
-#elif defined(linux)
+#elif defined(linux)
# define CALL_LIKE_SUN 9
#else
@@ -147,19 +152,19 @@
// ================= Machine-dependent definitions ==================
#ifdef CALL_LIKE_STARDENT
- // SStrParam is used in Ardent-like machines' fortran calls
- // for passing a string parameter
- DefineStructure(SStrPar)
- struct SStrPar {
- pstr S;
- int len;
- int id;
- };
+ // StrPar is used in Ardent-like machines' fortran calls
+ // for passing a string parameter
+ DefineStructure(StrPar)
+ struct StrPar {
+ pstr S;
+ int len;
+ int id;
+ };
#endif
//
-// Macro FORTRAN_SUBR(NAME,name,p_send,p_sstruct,p_sflw)
+// Macro FORTRAN_SUBR(NAME,name,p_send,p_struct,p_sflw)
// makes function header statements that allow for linking with
// programs written in FORTRAN.
//
@@ -169,7 +174,7 @@
// name name of the FORTRAN subroutine in small letters
// p_send parameter list (in brackets) with string lengths
// attached to the end of it (see below)
-// p_sstruct parameter list (in brackets) with strings passed
+// p_struct parameter list (in brackets) with strings passed
// as complex parameters, or structures
// p_sflw parameter list (in brackets) with string lengths
// following immediately the string parameters
@@ -194,7 +199,7 @@
// complex parameter, 'fpstr' is identical to the
// pointer on the corresponding structure:
// CALL_LIKE_STARDENT :
-// 'fpstr' is identical to 'PSStrPar'
+// 'fpstr' is identical to 'PStrPar'
// CALL_LIKE_VMS :
// 'fpstr' is identical to 'dsc$descriptor_s *'
//
@@ -206,7 +211,7 @@
// ii) FTN_LEN(s) - returns integer length of fortran-
// passed string s. For this macro to
// work properly with SUN- and MVS-like
-// machines, always use suffix '_len'
+// machines, always use suffix '_len'
// for the string length parameters as
// described in a) above.
//
@@ -224,7 +229,7 @@
// retain the order in which the strings appear
// in the list.
//
-// p_sstruct strings enter their place in the list as in
+// p_struct strings enter their place in the list as in
// the corresponding FORTRAN call, having 'fpstr'
// parameter type.
//
@@ -268,7 +273,7 @@
//
//
//
-// Macro FORTRAN_CALL(NAME,name,p_send,p_sstruct,p_sflw)
+// Macro FORTRAN_CALL(NAME,name,p_send,p_struct,p_sflw)
// calls function defined with macro FORTRAN_SUBR(...), from
// a C/C++ application. Its parameters and their meaning are
// exactly identical to those of FORTRAN_SUBR(...).
@@ -279,27 +284,27 @@
// **** type of real numbers in the API functions
// comment or uncomment the proper string
-typedef float apireal; // FORTRAN real*4
+ typedef float apireal; // FORTRAN real*4
/*
-typedef double apireal; // FORTRAN real*8
+ typedef double apireal; // FORTRAN real*8
*/
#if defined(CALL_LIKE_SUN)
- typedef pstr fpstr;
+ typedef pstr fpstr;
# define FTN_STR(s) s
# define FTN_LEN(s) s##_len
# define char_struct(s) \
- pstr s; \
+ mmdb::pstr s; \
int s##_len;
# define fill_char_struct(s,str) \
s = str; \
s##_len = strlen(str);
-# ifdef __cplusplus
+# ifdef __cplusplus
# define FORTRAN_SUBR(NAME,name,p_sun,p_stardent,p_mvs) \
extern "C" void name##_ p_sun
# else
@@ -315,7 +320,7 @@ typedef double apireal; // FORTRAN real*8
# elif defined(CALL_LIKE_HPUX)
- typedef pstr fpstr;
+ typedef pstr fpstr;
# define FTN_STR(s) s
# define FTN_LEN(s) s##_len
@@ -327,7 +332,7 @@ typedef double apireal; // FORTRAN real*8
s = str; \
s##_len = strlen(str);
-# ifdef __cplusplus
+# ifdef __cplusplus
# define FORTRAN_SUBR(NAME,name,p_sun,p_stardent,p_mvs) \
extern "C" void name p_sun
# else
@@ -343,35 +348,35 @@ typedef double apireal; // FORTRAN real*8
#elif defined(CALL_LIKE_STARDENT)
- typedef PStrPar fpstr;
+ typedef PStrPar fpstr;
# define FTN_STR(s) s->S
# define FTN_LEN(s) s->len
# define char_struct(s) \
- SStrPar s;
+ StrPar s;
# define fill_char_struct(s,str) \
s.S = str; \
s.len = strlen(FName); \
s.id = 0;
-# ifdef __cplusplus
-# define FORTRAN_SUBR(NAME,name,p_send,p_sstruct,p_sflw) \
+# ifdef __cplusplus
+# define FORTRAN_SUBR(NAME,name,p_send,p_struct,p_sflw) \
extern "C" void NAME p_stardent
# else
-# define FORTRAN_SUBR(NAME,name,p_send,p_sstruct,p_sflw) \
+# define FORTRAN_SUBR(NAME,name,p_send,p_struct,p_sflw) \
void NAME p_stardent
# endif
# define FORTRAN_EXTERN(NAME,name,p_sun,p_stardent,p_mvs) \
extern "C" void NAME p_stardent
-# define FORTRAN_CALL(NAME,name,p_send,p_sstruct,p_sflw) \
+# define FORTRAN_CALL(NAME,name,p_send,p_struct,p_sflw) \
NAME p_stardent
#elif defined(CALL_LIKE_VMS)
- typedef dsc$descriptor_s * fpstr;
+ typedef dsc$descriptor_s * fpstr;
# define FTN_STR(s) s->dsc$a_pointer;
# define FTN_LEN(s) s->dsc$w_length;
@@ -384,7 +389,7 @@ typedef double apireal; // FORTRAN real*8
s.dsc$b_dtype = DSC$K_DTYPE_T; \
s.dsc$b_class = DSC$K_CLASS_S;
-# ifdef __cplusplus
+# ifdef __cplusplus
# define FORTRAN_SUBR(NAME,name,p_sun,p_stardent,p_mvs) \
extern "C" void NAME p_stardent
# else
@@ -400,7 +405,7 @@ typedef double apireal; // FORTRAN real*8
#elif defined(CALL_LIKE_MVS)
- typedef pstr fpstr;
+ typedef pstr fpstr;
# define FTN_STR(s) s
# define FTN_LEN(s) s##_len
@@ -430,7 +435,7 @@ typedef double apireal; // FORTRAN real*8
# error Unknown machine!!!
- typedef pstr fpstr;
+ typedef pstr fpstr;
# define FTN_STR(s) s
# define FTN_LEN(s) s##_len
@@ -442,7 +447,7 @@ typedef double apireal; // FORTRAN real*8
s = str; \
s##_len = strlen(str);
-# ifdef __cplusplus
+# ifdef __cplusplus
# define FORTRAN_SUBR(NAME,name,p_sun,p_stardent,p_mvs) \
extern "C" void name##_ p_sun
# else
@@ -459,12 +464,14 @@ typedef double apireal; // FORTRAN real*8
#endif
+ // ============== Machine-dependent functions ===============
-// ================ Machine-dependent functions =================
+ extern int GetMachineID ();
+ extern mmdb::cpstr GetMachineName ();
+ extern mmdb::cpstr GetMachineName ( int MachineID );
-extern int GetMachineID ();
-extern cpstr GetMachineName ();
-extern cpstr GetMachineName ( int MachineID );
+ }
+}
#endif
diff --git a/mmdb2/mmdb_manager.cpp b/mmdb2/mmdb_manager.cpp
new file mode 100644
index 0000000..4681adb
--- /dev/null
+++ b/mmdb2/mmdb_manager.cpp
@@ -0,0 +1,389 @@
+// $Id: mmdb_manager.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 15.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : mmdb_manager <implementation>
+// ~~~~~~~~~
+// Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::Manager ( MMDB file manager )
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+
+#include <string.h>
+
+#include "mmdb_manager.h"
+
+namespace mmdb {
+
+// ===================== Manager =======================
+
+ Manager::Manager() : BondManager() {
+ }
+
+ Manager::Manager ( io::RPStream Object ) : BondManager(Object) {
+ }
+
+ Manager::~Manager() {}
+
+ void Manager::Copy ( PManager MMDB, COPY_MASK CopyMask ) {
+ PModel mdl;
+ PPChain chain;
+ PChain ch;
+ ChainID chID;
+ int i,j, nchains;
+
+ if (CopyMask & MMDBFCM_Flags) Flags = MMDB->Flags;
+
+ if (CopyMask & MMDBFCM_Title) title.Copy ( &(MMDB->title) );
+ if (CopyMask & MMDBFCM_Cryst) cryst.Copy ( &(MMDB->cryst) );
+
+ if (CopyMask & MMDBFCM_Coord) {
+
+ FreeCoordMemory ();
+ DeleteAllSelections();
+
+ nAtoms = MMDB->nAtoms;
+ atmLen = nAtoms;
+ if (nAtoms>0) {
+ atom = new PAtom[atmLen];
+ for (i=0;i<nAtoms;i++) {
+ if (MMDB->atom[i]) {
+ atom[i] = newAtom();
+ atom[i]->Copy ( MMDB->atom[i] );
+ // the internal atom references are installed
+ // by residue classes when they are read in
+ // model->chain below
+ atom[i]->SetAtomIndex ( i+1 );
+ } else
+ atom[i] = NULL;
+ }
+ }
+
+ nModels = MMDB->nModels;
+ if (nModels>0) {
+ model = new PModel[nModels];
+ for (i=0;i<nModels;i++) {
+ if (MMDB->model[i]) {
+ model[i] = newModel();
+ model[i]->SetMMDBManager ( this,0 );
+ model[i]->_copy ( MMDB->model[i] );
+ } else
+ model[i] = NULL;
+ }
+ }
+
+ crModel = NULL;
+ crChain = NULL;
+ crRes = NULL;
+
+ if (MMDB->crModel) {
+
+ for (i=0;i<nModels;i++)
+ if (model[i]) {
+ if (model[i]->serNum==MMDB->crModel->serNum) {
+ crModel = model[i];
+ break;
+ }
+ }
+
+ if (crModel && crModel->chain && MMDB->crChain)
+ for (i=0;i<crModel->nChains;i++)
+ if (crModel->chain[i]) {
+ if (!strcmp(crModel->chain[i]->chainID,
+ MMDB->crModel->chain[i]->chainID)) {
+ crChain = crModel->chain[i];
+ break;
+ }
+ }
+
+ if (crChain && crChain->residue && MMDB->crRes)
+ for (i=0;i<crChain->nResidues;i++)
+ if (crChain->residue[i]) {
+ if ((!strcmp(crChain->residue[i]->name,
+ MMDB->crRes->name)) &&
+ (crChain->residue[i]->seqNum==MMDB->crRes->seqNum) &&
+ (!strcmp(crChain->residue[i]->insCode,
+ MMDB->crRes->insCode))) {
+ crRes = crChain->residue[i];
+ break;
+ }
+ }
+ }
+
+ /*
+ if ((MMDB->nSelections>0) && MMDB->Mask) {
+ nSelections = MMDB->nSelections;
+ if (nSelections>0) {
+ Mask = new PCMask [nSelections];
+ SelAtom = new PPAtom[nSelections];
+ nSelAtoms = new int [nSelections];
+ for (i=0;i<nSelections;i++) {
+ Mask[i] = new CMask();
+ Mask[i]->CopyMask ( MMDB->Mask[i] );
+ nSelAtoms[i] = MMDB->nSelAtoms[i];
+ if (nSelAtoms[i]>0) {
+ SelAtom[i] = new PAtom[nSelAtoms[i]];
+ for (j=0;j<nSelAtoms[i];j++)
+ SelAtom[i][j] = Atom[MMDB->SelAtom[i][j]->index];
+ } else
+ SelAtom[i] = NULL;
+ }
+ }
+ }
+ */
+
+ } else if (CopyMask & (MMDBFCM_HetInfo | MMDBFCM_SecStruct |
+ MMDBFCM_Links | MMDBFCM_CisPeps |
+ MMDBFCM_ChainAnnot)) {
+
+ for (i=0;i<MMDB->nModels;i++)
+ if (MMDB->model[i]) {
+
+ mdl = GetModel ( i+1 );
+ if (!mdl) {
+ mdl = new Model( NULL,i+1 );
+ AddModel ( mdl );
+ }
+
+ if (CopyMask & MMDBFCM_HetInfo)
+ mdl->CopyHets ( MMDB->model[i] );
+ if (CopyMask & MMDBFCM_SecStruct)
+ mdl->CopySecStructure ( MMDB->model[i] );
+ if (CopyMask & MMDBFCM_Links) {
+ mdl->CopyLinks ( MMDB->model[i] );
+ mdl->CopyLinkRs ( MMDB->model[i] );
+ }
+ if (CopyMask & MMDBFCM_CisPeps)
+ mdl->CopyCisPeps ( MMDB->model[i] );
+ if (CopyMask & MMDBFCM_ChainAnnot) {
+ MMDB->GetChainTable ( i+1,chain,nchains );
+ for (j=0;j<nchains;j++)
+ if (chain[j]) {
+ chain[j]->GetChainID ( chID );
+ ch = mdl->GetChain ( chID );
+ if (!ch) {
+ ch = new Chain();
+ ch->SetChainID ( chID );
+ mdl->AddChain ( ch );
+ }
+ ch->CopyAnnotations ( chain[j] );
+ }
+
+ }
+
+ }
+
+ }
+
+ if (CopyMask & MMDBFCM_SA) SA.Copy ( &(MMDB->SA) );
+ if (CopyMask & MMDBFCM_SB) SB.Copy ( &(MMDB->SB) );
+ if (CopyMask & MMDBFCM_SC) SC.Copy ( &(MMDB->SC) );
+ if (CopyMask & MMDBFCM_Footnotes)
+ Footnote.Copy ( &(MMDB->Footnote) );
+
+ if (CopyMask & MMDBFCM_Buffer) {
+ lcount = MMDB->lcount;
+ strncpy ( S,MMDB->S,sizeof(S) );
+ }
+
+ }
+
+ void Manager::Delete ( word DelMask ) {
+ PPModel model;
+ PPChain chain;
+ int i,j,nm, nchains;
+
+ if (DelMask & MMDBFCM_Flags) Flags = 0;
+
+ if (DelMask & MMDBFCM_Title) title.Copy ( NULL );
+ if (DelMask & MMDBFCM_TitleKeepBM) title.FreeMemory ( true );
+ if (DelMask & MMDBFCM_Cryst) cryst.Copy ( NULL );
+
+ if (DelMask & MMDBFCM_Coord) {
+ FreeCoordMemory ();
+ DeleteAllSelections();
+ }
+
+ if (DelMask & MMDBFCM_SecStruct) {
+ GetModelTable ( model,nm );
+ if (model)
+ for (i=0;i<nm;i++)
+ if (model[i])
+ model[i]->RemoveSecStructure();
+ }
+
+ if (DelMask & MMDBFCM_HetInfo) {
+ GetModelTable ( model,nm );
+ if (model)
+ for (i=0;i<nm;i++)
+ if (model[i])
+ model[i]->RemoveHetInfo();
+ }
+
+ if (DelMask & MMDBFCM_Links) {
+ GetModelTable ( model,nm );
+ if (model)
+ for (i=0;i<nm;i++)
+ if (model[i]) {
+ model[i]->RemoveLinks ();
+ model[i]->RemoveLinkRs();
+ }
+ }
+
+ if (DelMask & MMDBFCM_CisPeps) {
+ GetModelTable ( model,nm );
+ if (model)
+ for (i=0;i<nm;i++)
+ if (model[i])
+ model[i]->RemoveCisPeps();
+ }
+
+ if (DelMask & MMDBFCM_ChainAnnot) {
+ nm = GetNumberOfModels();
+ for (i=1;i<=nm;i++) {
+ GetChainTable ( i,chain,nchains );
+ if (chain)
+ for (j=0;j<nchains;j++)
+ if (chain[j])
+ chain[j]->FreeAnnotations();
+ }
+ }
+
+ if (DelMask & MMDBFCM_SA) SA.FreeContainer();
+ if (DelMask & MMDBFCM_SB) SB.FreeContainer();
+ if (DelMask & MMDBFCM_SC) SC.FreeContainer();
+ if (DelMask & MMDBFCM_Footnotes) Footnote.FreeContainer();
+
+ if (DelMask & MMDBFCM_Buffer) {
+ lcount = 0;
+ S[0] = char(0);
+ }
+
+ }
+
+ PTitleContainer Manager::GetRemarks() {
+ return title.GetRemarks();
+ }
+
+
+ PTitleContainer Manager::GetJournal() {
+ return title.GetJournal();
+ }
+
+ realtype Manager::GetResolution() {
+ return title.GetResolution();
+ }
+
+ int Manager::ParseBiomolecules() {
+ return title.ParseBiomolecules();
+ }
+
+ int Manager::GetNofBiomolecules() {
+ return title.GetNofBiomolecules();
+ }
+
+ void Manager::GetBiomolecules ( PPBiomolecule & BM, int & nBMs ) {
+ title.GetBiomolecules ( BM,nBMs );
+ }
+
+ PBiomolecule Manager::GetBiomolecule ( int bmNo ) {
+ return title.GetBiomolecule ( bmNo );
+ }
+
+ PManager Manager::MakeBiomolecule ( int bmNo, int modelNo ) {
+ PManager M;
+ PPChain ch;
+ PChain chain;
+ PModel model;
+ PBiomolecule BM;
+ int i,j,k,n,n0,nChains;
+
+ BM = title.GetBiomolecule ( bmNo );
+ if (!BM) return NULL;
+
+ GetChainTable ( modelNo,ch,nChains );
+ if ((!ch) || (nChains<=0)) return NULL;
+
+ n0 = 0;
+ model = new Model();
+
+ for (i=0;(i<BM->nBMAs) && (n0>=0);i++)
+ if (BM->bmApply[i]) {
+ for (j=0;(j<BM->bmApply[i]->nMatrices) && (n0>=0);j++)
+ for (k=0;(k<BM->bmApply[i]->nChains) && (n0>=0);k++) {
+ n0 = -1;
+ for (n=0;(n<nChains) && (n0<0);n++)
+ if (!strcmp(ch[n]->GetChainID(),BM->bmApply[i]->chain[k]))
+ n0 = n;
+ if (n0>=0) {
+ chain = new Chain();
+ chain->Copy ( ch[n0] );
+ chain->ApplyTransform ( BM->bmApply[i]->tm[j] );
+ model->AddChain ( chain );
+ }
+ }
+ }
+
+ if (n0>=0) {
+ M = new Manager();
+ M->AddModel ( model );
+ M->PDBCleanup ( PDBCLEAN_SERIAL | PDBCLEAN_INDEX );
+ } else {
+ delete model;
+ M = NULL;
+ }
+
+ return M;
+
+ }
+
+
+ // ------------------- Stream functions ----------------------
+
+
+ void Manager::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ BondManager::write ( f );
+ }
+
+ void Manager::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ BondManager::read ( f );
+ }
+
+
+ MakeStreamFunctions(Manager)
+
+} // namespace mmdb
diff --git a/mmdb2/mmdb_manager.h b/mmdb2/mmdb_manager.h
new file mode 100644
index 0000000..c70d804
--- /dev/null
+++ b/mmdb2/mmdb_manager.h
@@ -0,0 +1,124 @@
+// $Id: mmdb_manager.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 15.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : mmdb_manager <interface>
+// ~~~~~~~~~
+// Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::Manager ( MMDB file manager )
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_Manager__
+#define __MMDB_Manager__
+
+#include "mmdb_bondmngr.h"
+
+namespace mmdb {
+
+ // ======================= Manager ===========================
+
+ // copy masks
+ enum COPY_MASK {
+ MMDBFCM_None = 0x00000000,
+ MMDBFCM_All = 0xFFFFFFFF,
+ MMDBFCM_Title = 0x00000001,
+ MMDBFCM_TitleKeepBM = 0x00000002,
+ MMDBFCM_Cryst = 0x00000004,
+ MMDBFCM_Coord = 0x00000008,
+ MMDBFCM_SecStruct = 0x00000010,
+ MMDBFCM_HetInfo = 0x00000020,
+ MMDBFCM_Links = 0x00000040,
+ MMDBFCM_CisPeps = 0x00000080,
+ MMDBFCM_SA = 0x00000100,
+ MMDBFCM_SB = 0x00000200,
+ MMDBFCM_SC = 0x00000400,
+ MMDBFCM_Footnotes = 0x00000800,
+ MMDBFCM_ChainAnnot = 0x00001000,
+ MMDBFCM_Flags = 0x00002000,
+ MMDBFCM_Buffer = 0x80000000,
+ MMDBFCM_Top = 0xFFFFFFF7
+ };
+
+ DefineStreamFunctions(Manager);
+
+ class Manager : public BondManager {
+
+ public :
+
+ Manager ();
+ Manager ( io::RPStream Object );
+ ~Manager();
+
+
+ // --------------- Copying/Deleting -----------------------
+
+ // Copy(..) will transfer different sort of information
+ // between two MMDB's according to the copy mask given
+ // (cf. MMDBFCM_XXXXX values). Note that the copying content
+ // replaces the corresponding information (e.g. copying
+ // coordinates will replace existing coordinates rather than
+ // add to them).
+ void Copy ( PManager MMDB, COPY_MASK CopyMask );
+
+ // Delete(..) deletes different sort of information from
+ // the MMDB according to the delete mask given.
+ void Delete ( word DelMask ); // DelMask is the same as CopyMask
+
+ PTitleContainer GetRemarks();
+ PTitleContainer GetJournal();
+
+ realtype GetResolution(); // -1.0 means no resolution record in file
+
+ int ParseBiomolecules(); // returns the number of biomolecules,
+ // -2 for general format error
+ // -3 for errors in BIOMT records
+ int GetNofBiomolecules();
+ void GetBiomolecules ( PPBiomolecule & BM, int & nBMs );
+
+ PBiomolecule GetBiomolecule ( int bmNo ); // bmno=0,1,..
+ // returns NULL if bmNo is incorrect
+ PManager MakeBiomolecule ( int bmNo, int modelNo=1 );
+
+
+ protected :
+
+ // --------------- Stream I/O -----------------------------
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ };
+
+} // namespace mmdb
+
+#endif
+
diff --git a/mmdb2/mmdb_mask.cpp b/mmdb2/mmdb_mask.cpp
new file mode 100644
index 0000000..dbf9891
--- /dev/null
+++ b/mmdb2/mmdb_mask.cpp
@@ -0,0 +1,240 @@
+// $Id: mmdb_mask.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDBF_Mask <implementation>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+//
+// **** Classes : mmdb::Mask ( atom selection mask )
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "mmdb_mask.h"
+
+namespace mmdb {
+
+ // ==================== Mask ========================
+
+ Mask::Mask() : io::Stream() {
+ InitMask();
+ }
+
+ Mask::Mask ( io::RPStream Object ) : io::Stream(Object) {
+ InitMask();
+ }
+
+ Mask::~Mask() {
+ ClearMask();
+ }
+
+ void Mask::InitMask() {
+ mlen = 0;
+ m = NULL;
+ }
+
+ void Mask::SetMaskBit ( int BitNo ) {
+ int n,i;
+ n = BitNo/(8*sizeof(word));
+ Expand ( n+1 );
+ i = BitNo - n*(8*sizeof(word));
+ m[n] |= ((word)1 << i);
+ }
+
+ void Mask::Expand ( int n ) {
+ wvector m1;
+ int i;
+ if (mlen<n) {
+ m1 = new word[n];
+ for (i=0;i<mlen;i++)
+ m1[i] = m[i];
+ for (i=mlen;i<n;i++)
+ m1[i] = 0;
+ if (m) delete[] m;
+ m = m1;
+ mlen = n;
+ }
+ }
+
+ void Mask::NewMask ( PPMask Mask, int nMasks ) {
+ int i,nlen;
+ word w;
+ ClearMask();
+ if (Mask && (nMasks>0)) {
+ nlen = 0;
+ w = 0;
+ while (w==0) {
+ for (i=0;i<nMasks;i++)
+ if (Mask[i]) {
+ if (nlen<Mask[i]->mlen)
+ w |= Mask[i]->m[nlen];
+ }
+ nlen++;
+ w = ~w;
+ }
+ Expand ( nlen );
+ i = nlen-1;
+ m[i] = 1;
+ while (!(m[i] & w))
+ m[i] <<= 1;
+ } else {
+ Expand ( 1 );
+ m[0] = 1;
+ }
+ }
+
+ void Mask::CopyMask ( PMask Mask ) {
+ int i;
+ if (mlen!=Mask->mlen) ClearMask();
+ if (Mask) {
+ mlen = Mask->mlen;
+ if (mlen>0) {
+ m = new word[mlen];
+ for (i=0;i<mlen;i++)
+ m[i] = Mask->m[i];
+ }
+ }
+ }
+
+ void Mask::SetMask ( PMask Mask ) {
+ int i;
+ if (Mask) {
+ Expand ( Mask->mlen );
+ for (i=0;i<Mask->mlen;i++)
+ m[i] |= Mask->m[i];
+ }
+ }
+
+ void Mask::RemoveMask ( PMask Mask ) {
+ int i,l;
+ if (Mask) {
+ l = IMin(mlen,Mask->mlen);
+ for (i=0;i<l;i++)
+ m[i] &= ~Mask->m[i];
+ }
+ }
+
+ void Mask::SelMask ( PMask Mask ) {
+ int i,l;
+ if (Mask) {
+ l = IMin(mlen,Mask->mlen);
+ for (i=0;i<l;i++)
+ m[i] &= Mask->m[i];
+ for (i=l;i<mlen;i++)
+ m[i] = 0;
+ } else
+ ClearMask();
+ }
+
+ void Mask::XadMask ( PMask Mask ) {
+ int i;
+ if (Mask) {
+ Expand ( Mask->mlen );
+ for (i=0;i<Mask->mlen;i++)
+ m[i] ^= Mask->m[i];
+ }
+ }
+
+ void Mask::ClearMask() {
+ if (m) delete[] m;
+ m = NULL;
+ mlen = 0;
+ }
+
+ void Mask::NegMask() {
+ int i;
+ for (i=0;i<mlen;i++)
+ m[i] = ~m[i];
+ }
+
+ bool Mask::CheckMask ( PMask Mask ) {
+ int i,l;
+ if (Mask) {
+ i = 0;
+ l = IMin(mlen,Mask->mlen);
+ while ((i<l) && (!(m[i] & Mask->m[i]))) i++;
+ return (i<l);
+ } else
+ return false;
+ }
+
+ bool Mask::isMask() {
+ int i=0;
+ while ((i<mlen) && (!m[i])) i++;
+ return (i<mlen);
+ }
+
+ pstr Mask::Print ( pstr S ) {
+ int i,j,k;
+ word w;
+ j = 0;
+ for (i=0;i<mlen;i++) {
+ w = 1;
+ for (k=0;k<8*(int)sizeof(word);k++) {
+ if (w & m[i]) S[j] = '1';
+ else S[j] = '0';
+ w <<= 1;
+ j++;
+ }
+ }
+ S[j] = char(0);
+ return S;
+ }
+
+ void Mask::write ( io::RFile f ) {
+ int i;
+ f.WriteInt ( &mlen );
+ for (i=0;i<mlen;i++)
+ f.WriteWord ( &(m[i]) );
+ }
+
+ void Mask::read ( io::RFile f ) {
+ int i;
+ if (m) {
+ delete[] m;
+ m = NULL;
+ }
+ f.ReadInt ( &mlen );
+ if (mlen>0) {
+ m = new word[mlen];
+ for (i=0;i<mlen;i++)
+ f.ReadWord ( &(m[i]) );
+ }
+ }
+
+ MakeStreamFunctions(Mask)
+
+} // namespace mmdb
+
diff --git a/mmdb/mmdb_mask.h b/mmdb2/mmdb_mask.h
old mode 100755
new mode 100644
similarity index 50%
rename from mmdb/mmdb_mask.h
rename to mmdb2/mmdb_mask.h
index 62930d4..697b328
--- a/mmdb/mmdb_mask.h
+++ b/mmdb2/mmdb_mask.h
@@ -1,10 +1,10 @@
-// $Id: mmdb_mask.h,v 1.19 2012/01/26 17:52:20 ekr Exp $
+// $Id: mmdb_mask.h $
// =================================================================
//
// CCP4 Coordinate Library: support of coordinate-related
// functionality in protein crystallography applications.
//
-// Copyright (C) Eugene Krissinel 2000-2008.
+// Copyright (C) Eugene Krissinel 2000-2013.
//
// This library is free software: you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,7 @@
//
// =================================================================
//
-// 17.11.00 <-- Date of Last Modification.
+// 12.09.13 <-- Date of Last Modification.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// -----------------------------------------------------------------
//
@@ -31,10 +31,10 @@
// **** Project : MacroMolecular Data Base (MMDB)
// ~~~~~~~~~
//
-// **** Classes : CMask ( atom selection mask )
+// **** Classes : mmdb::Mask ( atom selection mask )
// ~~~~~~~~~
//
-// (C) E. Krissinel 2000-2008
+// (C) E. Krissinel 2000-2013
//
// =================================================================
//
@@ -42,56 +42,54 @@
#ifndef __MMDB_Mask__
#define __MMDB_Mask__
+#include "mmdb_io_stream.h"
-#ifndef __Stream__
-#include "stream_.h"
-#endif
-
-
+namespace mmdb {
-// ==================== CMask ========================
+ // ========================== Mask =============================
-DefineClass(CMask)
-DefineStreamFunctions(CMask)
+ DefineClass(Mask);
+ DefineStreamFunctions(Mask);
-class CMask : public CStream {
+ class Mask : public io::Stream {
- public :
+ public :
- CMask ();
- CMask ( RPCStream Object );
- ~CMask();
+ Mask ();
+ Mask ( io::RPStream Object );
+ ~Mask();
- void SetMaskBit ( int BitNo );
- void NewMask ( PPCMask Mask, int nMasks );
+ void SetMaskBit ( int BitNo );
+ void NewMask ( PPMask Mask, int nMasks );
- void CopyMask ( PCMask Mask ); // this = Mask
- void SetMask ( PCMask Mask ); // this = this | Mask
- void RemoveMask ( PCMask Mask ); // this = this & (~Mask)
- void SelMask ( PCMask Mask ); // this = this & Mask
- void XadMask ( PCMask Mask ); // this = this ^ Mask
- void ClearMask (); // this = NULL
- void NegMask (); // this = ~this
+ void CopyMask ( PMask Mask ); // this = Mask
+ void SetMask ( PMask Mask ); // this = this | Mask
+ void RemoveMask ( PMask Mask ); // this = this & (~Mask)
+ void SelMask ( PMask Mask ); // this = this & Mask
+ void XadMask ( PMask Mask ); // this = this ^ Mask
+ void ClearMask (); // this = NULL
+ void NegMask (); // this = ~this
- Boolean CheckMask ( PCMask Mask ); // True if the bit is on
- Boolean isMask (); // true if any mask bit is on
+ bool CheckMask ( PMask Mask ); // true if the bit is on
+ bool isMask (); // true if any mask bit is on
- inline int getLength() { return mlen; }
+ inline int getLength() { return mlen; }
- pstr Print ( pstr S ); // returns binary string
+ pstr Print ( pstr S ); // returns binary string
- void write ( RCFile f );
- void read ( RCFile f );
+ void write ( io::RFile f );
+ void read ( io::RFile f );
- protected :
- int mlen;
- wvector m;
+ protected :
+ int mlen;
+ wvector m;
- void InitMask();
- void Expand ( int n );
+ void InitMask();
+ void Expand ( int n );
-};
+ };
+} // namespace mmdb
#endif
diff --git a/mmdb2/mmdb_math_.cpp b/mmdb2/mmdb_math_.cpp
new file mode 100644
index 0000000..23cfdc8
--- /dev/null
+++ b/mmdb2/mmdb_math_.cpp
@@ -0,0 +1,203 @@
+// $Id: mmdb_math.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 11.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : Math <implementation>
+// ~~~~~~~~~
+// **** Functions : mmdb::math::GetTorsion
+// ~~~~~~~~~~~ mmdb::math::GetAngle
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include <math.h>
+
+#include "mmdb_math_.h"
+
+namespace mmdb {
+
+ namespace math {
+
+ // --------------------------------------------------------------
+
+ realtype GetTorsion ( rvector U, rvector W, rvector V ) {
+ // U W V
+ // o<----o----->o----->o
+ //
+ realtype A[3],B[3],C[3],Wmag,S,T;
+
+ A[0] = U[1]*W[2] - W[1]*U[2];
+ A[1] = U[2]*W[0] - W[2]*U[0];
+ A[2] = U[0]*W[1] - W[0]*U[1];
+
+ B[0] = V[1]*W[2] - W[1]*V[2];
+ B[1] = V[2]*W[0] - W[2]*V[0];
+ B[2] = V[0]*W[1] - W[0]*V[1];
+
+ C[0] = A[1]*B[2] - B[1]*A[2];
+ C[1] = A[2]*B[0] - B[2]*A[0];
+ C[2] = A[0]*B[1] - B[0]*A[1];
+
+ Wmag = sqrt(W[0]*W[0]+W[1]*W[1]+W[2]*W[2]);
+
+ S = C[0]*W[0] + C[1]*W[1] + C[2]*W[2];
+ T = A[0]*B[0] + A[1]*B[1] + A[2]*B[2];
+ T *= Wmag;
+
+ if ((S==0.0) && (T==0.0)) return NO_TORSION;
+ else return atan2(S,T);
+
+ }
+
+
+ realtype GetAngle ( rvector v1, rvector v2 ) {
+ realtype l1,l2;
+
+ l1 = v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2];
+ if (l1==0.0) l1 = 1.0;
+ l2 = v2[0]*v2[0] + v2[1]*v2[1] + v2[2]*v2[2];
+ if (l2==0.0) l2 = 1.0;
+
+ return acos((v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])/sqrt(l1*l2));
+
+ }
+
+
+ #define nCombMax 500
+
+ realtype Combinations ( int n, int m ) {
+ // 0<=n<=nCombMax, 0<=m<=n
+ realtype P[nCombMax+1];
+ int i,j;
+ if ((m<0) || (m>n)) return 0.0;
+ if ((m==0) || (m==n)) return 1.0;
+ if ((m==1) || (m==n-1)) return realtype(n);
+ P[0] = 1.0;
+ P[1] = 3.0;
+ P[2] = 3.0;
+ P[3] = 1.0;
+ for (i=4;i<=n;i++) {
+ P[i] = 1.0;
+ for (j=i-1;j>0;j--)
+ P[j] += P[j-1];
+ }
+ return P[m];
+ }
+
+ realtype log1mx ( realtype x ) {
+ // Calculates precisely log(1-x) for x<1, including
+ // very small x
+ realtype z,z1,z2,n;
+
+ if (x>=1.0-10.0*MachEps) z = -MaxReal;
+ else if (fabs(x)>1.0e-8) z = log(1.0-x);
+ else {
+ z1 = x;
+ z = 0.0;
+ n = 1.0;
+ do {
+ z2 = z;
+ z -= z1/n;
+ z1 *= x;
+ n += 1.0;
+ } while (z!=z2);
+ }
+
+ return z;
+
+ }
+
+ realtype expc ( realtype x ) {
+ // Calculates precisely 1 - exp(x) for any x including
+ // very small values
+ realtype z,z1,z2,n;
+
+ if (x>LnMaxReal) z = -MaxReal;
+ else if (x<-LnMaxReal) z = 1.0;
+ else if (fabs(x)>1.0e-8) z = 1.0 - Exp(x);
+ else {
+ z1 = x;
+ z = x;
+ n = 1.0;
+ do {
+ z2 = z;
+ n += 1.0;
+ z1 *= x/n;
+ z += z1;
+ } while (z!=z2);
+ z = -z;
+ }
+
+ return z;
+
+ }
+
+
+ realtype expc1mx ( realtype x, realtype y ) {
+ // Calculates precisely 1-(1-x)**y including very small x and
+ // very large y
+ realtype z,z1,z2,n,s;
+
+ // Calculate (1-x)**y as exp(y*log(1-x)). Get log(1-x) first:
+ if (x>1.0e-8) z = log(1.0-x);
+ else {
+ z1 = x;
+ z = 0.0;
+ n = 1.0;
+ do {
+ z2 = z;
+ z -= z1/n;
+ z1 *= x;
+ n += 1.0;
+ } while (z!=z2);
+ }
+
+ // Now calculate 1 - exp(y*log(1-x)) :
+ z *= y;
+ if (fabs(z)>1.0e-8) s = 1.0 - exp(z);
+ else {
+ z1 = z;
+ s = z;
+ n = 1.0;
+ do {
+ z2 = s;
+ n += 1.0;
+ z1 *= z/n;
+ s += z1;
+ } while (s!=z2);
+ s = -s;
+ }
+
+ return s;
+
+ }
+
+ }
+
+}
diff --git a/mmdb2/mmdb_math_.h b/mmdb2/mmdb_math_.h
new file mode 100644
index 0000000..70172ee
--- /dev/null
+++ b/mmdb2/mmdb_math_.h
@@ -0,0 +1,77 @@
+// $Id: mmdb_math.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 11.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : Math <interface>
+// ~~~~~~~~~
+// **** Functions : mmdb::math::GetTorsion
+// ~~~~~~~~~~~ mmdb::math::GetAngle
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_Math__
+#define __MMDB_Math__
+
+#include "mmdb_mattype.h"
+
+namespace mmdb {
+
+ namespace math {
+
+ // ------------------------------------------------------------------
+
+ const realtype NO_TORSION = -MaxReal;
+
+ // U[0,1,2] = x,y,z
+ extern realtype GetTorsion ( rvector U, rvector W, rvector V );
+ extern realtype GetAngle ( rvector U, rvector V );
+
+ // Calculates the binomial coefficient n choose m, 0<=n<=500, 0<=m<=n
+ extern realtype Combinations ( int n, int m );
+
+ // Calculates precisely log(1-x) for x<1, including very small x
+ extern realtype log1mx ( realtype x );
+
+ // Calculates precisely 1 - exp(x) for any x including very small values
+ extern realtype expc ( realtype x );
+
+ inline double exp10 ( double x ) { return exp(x*ln10); }
+
+ // Calculates precisely 1-(1-x)**y including very small x and very large y
+ extern realtype expc1mx ( realtype x, realtype y );
+
+ }
+
+}
+
+
+#endif
+
+
diff --git a/mmdb2/mmdb_math_align.cpp b/mmdb2/mmdb_math_align.cpp
new file mode 100644
index 0000000..a974839
--- /dev/null
+++ b/mmdb2/mmdb_math_align.cpp
@@ -0,0 +1,1226 @@
+// $Id: mmdb_math_align.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : Align <implementation>
+// ~~~~~~~~~
+// **** Classes : mmdb::math::Alignment (char strings alignment)
+// ~~~~~~~~~~~~ mmdb::math::Alignment1 (int vectors alignment)
+//
+// (C) E.Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include <string.h>
+#include <math.h>
+
+#include "mmdb_math_align.h"
+
+
+namespace mmdb {
+
+ namespace math {
+
+ // ===================== CAligParams ======================
+
+ AlignParams::AlignParams() : Stream() {
+ InitAlignParams();
+ }
+
+ AlignParams::AlignParams ( io::RPStream Object ) :
+ io::Stream ( Object ) {
+ InitAlignParams();
+ }
+
+ void AlignParams::InitAlignParams() {
+ gapWeight = -1.0;
+ spaceWeight = -1.0;
+ equalScore = 2.0;
+ nequalScore = -1.0;
+ method = ALIGN_GLOBAL;
+ }
+
+ void AlignParams::write ( io::RFile f ) {
+ f.WriteReal ( &gapWeight );
+ f.WriteReal ( &spaceWeight );
+ f.WriteReal ( &equalScore );
+ f.WriteReal ( &nequalScore );
+ f.WriteInt ( &method );
+ }
+
+ void AlignParams::read ( io::RFile f ) {
+ f.ReadReal ( &gapWeight );
+ f.ReadReal ( &spaceWeight );
+ f.ReadReal ( &equalScore );
+ f.ReadReal ( &nequalScore );
+ f.ReadInt ( &method );
+ }
+
+ MakeStreamFunctions(AlignParams)
+
+
+ // ===================== Alignment ======================
+
+ Alignment::Alignment() : io::Stream() {
+ InitAlignment();
+ }
+
+ Alignment::Alignment ( io::RPStream Object ) :
+ io::Stream ( Object ) {
+ InitAlignment();
+ }
+
+ Alignment::~Alignment() {
+ FreeMemory();
+ }
+
+ void Alignment::InitAlignment() {
+ Space = '-';
+ SLen = 0;
+ TLen = 0;
+ VT = NULL;
+ ET = NULL;
+ FT = NULL;
+ AlgnS = NULL;
+ AlgnT = NULL;
+ AlignKey = ALIGN_GLOBAL;
+ VAchieved = 0.0;
+ SEq = 2.0;
+ SNEq = -1.0;
+ Wg = 0.0;
+ Ws = -1.0;
+ }
+
+ void Alignment::FreeMemory() {
+ FreeMatrixMemory ( VT,TLen+1,0,0 );
+ FreeMatrixMemory ( ET,TLen+1,0,0 );
+ FreeMatrixMemory ( FT,TLen+1,0,0 );
+ if (AlgnS) {
+ delete[] AlgnS;
+ AlgnS = NULL;
+ }
+ if (AlgnT) {
+ delete[] AlgnT;
+ AlgnT = NULL;
+ }
+ TLen = 0;
+ SLen = 0;
+ }
+
+ void Alignment::SetAffineModel ( realtype WGap, realtype WSpace ) {
+ Wg = WGap;
+ Ws = WSpace;
+ }
+
+ void Alignment::SetScores ( realtype SEqual, realtype SNEqual ) {
+ SEq = SEqual;
+ SNEq = SNEqual;
+ }
+
+ void Alignment::Align ( cpstr S, cpstr T, ALIGN_METHOD Method ) {
+ int i,j,i0,j0;
+
+ FreeMemory();
+
+ AlignKey = Method;
+
+ switch (Method) {
+
+ default :
+ case ALIGN_GLOBAL : // global pairwise alignment of S and T
+ BuildGATable ( S,T, false,false );
+ VAchieved = VT[TLen][SLen];
+ Backtrace ( S,T,SLen,TLen,false );
+ if ((AlgnS[0]!=Space) && (AlgnT[0]!=Space))
+ VAchieved -= Wg;
+ break;
+
+ case ALIGN_LOCAL : // local pairwise alignment of S and T
+ BuildLATable ( S,T );
+ VAchieved = 0.0;
+ i0 = -1;
+ j0 = -1;
+ for (i=0;i<=TLen;i++)
+ for (j=0;j<=SLen;j++)
+ if (VT[i][j]>VAchieved) {
+ VAchieved = VT[i][j];
+ i0 = i;
+ j0 = j;
+ }
+ Backtrace ( S,T,j0,i0,true );
+ break;
+
+ case ALIGN_GLOBLOC : // global alignment with non-penalized
+ // end gaps in T
+ BuildGATable ( S,T,false,true );
+ VAchieved = -MaxReal;
+ i0 = -1;
+ j0 = -1;
+ for (i=0;i<=TLen;i++)
+ if (VT[i][SLen]>VAchieved) {
+ VAchieved = VT[i][SLen];
+ i0 = i;
+ j0 = SLen;
+ }
+ Backtrace ( S,T,j0,i0,false );
+ AdjustEnds ( S,T,j0,i0 );
+ break;
+
+ case ALIGN_FREEENDS : // global alignment with non-penalized
+ // end gaps in both S and T
+ BuildGATable ( S,T,true,true );
+ VAchieved = -MaxReal;
+ i0 = -1;
+ j0 = -1;
+ for (i=0;i<=TLen;i++)
+ if (VT[i][SLen]>VAchieved) {
+ VAchieved = VT[i][SLen];
+ i0 = i;
+ j0 = SLen;
+ }
+ for (j=0;j<=SLen;j++)
+ if (VT[TLen][j]>VAchieved) {
+ VAchieved = VT[TLen][j];
+ i0 = TLen;
+ j0 = j;
+ }
+ Backtrace ( S,T,j0,i0,false );
+ AdjustEnds ( S,T,j0,i0 );
+
+ }
+
+ }
+
+
+ void Alignment::BuildGATable ( cpstr S, cpstr T,
+ bool FreeSEnd, bool FreeTEnd ) {
+ int i,j;
+ realtype V1;
+
+ SLen = strlen ( S );
+ TLen = strlen ( T );
+ GetMatrixMemory ( VT,TLen+1,SLen+1,0,0 );
+ GetMatrixMemory ( ET,TLen+1,SLen+1,0,0 );
+ GetMatrixMemory ( FT,TLen+1,SLen+1,0,0 );
+
+ // Base conditions
+ if (FreeSEnd || FreeTEnd) VT[0][0] = RMax(0.0,Wg);
+ else VT[0][0] = Wg;
+ ET[0][0] = VT[0][0];
+ FT[0][0] = VT[0][0];
+
+ if (FreeTEnd)
+ for (i=1;i<=TLen;i++) {
+ V1 = RMax ( 0.0,VT[i-1][0]+Ws );
+ VT[i][0] = V1;
+ ET[i][0] = V1;
+ }
+ else
+ for (i=1;i<=TLen;i++) {
+ V1 = VT[i-1][0] + Ws;
+ VT[i][0] = V1;
+ ET[i][0] = V1;
+ }
+
+ if (FreeSEnd)
+ for (j=1;j<=SLen;j++) {
+ V1 = RMax ( 0.0,VT[0][j-1]+Ws );
+ VT[0][j] = V1;
+ FT[0][j] = V1;
+ }
+ else
+ for (j=1;j<=SLen;j++) {
+ V1 = VT[0][j-1] + Ws;
+ VT[0][j] = V1;
+ FT[0][j] = V1;
+ }
+
+ // Recurrence
+ for (i=1;i<=TLen;i++)
+ for (j=1;j<=SLen;j++) {
+ V1 = VT[i-1][j-1] + Score(T[i-1],S[j-1]);
+ ET[i][j] = RMax ( ET[i][j-1]+Ws,VT[i][j-1]+Wg+Ws );
+ FT[i][j] = RMax ( FT[i-1][j]+Ws,VT[i-1][j]+Wg+Ws );
+ VT[i][j] = RMax ( RMax(V1,ET[i][j]),FT[i][j] );
+ }
+
+ FreeMatrixMemory ( ET,TLen+1,0,0 );
+ FreeMatrixMemory ( FT,TLen+1,0,0 );
+
+ // PrintVT ( S,T );
+
+ }
+
+
+ void Alignment::BuildLATable ( cpstr S, cpstr T ) {
+ int i,j;
+ realtype V1;
+
+ SLen = strlen ( S );
+ TLen = strlen ( T );
+ GetMatrixMemory ( VT,TLen+1,SLen+1,0,0 );
+ GetMatrixMemory ( ET,TLen+1,SLen+1,0,0 );
+ GetMatrixMemory ( FT,TLen+1,SLen+1,0,0 );
+
+ // Base conditions
+ VT[0][0] = RMax ( 0.0,Wg );
+ ET[0][0] = VT[0][0];
+ FT[0][0] = VT[0][0];
+ for (i=1;i<=TLen;i++) {
+ V1 = RMax ( 0.0,VT[i-1][0]+Ws );
+ VT[i][0] = V1;
+ ET[i][0] = V1;
+ }
+ for (j=1;j<=SLen;j++) {
+ V1 = RMax ( 0.0,VT[0][j-1]+Ws );
+ VT[0][j] = V1;
+ FT[0][j] = V1;
+ }
+
+ // Recurrence
+ for (i=1;i<=TLen;i++)
+ for (j=1;j<=SLen;j++) {
+ V1 = VT[i-1][j-1] + Score(T[i-1],S[j-1]);
+ ET[i][j] = RMax ( ET[i][j-1]+Ws,VT[i][j-1]+Wg+Ws );
+ FT[i][j] = RMax ( FT[i-1][j]+Ws,VT[i-1][j]+Wg+Ws );
+ VT[i][j] = RMax ( RMax(V1,ET[i][j]),RMax(0.0,FT[i][j]) );
+ }
+
+ FreeMatrixMemory ( ET,TLen+1,0,0 );
+ FreeMatrixMemory ( FT,TLen+1,0,0 );
+
+ // PrintVT ( S,T );
+
+ }
+
+ void Alignment::PrintVT ( cpstr S, cpstr T ) {
+ int i,j;
+ printf ( "\n " );
+ for (j=0;j<=SLen;j++)
+ printf ( " %2i",j );
+ printf ( " \n " );
+ for (j=1;j<=SLen;j++)
+ printf ( " %c ",S[j-1] );
+ printf ( " \n\n " );
+ for (i=0;i<=TLen;i++) {
+ if (i>0) printf ( " %2i %c ",i,T[i-1] );
+ else printf ( " %2i ",i );
+ for (j=0;j<=SLen;j++)
+ printf ( " %2i",mround(VT[i][j]) );
+ printf ( " \n " );
+ }
+ printf ( " \n" );
+ }
+
+
+ void Alignment::Backtrace ( cpstr S, cpstr T, int J, int I,
+ bool StopAtZero ) {
+ int i,j,k, i1,j1, sk,tk;
+ char C;
+ realtype V,SV,TV;
+ bool Stop;
+
+ // 1. Allocate memory
+
+ if (AlgnS) delete[] AlgnS;
+ if (AlgnT) delete[] AlgnT;
+
+ i = SLen+TLen+1;
+ AlgnS = new char[i];
+ AlgnT = new char[i];
+ memset ( AlgnS,Space,i );
+ memset ( AlgnT,Space,i );
+
+ // 2. Initialize backtracing
+ i = I; // backtracing
+ j = J; // indices
+ k = 0; // alignment index
+ SV = 0.0; sk = -1; // alignment indices and leading elements
+ TV = 0.0; tk = -1; // for vertical and horizontal sections
+
+
+ // 3. Backtracing
+ Stop = false;
+ while ((!Stop) && (i>0) && (j>0)) {
+
+ V = VT[i][j];
+
+ // find next leading element
+ if (VT[i][j-1]>VT[i-1][j]) {
+ i1 = i; j1 = j-1;
+ } else {
+ i1 = i-1; j1 = j;
+ }
+ if (VT[i-1][j-1]>=VT[i1][j1]) {
+ i1 = i-1; j1 = j-1;
+ }
+
+ //printf ( " i=%i j=%i \n",i,j );
+
+ Stop = StopAtZero && (VT[i1][j1]<=0.0); // used at local alignment
+
+ // treat horizontal section
+ if ((sk<0) || (V>SV)) {
+ sk = k;
+ SV = V;
+ }
+ if ((j1!=j) || Stop) { // end of horizontal section
+ AlgnS[sk] = S[j-1];
+ sk = -1;
+ }
+
+ // treat vertical section
+ if ((tk<0) || (V>TV)) {
+ tk = k;
+ TV = V;
+ }
+ if ((i1!=i) || Stop) { // end of vertical section
+ AlgnT[tk] = T[i-1];
+ tk = -1;
+ }
+
+ i = i1;
+ j = j1;
+ k++;
+
+ }
+
+ if (!StopAtZero) {
+ // 4. Finish the last horizontal section
+ sk = k;
+ while (j>0) AlgnS[k++] = S[--j];
+ // 5. Finish the last vertical section
+ while (i>0) AlgnT[sk++] = T[--i];
+ k = IMax ( k,sk );
+ }
+
+ // 6. Put the termination character
+ AlgnS[k] = char(0);
+ AlgnT[k] = char(0);
+
+ // 7. Reverse the strings
+ i = 0;
+ j = k-1;
+ if (StopAtZero) {
+ // should work only for local alignment
+ while ((j>0) && ((AlgnS[j]==Space) || (AlgnT[j]==Space))) j--;
+ k = j+1;
+ AlgnS[k] = char(0);
+ AlgnT[k] = char(0);
+ }
+ while (j>i) {
+ C = AlgnS[i]; AlgnS[i] = AlgnS[j]; AlgnS[j] = C;
+ C = AlgnT[i]; AlgnT[i] = AlgnT[j]; AlgnT[j] = C;
+ i++;
+ j--;
+ }
+
+ // 8. Collapse the alternating spaces
+ do {
+ k = 0;
+ i = 0;
+ while (AlgnS[k]) {
+ if ((AlgnS[k]==Space) && (AlgnT[k]==Space)) k++;
+ else if ((AlgnS[k]==Space) && (AlgnS[k+1]!=Space) &&
+ (AlgnT[k]!=Space) && (AlgnT[k+1]==Space)) {
+ AlgnS[i] = AlgnS[k+1];
+ AlgnT[i] = AlgnT[k];
+ k++;
+ } else if ((AlgnS[k]!=Space) && (AlgnS[k+1]==Space) &&
+ (AlgnT[k]==Space) && (AlgnT[k+1]!=Space)) {
+ AlgnS[i] = AlgnS[k];
+ AlgnT[i] = AlgnT[k+1];
+ k++;
+ } else if (i!=k) {
+ AlgnS[i] = AlgnS[k];
+ AlgnT[i] = AlgnT[k];
+ }
+ if (AlgnS[k]) {
+ k++;
+ i++;
+ }
+ }
+ if (i!=k) { // terminating character
+ AlgnS[i] = AlgnS[k];
+ AlgnT[i] = AlgnT[k];
+ }
+ } while (k>i);
+
+ }
+
+
+ void Alignment::AdjustEnds ( cpstr S, cpstr T, int J, int I ) {
+ int si,ti,m;
+
+ if (J<SLen) strcat ( AlgnS,&(S[J]) );
+ if (I<TLen) strcat ( AlgnT,&(T[I]) );
+ si = strlen ( AlgnS );
+ ti = strlen ( AlgnT );
+ m = IMax ( si,ti );
+ while (si<m) AlgnS[si++] = Space;
+ while (ti<m) AlgnT[ti++] = Space;
+ AlgnS[si] = char(0);
+ AlgnT[ti] = char(0);
+
+ /*
+ int k,m;
+
+ if (J>I) {
+ k = J-I;
+ strcat ( AlgnT,&(T[IMax(0,TLen-k)]) );
+ k = strlen ( AlgnS );
+ m = strlen ( AlgnT );
+ while (k<m)
+ AlgnS[k++] = Space;
+ AlgnS[k] = char(0);
+ } else if (I>J) {
+ k = I-J;
+ strcat ( AlgnS,&(S[IMax(0,SLen-k)]) );
+ k = strlen ( AlgnT );
+ m = strlen ( AlgnS );
+ while (k<m)
+ AlgnT[k++] = Space;
+ AlgnT[k] = char(0);
+ }
+ */
+
+ }
+
+
+ realtype Alignment::Score ( char A, char B ) {
+ if (A==B) return SEq;
+ if ((A==Space) || (B==Space)) return Ws;
+ return SNEq;
+ }
+
+ realtype Alignment::GetSimilarity() {
+ realtype s,a;
+ int i,n;
+
+ s = 0.0;
+ a = 0.0;
+ n = IMin ( strlen(AlgnS),strlen(AlgnT) );
+
+ for (i=0;i<n;i++)
+ if ((AlgnS[i]!=Space) || (AlgnT[i]!=Space)) {
+ a += RMax ( Score(AlgnS[i],AlgnS[i]),Score(AlgnT[i],AlgnT[i]) );
+ s += Score ( AlgnS[i],AlgnT[i] );
+ }
+
+ if ((s>0.0) && (a>0.0)) return s/a;
+ return 0.0;
+
+ }
+
+
+ realtype Alignment::GetSeqId() {
+ realtype s;
+ int i,n,ne,ns,nt;
+
+ ne = 0;
+ ns = 0;
+ nt = 0;
+ n = IMin ( strlen(AlgnS),strlen(AlgnT) );
+
+ for (i=0;i<n;i++) {
+ if (AlgnS[i]!=Space) ns++;
+ if (AlgnT[i]!=Space) {
+ nt++;
+ if (AlgnS[i]==AlgnT[i])
+ ne++;
+ }
+ }
+
+ s = IMin ( ns,nt );
+ if (s>0.0) return ne/s;
+ return 0.0;
+
+ }
+
+
+ #define WrapPeriod 61
+
+ void Alignment::OutputResults ( io::RFile f, cpstr S, cpstr T ) {
+ int k,l,n;
+ char P[3];
+
+ P[1] = char(0);
+ if ((!AlgnS) || (!AlgnT)) {
+ f.LF();
+ f.WriteLine ( pstr(" NO ALIGNMENT HAS BEEN DONE.") );
+ f.shut();
+ return;
+ }
+ f.LF();
+ f.WriteLine ( pstr(" ======== INPUT DATA") );
+ f.LF();
+ f.WriteLine ( pstr(" String S:") );
+ f.Write ( pstr(" ") );
+ l = 1;
+ k = 0;
+ while (S[k]) {
+ P[0] = S[k++];
+ f.Write ( P );
+ l++;
+ if (l>=WrapPeriod) {
+ f.LF(); f.Write ( pstr(" ") ); l = 1;
+ }
+ }
+ f.LF();
+ f.LF();
+ f.WriteLine ( pstr(" String T:") );
+ f.Write ( pstr(" ") );
+ l = 1;
+ k = 0;
+ while (T[k]) {
+ P[0] = T[k++];
+ f.Write ( P );
+ l++;
+ if (l>=WrapPeriod) {
+ f.LF(); f.Write ( pstr(" ") ); l = 1;
+ }
+ }
+ f.LF();
+ f.LF();
+ f.WriteParameter ( pstr(" Score equal") ,SEq ,20,10 );
+ f.WriteParameter ( pstr(" Score unequal"),SNEq,20,10 );
+ f.LF();
+ f.WriteParameter ( pstr(" Gap weight") ,Wg ,20,10 );
+ f.WriteParameter ( pstr(" Space weight") ,Ws ,20,10 );
+ f.LF();
+ f.LF();
+ f.Write ( pstr(" ======== RESULT OF ") );
+ switch (AlignKey) {
+ default :
+ case ALIGN_GLOBAL : f.Write ( pstr("GLOBAL") ); break;
+ case ALIGN_LOCAL : f.Write ( pstr("LOCAL") ); break;
+ case ALIGN_GLOBLOC : f.Write ( pstr("GLOBAL/LOCAL") ); break;
+ case ALIGN_FREEENDS : f.Write ( pstr("FREE-ENDS") );
+ }
+ f.WriteLine ( pstr(" ALIGNMENT") );
+ f.LF();
+ if (AlignKey==ALIGN_GLOBLOC) {
+ f.WriteLine ( pstr(" End gaps in T-string were not penalized") );
+ f.LF();
+ }
+ f.WriteParameter ( pstr(" Highest score achieved:"),VAchieved,26,10 );
+ f.LF();
+ f.WriteLine ( pstr(" Aligned S (upper string) and T (lower string):") );
+ f.LF();
+ k = 0;
+ n = 0;
+ l = 1; f.Write ( pstr(" ") );
+ while (AlgnS[k]) {
+ P[0] = AlgnS[k++];
+ f.Write ( P );
+ l++;
+ if ((l>=WrapPeriod) || (!AlgnS[k])) {
+ f.LF(); f.Write ( pstr(" ") ); l = 1;
+ while (AlgnT[n] && (l<WrapPeriod)) {
+ P[0] = AlgnT[n++];
+ f.Write ( P );
+ l++;
+ }
+ f.LF(); f.LF(); f.Write ( pstr(" ") ); l = 1;
+ }
+ }
+
+ }
+
+
+ // ----------------- Streaming -----------------------------
+
+ void Alignment::write ( io::RFile f ) {
+ int Version=1;
+ f.WriteFile ( &Version,sizeof(Version) );
+ Stream::write ( f );
+ }
+
+ void Alignment::read ( io::RFile f ) {
+ int Version;
+ f.ReadFile ( &Version,sizeof(Version) );
+ Stream::write ( f );
+ }
+
+
+
+ // ===================== Alignment1 ======================
+
+ Alignment1::Alignment1() : io::Stream() {
+ InitAlignment1();
+ }
+
+ Alignment1::Alignment1 ( io::RPStream Object ) :
+ io::Stream ( Object ) {
+ InitAlignment1();
+ }
+
+ Alignment1::~Alignment1() {
+ FreeMemory();
+ }
+
+ void Alignment1::InitAlignment1() {
+ Space = 0;
+ SLen = 0;
+ TLen = 0;
+ AlgnLen = 0;
+ VT = NULL;
+ ET = NULL;
+ FT = NULL;
+ AlgnS = NULL;
+ AlgnT = NULL;
+ AlignKey = ALIGN_GLOBAL;
+ VAchieved = 0.0;
+ SEq = 2.0;
+ SNEq = -1.0;
+ Wg = 0.0;
+ Ws = -1.0;
+ }
+
+ void Alignment1::FreeMemory() {
+ FreeMatrixMemory ( VT,TLen+1,0,0 );
+ FreeMatrixMemory ( ET,TLen+1,0,0 );
+ FreeMatrixMemory ( FT,TLen+1,0,0 );
+ FreeVectorMemory ( AlgnS,0 );
+ FreeVectorMemory ( AlgnT,0 );
+ TLen = 0;
+ SLen = 0;
+ AlgnLen = 0;
+ }
+
+ void Alignment1::SetAffineModel ( realtype WGap, realtype WSpace ) {
+ Wg = WGap;
+ Ws = WSpace;
+ }
+
+ void Alignment1::SetScores ( realtype SEqual, realtype SNEqual ) {
+ SEq = SEqual;
+ SNEq = SNEqual;
+ }
+
+ void Alignment1::Align ( ivector S, int SLength,
+ ivector T, int TLength,
+ ALIGN_METHOD Method ) {
+ int i,j,i0,j0;
+
+ FreeMemory();
+
+ SLen = SLength;
+ TLen = TLength;
+
+ AlignKey = Method;
+
+ switch (Method) {
+
+ default :
+ case ALIGN_GLOBAL : // global pairwise alignment of S and T
+ BuildGATable ( S,T, false,false );
+ VAchieved = VT[TLen][SLen];
+ Backtrace ( S,T,SLen,TLen,false );
+ if ((AlgnS[0]!=Space) && (AlgnT[0]!=Space))
+ VAchieved -= Wg;
+ break;
+
+ case ALIGN_LOCAL : // local pairwise alignment of S and T
+ BuildLATable ( S,T );
+ VAchieved = 0.0;
+ i0 = -1;
+ j0 = -1;
+ for (i=0;i<=TLen;i++)
+ for (j=0;j<=SLen;j++)
+ if (VT[i][j]>VAchieved) {
+ VAchieved = VT[i][j];
+ i0 = i;
+ j0 = j;
+ }
+ Backtrace ( S,T,j0,i0,true );
+ break;
+
+ case ALIGN_GLOBLOC : // global alignment with non-penalized
+ // end gaps in T
+ BuildGATable ( S,T,false,true );
+ VAchieved = -MaxReal;
+ i0 = -1;
+ j0 = -1;
+ for (i=0;i<=TLen;i++)
+ if (VT[i][SLen]>VAchieved) {
+ VAchieved = VT[i][SLen];
+ i0 = i;
+ j0 = SLen;
+ }
+ Backtrace ( S,T,j0,i0,false );
+ AdjustEnds ( S,T,j0,i0 );
+ break;
+
+ case ALIGN_FREEENDS : // global alignment with non-penalized
+ // end gaps in both S and T
+ BuildGATable ( S,T,true,true );
+ VAchieved = -MaxReal;
+ i0 = -1;
+ j0 = -1;
+ for (i=0;i<=TLen;i++)
+ if (VT[i][SLen]>VAchieved) {
+ VAchieved = VT[i][SLen];
+ i0 = i;
+ j0 = SLen;
+ }
+ for (j=0;j<=SLen;j++)
+ if (VT[TLen][j]>VAchieved) {
+ VAchieved = VT[TLen][j];
+ i0 = TLen;
+ j0 = j;
+ }
+ Backtrace ( S,T,j0,i0,false );
+ AdjustEnds ( S,T,j0,i0 );
+ }
+
+ }
+
+
+ void Alignment1::BuildGATable ( ivector S, ivector T,
+ bool FreeSEnd, bool FreeTEnd ) {
+ int i,j;
+ realtype V1;
+
+ GetMatrixMemory ( VT,TLen+1,SLen+1,0,0 );
+ GetMatrixMemory ( ET,TLen+1,SLen+1,0,0 );
+ GetMatrixMemory ( FT,TLen+1,SLen+1,0,0 );
+
+ // Base conditions
+ if (FreeSEnd || FreeTEnd) VT[0][0] = RMax(0.0,Wg);
+ else VT[0][0] = Wg;
+ ET[0][0] = VT[0][0];
+ FT[0][0] = VT[0][0];
+
+ if (FreeTEnd)
+ for (i=1;i<=TLen;i++) {
+ V1 = RMax ( 0.0,VT[i-1][0]+Ws );
+ VT[i][0] = V1;
+ ET[i][0] = V1;
+ }
+ else
+ for (i=1;i<=TLen;i++) {
+ V1 = VT[i-1][0] + Ws;
+ VT[i][0] = V1;
+ ET[i][0] = V1;
+ }
+
+ if (FreeSEnd)
+ for (j=1;j<=SLen;j++) {
+ V1 = RMax ( 0.0,VT[0][j-1]+Ws );
+ VT[0][j] = V1;
+ FT[0][j] = V1;
+ }
+ else
+ for (j=1;j<=SLen;j++) {
+ V1 = VT[0][j-1] + Ws;
+ VT[0][j] = V1;
+ FT[0][j] = V1;
+ }
+
+ // Recurrence
+ for (i=1;i<=TLen;i++)
+ for (j=1;j<=SLen;j++) {
+ V1 = VT[i-1][j-1] + Score(T[i-1],S[j-1]);
+ ET[i][j] = RMax ( ET[i][j-1]+Ws,VT[i][j-1]+Wg+Ws );
+ FT[i][j] = RMax ( FT[i-1][j]+Ws,VT[i-1][j]+Wg+Ws );
+ VT[i][j] = RMax ( RMax(V1,ET[i][j]),FT[i][j] );
+ }
+
+ FreeMatrixMemory ( ET,TLen+1,0,0 );
+ FreeMatrixMemory ( FT,TLen+1,0,0 );
+
+ // PrintVT ( S,T );
+
+ }
+
+
+ void Alignment1::BuildLATable ( ivector S, ivector T ) {
+ int i,j;
+ realtype V1;
+
+ GetMatrixMemory ( VT,TLen+1,SLen+1,0,0 );
+ GetMatrixMemory ( ET,TLen+1,SLen+1,0,0 );
+ GetMatrixMemory ( FT,TLen+1,SLen+1,0,0 );
+
+ // Base conditions
+ VT[0][0] = RMax ( 0.0,Wg );
+ ET[0][0] = VT[0][0];
+ FT[0][0] = VT[0][0];
+ for (i=1;i<=TLen;i++) {
+ V1 = RMax ( 0.0,VT[i-1][0]+Ws );
+ VT[i][0] = V1;
+ ET[i][0] = V1;
+ }
+ for (j=1;j<=SLen;j++) {
+ V1 = RMax ( 0.0,VT[0][j-1]+Ws );
+ VT[0][j] = V1;
+ FT[0][j] = V1;
+ }
+
+ // Recurrence
+ for (i=1;i<=TLen;i++)
+ for (j=1;j<=SLen;j++) {
+ V1 = VT[i-1][j-1] + Score(T[i-1],S[j-1]);
+ ET[i][j] = RMax ( ET[i][j-1]+Ws,VT[i][j-1]+Wg+Ws );
+ FT[i][j] = RMax ( FT[i-1][j]+Ws,VT[i-1][j]+Wg+Ws );
+ VT[i][j] = RMax ( RMax(V1,ET[i][j]),RMax(0.0,FT[i][j]) );
+ }
+
+ FreeMatrixMemory ( ET,TLen+1,0,0 );
+ FreeMatrixMemory ( FT,TLen+1,0,0 );
+
+ // PrintVT ( S,T );
+
+ }
+
+ void Alignment1::PrintVT ( ivector S, ivector T ) {
+ int i,j;
+ printf ( "\n " );
+ for (j=0;j<=SLen;j++)
+ printf ( " %2i",j );
+ printf ( " \n " );
+ for (j=1;j<=SLen;j++)
+ printf ( " %3i ",S[j-1] );
+ printf ( " \n\n " );
+ for (i=0;i<=TLen;i++) {
+ if (i>0) printf ( " %2i %3i ",i,T[i-1] );
+ else printf ( " %2i ",i );
+ for (j=0;j<=SLen;j++)
+ printf ( " %2i",mround(VT[i][j]) );
+ printf ( " \n " );
+ }
+ printf ( " \n" );
+ }
+
+
+ void Alignment1::Backtrace ( ivector S, ivector T, int J, int I,
+ bool StopAtZero ) {
+ int i,j,k, i1,j1, sk,tk;
+ int C;
+ realtype V,SV,TV;
+ bool Stop;
+
+ // 1. Allocate memory
+
+ FreeVectorMemory ( AlgnS,0 );
+ FreeVectorMemory ( AlgnT,0 );
+ AlgnLen = 0;
+
+ k = SLen+TLen+1;
+ GetVectorMemory ( AlgnS,k,0 );
+ GetVectorMemory ( AlgnT,k,0 );
+ for (i=0;i<k;i++) {
+ AlgnS[i] = Space;
+ AlgnT[i] = Space;
+ }
+
+ // 2. Initialize backtracing
+ i = I; // backtracing
+ j = J; // indices
+
+ k = 0; // alignment index
+ SV = 0.0; sk = -1; // alignment indices and leading elements
+ TV = 0.0; tk = -1; // for vertical and horizontal sections
+
+
+ // 3. Backtracing
+ Stop = false;
+ while ((!Stop) && (i>0) && (j>0)) {
+
+ V = VT[i][j];
+
+ // find next leading element
+ if (VT[i][j-1]>VT[i-1][j]) {
+ i1 = i; j1 = j-1;
+ } else {
+ i1 = i-1; j1 = j;
+ }
+ if (VT[i-1][j-1]>=VT[i1][j1]) {
+ i1 = i-1; j1 = j-1;
+ }
+
+ Stop = StopAtZero && (VT[i1][j1]<=0.0); // used at local alignment
+
+ // treat horizontal section
+ if ((sk<0) || (V>SV)) {
+ sk = k;
+ SV = V;
+ }
+ if ((j1!=j) || Stop) { // end of horizontal section
+ AlgnS[sk] = S[j-1];
+ sk = -1;
+ }
+
+ // treat vertical section
+ if ((tk<0) || (V>TV)) {
+ tk = k;
+ TV = V;
+ }
+ if ((i1!=i) || Stop) { // end of vertical section
+ AlgnT[tk] = T[i-1];
+ tk = -1;
+ }
+
+ i = i1;
+ j = j1;
+ k++;
+
+ }
+
+ if (!StopAtZero) {
+ // 4. Finish the last horizontal section
+ sk = k;
+ while (j>0) AlgnS[k++] = S[--j];
+ // 5. Finish the last vertical section
+ while (i>0) AlgnT[sk++] = T[--i];
+ k = IMax ( k,sk );
+ }
+
+ // 6. Put the termination character
+ AlgnLen = k;
+
+ // 7. Reverse the strings
+ i = 0;
+ j = k-1;
+ if (StopAtZero) {
+ // should work only for local alignment
+ while ((j>0) && ((AlgnS[j]==Space) || (AlgnT[j]==Space))) j--;
+ AlgnLen = j+1;
+ }
+ while (j>i) {
+ C = AlgnS[i]; AlgnS[i] = AlgnS[j]; AlgnS[j] = C;
+ C = AlgnT[i]; AlgnT[i] = AlgnT[j]; AlgnT[j] = C;
+ i++;
+ j--;
+ }
+
+ // 8. Filter out parasite spaces
+ k = 0;
+ i = 0;
+ while (k<AlgnLen) {
+ while ((k<AlgnLen) && (AlgnS[k]==Space) && (AlgnT[k]==Space)) k++;
+ if (k<AlgnLen) {
+ AlgnS[i] = AlgnS[k];
+ AlgnT[i] = AlgnT[k];
+ k++;
+ i++;
+ }
+ }
+
+ AlgnLen = i;
+
+ // 9. Collapse the alternating spaces
+ do {
+
+ k = 0;
+ i = 0;
+ while (k<AlgnLen) {
+ if ((AlgnS[k]==Space) && (AlgnT[k]==Space)) k++;
+ else if ((k+1<AlgnLen) &&
+ (AlgnS[k]==Space) && (AlgnS[k+1]!=Space) &&
+ (AlgnT[k]!=Space) && (AlgnT[k+1]==Space)) {
+ AlgnS[i] = AlgnS[k+1];
+ AlgnT[i] = AlgnT[k];
+ k++;
+ } else if ((k+1<AlgnLen) &&
+ (AlgnS[k]!=Space) && (AlgnS[k+1]==Space) &&
+ (AlgnT[k]==Space) && (AlgnT[k+1]!=Space)) {
+ AlgnS[i] = AlgnS[k];
+ AlgnT[i] = AlgnT[k+1];
+ k++;
+ } else if (i!=k) {
+ AlgnS[i] = AlgnS[k];
+ AlgnT[i] = AlgnT[k];
+ }
+ if (k<AlgnLen) {
+ k++;
+ i++;
+ }
+ }
+
+ AlgnLen = i;
+
+ } while (k>i);
+
+
+ }
+
+
+ void Alignment1::AdjustEnds ( ivector S, ivector T, int J, int I ) {
+ int is,it;
+ is = J;
+ it = I;
+ while ((is<SLen) || (it<TLen)) {
+ if (is<SLen) AlgnS[AlgnLen] = S[is];
+ else AlgnS[AlgnLen] = Space;
+ if (it<TLen) AlgnT[AlgnLen] = T[it];
+ else AlgnT[AlgnLen] = Space;
+ is++;
+ it++;
+ AlgnLen++;
+ }
+ }
+
+ realtype Alignment1::Score ( int A, int B ) {
+ if (A==B) {
+ if (A==Space) return 0.0;
+ else return SEq;
+ }
+ if ((A==Space) || (B==Space)) return Ws;
+ return SNEq;
+ }
+
+
+ realtype Alignment1::GetSimilarity() {
+ realtype s,a;
+ int i;
+
+ s = 0.0;
+ a = 0.0;
+
+ for (i=0;i<AlgnLen;i++)
+ if ((AlgnS[i]!=Space) || (AlgnT[i]!=Space)) {
+ a += RMax ( Score(AlgnS[i],AlgnS[i]),Score(AlgnT[i],AlgnT[i]) );
+ s += Score ( AlgnS[i],AlgnT[i] );
+ }
+
+ if ((s>0.0) && (a>0.0)) return s/a;
+ return 0.0;
+
+ }
+
+
+ void Alignment1::OutputResults ( io::RFile f, ivector S, int lenS,
+ ivector T, int lenT ) {
+ int k,l,n;
+ char P[10];
+
+ if ((!AlgnS) || (!AlgnT)) {
+ f.LF();
+ f.WriteLine ( pstr(" NO ALIGNMENT HAS BEEN DONE.") );
+ f.shut();
+ return;
+ }
+ f.LF();
+ f.WriteLine ( pstr(" ======== INPUT DATA") );
+ f.LF();
+ f.WriteLine ( pstr(" String S:") );
+ f.Write ( pstr(" ") );
+ l = 1;
+ k = 0;
+ while (k<lenS) {
+ sprintf ( P,"%4i ",S[k++] );
+ f.Write ( P );
+ l += 5;
+ if (l>=WrapPeriod) {
+ f.LF(); f.Write ( pstr(" ") ); l = 1;
+ }
+ }
+ f.LF();
+ f.LF();
+ f.WriteLine ( pstr(" String T:") );
+ f.Write ( pstr(" ") );
+ l = 1;
+ k = 0;
+ while (k<lenT) {
+ sprintf ( P,"%4i ",T[k++] );
+ f.Write ( P );
+ l += 5;
+ if (l>=WrapPeriod) {
+ f.LF(); f.Write ( pstr(" ") ); l = 1;
+ }
+ }
+ f.LF();
+ f.LF();
+ f.WriteParameter ( pstr(" Score equal") ,SEq ,20,10 );
+ f.WriteParameter ( pstr(" Score unequal"),SNEq,20,10 );
+ f.LF();
+ f.WriteParameter ( pstr(" Gap weight") ,Wg ,20,10 );
+ f.WriteParameter ( pstr(" Space weight") ,Ws ,20,10 );
+ f.LF();
+ f.LF();
+ f.Write ( pstr(" ======== RESULT OF ") );
+ switch (AlignKey) {
+ default :
+ case ALIGN_GLOBAL : f.Write ( pstr("GLOBAL") ); break;
+ case ALIGN_LOCAL : f.Write ( pstr("LOCAL") ); break;
+ case ALIGN_GLOBLOC : f.Write ( pstr("GLOBAL/LOCAL") ); break;
+ case ALIGN_FREEENDS : f.Write ( pstr("FREE-ENDS") );
+ }
+ f.WriteLine ( pstr(" ALIGNMENT") );
+ f.LF();
+ if (AlignKey==ALIGN_GLOBLOC) {
+ f.WriteLine ( pstr(" End gaps in T-string were not penalized") );
+ f.LF();
+ }
+ f.WriteParameter ( pstr(" Highest score achieved:"),
+ VAchieved,26,10 );
+ f.LF();
+ f.WriteLine ( pstr(" Aligned S (upper string) and T "
+ "(lower string):") );
+ f.LF();
+ k = 0;
+ n = 0;
+ l = 1; f.Write ( pstr(" ") );
+ while (k<AlgnLen) {
+ sprintf ( P,"%4i ",AlgnS[k++] );
+ f.Write ( P );
+ l += 5;
+ if ((l>=WrapPeriod) || (!AlgnS[k])) {
+ f.LF(); f.Write ( pstr(" ") ); l = 1;
+ while ((n<AlgnLen) && (l<WrapPeriod)) {
+ sprintf ( P,"%4i ",AlgnT[n++] );
+ f.Write ( P );
+ l += 5;
+ }
+ f.LF(); f.LF(); f.Write ( pstr(" ") ); l = 1;
+ }
+ }
+
+ }
+
+
+ // ----------------- Streaming -----------------------------
+
+ void Alignment1::write ( io::RFile f ) {
+ int Version=1;
+ f.WriteFile ( &Version,sizeof(Version) );
+ Stream::write ( f );
+ }
+
+ void Alignment1::read ( io::RFile f ) {
+ int Version;
+ f.ReadFile ( &Version,sizeof(Version) );
+ Stream::write ( f );
+ }
+
+
+ } // namespace math
+
+} // namespace mmdb
diff --git a/mmdb2/mmdb_math_align.h b/mmdb2/mmdb_math_align.h
new file mode 100644
index 0000000..fca7bc6
--- /dev/null
+++ b/mmdb2/mmdb_math_align.h
@@ -0,0 +1,195 @@
+// $Id: mmdb_math_align.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : Align <interface>
+// ~~~~~~~~~
+// **** Classes : mmdb::math::Alignment (char strings alignment)
+// ~~~~~~~~~~~~ mmdb::math::Alignment1 (int vectors alignment)
+//
+// (C) E.Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_MATH_Align__
+#define __MMDB_MATH_Align__
+
+#include "mmdb_io_stream.h"
+
+namespace mmdb {
+
+ namespace math {
+
+ // ===================== AlignParams ======================
+
+ DefineClass(AlignParams);
+ DefineStreamFunctions(AlignParams);
+
+ class AlignParams : public io::Stream {
+
+ public :
+
+ realtype gapWeight,spaceWeight;
+ realtype equalScore,nequalScore;
+ int method;
+
+ AlignParams();
+ AlignParams ( io::RPStream Object );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+ void InitAlignParams();
+
+ };
+
+
+ // ====================== Alignment =======================
+
+ DefineClass(Alignment);
+
+ enum ALIGN_METHOD {
+ ALIGN_GLOBAL = 0,
+ ALIGN_LOCAL = 1,
+ ALIGN_GLOBLOC = 2,
+ ALIGN_FREEENDS = 3
+ };
+
+ class Alignment : public io::Stream {
+
+ public :
+
+ Alignment ();
+ Alignment ( io::RPStream Object );
+ ~Alignment ();
+
+ void SetAffineModel ( realtype WGap, realtype WSpace );
+ void SetScores ( realtype SEqual, realtype SNEqual );
+
+ void Align ( cpstr S, cpstr T,
+ ALIGN_METHOD Method=ALIGN_GLOBAL );
+
+ inline pstr GetAlignedS() { return AlgnS; }
+ inline pstr GetAlignedT() { return AlgnT; }
+ inline realtype GetScore () { return VAchieved; }
+ inline char GetSpace () { return Space; }
+
+ realtype GetSimilarity(); // Score-weighted sequence id
+ realtype GetSeqId (); // Primitive sequence id
+
+ virtual void OutputResults ( io::RFile f, cpstr S, cpstr T );
+
+ void read ( io::RFile f );
+ void write ( io::RFile f );
+
+ protected :
+
+ char Space;
+ int AlignKey, SLen,TLen;
+ rmatrix VT,ET,FT;
+ pstr AlgnS,AlgnT;
+ realtype VAchieved;
+ realtype SEq,SNEq, Wg,Ws;
+
+ virtual void InitAlignment();
+ virtual void FreeMemory ();
+ virtual realtype Score ( char A, char B );
+
+ void BuildGATable ( cpstr S, cpstr T,
+ bool FreeSEnd, bool FreeTEnd );
+ void BuildLATable ( cpstr S, cpstr T );
+ void Backtrace ( cpstr S, cpstr T, int J, int I,
+ bool StopAtZero );
+ void AdjustEnds ( cpstr S, cpstr T, int J, int I );
+ void PrintVT ( cpstr S, cpstr T );
+
+ };
+
+
+
+ // ====================== Alignment1 =======================
+
+ DefineClass(Alignment1);
+
+ class Alignment1 : public io::Stream {
+
+ public :
+
+ Alignment1 ();
+ Alignment1 ( io::RPStream Object );
+ ~Alignment1();
+
+ void SetAffineModel ( realtype WGap, realtype WSpace );
+ void SetScores ( realtype SEqual, realtype SNEqual );
+
+ void Align ( ivector S, int SLength,
+ ivector T, int TLength,
+ ALIGN_METHOD Method=ALIGN_GLOBAL );
+
+ inline ivector GetAlignedS () { return AlgnS; }
+ inline ivector GetAlignedT () { return AlgnT; }
+ inline int GetAlignLength() { return AlgnLen; }
+ inline realtype GetScore () { return VAchieved; }
+
+ realtype GetSimilarity(); // Score-weighted sequence id
+
+ virtual void OutputResults ( io::RFile f, ivector S, int lenS,
+ ivector T, int lenT );
+
+ void read ( io::RFile f );
+ void write ( io::RFile f );
+
+ protected :
+
+ int Space;
+ int AlignKey, SLen,TLen, AlgnLen;
+ rmatrix VT,ET,FT;
+ ivector AlgnS,AlgnT;
+ realtype VAchieved;
+ realtype SEq,SNEq, Wg,Ws;
+
+ virtual void InitAlignment1();
+ virtual void FreeMemory ();
+ virtual realtype Score ( int A, int B );
+
+ void BuildGATable ( ivector S, ivector T,
+ bool FreeSEnds, bool FreeTEnds );
+ void BuildLATable ( ivector S, ivector T );
+ void Backtrace ( ivector S, ivector T, int J, int I,
+ bool StopAtZero );
+ void AdjustEnds ( ivector S, ivector T, int J, int I );
+ void PrintVT ( ivector S, ivector T );
+
+ };
+
+ } // namespace math
+
+} // namespace mmdb
+
+#endif
diff --git a/mmdb2/mmdb_math_bfgsmin.cpp b/mmdb2/mmdb_math_bfgsmin.cpp
new file mode 100644
index 0000000..989608a
--- /dev/null
+++ b/mmdb2/mmdb_math_bfgsmin.cpp
@@ -0,0 +1,938 @@
+// $Id: mmdb_math_bfgsmin.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : BFGSMin <implementation>
+// ~~~~~~~~~
+// **** Classes : mmdb::math::BFGSMin ( minimization driver )
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include <math.h>
+
+#include "mmdb_math_bfgsmin.h"
+
+namespace mmdb {
+
+ namespace math {
+
+ // ==============================================================
+
+ BFGSMin::BFGSMin() {
+
+ MFunc = NULL;
+ MFuncData = NULL;
+ PFunc = NULL;
+ PFuncData = NULL;
+
+ N = 0;
+ NAlloc = 0;
+
+ Hsn = NULL;
+ TL = NULL;
+ LL = NULL;
+ XOpt = NULL;
+ XPlus = NULL;
+ Sx = NULL;
+ SN = NULL;
+ HDiag = NULL;
+ GradX = NULL;
+ GPlus = NULL;
+ StepSize = NULL;
+ FNeighbor = NULL;
+ us = NULL;
+ uy = NULL;
+ ut = NULL;
+ Freese = NULL;
+ Func = 0.0;
+ FPlus = 0.0;
+ FOpt = 0.0;
+ TakenLambda = 0.0;
+ ForDiff = false;
+ CalcHess = false;
+
+ Etha = 0.0;
+ SqrtEtha = 0.0;
+ CubertEtha = 0.0;
+ TpF = 1.0;
+ GrdEps = 0.0;
+ StpEps = 0.0;
+ MxStep = MaxReal;
+ CnsMax = 0;
+ MaxItn = 100;
+ TermCode = BFGS_NoTermination;
+ ModF = false;
+
+ }
+
+ BFGSMin::~BFGSMin() {
+ FreeMemory();
+ }
+
+ void BFGSMin::MinFunc ( rvector X, realtype & F ) {
+ if (MFunc) (*MFunc)(MFuncData,N,X,F);
+ else F = 0.0;
+ }
+
+ void BFGSMin::MinFunc1 ( rvector X, realtype & F ) {
+ int i;
+ MinFunc ( X,F );
+ if (ModF && (F<FOpt)) {
+ for (i=1;i<=N;i++)
+ XOpt[i] = X[i];
+ FOpt = F;
+ }
+ }
+
+ void BFGSMin::Print ( int Itn, rvector X, rvector G, realtype F ) {
+ if (PFunc) (*PFunc)(PFuncData,N,Itn,X,G,F);
+ }
+
+ void BFGSMin::SetMinFunction ( void * UserData, PBFGSMinFunc Fnc ) {
+ MFuncData = UserData;
+ MFunc = Fnc;
+ }
+
+ void BFGSMin::SetPrintFunction ( void * UserData, PBFGSPrintFunc Fnc ) {
+ PFuncData = UserData;
+ PFunc = Fnc;
+ }
+
+
+ // -------------------------------------------------------------------
+
+ void BFGSMin::UMInCk ( rvector x0, rvector TypX,
+ int Digits, realtype TypF,
+ realtype GrdTol, realtype StpTol,
+ realtype MaxStp, int ItnLmt ) {
+ int i;
+ realtype S0,S1,S2;
+
+ SqrtEps = sqrt(MachEps);
+
+ if (N<1) {
+ TermCode = BFGS_WrongSpaceDim;
+ return;
+ }
+
+ for (i=1;i<=N;i++)
+ if (fabs(TypX[i])!=0.0) Sx[i] = 1.0/fabs(TypX[i]);
+ else Sx[i] = 1.0;
+
+ if (Digits<=0) Etha = MachEps;
+ else {
+ Etha = Exp((-Digits)*log(10.0));
+ if (MachEps>Etha) Etha = MachEps;
+ }
+ SqrtEtha = sqrt(Etha);
+ CubertEtha = Exp ( log(Etha)/3.0 );
+
+ if (Etha>0.01) {
+ TermCode = BFGS_TooFewDigits;
+ return;
+ }
+
+ if (TypF<=0.0) TpF = 1.0;
+ else TpF = TypF;
+
+ S1 = Exp(log(MachEps)/3.0);
+ if (GrdTol>0.0) GrdEps = GrdTol;
+ else {
+ GrdEps = sqrt(Etha);
+ if (S1>GrdEps) GrdEps = S1;
+ }
+
+ if (StpTol>0.0) StpEps = StpTol;
+ else StpEps = Exp ( log(MachEps)*2.0/3.0 );
+
+ if (MaxStp>0.0) MxStep = MaxStp;
+ else {
+ S1 = 0.0;
+ S2 = 0.0;
+ for (i=1;i<=N;i++) {
+ S0 = Sx[i];
+ S0 *= Sx[i];
+ S2 += S0;
+ S0 *= x0[i];
+ S1 += S0*x0[i];
+ }
+ S1 = sqrt(S1);
+ S2 = sqrt(S2);
+ if (S2>S1) MxStep = S2;
+ else MxStep = S1;
+ MxStep *= 1000.0;
+ }
+
+ if (ItnLmt>0) MaxItn = ItnLmt;
+ else MaxItn = 100;
+
+ TermCode = BFGS_NoTermination;
+
+ }
+
+
+ // -------------------------------------------------------------------
+
+ void BFGSMin::UMStop0 ( rvector x0, rvector Grad ) {
+ int i;
+ realtype S,Fmax,St;
+
+ CnsMax = 0;
+ if (TpF>fabs(Func)) Fmax = TpF;
+ else Fmax = fabs(Func);
+ S = 0.0;
+ for (i=1;i<=N;i++) {
+ St = fabs(x0[i]);
+ if (1.0/Sx[i]>St) St = 1.0/Sx[i];
+ St = fabs(Grad[i])*St/Fmax;
+ if (St>S) S = St;
+ }
+ if (S>=0.001*GrdEps) TermCode = BFGS_NoTermination;
+ else TermCode = BFGS_SmallGradient;
+
+ }
+
+
+ // -------------------------------------------------------------------
+
+ void BFGSMin::UMStop ( rvector x0, rvector Grad,
+ int RetCode, int ItnCnt,
+ bool MaxTkn ) {
+
+ // A7.2.1 : Checking the Stop Conditions
+
+ int i;
+ realtype Max1,Max2,MaxGrad,MaxStep, BB1,BB2;
+
+ TermCode = BFGS_NoTermination;
+ if (RetCode==1) TermCode = BFGS_LineSearchComplete;
+ else {
+ if (fabs(FPlus)>TpF) Max2 = fabs(FPlus);
+ else Max2 = TpF;
+ MaxGrad = 0.0;
+ MaxStep = 0.0;
+ for (i=1;i<=N;i++) {
+ BB1 = fabs(XPlus[i]);
+ BB2 = 1.0/Sx[i];
+ if (BB1>BB2) Max1 = BB1;
+ else Max1 = BB2;
+ BB1 = fabs(Grad[i])*Max1/Max2;
+ if (BB1>MaxGrad) MaxGrad = BB1;
+ BB2 = fabs(XPlus[i]-x0[i])/Max1;
+ if (BB2>MaxStep) MaxStep = BB2;
+ }
+ if (MaxGrad<GrdEps) TermCode = BFGS_SmallGradient;
+ else if (MaxStep<StpEps) TermCode = BFGS_SmallStep;
+ else if (ItnCnt>MaxItn) TermCode = BFGS_IterationLimit;
+ else if (MaxTkn) {
+ CnsMax++;
+ if (CnsMax==5) TermCode = BFGS_LargeSteps;
+ } else
+ CnsMax = 0;
+ }
+
+ }
+
+
+ // -------------------------------------------------------------------
+
+ void BFGSMin::MdHess ( rmatrix H, rvector HDg ) {
+
+ // A5.5.1 : Setting up the hessian of model
+
+ int i,j;
+ realtype MaxDiag,MaxOff, MinEv,Mue,MaxPosDiag;
+ realtype MaxOffl,MinDiag,MaxEv,MaxAdd,Sdd,OffRow;
+ realtype BB;
+
+ // Scaling
+ for (i=1;i<=N;i++)
+ for (j=i;j<=N;j++)
+ H[i][j] /= (Sx[i]*Sx[j]);
+
+ MaxDiag = H[1][1];
+ MinDiag = H[1][1];
+ MaxOff = 0.0;
+ for (i=1;i<=N;i++) {
+ if (H[i][i]>MaxDiag) MaxDiag = H[i][i];
+ if (H[i][i]<MinDiag) MinDiag = H[i][i];
+ if (i<N)
+ for (j=i+1;j<=N;j++) {
+ BB = fabs(H[i][j]);
+ if (BB>MaxOff) MaxOff = BB;
+ }
+ }
+ MaxPosDiag = 0.0;
+ if (MaxDiag>MaxPosDiag) MaxPosDiag = MaxDiag;
+
+ // Computing the shift of the spectra (the Mue)
+ if (MinDiag>SqrtEps*MaxPosDiag) Mue = 0.0;
+ else {
+ Mue = 2.0*(MaxPosDiag-MinDiag)*SqrtEps-MinDiag;
+ MaxDiag += Mue;
+ }
+ BB = MaxOff*(1.0+2.0*SqrtEps);
+ if (BB>MaxDiag) {
+ Mue = Mue+(MaxOff-MaxDiag)+2.0*SqrtEps*MaxOff;
+ MaxDiag = BB;
+ }
+ if (MaxDiag==0.0) { // H = 0
+ Mue = 1.0;
+ MaxDiag = 1.0;
+ }
+ if (Mue>0.0)
+ for (i=1;i<=N;i++)
+ Hsn[i][i] += Mue;
+
+ MaxOffl = MaxOff/N;
+ if (MaxDiag>MaxOffl) MaxOffl = MaxDiag;
+ MaxOffl = sqrt(MaxOffl);
+ for (i=1;i<=N;i++)
+ HDg[i] = H[i][i];
+
+ PbCholDecomp ( N,HDg,MaxOffl,MachEps,H,MaxAdd );
+
+ if (MaxAdd>0.0) {
+ MaxEv = HDg[1];
+ MinEv = HDg[1];
+ for (i=1;i<=N;i++) {
+ OffRow = 0.0;
+ if (i>1)
+ for (j=1;j<i;j++)
+ OffRow += fabs(H[j][i]);
+ if (i<N)
+ for (j=i+1;j<=N;j++)
+ OffRow += fabs(H[i][j]);
+ BB = HDg[i]+OffRow;
+ if (BB>MaxEv) MaxEv = BB;
+ BB = HDg[i]-OffRow;
+ if (BB<MinEv) MinEv = BB;
+ }
+ Sdd = (MaxEv-MinEv)*SqrtEps-MinEv;
+ if (Sdd<0.0) Sdd = 0.0;
+ if (MaxAdd<Sdd) Mue = MaxAdd;
+ else Mue = Sdd;
+ for (i=1;i<=N;i++)
+ HDg[i] += Mue;
+
+ PbCholDecomp ( N,HDg,0.0,MachEps,H,MaxAdd );
+
+ }
+
+ // Scaling back
+ for (i=1;i<=N;i++) {
+ if (i<N)
+ for (j=i+1;j<=N;j++)
+ H[i][j] *= (Sx[i]*Sx[j]);
+ HDg[i] *= Sx[i]*Sx[i];
+ for (j=1;j<=i;j++)
+ H[i][j] *= Sx[i];
+ }
+
+ }
+
+
+ // -------------------------------------------------------------------
+
+ void BFGSMin::FDGrad ( rvector X, rvector G, realtype Fc ) {
+
+ // A5.6.4 : Forward Finite-Differencies Approximation of
+ // the Gradient
+
+ realtype StepSizeJ,TempJ,Fj, BB1,BB2;
+ int j;
+
+ for (j=1;j<=N;j++) {
+ BB1 = fabs(X[j]);
+ BB2 = 1.0/Sx[j];
+ if (BB1>BB2) StepSizeJ = BB1;
+ else StepSizeJ = BB2;
+ if (X[j]<0.0) StepSizeJ = -StepSizeJ;
+ StepSizeJ *= SqrtEtha;
+ TempJ = X[j];
+ X[j] += StepSizeJ;
+ StepSizeJ = X[j]-TempJ;
+ MinFunc1 ( X,Fj );
+ if (TermCode!=BFGS_NoTermination) return;
+ G[j] = (Fj-Fc)/StepSizeJ;
+ X[j] = TempJ;
+ Freese[j] = false;
+ if (TL) {
+ if ((fabs(X[j]-TL[j])<=StepSizeJ) && (G[j]<0.0)) {
+ G[j] = 0.0; Freese[j] = true;
+ }
+ }
+ if (LL) {
+ if ((fabs(X[j]-LL[j])<=StepSizeJ) && (G[j]>0.0)) {
+ G[j] = 0.0; Freese[j] = true;
+ }
+ }
+ }
+
+ }
+
+
+ // -------------------------------------------------------------------
+
+ void BFGSMin::CDGrad ( rvector X, rvector G ) {
+
+ // A5.6.4 : Central Differencies Approximation of
+ // Gradient
+
+ realtype StepSizeJ,TempJ,Fp,Fm, BB1,BB2;
+ int j;
+
+ for (j=1;j<=N;j++) {
+ BB1 = fabs(X[j]);
+ BB2 = 1.0/Sx[j];
+ if (BB1>BB2) StepSizeJ = BB1;
+ else StepSizeJ = BB2;
+ if (X[j]<0.0) StepSizeJ = -StepSizeJ;
+ StepSizeJ *= CubertEtha;
+ TempJ = X[j];
+ X[j] += StepSizeJ;
+ StepSizeJ = X[j]-TempJ;
+ MinFunc1 ( X,Fp );
+ if (TermCode!=BFGS_NoTermination) return;
+ X[j] = TempJ-StepSizeJ;
+ MinFunc1 ( X,Fm );
+ if (TermCode!=BFGS_NoTermination) return;
+ G[j] = (Fp-Fm)/(2.0*StepSizeJ);
+ X[j] = TempJ;
+ }
+
+ }
+
+
+ // -------------------------------------------------------------------
+
+ void BFGSMin::Gradient ( rvector X, rvector G, realtype Fc ) {
+ if (ForDiff) FDGrad ( X,G,Fc );
+ else CDGrad ( X,G );
+ }
+
+
+ // -------------------------------------------------------------------
+
+ void BFGSMin::FDHessF ( realtype Fc, rvector X ) {
+
+ // A5.6.2 : Finite-Difference Approximation of
+ // the Hessian employing only the
+ // function's values
+
+ int i,j;
+ realtype S,TempI,Fii,TempJ,Fij, BB1,BB2;
+
+
+ for (i=1;i<=N;i++)
+ if (!Freese[i]) {
+ BB1 = fabs(X[i]);
+ BB2 = 1.0/Sx[i];
+ if (BB1>BB2) S = BB1;
+ else S = BB2;
+ if (X[i]<0.0) S = -S;
+ StepSize[i] = S*CubertEtha;
+ TempI = X[i];
+ X[i] += StepSize[i];
+ StepSize[i] = X[i]-TempI;
+ MinFunc1 ( X,FNeighbor[i] );
+ X[i] = TempI;
+ if (TermCode!=BFGS_NoTermination) return;
+ }
+ for (i=1;i<=N;i++)
+ if (!Freese[i]) {
+ TempI = X[i];
+ X[i] += 2.0*StepSize[i];
+ MinFunc1 ( X,Fii );
+ if (TermCode!=BFGS_NoTermination) return;
+ Hsn[i][i] = (( Fc -FNeighbor[i] ) +
+ ( Fii-FNeighbor[i] )) /
+ (StepSize[i]*StepSize[i]);
+ X[i] = TempI+StepSize[i];
+ if (i<N)
+ for (j=i+1;j<=N;j++)
+ if (!Freese[j]) {
+ TempJ = X[j];
+ X[j] += StepSize[j];
+ MinFunc1 ( X,Fij );
+ if (TermCode!=BFGS_NoTermination) return;
+ Hsn[i][j] = (( Fc -FNeighbor[i] ) +
+ ( Fij-FNeighbor[j] )) /
+ (StepSize[i]*StepSize[j]);
+ X[j] = TempJ;
+ } else
+ Hsn[i][j] = 0.0;
+ X[i] = TempI;
+ } else
+ for (j=i;j<=N;j++)
+ Hsn[i][j] = 0.0;
+
+ }
+
+
+ // -------------------------------------------------------------------
+
+ void BFGSMin::InitHessUnFac ( realtype F, rmatrix H ) {
+
+ // A9.4.3 - Initialization of the unfactorized BFGS
+
+ realtype Temp;
+ int i,j;
+
+ Temp = fabs(F);
+ if (TpF>Temp) Temp = TpF;
+ for (i=1;i<=N;i++) {
+ H[i][i] = Temp*Sx[i]*Sx[i];
+ if (i<N)
+ for (j=i+1;j<=N;j++)
+ H[i][j] = 0.0;
+ }
+
+ }
+
+
+ // -------------------------------------------------------------------
+
+ void BFGSMin::BFGSUnFac ( rvector Xc, rvector Xp,
+ rvector Gc, rvector Gp,
+ bool AnalGrad, rvector HDg,
+ rmatrix H ) {
+
+ // A9.4.1 - Calculation of the Hessian by the
+ // unfactorized BFGS
+
+ int i,j;
+ realtype Temp1,Temp2, NormS,NormY,Tol,tt, BB;
+ bool SkipUpdate;
+
+ Temp1 = 0.0;
+ NormS = 0.0;
+ NormY = 0.0;
+ for (i=1;i<=N;i++) {
+ H[i][i] = HDg[i];
+ us[i] = Xp[i] - Xc[i];
+ uy[i] = Gp[i] - Gc[i];
+ Temp1 += us[i]*uy[i];
+ NormS += us[i]*us[i];
+ NormY += uy[i]*uy[i];
+ }
+
+ if (Temp1>sqrt(MachEps*NormS*NormY)) {
+ if (AnalGrad) Tol = Etha;
+ else Tol = sqrt(Etha);
+ SkipUpdate = true;
+ for (i=1;i<=N;i++) {
+ tt = 0.0;
+ for (j=1;j<=i;j++)
+ tt += H[j][i]*us[j];
+ if (i<N)
+ for (j=i+1;j<=N;j++)
+ tt += H[i][j]*us[j];
+ ut[i] = tt;
+ tt = fabs(Gc[i]);
+ BB = fabs(Gp[i]);
+ if (BB>tt) tt = BB;
+ if (fabs(uy[i]-ut[i])>=Tol*tt)
+ SkipUpdate = false;
+ }
+
+ if (!SkipUpdate) {
+ Temp2 = 0.0;
+ for (i=1;i<=N;i++)
+ Temp2 += us[i]*ut[i];
+ for (i=1;i<=N;i++)
+ for (j=i;j<=N;j++)
+ H[i][j] += uy[i]*uy[j]/Temp1 -
+ ut[i]*ut[j]/Temp2;
+ }
+
+ }
+
+ }
+
+
+ // -------------------------------------------------------------------
+
+ void BFGSMin::Choose_Lambda ( rvector X, rvector S,
+ realtype & Lambda0 ) {
+ int i;
+ realtype SS;
+
+ for (i=1;i<=N;i++)
+ if ((S[i]!=0.0) && (!Freese[i])) {
+ SS = X[i] + Lambda0*S[i];
+ if (TL) {
+ if (SS>TL[i]) Lambda0 = (TL[i]-X[i])/S[i]/(1.0+MachEps);
+ }
+ if (LL) {
+ if (SS<LL[i]) Lambda0 = (LL[i]-X[i])/S[i]/(1.0+MachEps);
+ }
+ } else if (Freese[i]) S[i] = 0.0;
+
+ }
+
+
+ // -------------------------------------------------------------------
+
+ void BFGSMin::Stop() {
+ TermCode = BFGS_Stopped;
+ }
+
+
+ // -------------------------------------------------------------------
+
+ void BFGSMin::LineSearch ( rvector px0, rvector G,
+ rvector P, realtype pFunc,
+ int & RetCode, bool & MaxTkn ) {
+
+ // A6.3.1 : Linear Search
+
+ int i;
+ realtype Alpha, NewtLn, S, InitSp, RelLng, MinLam;
+ realtype Lambda,LamTem, LamPre, FplPre, A, B;
+ realtype Disc, B1, B2, Lambda0;
+
+ LamPre = 1.0; // only to keep compiler happy
+ FplPre = 1.0; // only to keep compiler happy
+
+ MaxTkn = false;
+ RetCode = 2;
+ Alpha = 1.0e-4;
+ NewtLn = 0.0;
+ for (i=1;i<=N;i++) { // calculate Newtonian step along the -gradient
+ B1 = Sx[i]*P[i];
+ NewtLn += B1*B1;
+ }
+ NewtLn = sqrt(NewtLn);
+
+ if (NewtLn>MxStep) { // restrict Newtonian step to MxStep
+ S = MxStep/NewtLn;
+ for (i=1;i<=N;i++)
+ P[i] *= S;
+ NewtLn = MxStep;
+ }
+
+ InitSp = 0.0;
+ RelLng = 0.0;
+ Lambda0 = 1.0;
+ Choose_Lambda ( px0,P,Lambda0 );
+ for (i=1;i<=N;i++) {
+ InitSp += G[i]*P[i];
+ B1 = fabs(px0[i]);
+ B2 = 1.0/Sx[i];
+ if (B1>B2) S = B1;
+ else S = B2;
+ S = fabs(P[i])/S;
+ if (S>RelLng) RelLng = S;
+ }
+ InitSp *= Lambda0;
+
+ MinLam = StpEps/RelLng;
+ Lambda = Lambda0;
+ do {
+ for (i=1;i<=N;i++)
+ XPlus[i] = px0[i] + Lambda*P[i];
+
+ MinFunc1 ( XPlus,FPlus );
+ if (TermCode!=BFGS_NoTermination) return;
+ if (FPlus<=pFunc+Alpha*Lambda*InitSp) {
+ RetCode = 0;
+ MaxTkn = (Lambda==Lambda0) && (NewtLn>0.99*MxStep);
+ } else if (Lambda<MinLam) {
+ RetCode = 1;
+ for (i=1;i<=N;i++)
+ XPlus[i] = px0[i];
+ } else if (Lambda==Lambda0) {
+ LamTem = -InitSp/(2.0*(FPlus-pFunc-InitSp));
+ LamTem = LamTem*Lambda;
+ LamPre = Lambda;
+ FplPre = FPlus;
+ if (LamTem>0.1*Lambda) Lambda = LamTem;
+ else {
+ Lambda *= 0.1;
+ Lambda0 = Lambda;
+ }
+ if (Lambda>Lambda0) {
+ Lambda = Lambda0;
+ RetCode = 0;
+ for (i=1;i<=N;i++)
+ XPlus[i] = px0[i] + Lambda*P[i];
+ }
+ } else {
+ B1 = FPlus - pFunc - Lambda*InitSp;
+ B2 = FplPre - pFunc - LamPre*InitSp;
+ A = ( B1/(Lambda*Lambda) - B2/(LamPre*LamPre) ) /
+ ( Lambda - LamPre );
+ B = ( -LamPre*B1/(Lambda*Lambda) +
+ Lambda*B2/(LamPre*LamPre) ) /
+ ( Lambda - LamPre );
+ Disc = B*B - 3.0*A*InitSp;
+ if (A==0.0) LamTem = -InitSp/(2.0*B);
+ else LamTem = (-B+sqrt(RMax(Disc,0.0)))/(3.0*A);
+ B1 = 0.5*Lambda;
+ if (B1<LamTem) LamTem = B1;
+ LamPre = Lambda;
+ FplPre = FPlus;
+ if (LamTem>0.1*Lambda) Lambda = LamTem;
+ else {
+ Lambda *= 0.1;
+ Lambda0 = Lambda;
+ }
+ if (Lambda>Lambda0) {
+ Lambda = Lambda0;
+ RetCode = 0;
+ for (i=1;i<=N;i++)
+ XPlus[i] = px0[i] + Lambda*P[i];
+ }
+ }
+
+ } while (RetCode>=2);
+
+ TakenLambda = Lambda;
+
+ }
+
+
+ // -------------------------------------------------------------------
+
+ void BFGSMin::GetMemory() {
+ if (N!=NAlloc) {
+ FreeMemory();
+ GetMatrixMemory ( Hsn , N,N, 1,1 );
+ GetVectorMemory ( GPlus , N, 1 );
+ GetVectorMemory ( GradX , N, 1 );
+ GetVectorMemory ( HDiag , N, 1 );
+ GetVectorMemory ( SN , N, 1 );
+ GetVectorMemory ( Sx , N, 1 );
+ GetVectorMemory ( XPlus , N, 1 );
+ GetVectorMemory ( XOpt , N, 1 );
+ GetVectorMemory ( Freese, N, 1 );
+ if (CalcHess) {
+ GetVectorMemory ( StepSize , N, 1 );
+ GetVectorMemory ( FNeighbor, N, 1 );
+ } else {
+ GetVectorMemory ( us , N, 1 );
+ GetVectorMemory ( uy , N, 1 );
+ GetVectorMemory ( ut , N, 1 );
+ }
+ NAlloc = N;
+ }
+ }
+
+ void BFGSMin::FreeMemory() {
+ if (NAlloc>0) {
+ FreeVectorMemory ( us , 1 );
+ FreeVectorMemory ( uy , 1 );
+ FreeVectorMemory ( ut , 1 );
+ FreeVectorMemory ( Freese , 1 );
+ FreeVectorMemory ( StepSize , 1 );
+ FreeVectorMemory ( FNeighbor, 1 );
+ FreeVectorMemory ( XOpt , 1 );
+ FreeVectorMemory ( XPlus , 1 );
+ FreeVectorMemory ( Sx , 1 );
+ FreeVectorMemory ( SN , 1 );
+ FreeVectorMemory ( HDiag , 1 );
+ FreeVectorMemory ( GradX , 1 );
+ FreeVectorMemory ( GPlus , 1 );
+ FreeMatrixMemory ( Hsn , NAlloc, 1,1 );
+ }
+ NAlloc = 0;
+ }
+
+
+ // -------------------------------------------------------------------
+
+ void BFGSMin::Relax() {
+ int i;
+ if (FPlus>FOpt) {
+ for (i=1;i<=N;i++)
+ XPlus[i] = XOpt[i];
+ FPlus = FOpt;
+ } else {
+ for (i=1;i<=N;i++)
+ XOpt[i] = XPlus[i];
+ FOpt = FPlus;
+ }
+ }
+
+ void BFGSMin::CopyPlus ( rvector x0 ) {
+ int i;
+ for (i=1;i<=N;i++) {
+ x0 [i] = XPlus[i];
+ GradX[i] = GPlus[i];
+ }
+ Func = FPlus;
+ }
+
+
+ // -------------------------------------------------------------------
+
+ void BFGSMin::BFGS_Driver ( int MinN,
+ rvector x0,
+ rvector TypX,
+ realtype & FuncValue,
+ int & TerminationCode,
+ int Digits,
+ int ItnLmt,
+ realtype TypF,
+ realtype GrdTol,
+ realtype StpTol,
+ realtype MaxStp,
+ bool Hess,
+ rvector LowLimit,
+ rvector TopLimit ) {
+
+ // D6.1.1 : Unconstrained Minimization Driver
+
+ int i,RetCode;
+ int ItnCnt;
+ bool MaxTkn;
+
+ TL = TopLimit;
+ LL = LowLimit;
+ ForDiff = true;
+ N = MinN;
+ CalcHess = Hess;
+
+ ModF = false;
+
+ GetMemory();
+
+ UMInCk ( x0,TypX,Digits,TypF,
+ GrdTol,StpTol,MaxStp,
+ ItnLmt );
+ if (TermCode!=BFGS_NoTermination) {
+ FreeMemory();
+ FuncValue = Func;
+ TerminationCode = TermCode;
+ return;
+ }
+
+ ItnCnt = 0;
+
+ MinFunc1 ( x0,Func );
+ if (TermCode!=BFGS_NoTermination) {
+ FreeMemory();
+ FuncValue = Func;
+ TerminationCode = TermCode;
+ return;
+ }
+ FOpt = Func;
+ FPlus = Func;
+ for (i=1;i<=N;i++) {
+ XOpt [i] = x0[i];
+ XPlus[i] = x0[i];
+ }
+ ModF = true;
+ Gradient ( x0,GradX,Func );
+ Print ( ItnCnt,x0,GradX,Func );
+ for (i=1;i<=N;i++)
+ GPlus[i] = GradX[i];
+ if (TermCode!=BFGS_NoTermination) {
+ Relax ();
+ CopyPlus ( x0 );
+ FreeMemory();
+ FuncValue = Func;
+ TerminationCode = TermCode;
+ return;
+ }
+
+ UMStop0 ( x0,GradX );
+ if (TermCode!=BFGS_NoTermination) {
+ FreeMemory();
+ FuncValue = Func;
+ TerminationCode = TermCode;
+ return;
+ }
+
+ if (!CalcHess) InitHessUnFac ( Func,Hsn );
+
+ RetCode = 0;
+ while (TermCode==BFGS_NoTermination) {
+ ItnCnt++;
+ if (RetCode>=0) {
+ if (CalcHess) {
+ FDHessF ( Func,x0 );
+ if (TermCode!=BFGS_NoTermination) {
+ Relax ();
+ CopyPlus ( x0 );
+ FreeMemory();
+ FuncValue = Func;
+ TerminationCode = TermCode;
+ return;
+ }
+ }
+ MdHess ( Hsn,HDiag );
+ }
+ ChSolve ( N,Hsn,GradX,SN );
+ LineSearch ( x0,GradX,SN,Func,RetCode,MaxTkn );
+ if ((RetCode==1) && ForDiff) {
+ RetCode = -1;
+ ForDiff = false;
+ } else
+ Relax();
+ if (TermCode!=BFGS_NoTermination) {
+ Relax ();
+ CopyPlus ( x0 );
+ FreeMemory();
+ FuncValue = Func;
+ TerminationCode = TermCode;
+ return;
+ } else
+ Gradient ( XPlus,GPlus,FPlus );
+ if (TermCode!=BFGS_NoTermination) {
+ Relax ();
+ CopyPlus ( x0 );
+ FreeMemory();
+ FuncValue = Func;
+ TerminationCode = TermCode;
+ return;
+ }
+ if (RetCode>=0) {
+ UMStop ( x0,GPlus,RetCode,ItnCnt,MaxTkn );
+ if ((!CalcHess) && (TermCode==BFGS_NoTermination))
+ BFGSUnFac ( x0,XPlus,GradX,GPlus,false,HDiag,Hsn );
+ }
+ CopyPlus ( x0 );
+ Print ( ItnCnt, x0,GradX,Func );
+ }
+
+ Relax ();
+ FreeMemory();
+ FuncValue = Func;
+ TerminationCode = TermCode;
+
+ }
+
+ } // namespace math
+
+} // namespace mmdb
+
diff --git a/mmdb2/mmdb_math_bfgsmin.h b/mmdb2/mmdb_math_bfgsmin.h
new file mode 100644
index 0000000..389ebe4
--- /dev/null
+++ b/mmdb2/mmdb_math_bfgsmin.h
@@ -0,0 +1,260 @@
+// $Id: mmdb_math_bfgsmin.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : BFGSMin <interface>
+// ~~~~~~~~~
+// **** Classes : mmdb::math::BFGSMin ( minimization driver )
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_MATH_BFGSMin__
+#define __MMDB_MATH_BFGSMin__
+
+#include <stdlib.h>
+
+#include "mmdb_mattype.h"
+#include "mmdb_math_linalg.h"
+
+
+namespace mmdb {
+
+ namespace math {
+
+ // ==============================================================
+
+ enum BFGS_RC {
+ BFGS_TooFewDigits = -2,
+ BFGS_WrongSpaceDim = -1,
+ BFGS_NoTermination = 0,
+ BFGS_SmallGradient = 1,
+ BFGS_SmallStep = 2,
+ BFGS_LineSearchComplete = 3,
+ BFGS_IterationLimit = 4,
+ BFGS_LargeSteps = 5,
+ BFGS_Stopped = 6
+ };
+
+ typedef void BFGSMinFunc ( void * UserData, int N, rvector X,
+ realtype & F );
+ typedef BFGSMinFunc * PBFGSMinFunc;
+
+ typedef void BFGSPrintFunc ( void * UserData, int N, int Itn,
+ rvector X, rvector G, realtype F );
+ typedef BFGSPrintFunc * PBFGSPrintFunc;
+
+ DefineClass(BFGSMin);
+
+ class BFGSMin {
+
+ public :
+
+ BFGSMin ();
+ virtual ~BFGSMin();
+
+ virtual void MinFunc ( rvector X, realtype & F );
+ virtual void Print ( int Itn, rvector X, rvector G,
+ realtype F );
+
+ void SetMinFunction ( void * UserData, PBFGSMinFunc Fnc );
+ void SetPrintFunction ( void * UserData, PBFGSPrintFunc Fnc );
+
+
+ // ======================================================
+ //
+ // .--------------------------------------------.
+ // | |
+ // | UNCONSTRAINED MINIMIZATION DRIVER |
+ // | |
+ // `--------------------------------------------'
+ //
+ // Finds a minimum of function F(X), X is vector [1..N],
+ // defined by virtual MinFunc. Virtual Print provides
+ // information on every iteration step.
+ //
+ //
+ // Input parameters :
+ // -----------------------
+ //
+ // N is the dimension the minimization space
+ //
+ // x0 [1..N] is the initial point for minimization
+ //
+ // TypX [1..N] is the array of the typical ranges of
+ // X - components, which are used for the scaling.
+ // If TypX<=0.0 then 1.0 will be substituted
+ //
+ // Digits is the number of valid decimal digits in
+ // the calculated value of minimizing function ( F ).
+ // If Digits<=0 then the Driver will consider
+ // that the F is computed with usual machine's
+ // noise
+ //
+ // ItnLmt is the maximum available number of iterations.
+ // If ItnLmt=0 then 100 will be substituted
+ //
+ // TypF is the expected absolute value of F in the
+ // minimum, which is used in the stop criterion.
+ // If TypF<=0.0 then 1.0 will be substituted
+ //
+ // GrdTol is the desired absolute value of the gradient
+ // vector in the minimum of F . If GrdTol<=0.0
+ // then the some value correlated with machine's
+ // noise will be substituted
+ //
+ // StpTol is the minimum available step for the minimi-
+ // zation. The execution stops if the distance
+ // between two consequential approximation will be
+ // less then StpTol . If StpTol<=0.0 then the
+ // some value correlated with machine's noise
+ // will be substituted
+ //
+ // MaxStp is the maximum available step for then minimi-
+ // zation. This parameter only prevents the appea-
+ // rance of the too large steps, but the execution
+ // stops if more than 5 steps with length of MaxStep
+ // will consequently appear.
+ //
+ //
+ //
+ // Outpute parameters :
+ // --------------------------
+ //
+ // x0 will be the point at which the minimisation
+ // had stopped
+ //
+ // Func will be the function's value at x0
+ //
+ // TermCode will be the reason of stopping :
+ //
+ // 1 <=> the norm of gradient vector at x0 is
+ // less than GrdTol ; the x0 is probable
+ // point of the minimum
+ // 2 <=> the distance between two last approxima-
+ // tions was less than StpTol ; the x0
+ // may be the point of minimum
+ // 3 <=> the gradient length is greater than
+ // GrdTol , but future minimization fails ;
+ // it may be the consequence of the errors
+ // at the computing of gradient, but also
+ // x0 could be the point of minimum
+ // 4 <=> the iteration limit had been exchausted
+ // 5 <=> more than 5 steps with length of
+ // MaxStp had been made
+ // 6 <=> the termination key ( Esc or End )
+ // had been pressed.
+ //
+ //
+ // ========================================================
+
+ void BFGS_Driver ( int MinN,
+ rvector x0,
+ rvector TypX,
+ realtype & FuncValue,
+ int & TerminationCode,
+ int Digits = 0,
+ int ItnLmt = 0,
+ realtype TypF = 0.0,
+ realtype GrdTol = 0.0,
+ realtype StpTol = 0.0,
+ realtype MaxStp = MaxReal,
+ bool Hess = false,
+ rvector LowLimit = NULL,
+ rvector TopLimit = NULL );
+
+ void Stop(); // generates stop signal to stop optimization
+
+
+ protected :
+
+ PBFGSMinFunc MFunc;
+ void * MFuncData;
+ PBFGSPrintFunc PFunc;
+ void * PFuncData;
+
+ int N,NAlloc;
+ rmatrix Hsn;
+ rvector TL,LL,XOpt,XPlus,Sx,SN,HDiag,GradX,GPlus;
+ rvector StepSize,FNeighbor;
+ rvector us,uy,ut;
+ bvector Freese;
+ realtype Func,FPlus,FOpt;
+ realtype TakenLambda;
+ bool ForDiff; // if True then forward differences are
+ // used for the 1st estimation of the
+ // Hessian (which is less expensive),
+ // otherwise central differences will
+ // be employed (which is more expensive).
+ bool CalcHess;
+
+ realtype Etha,SqrtEtha,CubertEtha,TpF,GrdEps,StpEps,MxStep;
+ realtype SqrtEps;
+ int CnsMax,MaxItn,TermCode;
+ bool ModF;
+
+ void MinFunc1 ( rvector X, realtype & F );
+ void UMInCk ( rvector x0, rvector TypX,
+ int Digits, realtype TypF,
+ realtype GrdTol, realtype StpTol,
+ realtype MaxStp, int ItnLmt );
+ void UMStop0 ( rvector x0, rvector Grad );
+ void UMStop ( rvector x0, rvector Grad, int RetCode,
+ int ItnCnt, bool MaxTkn );
+
+ virtual void Gradient ( rvector X, rvector G, realtype Fc );
+ virtual void FDHessF ( realtype Fc, rvector X );
+
+ void FDGrad ( rvector X, rvector G, realtype Fc );
+ void CDGrad ( rvector X, rvector G );
+ void MdHess ( rmatrix H, rvector HDg );
+ void InitHessUnFac ( realtype F, rmatrix H );
+ void BFGSUnFac ( rvector Xc, rvector Xp,
+ rvector Gc, rvector Gp,
+ bool AnalGrad, rvector HDg,
+ rmatrix H );
+ void Choose_Lambda ( rvector X, rvector S, realtype & Lambda0 );
+ void LineSearch ( rvector px0, rvector G,
+ rvector P, realtype pFunc,
+ int & RetCode, bool & MaxTkn );
+ void GetMemory ();
+ void FreeMemory ();
+ void Relax ();
+ void CopyPlus ( rvector x0 );
+
+ };
+
+ }
+
+}
+
+#endif
+
+
diff --git a/mmdb2/mmdb_math_fft.cpp b/mmdb2/mmdb_math_fft.cpp
new file mode 100755
index 0000000..bf449b3
--- /dev/null
+++ b/mmdb2/mmdb_math_fft.cpp
@@ -0,0 +1,338 @@
+// $Id: mmdb_math_fft.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2005-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : FFT <implementation>
+// ~~~~~~~~~
+// **** Functions: mmdb::math::FFT
+// ~~~~~~~~~ mmdb::math::RealFFT
+// mmdb::math::TwoFFT
+// mmdb::math::Convolve
+// mmdb::math::mConvolve
+//
+// (C) E.Krissinel 2005-2013
+//
+// =================================================================
+//
+
+#include <math.h>
+
+#include "mmdb_math_fft.h"
+
+namespace mmdb {
+
+ namespace math {
+
+ void FFT ( rvector data, int nn, bool Forward ) {
+ // Replaces data[1:2*nn] by its discrete Fourier transform,
+ // if Forward is true; or replaces data[1:2*nn] by nn times its
+ // inverse discrete Fourier transform if Forward is false.
+ // On call,
+ // data[i], i=1,3,5 ... nn-1 are real parts of function,
+ // data[i], i=2,4,6 ... nn are imaginary parts.
+ // nn MUST be an integer power of 2 (this is not checked for!).
+ // User should allocate data with GetVectorMemory and deallocate
+ // it with FreeVectorMemory to assure correct managing of indices
+ // 1..2*nn (not 0..2*nn-1).
+ // On return,
+ // data[i], i=1,3,5 ... nn-1 are real parts, and
+ // data[i], i=2,4,6 ... nn are imaginary parts of positive part
+ // of spectra, with frequences
+ // 0,1/(nn*D),2/(nn*D) ... (nn/2-1)/(nn*D);
+ // data[nn+1] and data[nn+2] are real and imaginary parts for
+ // the frequances +/-1/(2*D)
+ // data[i], i=nn+3,nn+5,nn+7 ... 2*nn-1 are real parts, and
+ // data[i], i=nn+4,nn+6,nn+8 ... 2*nn are imaginary parts of
+ // negative part of the spectra with frequences
+ // -(nn/2-1)/(nn*D), -(nn/2-2)/(nn*D), -1/(nn*D)
+ //
+ int i,istep,j,m,mmax,n;
+ realtype tempi,tempr;
+ long double theta,wi,wpi,wpr,wr,wtemp; // this should be of
+ // maximal precision
+ n = 2*nn;
+ j = 1;
+ for (i=1;i<=n;i+=2) {
+ if (j>i) {
+ tempr = data[j];
+ tempi = data[j+1];
+ data[j] = data[i];
+ data[j+1] = data[i+1];
+ data[i] = tempr;
+ data[i+1] = tempi;
+ }
+ m = n/2;
+ while ((m>=2) && (j>m)) {
+ j -= m;
+ m /= 2;
+ }
+ j += m;
+ }
+ mmax = 2;
+ while (n>mmax) {
+ istep = 2*mmax;
+ theta = 2.0*Pi/mmax;
+ if (!Forward) theta = -theta;
+ wpr = sin(0.5*theta);
+ wpr = -2.0*wpr*wpr;
+ wpi = sin(theta);
+ wr = 1.0;
+ wi = 0.0;
+ for (m=1;m<=mmax;m+=2) {
+ for (i=m;i<=n;i+=istep) {
+ j = i + mmax;
+ tempr = wr*data[j] - wi*data[j+1];
+ tempi = wr*data[j+1] + wi*data[j];
+ data[j] = data[i] - tempr;
+ data[j+1] = data[i+1] - tempi;
+ data[i] = data[i] + tempr;
+ data[i+1] = data[i+1] + tempi;
+ }
+ wtemp = wr;
+ wr = wr*wpr - wi*wpi + wr;
+ wi = wi*wpr + wtemp*wpi + wi;
+ }
+ mmax = istep;
+ }
+ }
+
+ void RealFFT ( rvector data, int n, bool Forward ) {
+ // Calculates the Fourier transform of a set of n real-valued data
+ // points. Replaces this data (which is stored in array data[1:n])
+ // by the positive frequency half of its complex Fourier transform.
+ // The real-valued first and last components of the complex transform
+ // are returned as elements data[1] and data[2], respectively.
+ // n MUST be a power of 2. This routine also calculates the
+ // inverse transform of a complex data array if it is the transform
+ // of real data (Result in this case must be multiplied by 2/n).
+ // Array data should be allocated with GetVectorMemory.
+ //
+ int i,i1,i2,i3,i4,n2p3;
+ realtype c1,c2,h1i,h1r,h2i,h2r;
+ long double theta,wi,wpi,wpr,wr,wtemp;
+
+ theta = 2.0*Pi/n;
+ c1 = 0.5;
+ if (Forward) {
+ c2 = -0.5;
+ FFT ( data,n/2,true );
+ } else {
+ c2 = 0.5;
+ theta = -theta;
+ }
+ wpr = sin(0.5*theta);
+ wpr = -2.0*wpr*wpr;
+ wpi = sin(theta);
+ wr = 1.0 + wpr;
+ wi = wpi;
+ n2p3 = n + 3;
+ for (i=2;i<=n/4;i++) {
+ i1 = 2*i - 1;
+ i2 = i1 + 1;
+ i3 = n2p3 - i2;
+ i4 = i3 + 1;
+ h1r = c1*(data[i1] + data[i3]);
+ h1i = c1*(data[i2] - data[i4]);
+ h2r = -c2*(data[i2] + data[i4]);
+ h2i = c2*(data[i1] - data[i3]);
+ data[i1] = h1r + wr*h2r - wi*h2i;
+ data[i2] = h1i + wr*h2i + wi*h2r;
+ data[i3] = h1r - wr*h2r + wi*h2i;
+ data[i4] = -h1i + wr*h2i + wi*h2r;
+ wtemp = wr;
+ wr = wr*wpr - wi*wpi + wr;
+ wi = wi*wpr + wtemp*wpi + wi;
+ }
+ if (Forward) {
+ h1r = data[1];
+ data[1] = h1r + data[2];
+ data[2] = h1r - data[2];
+ } else {
+ h1r = data[1];
+ data[1] = c1*(h1r+data[2]);
+ data[2] = c1*(h1r-data[2]);
+ FFT ( data,n/2,false );
+ }
+ }
+
+ void TwoFFT ( rvector data1, rvector data2,
+ rvector fft1, rvector fft2, int n ) {
+ // Given two real input arrays data1[1:n] and data2[1:n],
+ // this routine calls FFT and returns two "complex" output
+ // arrays fft1[1:2*n] and fft2[1:2*n] (2*i-1 ith real,
+ // 2*i ith imaginary), which contain the discrete Fourier
+ // transforms of the respective data arrays. n MUST be
+ // an integer power of 2.
+ int i,j,n2, bj,bn;
+ realtype h1r,h1i,h2r,h2i;
+ i = 1;
+ for (j=1;j<=n;j++) {
+ fft1[i++] = data1[j];
+ fft1[i++] = data2[j];
+ }
+ FFT ( fft1,n,true );
+ fft2[1] = fft1[2]; fft2[2] = 0.0;
+ fft1[2] = 0.0;
+ n2 = n + 2;
+ for (j=2;j<=n/2+1;j++) {
+ bj = 2*j-1; bn = 2*(n2-j)-1;
+ h1r = 0.5*(fft1[bj] + fft1[bn]);
+ h1i = 0.5*(fft1[bj+1] - fft1[bn+1]);
+ h2r = 0.5*(fft1[bj+1] + fft1[bn+1]);
+ h2i = 0.5*(fft1[bn] - fft1[bj]);
+ fft1[bj] = h1r; fft1[bj+1] = h1i;
+ fft1[bn] = h1r; fft1[bn+1] = -h1i;
+ fft2[bj] = h2r; fft2[bj+1] = h2i;
+ fft2[bn] = h2r; fft2[bn+1] = -h2i;
+ }
+ }
+
+ void Convolve ( rvector data, int n, rvector respns, int m,
+ rvector ans, bool Conv ) {
+ // Convolves or Deconvolves a real data set data[1:n] (including
+ // any user-supplied zero padding) with a response function
+ // respns[1..n], stored in wrap-around order in a real array of
+ // length m<n (m should be an odd (3,5,7...) integer). Wrap-around
+ // order means that the first half of the array contains the impulse
+ // response function at positive times, while the second half of
+ // the array contains the impulse response function at negative
+ // times, counting down from the highest element respns[m]. On
+ // input Conv=true for convolution, false for deconvolution.
+ // The answer is returned in the first n component of ans.
+ // However, ans must be supplied in the calling program with
+ // length at least 2*n, for consistency with TwoFFT. n MUST
+ // be an integer power of 2.
+ //
+ int i,no2,rp,ip;
+ rvector fft;
+ realtype B,D;
+
+ GetVectorMemory ( fft,2*n,1 );
+ for (i=1;i<=(m-1)/2;i++)
+ respns[n+1-i] = respns[m+1-i];
+ for (i=(m+3)/2;i<=n-(m-1)/2;i++)
+ respns[i] = 0.0;
+
+ TwoFFT ( data,respns,fft,ans,n );
+
+ no2 = n/2;
+ rp = 1; // pointer to real part
+ ip = 2; // pointer to imaginary part
+ for (i=1;i<=no2+1;i++) {
+ if (Conv) {
+ B = (fft[rp]*ans[rp] - fft[ip]*ans[ip])/no2;
+ ans[ip] = (fft[ip]*ans[rp] + fft[rp]*ans[ip])/no2;
+ ans[rp] = B;
+ } else {
+ D = (ans[rp]*ans[rp] + ans[ip]*ans[ip])*no2;
+ if (D==0.0) {
+ // poor deconvolve at zero response
+ ans[rp] = 0.0;
+ ans[ip] = 0.0;
+ } else {
+ B = (fft[rp]*ans[rp] + fft[ip]*ans[ip])/D;
+ ans[ip] = (fft[ip]*ans[rp] - fft[rp]*ans[ip])/D;
+ ans[rp] = B;
+ }
+ }
+ rp += 2;
+ ip += 2;
+ }
+
+ ans[2] = ans[2*no2+1];
+ FreeVectorMemory ( fft,1 );
+
+ RealFFT ( ans,n,false );
+
+ }
+
+
+ void mConvolve ( rvector data, int n, int m ) {
+ //
+ // Replaces array data[0..n-1] with the result of m recursive
+ // convolutions (m>1) defined as
+ //
+ // data_m = data (*) data_{m-1}
+ //
+ // where data_m is the result of mth convolution, data_0=data.
+ // The definition of the convolution is
+ //
+ // [a (*) b]_i = Sum_j { a_j * b_{i-j} }
+ //
+ // On input, data[] is considered as containing the signal
+ // sampled at both positive and negative times in the wrap-around
+ // order, that is
+ //
+ // data[i], 0<=i<n/2 signal sampled at times dt*i
+ // data[i], n/2<=i<n signal sampled at times -dt*(n-i)
+ //
+ // and the same wrap-around order is used to interprete the output
+ // data. This means that if only m positive sampling times are
+ // used, the length of data must be at least n=2*m, the rest being
+ // padded with zeroes.
+ //
+ // The number of sampling nodes n *must* be an integer power of
+ // two, i.e. 2,4,8,16 ... .
+ //
+ realtype R,G,phi,B,m2,n2,d1;
+ int i,m1;
+
+ if (m<1) return;
+
+ RealFFT ( data-1,n,true );
+
+ m1 = m+1;
+ m2 = m1/2.0;
+ n2 = 2.0/n;
+ d1 = data[1];
+ for (i=0;i<=n;i+=2) {
+ if (i<n) {
+ R = data[i];
+ if (i>1) G = data[i+1];
+ else G = 0.0;
+ } else {
+ R = d1;
+ G = 0.0;
+ }
+ phi = atan2(G,R) * m1;
+ B = pow(R*R+G*G,m2);
+ R = B*cos(phi);
+ G = B*sin(phi);
+ if (i<n) {
+ data[i] = R*n2;
+ data[i+1] = G*n2;
+ } else
+ data[1] = R*n2;
+ }
+
+ RealFFT ( data-1,n,false );
+
+ }
+
+ } // namespace math
+
+} // namespace mmdb
diff --git a/mmdb2/mmdb_math_fft.h b/mmdb2/mmdb_math_fft.h
new file mode 100755
index 0000000..6d91380
--- /dev/null
+++ b/mmdb2/mmdb_math_fft.h
@@ -0,0 +1,93 @@
+// $Id: mmdb_math_fft.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2005-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : FFT <interface>
+// ~~~~~~~~~
+// **** Functions: mmdb::math::FFT
+// ~~~~~~~~~ mmdb::math::RealFFT
+// mmdb::math::TwoFFT
+// mmdb::math::Convolve
+// mmdb::math::mConvolve
+//
+// (C) E.Krissinel 2005-2013
+//
+// =================================================================
+//
+
+#ifndef __FFT__
+#define __FFT__
+
+#include "mmdb_mattype.h"
+
+namespace mmdb {
+
+ namespace math {
+
+ extern void FFT ( rvector data, int nn, bool Forward=true );
+
+ extern void RealFFT ( rvector data, int n, bool Forward=true );
+
+ extern void TwoFFT ( rvector data1, rvector data2,
+ rvector fft1, rvector fft2, int n );
+
+ extern void Convolve ( rvector data, int n, rvector respns, int m,
+ rvector ans, bool Conv=true );
+
+
+ // mConvolve ( data,n,m ) replaces array data[0..n-1] with the result
+ // of m recursive convolutions (m>1) defined as
+ //
+ // data_m = data (*) data_{m-1}
+ //
+ // where data_m is the result of mth convolution, data_0=data.
+ // The definition of the convolution is
+ //
+ // [a (*) b]_i = Sum_j { a_j * b_{i-j} }
+ //
+ // On input, data[] is considered as containing the signal
+ // sampled at both positive and negative times in the wrap-around
+ // order, that is
+ //
+ // data[i], 0<=i<n/2 signal sampled at times dt*i
+ // data[i], n/2<=i<n signal sampled at times -dt*(n-i)
+ //
+ // and the same wrap-around order is used to interprete the output
+ // data. This means that if only m positive sampling times are
+ // used, the length of data must be at least n=2*m, the rest being
+ // padded with zeroes.
+ //
+ // The number of sampling nodes n *must* be an integer power of
+ // two, i.e. 2,4,8,16 ... .
+ //
+ extern void mConvolve ( rvector data, int n, int m );
+
+ } // namespace math
+
+} // namespace mmdb
+
+#endif
diff --git a/mmdb2/mmdb_math_graph.cpp b/mmdb2/mmdb_math_graph.cpp
new file mode 100644
index 0000000..b927665
--- /dev/null
+++ b/mmdb2/mmdb_math_graph.cpp
@@ -0,0 +1,2461 @@
+// $Id: mmdb_math_graph.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : mmdb_math_graph <implementation>
+// ~~~~~~~~~
+// **** Namespace: mmdb::math::
+// ~~~~~~~~~~
+// **** Classes : Vertex ( graph vertex )
+// ~~~~~~~~~ Edge ( graph edge )
+// Graph ( structural graph )
+// GMatch ( GMatch of structural graphs )
+// GraphMatch ( CSIA algorithms for graphs GMatching )
+//
+// (C) E. Krissinel 2000-2013
+//
+// When used, please cite:
+//
+// Krissinel, E. and Henrick, K. (2004)
+// Common subgraph isomorphism detection by backtracking search.
+// Software - Practice and Experience, 34, 591-607.
+//
+// =================================================================
+//
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "mmdb_math_graph.h"
+#include "mmdb_tables.h"
+
+
+namespace mmdb {
+
+ namespace math {
+
+ // ========================= Vertex ==========================
+
+ Vertex::Vertex() : io::Stream() {
+ InitVertex();
+ }
+
+ Vertex::Vertex ( io::RPStream Object ) : io::Stream(Object) {
+ InitVertex();
+ }
+
+ Vertex::Vertex ( cpstr chem_elem ) : io::Stream() {
+ InitVertex();
+ SetVertex ( chem_elem );
+ }
+
+ Vertex::Vertex ( int vtype ) : io::Stream() {
+ InitVertex();
+ SetVertex ( vtype );
+ }
+
+ Vertex::Vertex ( int vtype, cpstr vname ) : io::Stream() {
+ InitVertex();
+ SetVertex ( vtype,vname );
+ }
+
+ Vertex::Vertex ( cpstr chem_elem, cpstr vname ) : io::Stream() {
+ InitVertex ();
+ SetVertex ( chem_elem );
+ CreateCopy ( name,vname );
+ }
+
+ Vertex::~Vertex() {
+ if (name) delete[] name;
+ }
+
+ void Vertex::InitVertex() {
+ name = NULL;
+ type = 0;
+ type_ext = 0;
+ property = 0;
+ id = 0;
+ user_id = 0;
+ }
+
+
+ void Vertex::SetVertex ( cpstr chem_elem ) {
+ // This function generates vertex type according to a chemical
+ // element name passed in chem_elem.
+ //
+ // The element type has the following meaning:
+ //
+ // 0xCHSSTTTT
+ //
+ // where
+ // T - resreved for elemenmt type
+ // S - resreved for symmetry relief
+ // H - reserved for hydrogen bonds
+ // C - resreved for chirality flags
+ //
+ // Note that when more than 2 symbols are used for chemical element
+ // name (custom use), fields S may be reallocated for element type
+ // and then symmetry relief becomes impossible.
+ //
+ CreateCopy ( name,chem_elem );
+ type = getElementNo ( chem_elem );
+ if (type==ELEMENT_UNKNOWN) {
+ type = 0;
+ if (name[0]) {
+ type = (int)name[0];
+ if (name[1]) {
+ type = type*256+(int)name[1];
+ if (name[2]) type = type*256+(int)name[2];
+ }
+ }
+ type += nElementNames;
+ }
+ }
+
+ void Vertex::SetVertex ( int vtype ) {
+ // This function sets vertex type. See comments above for
+ // the general rule for vertex types implied by this code.
+ char N[50];
+ int type0;
+ type = vtype;
+ type0 = vtype & TYPE_MASK;
+ if ((type0>=1) && (type0<=nElementNames))
+ CreateCopy ( name,ElementName[type0-1] );
+ else {
+ sprintf ( N,"%i",type );
+ CreateCopy ( name,N );
+ }
+ }
+
+ void Vertex::SetType ( int vtype ) {
+ type = vtype;
+ }
+
+ void Vertex::SetTypeExt ( int typeExt ) {
+ type_ext = typeExt;
+ }
+
+ void Vertex::SetVertex ( int vtype, cpstr vname ) {
+ type = vtype;
+ CreateCopy ( name,vname );
+ }
+
+ void Vertex::SetName ( cpstr vname ) {
+ CreateCopy ( name,vname );
+ }
+
+ void Vertex::SetID ( int vid ) {
+ id = vid;
+ }
+
+ void Vertex::SetProperty ( int vprop ) {
+ property = vprop;
+ }
+
+ int Vertex::GetNBonds() {
+ return ((type & HYDROGEN_BOND) >> 24);
+ }
+
+ void Vertex::AddBond() {
+ int nb = GetNBonds()+1;
+ type &= ~HYDROGEN_BOND;
+ type |= nb << 24;
+ }
+
+ void Vertex::CopyNBonds ( PVertex V ) {
+ int nb = V->GetNBonds();
+ type &= ~HYDROGEN_BOND;
+ type |= nb << 24;
+ }
+
+ void Vertex::RemoveChirality() {
+ type &= CHIRAL_MASK;
+ }
+
+ void Vertex::LeaveChirality ( int eltype ) {
+ // leaves chirality only on specified elements
+ int vtype;
+ vtype = type & CHIRAL_MASK;
+ if (vtype!=eltype) type = vtype;
+ }
+
+ void Vertex::SaveType() {
+ user_id = type;
+ }
+
+ void Vertex::RestoreType() {
+ type = user_id;
+ }
+
+ void Vertex::CopyType ( PVertex V ) {
+ type = V->type;
+ }
+
+
+ void Vertex::Print ( int PKey ) {
+ if (PKey!=0)
+ printf ( " name type" );
+ else printf ( " %10s %5i",name,type );
+ }
+
+ void Vertex::Copy ( PVertex V ) {
+ CreateCopy ( name,V->name );
+ type = V->type;
+ type_ext = V->type_ext;
+ property = V->property;
+ id = V->id;
+ user_id = V->user_id;
+ }
+
+ void Vertex::write ( io::RFile f ) {
+ int Version=2;
+ f.WriteInt ( &Version );
+ f.CreateWrite ( name );
+ f.WriteInt ( &type );
+ f.WriteInt ( &property );
+ f.WriteInt ( &id );
+ f.WriteInt ( &user_id );
+ f.WriteInt ( &type_ext );
+ }
+
+ void Vertex::read ( io::RFile f ) {
+ int Version;
+ f.ReadInt ( &Version );
+ f.CreateRead ( name );
+ f.ReadInt ( &type );
+ f.ReadInt ( &property );
+ f.ReadInt ( &id );
+ f.ReadInt ( &user_id );
+ if (Version>1) f.ReadInt ( &type_ext );
+ else type_ext = 0;
+ }
+
+ void Vertex::mem_write ( pstr S, int & l ) {
+ byte Version=2;
+ mmdb::mem_write_byte ( Version,S,l );
+ mmdb::mem_write ( name ,S,l );
+ mmdb::mem_write ( type ,S,l );
+ mmdb::mem_write ( property,S,l );
+ mmdb::mem_write ( id ,S,l );
+ mmdb::mem_write ( user_id ,S,l );
+ mmdb::mem_write ( type_ext,S,l );
+ }
+
+ void Vertex::mem_read ( cpstr S, int & l ) {
+ byte Version;
+ mmdb::mem_read_byte ( Version,S,l );
+ mmdb::mem_read ( name ,S,l );
+ mmdb::mem_read ( type ,S,l );
+ mmdb::mem_read ( property,S,l );
+ mmdb::mem_read ( id ,S,l );
+ mmdb::mem_read ( user_id ,S,l );
+ mmdb::mem_read ( type_ext,S,l );
+ }
+
+ MakeStreamFunctions(Vertex)
+
+
+
+ // =========================== Edge =============================
+
+ Edge::Edge() : io::Stream() {
+ InitEdge();
+ }
+
+ Edge::Edge ( io::RPStream Object ) : io::Stream(Object) {
+ InitEdge();
+ }
+
+ Edge::Edge ( int vx1, int vx2, int btype ) {
+ InitEdge();
+ SetEdge ( vx1,vx2,btype );
+ }
+
+ Edge::~Edge() {}
+
+ void Edge::InitEdge() {
+ v1 = 0;
+ v2 = 0;
+ type = 0;
+ property = 0;
+ }
+
+
+ #define NofBondTypes 4
+
+ static pstr BondType[NofBondTypes+1] = {
+ pstr("SING"), pstr("DOUB"), pstr("AROM"), pstr("TRIP"),
+ pstr("") // should be here for safety
+ };
+
+
+ void Edge::SetEdge ( int vx1, int vx2, cpstr btype ) {
+ v1 = vx1;
+ v2 = vx2;
+ type = 0;
+ while (type<NofBondTypes)
+ if (!strncasecmp(btype,BondType[type],4)) break;
+ else type++;
+ if (type>=NofBondTypes) {
+ type = 0;
+ if (btype[0]) type = (int)btype[0];
+ if (btype[1]) type = type*16+(int)btype[1];
+ if (btype[2]) type = type*16+(int)btype[2];
+ type += NofBondTypes;
+ }
+ type++;
+ }
+
+ void Edge::SetEdge ( int vx1, int vx2, int btype ) {
+ v1 = vx1;
+ v2 = vx2;
+ type = btype;
+ }
+
+ void Edge::SetType ( int btype ) {
+ type = btype;
+ }
+
+ void Edge::SetProperty ( int eprop ) {
+ property = eprop;
+ }
+
+ void Edge::SaveType() {
+ property = type;
+ }
+
+ void Edge::RestoreType() {
+ type = property;
+ }
+
+ void Edge::Print ( int PKey ) {
+ if (PKey!=0)
+ printf ( " v1 v2 type" );
+ else printf ( " %5i %5i %5i",v1,v2,type );
+ }
+
+ void Edge::Copy ( PEdge G ) {
+ v1 = G->v1;
+ v2 = G->v2;
+ type = G->type;
+ property = G->property;
+ }
+
+ void Edge::write ( io::RFile f ) {
+ int Version=1;
+ f.WriteInt ( &Version );
+ f.WriteInt ( &v1 );
+ f.WriteInt ( &v2 );
+ f.WriteInt ( &type );
+ f.WriteInt ( &property );
+ }
+
+ void Edge::read ( io::RFile f ) {
+ int Version;
+ f.ReadInt ( &Version );
+ f.ReadInt ( &v1 );
+ f.ReadInt ( &v2 );
+ f.ReadInt ( &type );
+ f.ReadInt ( &property );
+ }
+
+ void Edge::mem_write ( pstr S, int & l ) {
+ byte Version=1;
+ mmdb::mem_write_byte ( Version,S,l );
+ mmdb::mem_write ( v1 ,S,l );
+ mmdb::mem_write ( v2 ,S,l );
+ mmdb::mem_write ( type ,S,l );
+ mmdb::mem_write ( property,S,l );
+ }
+
+ void Edge::mem_read ( cpstr S, int & l ) {
+ byte Version;
+ mmdb::mem_read_byte ( Version,S,l );
+ mmdb::mem_read ( v1 ,S,l );
+ mmdb::mem_read ( v2 ,S,l );
+ mmdb::mem_read ( type ,S,l );
+ mmdb::mem_read ( property,S,l );
+ }
+
+ MakeStreamFunctions(Edge)
+
+
+ // ========================== Graph ============================
+
+ Graph::Graph() : io::Stream() {
+ InitGraph();
+ }
+
+ Graph::Graph ( PResidue R, cpstr altLoc ) : io::Stream() {
+ InitGraph();
+ MakeGraph ( R,altLoc );
+ }
+
+ Graph::Graph ( io::RPStream Object ) : io::Stream(Object) {
+ InitGraph();
+ }
+
+ Graph::~Graph() {
+ FreeMemory();
+ }
+
+ void Graph::InitGraph() {
+ nVAlloc = 0;
+ nEAlloc = 0;
+ nGAlloc = 0;
+ nVertices = 0;
+ nEdges = 0;
+ nAllVertices = 0;
+ nAllEdges = 0;
+ vertex = NULL;
+ edge = NULL;
+ graph = NULL;
+ name = NULL;
+ CreateCopy ( name,pstr("UNNAMED") );
+ }
+
+ void Graph::FreeMemory() {
+ int i;
+
+ if (vertex) {
+ for (i=0;i<nVAlloc;i++)
+ if (vertex[i])
+ delete vertex[i];
+ delete[] vertex;
+ }
+ nVAlloc = 0;
+ nVertices = 0;
+ nAllVertices = 0;
+ vertex = NULL;
+
+ if (edge) {
+ for (i=0;i<nEAlloc;i++)
+ if (edge[i])
+ delete edge[i];
+ delete[] edge;
+ }
+ nEAlloc = 0;
+ nEdges = 0;
+ nAllEdges = 0;
+ edge = NULL;
+
+ FreeMatrixMemory ( graph,nGAlloc,1,1 );
+ nGAlloc = 0;
+
+ if (name) delete[] name;
+ name = NULL;
+
+ }
+
+ void Graph::Reset() {
+ FreeMemory();
+ CreateCopy ( name,pstr("UNNAMED") );
+ }
+
+ void Graph::SetName ( cpstr gname ) {
+ CreateCopy ( name,gname );
+ }
+
+
+ static int AllocPortion = 100;
+
+ void SetGraphAllocPortion ( int alloc_portion ) {
+ AllocPortion = alloc_portion;
+ }
+
+ void Graph::AddVertex ( PVertex V ) {
+ int i;
+ PVertex * V1;
+
+ if (nAllVertices>=nVAlloc) {
+ nVAlloc += AllocPortion;
+ V1 = new PVertex[nVAlloc];
+ for (i=0;i<nAllVertices;i++)
+ V1[i] = vertex[i];
+ for (i=nAllVertices;i<nVAlloc;i++)
+ V1[i] = NULL;
+ if (vertex) delete[] vertex;
+ vertex = V1;
+ }
+ if (vertex[nAllVertices])
+ delete vertex[nAllVertices];
+ vertex[nAllVertices] = V;
+ nAllVertices++;
+ nVertices = nAllVertices;
+
+ }
+
+ void Graph::SetVertices ( PPVertex V, int vlen ) {
+ if (nVAlloc>0) FreeMemory();
+ vertex = V;
+ nVertices = vlen;
+ nAllVertices = vlen;
+ nVAlloc = vlen;
+ }
+
+ int Graph::GetVertexID ( int vertexNo ) {
+ if ((vertexNo>0) && (vertexNo<=nAllVertices))
+ return vertex[vertexNo-1]->GetID();
+ else return MinInt4;
+ }
+
+ int Graph::GetNBondedVertices ( int vertexNo ) {
+ if ((vertexNo>0) && (vertexNo<=nAllVertices)) {
+ if (vertex[vertexNo-1])
+ return vertex[vertexNo-1]->GetNBonds();
+ }
+ return 0;
+ }
+
+ int Graph::GetBondedVertexID ( int vertexNo, int bond_vx_type,
+ int bondNo ) {
+ int i,k, v1,v2;
+ if ((vertexNo>0) && (vertexNo<=nAllVertices)) {
+ if (vertex[vertexNo-1]) {
+ if (vertex[vertexNo-1]->GetNBonds()>=bondNo) {
+ k = 0;
+ for (i=0;(i<nAllEdges) && (!k);i++)
+ if (edge[i]) {
+ v1 = edge[i]->v1;
+ v2 = edge[i]->v2;
+ if ((v1==vertexNo) &&
+ ((vertex[v2-1]->type & (int)TYPE_MASK) ==
+ bond_vx_type) &&
+ (vertex[v2-1]->GetNBonds()==bondNo))
+ k = v2;
+ if ((v2==vertexNo) &&
+ ((vertex[v1-1]->type & (int)TYPE_MASK) ==
+ bond_vx_type) &&
+ (vertex[v2-1]->GetNBonds()==bondNo))
+ k = v1;
+ }
+ if (k) return vertex[k-1]->GetID();
+ }
+ }
+ }
+ return MinInt4;
+ }
+
+ PVertex Graph::GetVertex ( int vertexNo ) {
+ if ((vertexNo>0) && (vertexNo<=nAllVertices))
+ return vertex[vertexNo-1];
+ else return NULL;
+ }
+
+ int Graph::GetVertexNo ( cpstr vname ) {
+ int i,k;
+ k = 0;
+ if (vname)
+ for (i=0;(i<nAllVertices) && (!k);i++)
+ if (!strcmp(vname,vertex[i]->name))
+ k = i+1;
+ return k;
+ }
+
+ PEdge Graph::GetEdge ( int edgeNo ) {
+ if ((edgeNo>0) && (edgeNo<=nAllEdges))
+ return edge[edgeNo-1];
+ else return NULL;
+ }
+
+ void Graph::AddEdge ( PEdge G ) {
+ int i;
+ PPEdge G1;
+
+ if (nAllEdges>=nEAlloc) {
+ nEAlloc += AllocPortion;
+ G1 = new PEdge[nEAlloc];
+ for (i=0;i<nAllEdges;i++)
+ G1[i] = edge[i];
+ for (i=nAllEdges;i<nEAlloc;i++)
+ G1[i] = NULL;
+ if (edge) delete[] edge;
+ edge = G1;
+ }
+ if (edge[nAllEdges])
+ delete edge[nAllEdges];
+ edge[nAllEdges] = G;
+ nAllEdges++;
+ nEdges = nAllEdges;
+
+ }
+
+ void Graph::SetEdges ( PPEdge G, int glen ) {
+ if (nEAlloc>0) FreeMemory();
+ edge = G;
+ nEdges = glen;
+ nAllEdges = glen;
+ nEAlloc = glen;
+ }
+
+ void Graph::GetVertices ( PPVertex & V, int & nV ) {
+ V = vertex;
+ nV = nVertices;
+ }
+
+ void Graph::GetEdges ( PPEdge & E, int & nE ) {
+ E = edge;
+ nE = nEdges;
+ }
+
+
+ int Graph::MakeGraph ( PResidue R, cpstr altLoc ) {
+ int i,j, a1,a2,e1,e2, nAltLocs,alflag, rc;
+ bool B;
+ rvector occupancy;
+ AltLoc aLoc;
+ PAltLoc aL;
+ realtype dx,dy,dz, sr;
+ PEdge G;
+
+ rc = MKGRAPH_Ok;
+ // reset graph
+ FreeMemory();
+
+ occupancy = NULL;
+ aL = NULL;
+ R->GetAltLocations ( nAltLocs,aL,occupancy,alflag );
+ if (nAltLocs<=0) return MKGRAPH_NoAtoms;
+
+ if (altLoc) strcpy ( aLoc,altLoc );
+ else aLoc[0] = char(0);
+ if (nAltLocs<=1) {
+ // Only one alt code is there, check if it is what was ordered
+ if (strcmp(aLoc,aL[0])) {
+ rc = MKGRAPH_ChangedAltLoc;
+ strcpy ( aLoc,aL[0] );
+ }
+ } else if ((alflag & ALF_Mess) ||
+ ((alflag & ALF_NoEmptyAltLoc) && (!aLoc[0]))) {
+ // There is a mess in the residue alt codes, or empty alt code
+ // does not designate a conformation but ordered. In this
+ // situation build graph for maximal-occupancy conformation
+ // and store its altLoc in aLoc.
+ rc = MKGRAPH_MaxOccupancy;
+ dx = -2.0;
+ for (i=0;i<nAltLocs;i++)
+ if ((aL[i][0]) && (occupancy[i]>dx)) {
+ dx = occupancy[i];
+ strcpy ( aLoc,aL[i] );
+ }
+ }
+
+ SetName ( R->name );
+
+ nVAlloc = R->nAtoms; // upper estimate for vertices to allocate
+ if (nVAlloc<=0) {
+ if (aL) delete[] aL;
+ FreeVectorMemory ( occupancy,0 );
+ return MKGRAPH_NoAtoms;
+ }
+
+ // allocate vertex array
+ vertex = new PVertex[nVAlloc];
+ for (i=0;i<nVAlloc;i++)
+ vertex[i] = NULL;
+
+ // make vertices
+ for (i=0;i<R->nAtoms;i++)
+ if (R->atom[i]) {
+ if (!R->atom[i]->Ter) {
+ if (nAltLocs>1) {
+ // This is a many-altcode residue. aLoc contains the altcode
+ // that has to be included. Check on it:
+ B = !strcmp(aLoc,R->atom[i]->altLoc);
+ if ((!B) && (!R->atom[i]->altLoc[0])) {
+ // We got a non-aLoc code that is an "empty-altcode".
+ // Check if this atom has the altcode that we need.
+ for (j=i+1;(j<R->nAtoms) && (!B);j++)
+ if (R->atom[j]) {
+ if ((!R->atom[j]->Ter) &&
+ (!strcmp(R->atom[j]->name,R->atom[i]->name)))
+ B = !strcmp(aLoc,R->atom[j]->altLoc);
+ }
+ // if altcode=aLoc is not there for the atom (B is set
+ // false) then we take its "empty-code" location
+ B = !B;
+ }
+ } else
+ B = true;
+ if (B) {
+ vertex[nVertices] = new Vertex ( R->atom[i]->element,
+ R->atom[i]->name );
+ vertex[nVertices]->id = nVertices;
+ vertex[nVertices]->user_id = i;
+ nVertices++;
+ }
+ }
+ }
+
+ if (nVertices<=0) {
+ if (aL) delete[] aL;
+ FreeVectorMemory ( occupancy,0 );
+ return MKGRAPH_NoAtoms;
+ }
+
+ // make edges
+ nEAlloc = 3*nVertices;
+ edge = new PEdge[nEAlloc];
+ for (i=0;i<nEAlloc;i++)
+ edge[i] = NULL;
+
+ for (i=0;i<nVertices;i++) {
+ a1 = vertex[i]->user_id;
+ e1 = vertex[i]->type;
+ if (e1>nElementNames) e1 = 6;
+ e1--;
+ for (j=i+1;j<nVertices;j++) {
+ a2 = vertex[j]->user_id;
+ e2 = vertex[j]->type;
+ if (e2>nElementNames) e2 = 6;
+ e2--;
+ dx = R->atom[a2]->x - R->atom[a1]->x;
+ dy = R->atom[a2]->y - R->atom[a1]->y;
+ dz = R->atom[a2]->z - R->atom[a1]->z;
+ // sr = CovalentRadius[e1] + CovalentRadius[e2] + 0.15;
+ sr = CovalentRadius[e1] + CovalentRadius[e2] + 0.25;
+ if (dx*dx+dy*dy+dz*dz<sr*sr) { // it's a bond
+ G = new Edge(i+1,j+1,1);
+ AddEdge ( G );
+ }
+ }
+ vertex[i]->id = i+1;
+ }
+
+ if (aL) delete[] aL;
+ FreeVectorMemory ( occupancy,0 );
+
+ nAllVertices = nVertices;
+ nAllEdges = nEdges;
+
+ return rc;
+
+ }
+
+ int Graph::MakeGraph ( PPAtom atom, int nAtoms ) {
+ PEdge G;
+ char atomID[100];
+ realtype dx,dy,dz, sr;
+ int i,j, a1,a2,e1,e2, rc;
+
+ rc = MKGRAPH_Ok;
+ // reset graph
+ FreeMemory();
+
+ nVAlloc = nAtoms; // upper estimate for vertices to allocate
+ if (nVAlloc<=0) return MKGRAPH_NoAtoms;
+
+ // allocate vertex array
+ vertex = new PVertex[nVAlloc];
+ for (i=0;i<nVAlloc;i++)
+ vertex[i] = NULL;
+
+ // make vertices
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (!atom[i]->Ter) {
+ vertex[nVertices] = new Vertex ( atom[i]->element,
+ atom[i]->GetAtomIDfmt(atomID) );
+ vertex[nVertices]->user_id = i;
+ nVertices++;
+ }
+ }
+
+ if (nVertices<=0) {
+ FreeMemory();
+ return MKGRAPH_NoAtoms;
+ }
+
+ // make edges
+ nEAlloc = 3*nVertices; // just an inital guess
+ edge = new PEdge[nEAlloc];
+ for (i=0;i<nEAlloc;i++)
+ edge[i] = NULL;
+
+ for (i=0;i<nVertices;i++) {
+ a1 = vertex[i]->user_id;
+ e1 = vertex[i]->type;
+ if (e1>nElementNames) e1 = 6;
+ e1--;
+ for (j=i+1;j<nVertices;j++) {
+ a2 = vertex[j]->user_id;
+ e2 = vertex[j]->type;
+ if (e2>nElementNames) e2 = 6;
+ e2--;
+ dx = atom[a2]->x - atom[a1]->x;
+ dy = atom[a2]->y - atom[a1]->y;
+ dz = atom[a2]->z - atom[a1]->z;
+ sr = CovalentRadius[e1] + CovalentRadius[e2] + 0.25;
+ if (dx*dx+dy*dy+dz*dz<sr*sr) { // it's a bond
+ G = new Edge(i+1,j+1,1); // don't guess on bond order here
+ AddEdge ( G );
+ }
+ }
+ vertex[i]->id = i+1;
+ }
+
+ nAllVertices = nVertices;
+ nAllEdges = nEdges;
+
+ return rc;
+
+ }
+
+
+ void Graph::MakeVertexIDs() {
+ int i;
+ for (i=0;i<nAllVertices;i++)
+ vertex[i]->id = i+1;
+ }
+
+ void Graph::HideType ( int bond_vx_type ) {
+ // 1. Moves vertices bond_vx_type to the end of vertex array
+ // 2. Moves edges to bond_vx_type vertices to the end of edge array
+ // 3. Saves lengths of full vertex and edge arrays, and redefines
+ // lengths to initial parts of the arrays not containing
+ // bond_vx_type vertices.
+ PPEdge Edge1;
+ PPVertex Vertex1;
+ int i,k,v1,v2, nEdges1,nVertices1;
+ ivector iv;
+
+ Edge1 = new PEdge[nEdges];
+ Vertex1 = new PVertex[nVertices];
+ GetVectorMemory ( iv,nVertices,1 );
+
+ for (i=0;i<nEdges;i++)
+ if (edge[i]) {
+ v1 = edge[i]->v1-1;
+ v2 = edge[i]->v2-1;
+ if (vertex[v1] && vertex[v2]) {
+ if ((vertex[v1]->type & (int)TYPE_MASK)==bond_vx_type) {
+ vertex[v2]->AddBond();
+ vertex[v1]->CopyNBonds ( vertex[v2] );
+ }
+ if ((vertex[v2]->type & (int)TYPE_MASK)==bond_vx_type) {
+ vertex[v1]->AddBond();
+ vertex[v2]->CopyNBonds ( vertex[v1] );
+ }
+ }
+ }
+
+ nVertices1 = 0;
+ for (i=0;i<nVertices;i++)
+ if (vertex[i]) {
+ if ((vertex[i]->type & (int)TYPE_MASK)!=bond_vx_type) {
+ Vertex1[nVertices1++] = vertex[i];
+ iv[i+1] = nVertices1;
+ }
+ }
+ k = nVertices1;
+ for (i=0;i<nVertices;i++)
+ if (vertex[i]) {
+ if ((vertex[i]->type & (int)TYPE_MASK)==bond_vx_type) {
+ Vertex1[k++] = vertex[i];
+ iv[i+1] = k;
+ }
+ }
+
+ nEdges1 = 0;
+ for (i=0;i<nEdges;i++)
+ if (edge[i]) {
+ edge[i]->v1 = iv[edge[i]->v1];
+ edge[i]->v2 = iv[edge[i]->v2];
+ if (((Vertex1[edge[i]->v1-1]->type & (int)TYPE_MASK) !=
+ bond_vx_type) &&
+ ((Vertex1[edge[i]->v2-1]->type & (int)TYPE_MASK) !=
+ bond_vx_type))
+ Edge1[nEdges1++] = edge[i];
+ }
+ k = nEdges1;
+ for (i=0;i<nEdges;i++)
+ if (edge[i]) {
+ if (((Vertex1[edge[i]->v1-1]->type & (int)TYPE_MASK) ==
+ bond_vx_type) ||
+ ((Vertex1[edge[i]->v2-1]->type & (int)TYPE_MASK) ==
+ bond_vx_type))
+ Edge1[k++] = edge[i];
+ }
+
+ nAllVertices = nVertices;
+ nAllEdges = nEdges;
+ nVAlloc = nVertices;
+ nEAlloc = nEdges;
+ nVertices = nVertices1;
+ nEdges = nEdges1;
+
+ if (vertex) delete[] vertex;
+ if (edge) delete[] edge;
+ FreeVectorMemory ( iv,1 );
+
+ vertex = Vertex1;
+ edge = Edge1;
+
+ }
+
+ void Graph::ExcludeType ( int type ) {
+ int i,k;
+ ivector iv;
+ GetVectorMemory ( iv,nAllVertices,1 );
+ k = 0;
+ for (i=0;i<nAllVertices;i++)
+ if ((vertex[i]->type & (int)TYPE_MASK)!=type) {
+ if (k<i) {
+ vertex[k] = vertex[i];
+ vertex[i] = NULL;
+ }
+ k++;
+ iv[i+1] = k;
+ } else {
+ delete vertex[i];
+ vertex[i] = NULL;
+ iv[i+1] = 0;
+ }
+ nAllVertices = k;
+ nVertices = nAllVertices;
+ k = 0;
+ for (i=0;i<nAllEdges;i++)
+ if ((iv[edge[i]->v1]!=0) && (iv[edge[i]->v2]!=0)) {
+ if (k<i) {
+ edge[k] = edge[i];
+ edge[i] = NULL;
+ }
+ edge[k]->v1 = iv[edge[k]->v1];
+ edge[k]->v2 = iv[edge[k]->v2];
+ k++;
+ } else {
+ delete edge[i];
+ edge[i] = NULL;
+ }
+ nAllEdges = k;
+ nEdges = nAllEdges;
+ FreeVectorMemory ( iv,1 );
+ }
+
+ void Graph::RemoveChirality() {
+ int i;
+ for (i=0;i<nAllVertices;i++)
+ if (vertex[i]) vertex[i]->RemoveChirality();
+ }
+
+ void Graph::LeaveChirality ( int eltype ) {
+ // leaves chirality for specified atom types
+ int i;
+ for (i=0;i<nAllVertices;i++)
+ if (vertex[i]) vertex[i]->LeaveChirality ( eltype );
+ }
+
+ void Graph::MakeSymmetryRelief ( bool noCO2 ) {
+ // This function looks for groups of equivalent vertices
+ // attached to a single vertice (e.g. chemical SO3 or
+ // PO3 groups), and re-lables them by adding a unique
+ // symmetry-relief number. This eliminates equivalent
+ // GMatches (3! for each SO3/PO3 group), and increases
+ // vertex diversity, which considerably speeds up GMatching.
+ // The function is cheap and harmless even if such groups
+ // of vertices are not found.
+ // If noCO2 is true then CO2 symmetry is not releaved.
+ ivector v,vc;
+ int i,j,k,n,m,almask,vjtype, ctype,otype;
+ bool noOxygens;
+
+ otype = 0;
+ ctype = 0;
+
+ GetVectorMemory ( v ,nVertices,0 );
+ GetVectorMemory ( vc,nVertices,1 );
+
+ for (i=1;i<=nVertices;i++)
+ vc[i] = 0;
+
+ for (j=0;j<nEdges;j++) {
+ if ((edge[j]->v1>0) && (edge[j]->v1<=nVertices))
+ vc[edge[j]->v1]++;
+ if ((edge[j]->v2>0) && (edge[j]->v2<=nVertices))
+ vc[edge[j]->v2]++;
+ }
+
+ almask = ~ATOM_LEAVING;
+
+ if (noCO2) {
+ ctype = getElementNo ( "C" );
+ otype = getElementNo ( "O" );
+ }
+
+ noOxygens = false;
+
+ for (i=1;i<=nVertices;i++)
+ if (vc[i]>1) { // vertex at more than 1 edge
+ // v[] will list connected vertices, k will be their number
+ k = 0;
+ for (j=0;j<nEdges;j++) {
+ if ((edge[j]->v1==i) && (vc[edge[j]->v2]==1) && (k<nVertices))
+ v[k++] = edge[j]->v2-1;
+ if ((edge[j]->v2==i) && (vc[edge[j]->v1]==1) && (k<nVertices))
+ v[k++] = edge[j]->v1-1;
+ }
+ if (k>1) {
+ if (noCO2) noOxygens = ((vertex[i-1]->type & almask)==ctype);
+ // A group of vertices with single connection is
+ // identified. Assign symmetry relief modifiers
+ // to *equivalent* vertices in the group
+ for (j=0;j<k;j++)
+ if ((v[j]>=0) && (v[j]<nVertices)) {
+ vjtype = vertex[v[j]]->type & almask;
+ if ((!noOxygens) || (vjtype!=otype)) {
+ n = 1; // symmetry relief modifier
+ for (m=j+1;m<k;m++)
+ if ((v[m]>=0) && (v[m]<nVertices)) {
+ if (vertex[v[j]]->type==
+ (vertex[v[m]]->type & almask)) {
+ vertex[v[m]]->type |= (n << 16);
+ n++;
+ v[m] = -1;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ FreeVectorMemory ( v ,0 );
+ FreeVectorMemory ( vc,1 );
+
+ }
+
+ int Graph::Build ( bool bondOrder ) {
+ int i,j, rc;
+
+ if (nVertices<=0) return 2;
+
+ if (nGAlloc<nVertices) {
+ FreeMatrixMemory ( graph,nGAlloc,1,1 );
+ nGAlloc = nVertices;
+ GetMatrixMemory ( graph,nGAlloc,nGAlloc,1,1 );
+ }
+
+ for (i=1;i<=nVertices;i++)
+ for (j=1;j<=nVertices;j++)
+ graph[i][j] = 0;
+
+ rc = 0;
+ if (bondOrder) {
+
+ for (i=0;(i<nEdges) && (!rc);i++)
+ if ((edge[i]->v1>=1) && (edge[i]->v1<=nVertices) &&
+ (edge[i]->v2>=1) && (edge[i]->v2<=nVertices)) {
+ graph[edge[i]->v1][edge[i]->v2] = edge[i]->type;
+ graph[edge[i]->v2][edge[i]->v1] = edge[i]->type;
+ } else
+ rc = 1;
+
+ } else {
+
+ for (i=0;i<nEdges;i++)
+ if ((edge[i]->v1>=1) && (edge[i]->v1<=nVertices) &&
+ (edge[i]->v2>=1) && (edge[i]->v2<=nVertices)) {
+ graph[edge[i]->v1][edge[i]->v2] = 1;
+ graph[edge[i]->v2][edge[i]->v1] = 1;
+ } else
+ rc = 1;
+
+ }
+
+ return rc;
+
+ }
+
+
+ const int ring_mask[] = {
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000001,
+ 0x00000002,
+ 0x00000004,
+ 0x00000008,
+ 0x00000010,
+ 0x00000020,
+ 0x00000040,
+ 0x00000080
+ };
+
+ void Graph::IdentifyRings() {
+ GraphMatch GM;
+ Graph ring;
+ ivector F1,F2;
+ AtomName aname;
+ realtype p1,p2;
+ int i,j,n,nrings,nv;
+
+ Build ( false );
+
+ for (i=0;i<nVertices;i++)
+ vertex[i]->type_ext = 0;
+
+ GM.SetFlag ( GMF_UniqueMatch );
+
+ for (n=3;n<=10;n++) {
+
+ ring.Reset();
+
+ for (i=1;i<=n;i++) {
+ sprintf ( aname,"C%i",i );
+ ring.AddVertex ( new Vertex("C",aname) );
+ }
+
+ ring.MakeVertexIDs();
+
+ for (i=1;i<=n;i++) {
+ j = i+1;
+ if (j>n) j = 1;
+ ring.AddEdge ( new Edge(i,j,1) );
+ }
+
+ ring.Build ( false );
+
+ GM.MatchGraphs ( this,&ring,n,false,EXTTYPE_Ignore );
+
+ nrings = GM.GetNofMatches();
+ for (i=0;i<nrings;i++) {
+ GM.GetMatch ( i,F1,F2,nv,p1,p2 );
+ for (j=1;j<nv;j++)
+ vertex[F1[j]-1]->type_ext |= ring_mask[n];
+ }
+
+ }
+
+ }
+
+ void Graph::markConnected ( int vno, int cno ) {
+ int i;
+
+ vertex[vno]->type_ext = cno;
+ for (i=0;i<nVertices;i++)
+ if (graph[vno+1][i+1] && (!vertex[i]->type_ext))
+ markConnected ( i,cno );
+
+ }
+
+
+ int Graph::IdentifyConnectedComponents() {
+ // Returns the number of connected components and sets
+ // vertex[]->type_ext equal to component number >=1.
+ int nComponents,i;
+
+ nComponents = 0;
+
+ Build ( false );
+
+ for (i=0;i<nVertices;i++)
+ vertex[i]->type_ext = 0;
+
+ i = 0;
+ while (i<nVertices) {
+ while (i<nVertices)
+ if (vertex[i]->type_ext) i++;
+ else break;
+ if (i<nVertices) {
+ nComponents++;
+ markConnected ( i,nComponents );
+ }
+ }
+
+ return nComponents;
+
+ }
+
+
+
+ void Graph::Print() {
+ int i;
+
+ printf ( " ===== Graph %s \n\n",name );
+
+ if (nVertices>0) {
+ printf ( " Vertices:\n"" ## " );
+ vertex[0]->Print(1);
+ printf ( "\n" );
+ for (i=0;i<nVertices;i++) {
+ printf ( " %4i ",i+1 );
+ vertex[i]->Print(0);
+ printf ( "\n" );
+ }
+ }
+
+ if (nEdges>0) {
+ printf ( " Edges:\n"" ## " );
+ edge[0]->Print(1);
+ printf ( "\n" );
+ for (i=0;i<nEdges;i++) {
+ printf ( " %4i ",i+1 );
+ edge[i]->Print(0);
+ printf ( "\n" );
+ }
+ }
+
+
+ }
+
+ void Graph::Print1() {
+ int i,j;
+ for (i=0;i<nVertices;i++) {
+ printf ( " %4i %5i %3i %7s ",
+ i+1,vertex[i]->id,vertex[i]->type,vertex[i]->name );
+ for (j=0;j<nEdges;j++)
+ if (edge[j]->v1==i+1)
+ printf ( " %4i(%i)",edge[j]->v2,edge[j]->type );
+ else if (edge[j]->v2==i+1)
+ printf ( " %4i(%i)",edge[j]->v1,edge[j]->type );
+ printf ( "\n" );
+ }
+ }
+
+
+ void Graph::Copy ( PGraph G ) {
+ int i;
+
+ FreeMemory();
+
+ CreateCopy ( name,G->name );
+ nVertices = G->nVertices;
+ nEdges = G->nEdges;
+ nAllVertices = G->nAllVertices;
+ nAllEdges = G->nAllEdges;
+ if (nAllVertices>0) {
+ nVAlloc = nAllVertices;
+ vertex = new PVertex[nVAlloc];
+ for (i=0;i<nAllVertices;i++) {
+ vertex[i] = new Vertex();
+ vertex[i]->Copy ( G->vertex[i] );
+ }
+ }
+ if (nAllEdges>0) {
+ nEAlloc = nAllEdges;
+ edge = new PEdge[nEAlloc];
+ for (i=0;i<nAllEdges;i++) {
+ edge[i] = new Edge();
+ edge[i]->Copy ( G->edge[i] );
+ }
+ }
+
+ }
+
+ void Graph::write ( io::RFile f ) {
+ int i;
+ int Version=2;
+ bool bondOrder=false;
+ f.WriteInt ( &Version );
+ f.WriteBool ( &bondOrder );
+ f.CreateWrite ( name );
+ f.WriteInt ( &nVertices );
+ f.WriteInt ( &nEdges );
+ f.WriteInt ( &nAllVertices );
+ f.WriteInt ( &nAllEdges );
+ for (i=0;i<nAllVertices;i++)
+ StreamWrite ( f,vertex[i] );
+ for (i=0;i<nAllEdges;i++)
+ StreamWrite ( f,edge[i] );
+ }
+
+ void Graph::read ( io::RFile f ) {
+ int i,Version;
+ bool bondOrder;
+
+ FreeMemory();
+
+ f.ReadInt ( &Version );
+ f.ReadBool ( &bondOrder );
+ f.CreateRead ( name );
+ f.ReadInt ( &nVertices );
+ f.ReadInt ( &nEdges );
+ if (Version>1) {
+ f.ReadInt ( &nAllVertices );
+ f.ReadInt ( &nAllEdges );
+ } else {
+ nAllVertices = nVertices;
+ nAllEdges = nEdges;
+ }
+ if (nAllVertices>0) {
+ nVAlloc = nAllVertices;
+ vertex = new PVertex[nVAlloc];
+ for (i=0;i<nAllVertices;i++) {
+ vertex[i] = NULL;
+ StreamRead ( f,vertex[i] );
+ }
+ }
+ if (nAllEdges>0) {
+ nEAlloc = nAllEdges;
+ edge = new PEdge[nEAlloc];
+ for (i=0;i<nAllEdges;i++) {
+ edge[i] = NULL;
+ StreamRead ( f,edge[i] );
+ }
+ }
+
+ // Build ( bondOrder );
+
+ }
+
+ void Graph::mem_write ( pstr S, int & l ) {
+ int i,k;
+ byte Version=2;
+ bool bondOrder=false;
+
+ mmdb::mem_write_byte ( Version,S,l );
+ mmdb::mem_write ( bondOrder ,S,l );
+ mmdb::mem_write ( name ,S,l );
+ mmdb::mem_write ( nVertices ,S,l );
+ mmdb::mem_write ( nEdges ,S,l );
+ mmdb::mem_write ( nAllVertices,S,l );
+ mmdb::mem_write ( nAllEdges ,S,l );
+ for (i=0;i<nAllVertices;i++)
+ if (vertex[i]) {
+ k = 1;
+ mmdb::mem_write ( k,S,l );
+ vertex[i]->mem_write ( S,l );
+ } else {
+ k = 0;
+ mmdb::mem_write ( k,S,l );
+ }
+ for (i=0;i<nAllEdges;i++)
+ if (edge[i]) {
+ k = 1;
+ mmdb::mem_write ( k,S,l );
+ edge[i]->mem_write ( S,l );
+ } else {
+ k = 0;
+ mmdb::mem_write ( k,S,l );
+ }
+
+ }
+
+ void Graph::mem_read ( cpstr S, int & l ) {
+ int i,k;
+ byte Version;
+ bool bondOrder;
+
+ FreeMemory();
+
+ mmdb::mem_read_byte ( Version,S,l );
+ mmdb::mem_read ( bondOrder ,S,l );
+ mmdb::mem_read ( name ,S,l );
+ mmdb::mem_read ( nVertices ,S,l );
+ mmdb::mem_read ( nEdges ,S,l );
+ mmdb::mem_read ( nAllVertices,S,l );
+ mmdb::mem_read ( nAllEdges ,S,l );
+ if (nAllVertices>0) {
+ nVAlloc = nAllVertices;
+ vertex = new PVertex[nVAlloc];
+ for (i=0;i<nAllVertices;i++) {
+ mmdb::mem_read ( k,S,l );
+ if (k) {
+ vertex[i] = new Vertex();
+ vertex[i]->mem_read ( S,l );
+ } else
+ vertex[i] = NULL;
+ }
+ }
+ if (nAllEdges>0) {
+ nEAlloc = nAllEdges;
+ edge = new PEdge[nEAlloc];
+ for (i=0;i<nAllEdges;i++) {
+ mmdb::mem_read ( k,S,l );
+ if (k) {
+ edge[i] = new Edge();
+ edge[i]->mem_read ( S,l );
+ } else {
+ edge[i] = NULL;
+ }
+ }
+ }
+
+ // Build ( bondOrder );
+
+ }
+
+ MakeStreamFunctions(Graph)
+
+
+ // ========================== GMatch ============================
+
+ GMatch::GMatch() : io::Stream() {
+ InitGMatch();
+ }
+
+ GMatch::GMatch ( io::RPStream Object ) : io::Stream ( Object ) {
+ InitGMatch();
+ }
+
+ GMatch::GMatch ( ivector FV1, ivector FV2, int nv, int n, int m ) {
+ int i;
+ if (FV1 && FV2) {
+ n1 = n;
+ n2 = m;
+ nAlloc = n;
+ GetVectorMemory ( F1,nAlloc,1 );
+ GetVectorMemory ( F2,nAlloc,1 );
+ mlength = nv;
+ for (i=1;i<=mlength;i++) {
+ F1[i] = FV1[i];
+ F2[i] = FV2[i];
+ }
+ } else
+ InitGMatch();
+ }
+
+ void GMatch::InitGMatch() {
+ mlength = 0;
+ n1 = 0;
+ n2 = 0;
+ nAlloc = 0;
+ F1 = NULL;
+ F2 = NULL;
+ }
+
+ GMatch::~GMatch() {
+ FreeVectorMemory ( F1,1 );
+ FreeVectorMemory ( F2,1 );
+ }
+
+ void GMatch::SetMatch ( ivector FV1, ivector FV2,
+ int nv, int n, int m ) {
+ int i;
+ if (FV1 && FV2) {
+ if (nv>nAlloc) {
+ FreeVectorMemory ( F1,1 );
+ FreeVectorMemory ( F2,1 );
+ nAlloc = n;
+ GetVectorMemory ( F1,nAlloc,1 );
+ GetVectorMemory ( F2,nAlloc,1 );
+ }
+ n1 = n;
+ n2 = m;
+ mlength = nv;
+ for (i=1;i<=mlength;i++) {
+ F1[i] = FV1[i];
+ F2[i] = FV2[i];
+ }
+ } else {
+ FreeVectorMemory ( F1,1 );
+ FreeVectorMemory ( F2,1 );
+ mlength = 0;
+ n1 = 0;
+ n2 = 0;
+ }
+ }
+
+
+ bool GMatch::isMatch ( ivector FV1, ivector FV2, int nv ) {
+ int i,j;
+ bool B;
+ if (FV1 && FV2 && (nv<=mlength)) {
+ B = true;
+ for (i=1;(i<=nv) && B;i++) {
+ B = false;
+ for (j=1;(j<=mlength) && (!B);j++)
+ B = (FV1[i]==F1[j]) && (FV2[i]==F2[j]);
+ }
+ return B;
+ }
+ return false;
+ }
+
+ bool GMatch::isCombination ( ivector FV1, ivector FV2, int nv ) {
+ int i,j;
+ bool B;
+ if (FV1 && FV2 && (nv==mlength)) {
+ B = true;
+ for (i=1;(i<=nv) && B;i++) {
+ B = false;
+ for (j=1;(j<=mlength) && (!B);j++)
+ B = (FV1[i]==F1[j]);
+ if (B) {
+ B = false;
+ for (j=1;(j<=mlength) && (!B);j++)
+ B = (FV2[i]==F2[j]);
+ }
+ }
+ return B;
+ }
+ return false;
+ }
+
+
+ void GMatch::GetMatch ( ivector & FV1, ivector & FV2, int & nv,
+ realtype & p1, realtype & p2 ) {
+ FV1 = F1;
+ FV2 = F2;
+ nv = mlength;
+ p1 = mlength;
+ if (p1>0.0) p1 /= n1;
+ p2 = mlength;
+ if (p2>0.0) p2 /= n2;
+ }
+
+ void GMatch::write ( io::RFile f ) {
+ int i;
+ int Version=1;
+ f.WriteInt ( &Version );
+ f.WriteInt ( &mlength );
+ f.WriteInt ( &n1 );
+ f.WriteInt ( &n2 );
+ for (i=1;i<=mlength;i++) {
+ f.WriteInt ( &(F1[i]) );
+ f.WriteInt ( &(F2[i]) );
+ }
+ }
+
+ void GMatch::read ( io::RFile f ) {
+ int i,Version;
+ FreeVectorMemory ( F1,1 );
+ FreeVectorMemory ( F2,1 );
+ f.ReadInt ( &Version );
+ f.ReadInt ( &mlength );
+ f.ReadInt ( &n1 );
+ f.ReadInt ( &n2 );
+ if (mlength>0) {
+ nAlloc = n1;
+ GetVectorMemory ( F1,nAlloc,1 );
+ GetVectorMemory ( F2,nAlloc,1 );
+ for (i=1;i<=mlength;i++) {
+ f.ReadInt ( &(F1[i]) );
+ f.ReadInt ( &(F2[i]) );
+ }
+ }
+ }
+
+ void GMatch::mem_write ( pstr S, int & l ) {
+ int i;
+ mmdb::mem_write ( mlength,S,l );
+ mmdb::mem_write ( n1 ,S,l );
+ mmdb::mem_write ( n2 ,S,l );
+ for (i=1;i<=mlength;i++) {
+ mmdb::mem_write ( F1[i],S,l );
+ mmdb::mem_write ( F2[i],S,l );
+ }
+ }
+
+ void GMatch::mem_read ( cpstr S, int & l ) {
+ int i;
+ FreeVectorMemory ( F1,1 );
+ FreeVectorMemory ( F2,1 );
+ mmdb::mem_read ( mlength,S,l );
+ mmdb::mem_read ( n1 ,S,l );
+ mmdb::mem_read ( n2 ,S,l );
+ if (mlength>0) {
+ nAlloc = n1;
+ GetVectorMemory ( F1,nAlloc,1 );
+ GetVectorMemory ( F2,nAlloc,1 );
+ for (i=1;i<=mlength;i++) {
+ mmdb::mem_read ( F1[i],S,l );
+ mmdb::mem_read ( F2[i],S,l );
+ }
+ }
+ }
+
+
+ MakeStreamFunctions(GMatch)
+
+
+
+ // ======================== GraphMatch ==========================
+
+ GraphMatch::GraphMatch()
+ : io::Stream() {
+ InitGraphMatch();
+ }
+
+ GraphMatch::GraphMatch ( io::RPStream Object )
+ : io::Stream ( Object ) {
+ InitGraphMatch();
+ }
+
+ GraphMatch::~GraphMatch() {
+ FreeMemory();
+ }
+
+ void GraphMatch::InitGraphMatch() {
+ G1 = NULL;
+ G2 = NULL;
+ n = 0;
+ m = 0;
+ P = NULL;
+ nAlloc = 0;
+ mAlloc = 0;
+ nMatches = 0;
+ maxNMatches = -1; // unlimited
+ Match = NULL;
+ nMAlloc = 0;
+ flags = 0;
+ swap = false;
+ wasFullMatch = false;
+ maxMatch = 0;
+ timeLimit = 0; // no time limit
+ Stop = false;
+ stopOnMaxNMathches = false;
+ F1 = NULL;
+ F2 = NULL;
+ iF1 = NULL;
+ ix = NULL;
+ #ifndef _UseRecursion
+ jj = NULL;
+ #endif
+ }
+
+
+ void GraphMatch::SetFlag ( word flag ) {
+ flags |= flag;
+ }
+
+ void GraphMatch::RemoveFlag ( word flag ) {
+ flags &= ~flag;
+ }
+
+ void GraphMatch::SetMaxNofMatches ( int maxNofGMatches,
+ bool stopOnMaxN ) {
+ maxNMatches = maxNofGMatches;
+ stopOnMaxNMathches = stopOnMaxN;
+ }
+
+ void GraphMatch::SetTimeLimit ( int maxTimeToRun ) {
+ timeLimit = maxTimeToRun;
+ }
+
+ void GraphMatch::Reset() {
+ FreeMemory();
+ }
+
+ void GraphMatch::FreeMemory() {
+ int i;
+
+ if (P) {
+ FreeMatrixMemory ( P[1],nAlloc,1,0 );
+ FreeRecHeap ();
+ P = P + 1;
+ delete[] P;
+ P = NULL;
+ }
+
+ FreeMatrixMemory ( iF1,nAlloc,1,1 );
+
+ FreeVectorMemory ( F1 ,1 );
+ FreeVectorMemory ( F2 ,1 );
+ FreeVectorMemory ( ix ,1 );
+ nAlloc = 0;
+ mAlloc = 0;
+
+ if (Match) {
+ for (i=0;i<nMAlloc;i++)
+ if (Match[i]) delete Match[i];
+ delete[] Match;
+ }
+ Match = NULL;
+ nMatches = 0;
+ nMAlloc = 0;
+
+ #ifndef _UseRecursion
+ FreeVectorMemory ( jj,1 );
+ #endif
+
+ }
+
+ void GraphMatch::FreeRecHeap() {
+ int i;
+ if (P)
+ for (i=2;i<=nAlloc;i++)
+ FreeMatrixMemory ( P[i],nAlloc,1,0 );
+ }
+
+
+ void GraphMatch::GetMemory() {
+ int i;
+
+ FreeMemory();
+
+ P = new imatrix[n];
+ P = P-1;
+ GetMatrixMemory ( P[1],n,m+1,1,0 );
+ for (i=2;i<=n;i++)
+ P[i] = NULL;
+
+ GetMatrixMemory ( iF1,n,n,1,1 );
+
+ GetVectorMemory ( F1,n,1 );
+ GetVectorMemory ( F2,n,1 );
+ GetVectorMemory ( ix,n,1 );
+
+ #ifndef _UseRecursion
+ GetVectorMemory ( jj,n,1 );
+ #endif
+
+ nAlloc = n;
+ mAlloc = m;
+
+ }
+
+ void GraphMatch::GetRecHeap() {
+ int i,j;
+ for (i=2;i<=n;i++) {
+ P[i] = new ivector[nAlloc];
+ P[i] = P[i]-1;
+ for (j=1;j<=n;j++)
+ GetVectorMemory ( P[i][j],P[1][j][0]+1,0 );
+ for (j=n+1;j<=nAlloc;j++)
+ P[i][j] = NULL;
+ }
+ }
+
+
+ void GraphMatch::MatchGraphs ( PGraph Gh1, PGraph Gh2,
+ int minMatch,
+ bool vertexType,
+ VERTEX_EXT_TYPE vertexExt ) {
+ // GMatchGraphs looks for maximal common subgraphs of size
+ // not less than minGMatch. The number of found subgraphs
+ // is returned by GetNofGMatches(), the subgraph vertices
+ // are returned by GetGMatch(..). Control parameters:
+ // vertexType true if vertex type should be taken
+ // into account and false otherwise
+ // vertexExt key to use extended vertex types (defined
+ // as type_ext in Vertex).
+ int n1;
+
+ if (Gh1->nVertices<=Gh2->nVertices) {
+ G1 = Gh1;
+ G2 = Gh2;
+ swap = false;
+ } else {
+ G1 = Gh2;
+ G2 = Gh1;
+ swap = true;
+ }
+ n = G1->nVertices;
+ m = G2->nVertices;
+ V1 = G1->vertex;
+ V2 = G2->vertex;
+ c1 = G1->graph;
+ c2 = G2->graph;
+
+ nMatches = 0;
+
+ if (n<=0) return;
+
+ if ((n>nAlloc) || (m>mAlloc)) GetMemory();
+ else FreeRecHeap();
+
+ n1 = Initialize ( vertexType,vertexExt );
+ if (n1<=0) return;
+
+ GetRecHeap();
+
+ maxMatch = IMax(1,IMin(n,minMatch));
+ Stop = false;
+ startTime = time(NULL);
+
+ // Use of Backtrack(..) and Ullman() is completely
+ // equivalent. One of them should be commented.
+
+ if (minMatch<n) {
+
+ if (n1>=minMatch) Backtrack1 ( 1,n1 );
+
+ } else if (n1>=n) {
+
+ #ifdef _UseRecursion
+ Backtrack ( 1 );
+ #else
+ Ullman();
+ #endif
+
+ }
+
+ }
+
+
+ int GraphMatch::Initialize ( bool vertexType, int vertexExt ) {
+ ivector jF1;
+ int i,j,v1type,v1type_ext,v2type_ext,almask,iW,pl;
+
+ wasFullMatch = false;
+
+ jF1 = iF1[1];
+ for (i=1;i<=n;i++)
+ jF1[i] = i;
+
+ almask = ~ATOM_LEAVING;
+
+ /* -- experiment for symmetry reliefs
+ int v2type,v1type_sr,srmask;
+ srmask = ~SYMREL_MASK;
+
+ for (i=1;i<=n;i++) {
+ if (vertexType) {
+ ix[i] = 0;
+ v1type = V1[i-1]->type & almask;
+ v1type_sr = v1type & srmask;
+ pl = 0;
+ for (j=1;j<=m;j++) {
+ v2type = V2[j-1]->type & almask;
+ if ((v1type==v2type) ||
+ (v1type_sr==v2type) ||
+ (v1type==(v2type & srmask)))
+ P[1][i][++pl] = j;
+ }
+ P[1][i][0] = pl;
+ if (pl) ix[i] = i;
+ } else {
+ ix[i] = i;
+ for (j=1;j<=m;j++)
+ P[1][i][j] = j;
+ P[1][i][0] = m;
+ }
+ F1[i] = 0;
+ F2[i] = 0;
+ }
+ */
+
+ for (i=1;i<=n;i++) {
+ ix[i] = 0;
+ v1type = V1[i-1]->type & almask;
+ v1type_ext = V1[i-1]->type_ext;
+ pl = 0;
+ for (j=1;j<=m;j++)
+ if ((v1type==(V2[j-1]->type & almask)) || (!vertexType)) {
+ if (vertexExt==EXTTYPE_Ignore)
+ P[1][i][++pl] = j;
+ else {
+ v2type_ext = V2[j-1]->type_ext;
+ if ((!v1type_ext) && (!v2type_ext))
+ P[1][i][++pl] = j;
+ else
+ switch (vertexExt) {
+ default :
+ case EXTTYPE_Ignore : P[1][i][++pl] = j;
+ break;
+ case EXTTYPE_Equal : if (v1type_ext==v2type_ext)
+ P[1][i][++pl] = j;
+ break;
+ case EXTTYPE_AND : if (v1type_ext & v2type_ext)
+ P[1][i][++pl] = j;
+ break;
+ case EXTTYPE_OR : if (v1type_ext | v2type_ext)
+ P[1][i][++pl] = j;
+ break;
+ case EXTTYPE_XOR : if (v1type_ext ^ v2type_ext)
+ P[1][i][++pl] = j;
+ break;
+ case EXTTYPE_NotEqual : if (v1type_ext!=v2type_ext)
+ P[1][i][++pl] = j;
+ break;
+ case EXTTYPE_NotAND : if ((v1type_ext & v2type_ext)
+ ==0)
+ P[1][i][++pl] = j;
+ break;
+ case EXTTYPE_NotOR : if ((v1type_ext | v2type_ext)
+ ==0)
+ P[1][i][++pl] = j;
+ }
+ }
+ }
+ P[1][i][0] = pl;
+ if (pl) ix[i] = i;
+ F1[i] = 0;
+ F2[i] = 0;
+ }
+ /*
+ } else {
+ for (i=1;i<=n;i++) {
+ ix[i] = i;
+ for (j=1;j<=m;j++)
+ P[1][i][j] = j;
+ P[1][i][0] = m;
+ F1[i] = 0;
+ F2[i] = 0;
+ }
+ }
+ */
+
+ i = 1;
+ j = n;
+ while (i<j)
+ if (ix[j]==0) // make sure that j points on a true-containing
+ j--; // row of P[1]
+ else {
+ if (ix[i]==0) { // swap lower empty row of P[1]
+ iW = ix[i]; // with the lth one, which
+ ix[i] = ix[j]; // is surely not empty
+ ix[j] = iW;
+ iW = jF1[i];
+ jF1[i] = jF1[j];
+ jF1[j] = iW;
+ }
+ i++;
+ }
+
+ if (ix[i]==0) return i-1;
+ else return i;
+
+ }
+
+
+ #ifdef _UseRecursion
+
+ void GraphMatch::Backtrack ( int i ) {
+ // Recursive version of Ullman's algorithm for exact
+ // (structure-to-structure or substructure-to-structure)
+ // GMatching
+ int i1,pli,cntj,j,k,pl1,pl2,cntl,l,c1ik;
+ ivector c1i,c2j;
+ ivector p1,p2;
+
+ if (Stop) return;
+ if (timeLimit>0)
+ Stop = (difftime(time(NULL),startTime)>timeLimit);
+
+ F1[i] = i;
+ pli = P[i][i][0];
+
+ if (i>=n) {
+
+ for (cntj=1;(cntj<=pli) && (!Stop);cntj++) {
+ F2[n] = P[n][n][cntj];
+ CollectMatch ( n );
+ }
+
+ } else {
+
+ i1 = i+1;
+ c1i = c1[i];
+
+ for (cntj=1;(cntj<=pli) && (!Stop);cntj++) {
+ j = P[i][i][cntj];
+ F2[i] = j; // mapped F1[i]:F2[i], i.e. i:j
+ // Forward checking
+ c2j = c2[j];
+ pl2 = 1;
+ for (k=i1;(k<=n) && (pl2>0);k++) {
+ p1 = P[i][k];
+ p2 = P[i1][k];
+ c1ik = c1i[k];
+ pl1 = p1[0];
+ pl2 = 0;
+ for (cntl=1;cntl<=pl1;cntl++) {
+ l = p1[cntl];
+ if ((c1ik==c2j[l]) && // check that bonds are compatible
+ (l!=j)) // and make sure jth vertex is excluded
+ p2[++pl2] = l;
+ }
+ p2[0] = pl2; // new length of P-row
+ }
+ if (pl2>0) Backtrack ( i1 );
+ }
+
+ }
+
+ }
+
+ #else
+
+ void GraphMatch::Ullman() {
+ // A non-recursive translation of Ullman's Backtrack.
+ // It might give some gain in performance, although tests
+ // on SGI machine show that the gain is negligible, (if
+ // there is any at all) if compiler's optimization is
+ // switched on.
+ int i,pl,i1,pli,cntj,j,pl1,pl2,k,cntl,l,l1,cik;
+ ivector ci,cj;
+ ivector p1,p2;
+
+ if (Stop) return;
+ if (timeLimit>0)
+ Stop = (difftime(time(NULL),startTime)>timeLimit);
+
+ i = 1;
+ jj[1] = 1;
+ pl = P[1][1][0];
+
+ do {
+
+ F1[i] = i;
+ pli = P[i][i][0];
+
+ if (i>=n) {
+
+ for (cntj=jj[n];(cntj<=pli) && (!Stop);cntj++) {
+ jj[n]++;
+ F2[n] = P[n][n][cntj];
+ CollectGMatch ( n );
+ }
+
+ } else {
+
+ i1 = i+1;
+ ci = c1[i];
+ for (cntj=jj[i];(cntj<=pli) && (!Stop);cntj++) {
+ jj[i]++;
+ j = P[i][i][cntj];
+ F2[i] = j;
+ // Forward checking
+ cj = c2[j];
+ pl2 = 1;
+ for (k=i1;(k<=n) && (pl2>0);k++) {
+ p1 = P[i][k];
+ p2 = P[i1][k];
+ cik = ci[k];
+ pl1 = p1[0];
+ pl2 = 0;
+ for (cntl=1;cntl<=pl1;cntl++) {
+ l = p1[cntl];
+ if ((cik==cj[l]) && // check that bonds are compatible
+ (l!=j)) // and make sure jth vertex is excluded
+ p2[++pl2] = l;
+ }
+ p2[0] = pl2; // new length of P-row
+ }
+ if (pl2>0) {
+ i++;
+ jj[i] = 1;
+ i++; // in order to compensate the following decrement
+ break;
+ }
+ }
+
+ }
+ i--;
+
+ } while ((!Stop) && ((jj[1]<=pl) || (i>1)));
+
+ }
+
+ #endif
+
+ void GraphMatch::Backtrack1 ( int i, int k0 ) {
+ // Recursive version of CSIA algorithm for partial
+ // (substructure-to-substructure) GMatching
+ int i1,pl0,cntj,j,k,pl1,pl2,cntl,l,c1ik,ii,iW,k1;
+ ivector jF1,c1i,c2j;
+ ivector p0,p1,p2;
+
+ if (Stop) return;
+ if (timeLimit>0)
+ Stop = (difftime(time(NULL),startTime)>timeLimit);
+
+ jF1 = iF1[i];
+
+ if (i>=k0) {
+
+ F1[i] = jF1[i];
+ p0 = P[i][jF1[i]];
+ pl0 = p0[0];
+
+ // collect GMatches of k0-th (the upmost) level
+ if (pl0>0) {
+ maxMatch = k0;
+ for (cntj=1;cntj<=pl0;cntj++) {
+ F2[k0] = p0[cntj];
+ CollectMatch ( k0 );
+ }
+ }
+
+ } else {
+
+ i1 = i+1;
+
+ pl0 = P[i][jF1[i]][0];
+ j = i;
+ for (k=i1;k<=k0;k++)
+ if (P[i][jF1[k]][0]<pl0) {
+ pl0 = P[i][jF1[k]][0];
+ j = k;
+ }
+ if (j>i) {
+ iW = jF1[i];
+ jF1[i] = jF1[j];
+ jF1[j] = iW;
+ }
+
+ F1[i] = jF1[i];
+ p0 = P[i][jF1[i]];
+ pl0 = p0[0];
+
+ c1i = c1[jF1[i]];
+
+ // 1. Find all GMatches that include jF1[i]th vertex of graph G1
+
+ for (cntj=1;(cntj<=pl0) && (!Stop);cntj++) {
+ j = p0[cntj];
+ F2[i] = j; // mapped F1[i]:F2[i], i.e. iF1[i][i]:j
+ // Forward checking
+ c2j = c2[j];
+ k1 = k0; // k1 is the limit for GMatch size
+ for (k=i1;(k<=k0) && (k1>=maxMatch);k++) {
+ ix[k] = 0;
+ p1 = P[i] [jF1[k]];
+ p2 = P[i1][jF1[k]];
+ c1ik = c1i [jF1[k]];
+ pl1 = p1[0];
+ pl2 = 0;
+ for (cntl=1;cntl<=pl1;cntl++) {
+ l = p1[cntl];
+ if ((c1ik==c2j[l]) && // check that bonds are compatible
+ (l!=j)) // and make sure jth vertex is excluded
+ p2[++pl2] = l;
+ }
+ p2[0] = pl2; // new length of P-row
+ if (pl2>0) {
+ ix[k] = k;
+ } else if (wasFullMatch) {
+ k1 = maxMatch-1; // we are not interested in partial
+ } else { // GMatch anymore
+ k1--;
+ }
+ }
+ if (k1>=maxMatch) {
+ // shift unGMatching vertices to the end
+ for (ii=1;ii<=n;ii++)
+ iF1[i1][ii] = jF1[ii];
+ k = i1;
+ l = k0;
+ while (k<l)
+ if (ix[l]==0) // make sure that l points on a true-containing
+ l--; // row of P[i1]
+ else {
+ if (ix[k]==0) { // swap lower empty row of P[i1]
+ iW = ix[k]; // with the lth one, which
+ ix[k] = ix[l]; // is surely not empty
+ ix[l] = iW;
+ iW = iF1[i1][k];
+ iF1[i1][k] = iF1[i1][l];
+ iF1[i1][l] = iW;
+ }
+ k++;
+ }
+ if (ix[i1]) Backtrack1 ( i1,k1 );
+ else if (i>=maxMatch) {
+ CollectMatch ( i ); // collect GMatch of ith level
+ maxMatch = i;
+ }
+ }
+ }
+
+ // 2. Find all GMatches that do not include jF1[i]th vertex
+ // of graph G1
+
+ if (k0>maxMatch) {
+ // Shift jF1[i]th vertex to the end
+ iW = jF1[i];
+ jF1[i] = jF1[k0];
+ jF1[k0] = iW;
+ Backtrack1 ( i,k0-1 );
+ }
+
+ }
+
+ }
+
+
+ void GraphMatch::CollectMatch ( int nm ) {
+ int i;
+ bool B;
+ PPGMatch M1;
+
+ if (maxNMatches==0) return;
+
+ // find out if this should be a new GMatch
+ if (nMatches>0) {
+ // a GMatch is already found; check with it
+ if (nm<Match[0]->mlength) return;
+ if (nm>Match[0]->mlength) {
+ nMatches = 0;
+ } else if (flags & GMF_UniqueMatch) {
+ // check if such a GMatch was already found
+ B = false;
+ for (i=0;(i<nMatches) && (!B);i++)
+ B = Match[i]->isMatch(F1,F2,nm);
+ if (B) return; // repeating GMatch -- just quit.
+ } else if (flags & GMF_NoCombinations) {
+ // check if such a GMatch was already found
+ B = false;
+ for (i=0;(i<nMatches) && (!B);i++)
+ B = Match[i]->isCombination(F1,F2,nm);
+ if (B) return; // repeating GMatch -- just quit.
+ }
+ }
+
+ if (nMatches>=nMAlloc) {
+ if ((nMAlloc<maxNMatches) || (maxNMatches<=0)) {
+ if (maxNMatches>0) nMAlloc = IMin(maxNMatches,nMAlloc+100);
+ else nMAlloc += 100;
+ M1 = new PGMatch[nMAlloc];
+ for (i=0;i<nMatches;i++)
+ M1[i] = Match[i];
+ for (i=nMatches;i<nMAlloc;i++)
+ M1[i] = NULL;
+ if (Match) delete[] Match;
+ Match = M1;
+ } else
+ nMatches--;
+ }
+
+ if (!Match[nMatches])
+ Match[nMatches] = new GMatch ( F1,F2,nm,n,m );
+ else Match[nMatches]->SetMatch ( F1,F2,nm,n,m );
+
+ if (nm==n) wasFullMatch = true;
+
+ if (nm>maxMatch) maxMatch = nm;
+
+ nMatches++;
+
+ if (stopOnMaxNMathches && (maxNMatches>0) &&
+ (nMatches>=maxNMatches))
+ Stop = true;
+
+ }
+
+ void GraphMatch::PrintMatches() {
+ int i,j,k;
+ if (nMatches<=0)
+ printf ( "\n\n *** NO GMatchES FOUND\n\n" );
+ else {
+ if (flags & GMF_UniqueMatch)
+ printf ( "\n\n *** FOUND Unique GMatches\n\n" );
+ else printf ( "\n\n *** FOUND GMatches\n\n" );
+ printf ( " ## Vertices\n" );
+ for (i=0;i<nMatches;i++) {
+ printf ( " %5i ",i+1 );
+ k = 8;
+ for (j=1;j<=Match[i]->mlength;j++) {
+ if (swap)
+ printf ( " (%i,%i)",Match[i]->F2[j],Match[i]->F1[j] );
+ else printf ( " (%i,%i)",Match[i]->F1[j],Match[i]->F2[j] );
+ k += 8;
+ if (k>70) {
+ printf ( "\n" );
+ k = 8;
+ }
+ }
+ printf ( "\n" );
+ }
+ }
+ printf ( "\n **************************\n" );
+ }
+
+ void GraphMatch::GetMatch ( int MatchNo, ivector & FV1,
+ ivector & FV2, int & nv,
+ realtype & p1, realtype & p2 ) {
+ // do not allocate or dispose FV1 and FV2 in application!
+ // FV1/p1 will always correspond to Gh1, and FV2/p2 -
+ // to Gh2 as specified in GMatchGraphs(..)
+ if ((MatchNo<0) || (MatchNo>=nMatches)) {
+ FV1 = NULL;
+ FV2 = NULL;
+ nv = 0;
+ p1 = 0.0;
+ p2 = 0.0;
+ } else if (swap)
+ Match[MatchNo]->GetMatch ( FV2,FV1,nv,p2,p1 );
+ else Match[MatchNo]->GetMatch ( FV1,FV2,nv,p1,p2 );
+
+ }
+
+
+ void GraphMatch::write ( io::RFile f ) {
+ int i;
+ int Version=1;
+ f.WriteInt ( &Version );
+ f.WriteInt ( &nMatches );
+ f.WriteWord ( &flags );
+ f.WriteBool ( &swap );
+ for (i=0;i<nMatches;i++)
+ Match[i]->write ( f );
+ }
+
+ void GraphMatch::read ( io::RFile f ) {
+ int i,Version;
+ FreeMemory ();
+ f.ReadInt ( &Version );
+ f.ReadInt ( &nMatches );
+ f.ReadWord ( &flags );
+ f.ReadBool ( &swap );
+ if (nMatches>0) {
+ nMAlloc = nMatches;
+ Match = new PGMatch[nMatches];
+ for (i=0;i<nMatches;i++) {
+ Match[i] = new GMatch();
+ Match[i]->read ( f );
+ }
+ }
+ }
+
+
+ void GraphMatch::mem_write ( pstr S, int & l ) {
+ int i;
+ mmdb::mem_write ( nMatches,S,l );
+ mmdb::mem_write ( flags ,S,l );
+ mmdb::mem_write ( swap ,S,l );
+ for (i=0;i<nMatches;i++)
+ Match[i]->mem_write ( S,l );
+ }
+
+ void GraphMatch::mem_read ( cpstr S, int & l ) {
+ int i;
+ FreeMemory ();
+ mmdb::mem_read ( nMatches,S,l );
+ mmdb::mem_read ( flags ,S,l );
+ mmdb::mem_read ( swap ,S,l );
+ if (nMatches>0) {
+ nMAlloc = nMatches;
+ Match = new PGMatch[nMatches];
+ for (i=0;i<nMatches;i++) {
+ Match[i] = new GMatch();
+ Match[i]->mem_read ( S,l );
+ }
+ }
+ }
+
+ MakeStreamFunctions(GraphMatch)
+
+
+ } // namespace math
+
+} // namespace mmdb
+
+
+// =============================================================
+
+/*
+static char Mol1[][3] = {
+ "C", "C", "C", "C", "C", "C" };
+
+static int Bond1[] = {
+ 1, 2,
+ 1, 6,
+ 2, 3,
+ 3, 4,
+ 4, 5,
+ 5, 6
+};
+
+static char Mol2[][3] = {
+ "C", "C", "C", "C", "C", "C",
+ "C", "C", "C", "C", "C", "C" };
+
+static int Bond2[] = {
+ 1, 2,
+ 1, 6,
+ 2, 3,
+ 3, 4,
+ 4, 5,
+ 5, 6,
+ 1, 7,
+ 2, 8,
+ 3, 9,
+ 4, 10,
+ 5, 11,
+ 6, 12
+};
+
+
+static char Mol1[][3] = {
+ "C", "C", "N", "C" };
+
+static int Bond1[] = {
+ 1, 2,
+ 2, 3,
+ 3, 4
+};
+
+static char Mol2[][3] = {
+ "C", "C", "N", "C" };
+
+static int Bond2[] = {
+ 1, 2,
+ 2, 3,
+ 2, 4,
+ 3, 4
+};
+
+void TestGraphMatch() {
+int i,k1,k2, nv1,nb1, nv2,nb2;
+PVertex V;
+PEdge G;
+Graph G1,G2;
+GraphMatch U;
+
+ G1.Reset ();
+ G1.SetName ( "#1" );
+
+ nv1 = sizeof(Mol1)/3;
+ for (i=0;i<nv1;i++) {
+ V = new Vertex();
+ V->SetVertex ( Mol1[i] );
+ G1.AddVertex ( V );
+ }
+ nb1 = sizeof(Bond1)/(2*sizeof(int));
+ k1 = 0;
+ k2 = 1;
+ for (i=0;i<nb1;i++) {
+ G = new Edge();
+ G->SetEdge ( Bond1[k1],Bond1[k2],1 );
+ G1.AddEdge ( G );
+ k1 += 2;
+ k2 += 2;
+ }
+
+ G2.Reset ();
+ G2.SetName ( "#2" );
+
+ nv2 = sizeof(Mol2)/3;
+ for (i=0;i<nv2;i++) {
+ V = new Vertex();
+ V->SetVertex ( Mol2[i] );
+ G2.AddVertex ( V );
+ }
+ nb2 = sizeof(Bond2)/(2*sizeof(int));
+ k1 = 0;
+ k2 = 1;
+ for (i=0;i<nb2;i++) {
+ G = new Edge();
+ G->SetEdge ( Bond2[k1],Bond2[k2],1 );
+ G2.AddEdge ( G );
+ k1 += 2;
+ k2 += 2;
+ }
+
+ G1.Build();
+ G2.Build();
+
+ U.GMatchGraphs ( &G1,&G2,nv1 );
+
+ U.PrintGMatches();
+
+
+}
+*/
+
diff --git a/mmdb2/mmdb_math_graph.h b/mmdb2/mmdb_math_graph.h
new file mode 100644
index 0000000..f30625f
--- /dev/null
+++ b/mmdb2/mmdb_math_graph.h
@@ -0,0 +1,494 @@
+// $Id: mmdb_math_graph.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : mmdb_math_graph <interface>
+// ~~~~~~~~~
+// **** Namespace: mmdb::math::
+// ~~~~~~~~~~
+// **** Classes : Vertex ( graph vertex )
+// ~~~~~~~~~ Edge ( graph edge )
+// Graph ( structural graph )
+// Match ( match of structural graphs )
+// GraphMatch ( CSIA algorithms for graphs matching )
+//
+// (C) E. Krissinel 2000-2013
+//
+// When used, please cite:
+//
+// Krissinel, E. and Henrick, K. (2004)
+// Common subgraph isomorphism detection by backtracking search.
+// Software - Practice and Experience, 34, 591-607.
+//
+// =================================================================
+//
+
+#ifndef __MMDB_MATH_Graph__
+#define __MMDB_MATH_Graph__
+
+#include <time.h>
+
+#include "mmdb_atom.h"
+
+namespace mmdb {
+
+ namespace math {
+
+ // ========================= Vertex ==========================
+
+ DefineClass(Vertex);
+
+ enum GRAPH_FLAG {
+ CHIRAL_RIGHT = 0x10000000,
+ CHIRAL_LEFT = 0x20000000,
+ ATOM_LEAVING = 0x40000000,
+ HYDROGEN_BOND = 0x0F000000,
+ SYMREL_MASK = 0x00FF0000,
+ CHIRAL_MASK = 0xCFFFFFFF,
+ TYPE_MASK = 0x00FFFFFF
+ };
+
+ class Vertex : public io::Stream {
+
+ friend class Graph;
+ friend class GraphMatch;
+
+ public:
+
+ Vertex ();
+ Vertex ( io::RPStream Object );
+ Vertex ( int vtype, cpstr vname );
+ Vertex ( int vtype );
+ Vertex ( cpstr chem_elem );
+ Vertex ( cpstr chem_elem, cpstr name );
+ ~Vertex();
+
+ void SetVertex ( cpstr chem_elem );
+ void SetVertex ( int vtype, cpstr vname );
+ void SetVertex ( int vtype );
+ void SetType ( int vtype );
+ void SetTypeExt ( int typeExt );
+
+ void RemoveChirality();
+ void LeaveChirality ( int eltype );
+
+ void SetName ( cpstr vname );
+ void SetProperty ( int vprop );
+ void SetID ( int vid );
+ void AddBond ();
+ void CopyNBonds ( PVertex V );
+ inline void SetUserID ( int vid ) { user_id = vid; }
+ inline int GetProperty () { return property; }
+ inline int GetID () { return id; }
+ inline int GetUserID () { return user_id; }
+ inline cpstr GetName () { return name; }
+ inline int GetType () { return type; }
+ inline int GetTypeExt () { return type_ext; }
+ int GetNBonds ();
+
+ void SaveType (); // in userid
+ void RestoreType (); // from userid
+ void CopyType ( PVertex V );
+
+ virtual void Print ( int PKey );
+
+ virtual void Copy ( PVertex V );
+
+ void read ( io::RFile f );
+ void write ( io::RFile f );
+
+ void mem_read ( cpstr S, int & l );
+ void mem_write ( pstr S, int & l );
+
+ protected:
+ pstr name; // name may be general, "C", "Hg", "Cl" etc.
+ int type; // type of vertex, see comments in
+ // mmdb_math_graph.cpp
+ int type_ext; // vertex type extention
+ int property; // flagwise properties -- user-defined
+ int id; // a graph-defined vertex id
+ int user_id; // a user-defined vertex id
+
+ void InitVertex();
+
+ };
+
+ DefineStreamFunctions(Vertex);
+
+
+ // ========================== Edge ===========================
+
+ enum GRAPH_BOND {
+ BOND_SINGLE = 1,
+ BOND_DOUBLE = 2,
+ BOND_AROMATIC = 3,
+ BOND_TRIPLE = 4
+ };
+
+ DefineClass(Edge);
+
+ class Edge : public io::Stream {
+
+ friend class Graph;
+ friend class CGMatch;
+
+ public:
+
+ Edge ();
+ Edge ( io::RPStream Object );
+ Edge ( int vx1, int vx2, int btype ); // vx1,vx2 are numbered
+ // as 1,2,3 on and refer
+ // to vertices in the order
+ // as they were added to
+ // the graph; btype>0
+ ~Edge();
+
+ void SetEdge ( int vx1, int vx2, cpstr btype );
+ void SetEdge ( int vx1, int vx2, int btype ); // btype>0
+
+ void SetType ( int btype );
+ void SetProperty ( int eprop );
+ void SaveType (); // in property
+ void RestoreType (); // from property
+
+ inline int GetVertex1 () { return v1; }
+ inline int GetVertex2 () { return v2; }
+ inline int GetType () { return type; }
+ inline int GetProperty () { return property; }
+
+ virtual void Print ( int PKey );
+
+ virtual void Copy ( PEdge G );
+
+ void read ( io::RFile f );
+ void write ( io::RFile f );
+
+ void mem_read ( cpstr S, int & l );
+ void mem_write ( pstr S, int & l );
+
+ protected:
+ int v1,v2; // >=1
+ int type;
+ int property;
+
+ void InitEdge();
+
+ };
+
+ DefineStreamFunctions(Edge);
+
+
+ // ========================== Graph ============================
+
+ enum GRAPH_RC {
+ MKGRAPH_Ok = 0,
+ MKGRAPH_NoAtoms = -1,
+ MKGRAPH_ChangedAltLoc = 1,
+ MKGRAPH_MaxOccupancy = 2
+ };
+
+ DefineClass(Graph);
+
+ class Graph : public io::Stream {
+
+ friend class GraphMatch;
+ friend class CSBase0;
+
+ public :
+
+ Graph ();
+ Graph ( PResidue R, cpstr altLoc=NULL );
+ Graph ( io::RPStream Object );
+ ~Graph();
+
+ void Reset ();
+ void SetName ( cpstr gname );
+ inline pstr GetName() { return name; }
+
+ // AddVertex(..) and AddEdge(..) do not copy the objects, but
+ // take them over. This means that application should forget
+ // about pointers to V and G once they were given to Graph.
+ // Vertices and edges must be allocated newly prior each call
+ // to AddVertex(..) and AddEdge(..).
+ void AddVertex ( PVertex V );
+ void AddEdge ( PEdge G );
+ void SetVertices ( PPVertex V, int vlen );
+ void SetEdges ( PPEdge G, int glen );
+
+ void RemoveChirality();
+ void LeaveChirality ( int eltype );
+
+ // MakeGraph(..) makes a graph corresponding to residue R.
+ // The graphs vertices then correspond to the residue's atoms
+ // (Vertex::userid points to atom R->atom[Vertex::userid]),
+ // edges are calculated as chemical bonds between atoms basing
+ // on the table of cut-off distances.
+ // altCode specifies a particular conformation that should be
+ // used for making the graph. If it is set to "" or NULL ("empty"
+ // altcode) but the residue does not have conformation which
+ // contains *only* ""-altcode atoms, a conformation corresponding
+ // to maximal occupancy will be used. The same will happen if
+ // altcode information in residue is not correct, whatever altCode
+ // is specified.
+ // After making the graph, Build(..) should be called as usual
+ // before graph matching.
+ // Non-negative return means that graph has been made.
+ // MakeGraph(..) may return:
+ // MKGRAPH_Ok everything is Ok
+ // MKGRAPH_NoAtoms residue does not have atoms, graph
+ // is not made
+ // MKGRAPH_ChangedAltLoc a different altcode was used because
+ // the residue has only one altcode and
+ // that is different of
+ // MKGRAPH_MaxOccupancy a maximal-occupancy conformation has
+ // been chosen because of default
+ // ""-altcode supplied or incorrect
+ // altcode information in the residue
+ int MakeGraph ( PResidue R, cpstr altLoc=NULL );
+
+ int MakeGraph ( PPAtom atom, int nAtoms );
+
+ void HideType ( int bond_vx_type );
+ void ExcludeType ( int type );
+
+ void MakeSymmetryRelief ( bool noCO2 );
+ void IdentifyRings ();
+ int IdentifyConnectedComponents(); // returns their number >= 1
+
+ int Build ( bool bondOrder ); // returns 0 if Ok
+
+ void MakeVertexIDs (); // simply numbers vertices as 1.. on
+ int GetVertexID ( int vertexNo );
+ int GetVertexNo ( cpstr vname );
+ // GetBondedVertexID(..) works after MoveType(..)
+ int GetNBondedVertices ( int vertexNo );
+ int GetBondedVertexID ( int vertexNo, int bond_vx_type,
+ int bondNo );
+
+ PVertex GetVertex ( int vertexNo ); // 1<=vertexNo<=nVertices
+ inline int GetNofVertices() { return nVertices; }
+
+ PEdge GetEdge ( int edgeNo ); // 1<=edgeNo<=nEdges
+ inline int GetNofEdges() { return nEdges; }
+
+ void GetVertices ( PPVertex & V, int & nV );
+ void GetEdges ( PPEdge & E, int & nE );
+
+ virtual void Print();
+ void Print1();
+
+ virtual void Copy ( PGraph G );
+
+ void read ( io::RFile f );
+ void write ( io::RFile f );
+
+ void mem_read ( cpstr S, int & l );
+ void mem_write ( pstr S, int & l );
+
+ protected :
+ pstr name;
+ int nVertices,nEdges, nAllVertices,nAllEdges;
+ PPVertex vertex;
+ PPEdge edge;
+ imatrix graph;
+
+ void InitGraph ();
+ void FreeMemory();
+
+ void markConnected ( int vno, int cno );
+
+ private :
+ int nVAlloc,nEAlloc,nGAlloc;
+
+ };
+
+ DefineStreamFunctions(Graph);
+
+
+ // ========================= GMatch ==========================
+
+ DefineClass(GMatch);
+ DefineStreamFunctions(GMatch);
+
+ class GMatch : public io::Stream {
+
+ friend class GraphMatch;
+
+ public :
+
+ GMatch ();
+ GMatch ( io::RPStream Object );
+ GMatch ( ivector FV1, ivector FV2, int nv, int n, int m );
+ ~GMatch();
+
+ // FV1[] and FV2[] are copied into internal buffers
+ void SetMatch ( ivector FV1, ivector FV2, int nv, int n, int m );
+
+ bool isMatch ( ivector FV1, ivector FV2, int nv );
+ bool isCombination ( ivector FV1, ivector FV2, int nv );
+
+ // do not allocate or dispose FV1 and FV2 in application!
+ void GetMatch ( ivector & FV1, ivector & FV2, int & nv,
+ realtype & p1, realtype & p2 );
+
+ void read ( io::RFile f );
+ void write ( io::RFile f );
+
+ void mem_read ( cpstr S, int & l );
+ void mem_write ( pstr S, int & l );
+
+ protected :
+ int n1,n2,mlength;
+ ivector F1,F2;
+
+ void InitGMatch();
+
+ private :
+ int nAlloc;
+
+ };
+
+
+ // ======================= GraphMatch =========================
+
+ #define _UseRecursion
+
+ enum GRAPH_MATCH_FLAG {
+ GMF_UniqueMatch = 0x00000001,
+ GMF_NoCombinations = 0x00000002
+ };
+
+ enum VERTEX_EXT_TYPE {
+ EXTTYPE_Ignore = 0,
+ EXTTYPE_Equal = 1,
+ EXTTYPE_AND = 2,
+ EXTTYPE_OR = 3,
+ EXTTYPE_XOR = 4,
+ EXTTYPE_NotEqual = 5,
+ EXTTYPE_NotAND = 6,
+ EXTTYPE_NotOR = 7
+ };
+
+ DefineClass(GraphMatch);
+
+ class GraphMatch : public io::Stream {
+
+ public :
+
+ GraphMatch ();
+ GraphMatch ( io::RPStream Object );
+ ~GraphMatch();
+
+ void SetFlag ( word flag );
+ void RemoveFlag ( word flag );
+ void SetMaxNofMatches ( int maxNofMatches, bool stopOnMaxN );
+ void SetTimeLimit ( int maxTimeToRun=0 );
+ inline bool GetStopSignal() { return Stop; }
+
+ void Reset();
+
+ // MatchGraphs looks for maximal common subgraphs of size
+ // not less than minMatch. The number of found subgraphs
+ // is returned by GetNofMatches(), the subgraph vertices
+ // are returned by GetMatch(..). Control parameters:
+ // vertexType true if vertex type should be taken
+ // into account and False otherwise
+ // vertexExt key to use extended vertex types (defined
+ // as type_ext in Vertex).
+ void MatchGraphs ( PGraph Gh1, PGraph Gh2, int minMatch,
+ bool vertexType=true,
+ VERTEX_EXT_TYPE vertexExt=EXTTYPE_Ignore );
+ void PrintMatches ();
+ inline int GetNofMatches () { return nMatches; }
+ inline int GetMaxMatchSize() { return maxMatch; }
+
+ // do not allocate or dispose FV1 and FV2 in application!
+ // FV1/p1 will always correspond to Gh1, and FV2/p2 -
+ // to Gh2 as specified in MatchGraphs(..)
+ void GetMatch ( int MatchNo, ivector & FV1, ivector & FV2,
+ int & nv, realtype & p1, realtype & p2 );
+
+ void read ( io::RFile f );
+ void write ( io::RFile f );
+
+ void mem_read ( cpstr S, int & l );
+ void mem_write ( pstr S, int & l );
+
+ protected :
+ PGraph G1,G2;
+ PPVertex V1;
+ PPVertex V2;
+ imatrix c1,c2;
+ bool swap;
+ #ifndef _UseRecursion
+ ivector jj;
+ #endif
+ int n,m;
+
+ imatrix3 P;
+ imatrix iF1;
+ ivector F1,F2,ix;
+
+ int nMatches,maxNMatches;
+ PPGMatch Match;
+ bool wasFullMatch,Stop,stopOnMaxNMathches;
+ word flags;
+ int maxMatch,timeLimit;
+
+ void InitGraphMatch();
+ void FreeMemory ();
+ void FreeRecHeap ();
+ void GetMemory ();
+ void GetRecHeap ();
+ int Initialize ( bool vertexType, int vertexExt );
+ #ifdef _UseRecursion
+ void Backtrack ( int i ); // exact matching
+ #else
+ void Ullman ();
+ #endif
+ void Backtrack1 ( int i, int k0 ); // exact/partial matching
+ void CollectMatch ( int nm );
+
+ private :
+ int nAlloc,mAlloc,nMAlloc;
+ time_t startTime;
+
+ };
+
+ DefineStreamFunctions(GraphMatch);
+
+ extern void SetGraphAllocPortion ( int alloc_portion );
+
+ /*
+ extern void TestGraphMatch();
+ */
+
+ } // namespace math
+
+} // namespace mmdb
+
+#endif
diff --git a/mmdb2/mmdb_math_linalg.cpp b/mmdb2/mmdb_math_linalg.cpp
new file mode 100644
index 0000000..3709101
--- /dev/null
+++ b/mmdb2/mmdb_math_linalg.cpp
@@ -0,0 +1,990 @@
+// $Id: mmdb_math_linalg.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : LinAlg <implementation>
+// ~~~~~~~~~
+// **** Project : MMDB ( MacroMolecular Data Base )
+// ~~~~~~~~~
+//
+// (C) E.Krissinel 2000-2013
+//
+// =================================================================
+//
+//
+
+#include <stdio.h>
+#include <math.h>
+
+#include "mmdb_math_linalg.h"
+
+namespace mmdb {
+
+ namespace math {
+
+
+ // ========================== Jacobi =============================
+
+
+ void Jacobi ( int N, // dimension of the matrix
+ rmatrix A, // matrix to diagonalize; the lower
+ // triangle, except the diagonal,
+ // will remain unchanged
+ rmatrix T, // eigenvectors placed as columns
+ rvector Eigen, // vector of eigenvalues, orderd
+ // by increasing
+ rvector Aik, // working array
+ int & Signal // 0 <=> Ok, ItMax <=> iteration limit
+ // exchausted.
+ ) {
+ // Diagonalization of symmetric matrices by the method of Jacobi.
+ // Key variables:
+ // ItMax - the maximum available number of iterations
+ // Eps1 - is used in SNA and CSA calculations
+ // Eps2 - is the level of the elimination of the
+ // non-diagonal matrix elements
+ // Eps3 - the criterion to stop the iterations.
+ // The iterations stop if (1-Sigma1/Sigma2)<=Eps3
+ // where Sigma1 is the dekart norm of the eigenvalues
+ // at the preceding iteration and Sigma2 is
+ // the same for the current iteration.
+
+ realtype Eps1,Eps2,Eps3;
+ realtype Sigma1,Sigma2,OffDsq, SPQ,CSA,SNA,Q,P, HoldIK,HoldKI;
+ int ItMax;
+ int i,j,k,Iter;
+
+ Eps1 = 6.0e-9;
+ Eps2 = 9.0e-12;
+ Eps3 = 1.0e-8;
+ ItMax = 9999;
+
+ Signal = 0;
+
+ if (N<=1) {
+ T[1][1] = 1.0;
+ Eigen[1] = A[1][1];
+ return;
+ }
+
+ for (i=1;i<=N;i++) {
+ for (j=1;j<=N;j++)
+ T[i][j] = 0.0;
+ T[i][i] = 1.0;
+ Eigen[i] = A[i][i];
+ }
+
+ Sigma1 = 0.0;
+ OffDsq = 0.0;
+
+ // Sigma1 is the Dekart measure of the diagonal elements
+ // OffDsq is the Dekart measure of the non-diagonal elements
+
+ for (i=1;i<=N;i++) {
+ Sigma1 += A[i][i]*A[i][i];
+ if (i<N)
+ for (j=i+1;j<=N;j++)
+ OffDsq += A[i][j]*A[i][j];
+ }
+
+ if (OffDsq<Eps2*Eps2) return;
+
+ // S = OffDsq*2.0+Sigma1;
+ Iter = 1;
+ HoldIK = 1.0;
+
+ while ((Iter<=ItMax) && (HoldIK>Eps3)) {
+
+ for (i=1;i<N;i++)
+ for (j=i+1;j<=N;j++) {
+
+ Q = fabs(A[i][i]-A[j][j]);
+
+ if ((Q<=Eps1) || (fabs(A[i][j])>Eps2)) {
+ if (Q>Eps1) {
+ P = 2.0*A[i][j]*(Q/(A[i][i]-A[j][j]));
+ SPQ = sqrt(P*P+Q*Q);
+ CSA = sqrt((1.0+Q/SPQ)/2.0);
+ SNA = P/(SPQ*CSA*2.0);
+ } else {
+ CSA = sqrt(0.5);
+ SNA = CSA;
+ }
+ for (k=1;k<=N;k++) {
+ HoldKI = T[k][i];
+ T[k][i] = HoldKI*CSA + T[k][j]*SNA;
+ T[k][j] = HoldKI*SNA - T[k][j]*CSA;
+ }
+
+ for (k=i;k<=N;k++)
+ if (k<=j) {
+ Aik[k] = A[i][k];
+ A[i][k] = CSA*Aik[k] + SNA*A[k][j];
+ if (k==j) {
+ A[j][k] = SNA*Aik[k] - CSA*A[j][k];
+ Aik[j] = SNA*Aik[i] - CSA*Aik[j];
+ }
+ } else {
+ HoldIK = A[i][k];
+ A[i][k] = CSA*HoldIK + SNA*A[j][k];
+ A[j][k] = SNA*HoldIK - CSA*A[j][k];
+ }
+
+ for (k=1;k<=j;k++)
+ if (k>i)
+ A[k][j] = SNA*Aik[k] - CSA*A[k][j];
+ else {
+ HoldKI = A[k][i];
+ A[k][i] = CSA*HoldKI + SNA*A[k][j];
+ A[k][j] = SNA*HoldKI - CSA*A[k][j];
+ }
+
+ }
+
+ }
+
+ Sigma2 = 0.0;
+ for (i=1;i<=N;i++) {
+ Eigen[i] = A[i][i];
+ Sigma2 += Eigen[i]*Eigen[i];
+ }
+
+ HoldIK = fabs(1.0-Sigma1/Sigma2);
+ Sigma1 = Sigma2;
+ Iter++;
+
+ }
+
+ if (Iter>ItMax) Signal = ItMax;
+
+ for (i=1;i<=N;i++) {
+ k = i;
+ for (j=i;j<=N;j++)
+ if (Eigen[j]<Eigen[k]) k = j;
+ if (k!=i) {
+ P = Eigen[k];
+ Eigen[k] = Eigen[i];
+ Eigen[i] = P;
+ for (j=1;j<=N;j++) {
+ P = T[j][k];
+ T[j][k] = T[j][i];
+ T[j][i] = P;
+ }
+ }
+ }
+
+
+ }
+
+
+ // -----------------------------------------------------
+
+ void PbCholDecomp ( int N,
+ rvector HDiag,
+ realtype MaxOff,
+ realtype MachEps,
+ rmatrix L,
+ realtype & MaxAdd ) {
+
+ // A5.5.2 : Perturbed Cholesky Decomposition
+ // Part of the modular software system from
+ // the appendix of the book "Numerical Methods for Unconstrained
+ // Optimization and Nonlinear Equations" by Dennis & Schnabel 1983.
+
+ int i,j,k;
+ realtype MinL,MinL2,S,MinLjj,MaxOffl, BB;
+
+ MaxOffl = MaxOff;
+ MinL = sqrt(sqrt(MachEps))*MaxOffl;
+ if (MaxOffl==0.0) {
+ for (i=1;i<=N;i++) {
+ BB = fabs(HDiag[i]);
+ if (BB>MaxOffl) MaxOffl = BB;
+ }
+ MaxOffl = sqrt(MaxOffl);
+ }
+
+ MinL2 = sqrt(MachEps)*MaxOffl;
+ MaxAdd = 0.0;
+ for (j=1;j<=N;j++) {
+ S = 0.0;
+ if (j>1)
+ for (i=1;i<j;i++)
+ S += L[j][i]*L[j][i];
+ L[j][j] = HDiag[j] - S;
+ MinLjj = 0.0;
+ if (j<N)
+ for (i=j+1;i<=N;i++) {
+ S = 0.0;
+ if (j>1)
+ for (k=1;k<j;k++)
+ S += L[i][k]*L[j][k];
+ L[i][j] = L[j][i] - S;
+ BB = fabs(L[i][j]);
+ if (BB>MinLjj) MinLjj = BB;
+ }
+ BB = MinLjj/MaxOffl;
+ if (BB>MinL) MinLjj = BB;
+ else MinLjj = MinL;
+ if (L[j][j]>MinLjj*MinLjj) L[j][j] = sqrt(L[j][j]);
+ else {
+ if (MinL2>MinLjj) MinLjj = MinL2;
+ BB = MinLjj*MinLjj-L[j][j];
+ if (BB>MaxAdd) MaxAdd = BB;
+ L[j][j] = MinLjj;
+ }
+ if (j<N)
+ for (i=j+1;i<=N;i++)
+ L[i][j] /= L[j][j];
+ }
+
+ }
+
+
+
+ // -----------------------------------------------------
+
+ void LSolve ( int N, rmatrix L, rvector B, rvector Y ) {
+ // A3.2.3a : Cholesky's L - Solution of
+ // L*Y = B ( given B )
+ int i,j;
+ Y[1] = B[1]/L[1][1];
+ if (N>1)
+ for (i=2;i<=N;i++) {
+ Y[i] = B[i];
+ for (j=1;j<i;j++)
+ Y[i] -= L[i][j]*Y[j];
+ Y[i] /= L[i][i];
+ }
+ }
+
+
+ // -----------------------------------------------------
+
+ void LTSolve ( int N, rmatrix L, rvector Y, rvector X ) {
+ // A3.2.3b : Cholesky's LT - Solution of
+ // LT*X = Y ( given Y )
+ int i,j;
+ X[N] = Y[N]/L[N][N];
+ if (N>1)
+ for (i=N-1;i>=1;i--) {
+ X[i] = Y[i];
+ for (j=i+1;j<=N;j++)
+ X[i] -= L[j][i]*X[j];
+ X[i] /= L[i][i];
+ }
+ }
+
+
+ // -----------------------------------------------------
+
+ void ChSolve ( int N, rmatrix L, rvector G, rvector S ) {
+ // A3.2.3 : Solution of the equation L*LT*S = G
+ // by the Cholesky's method
+ //int i;
+ LSolve ( N,L,G,S );
+ LTSolve ( N,L,S,S );
+ // for (i=1;i<=N;i++)
+ // S[i] = -S[i];
+ }
+
+
+
+ // ----------------------------------------------------
+
+ void FastInverse ( int N, rmatrix A, ivector J0,
+ //#D realtype & Det,
+ int & Signal ) {
+ //
+ // 17.01.91 <-- Last Date of Modification.
+ // ----------------------------
+ //
+ // ================================================
+ //
+ // Fast Inversion of the matrix A
+ // by the method of GAUSS - JOIRDAN .
+ //
+ // ------------------------------------------------
+ //
+ // Input parameters are :
+ //
+ // N - dimension of the matrix
+ // A - the matrix [1..N][1..N] to be inverted.
+ //
+ // ------------------------------------------------
+ //
+ // J0 - integer vector [1..N] for temporal storage
+ //
+ //
+ // ------------------------------------------------
+ //
+ // Output parameters are :
+ //
+ // A - the inverted matrix
+ // Signal - the error key :
+ // = 0 <=> O'K
+ // else
+ // degeneration was found, and
+ // the rang of matrix is Signal-1.
+ //
+ // Variable Det may return the determinant
+ // of matrix A. To obtain it, remove all comments
+ // of form //#D .
+ //
+ // ------------------------------------------------
+ //
+ // Key Variables are :
+ //
+ // Eps - is the level for the degeneration
+ // detection. Keep in mind, that
+ // this routine does not norm the
+ // matrix given, and thus Eps1
+ // is the ABSOLUTE value.
+ //
+ // ================================================
+ //
+
+ realtype Eps = 1.0e-16;
+
+ int i,j,k,i0;
+ realtype A0,B;
+ rvector Ai,Ai0;
+
+ Signal = 0;
+ if (N<=1) {
+ if (fabs(A[1][1])<Eps) {
+ Signal = 1;
+ return;
+ }
+ A[1][1] = 1.0/A[1][1];
+ //#D Det = A[1][1];
+ return;
+ }
+
+ if (N==2) {
+ A0 = A[1][1];
+ B = A0*A[2][2] - A[1][2]*A[2][1];
+ //#D Det = B;
+ if (fabs(B)<Eps) {
+ Signal = 1;
+ return;
+ }
+ A[1][1] = A[2][2]/B;
+ A[2][2] = A0/B;
+ B = -B;
+ A[1][2] /= B;
+ A[2][1] /= B;
+ return;
+ }
+
+ for (i=1;i<=N;i++) {
+ // 1. Finding of the leading element ( in A0 );
+ // i0 is the number of the leading string
+ A0 = 0.0;
+ i0 = 0;
+ for (j=i;j<=N;j++) {
+ if (fabs(A[j][i])>A0) {
+ A0 = fabs(A[j][i]);
+ i0 = j;
+ }
+ }
+ if (A0<Eps) {
+ Signal = i; // Degeneration is found here
+ return;
+ }
+
+ // 2. Swapping the string
+ J0[i] = i0;
+ B = 1.0/A[i0][i];
+ Ai = A[i0];
+ Ai0 = A[i];
+ A[i] = Ai;
+ A[i0] = Ai0;
+ for (j=1;j<=N;j++)
+ Ai[j] = Ai[j]*B;
+ Ai[i] = B;
+
+ // 3. Substracting the strings
+ for (j=1;j<=N;j++)
+ if (i!=j) {
+ Ai0 = A[j];
+ B = Ai0[i];
+ Ai0[i] = 0.0;
+ for (k=1;k<=N;k++)
+ Ai0[k] = Ai0[k] - B*Ai[k];
+ }
+
+ //#D Det = Det/Ai[i];
+
+ }
+
+ // 4. Back Swapping the columns
+ for (i=N;i>=1;i--) {
+ j = J0[i];
+ if (j!=i) {
+ //#D Det = -Det;
+ for (k=1;k<=N;k++) {
+ B = A[k][i];
+ A[k][i] = A[k][j];
+ A[k][j] = B;
+ }
+ }
+ }
+
+ return;
+
+ } // End of the procedure FastInverse
+
+
+
+
+ // ----------------------------------------------------
+
+ realtype Sign ( realtype A, realtype B ) {
+ if (B>=0.0) return A;
+ else return -A;
+ }
+
+ realtype SrX2Y2 ( realtype X, realtype Y ) {
+ realtype Ax,Ay;
+ Ax = fabs(X);
+ Ay = fabs(Y);
+ if (Ay>Ax) return Ay*sqrt((X*X)/(Y*Y)+1.0);
+ if (Ay==Ax) return Ax*sqrt(2.0);
+ return Ax*sqrt((Y*Y)/(X*X)+1.0);
+ }
+
+
+ // ----------------------------------------------------
+
+ void SVD ( int NA, int M, int N,
+ rmatrix A, rmatrix U, rmatrix V,
+ rvector W, rvector RV1,
+ bool MatU, bool MatV,
+ int & RetCode ) {
+ //
+ // 13.12.01 <-- Last Modification Date
+ // ------------------------
+ //
+ // ================================================
+ //
+ // The Singular Value Decomposition
+ // of the matrix A by the algorithm from
+ // G.Forsait, M.Malkolm, K.Mouler. Numerical
+ // methods of mathematical calculations
+ // M., Mir, 1980.
+ //
+ // Matrix A is represented as
+ //
+ // A = U * W * VT
+ //
+ // ------------------------------------------------
+ //
+ // All dimensions are indexed from 1 on.
+ //
+ // ------------------------------------------------
+ //
+ // Input parameters:
+ //
+ // NA - number of lines in A. NA may be
+ // equal to M or N only. If NA=M
+ // then usual SVD will be made. If MA=N
+ // then matrix A is transposed before
+ // the decomposition, and the meaning of
+ // output parameters U and V is
+ // swapped (U accepts VT and VT accepts U).
+ // In other words, matrix A has physical
+ // dimension of M x N , same as U and V;
+ // however the logical dimension of it
+ // remains that of N x M .
+ // M - number of lines in U
+ // N - number of columns in U,V and length
+ // of W,RV1 . Always provide M >= N !
+ // A - matrix [1..M][1..N] or [1..N][1..M]
+ // to be decomposed. The matrix does not
+ // change, and it may coincide with U or
+ // V, if NA=M (in which case A does change)
+ // MatU - compute U , if set True
+ // MatV - compute V , if set True
+ // RV1 - temporary array [1..N].
+ // U - should be always supplied as an array of
+ // [1..M][1..N], M>=N .
+ // V - should be suuplied as an array of
+ // [1..N][1..N] if MatV is True .
+ //
+ // ------------------------------------------------
+ //
+ // Output parameters are :
+ //
+ // W - N non-ordered singular values,
+ // if RetCode=0. If RetCode<>0, the
+ // RetCode+1 ... N -th values are still
+ // valid
+ // U - matrix of right singular vectors
+ // (arranged in columns), corresponding
+ // to the singular values in W, if
+ // RetCode=0 and MatU is True. If MatU
+ // is False, U is still used as a
+ // temporary array. If RetCode<>0 then
+ // the RetCode+1 ... N -th vectors
+ // are valid
+ // V - matrix of left singular vectors
+ // (arranged in columns), corresponding
+ // to the singular values in W, if
+ // RetCode=0 and MatV is True. If MatV
+ // is False, V is not used and may be set
+ // to NULL. If RetCode<>0 then the
+ // RetCode+1 ... N -th vectors are valid
+ // RetCode - the error key :
+ // = 0 <=> O'K
+ // else
+ // = k, if the k-th singular value
+ // was not computed after 30 iterations.
+ //
+ // ------------------------------------------------
+ //
+ // Key Variables are :
+ //
+ // ItnLimit - the limit for iterations
+ //
+ // This routine does not use any machine-dependent
+ // constants.
+ //
+ // ================================================
+ //
+ //
+ int ItnLimit=300;
+ int i,j,k,l,i1,k1,l1,its,mn,ExitKey;
+ realtype C,G,F,X,S,H,Y,Z,Scale,ANorm,GG;
+
+ l1 = 0; // this is to keep compiler happy
+ RetCode = 0;
+
+ if (U!=A) {
+ if (NA==M)
+ for (i=1;i<=M;i++)
+ for (j=1;j<=N;j++)
+ U[i][j] = A[i][j];
+ else
+ for (i=1;i<=M;i++)
+ for (j=1;j<=N;j++)
+ U[i][j] = A[j][i];
+ }
+
+ G = 0.0;
+ Scale = 0.0;
+ ANorm = 0.0;
+
+ for (i=1;i<=N;i++) {
+ l = i+1;
+ RV1[i] = Scale*G;
+ G = 0.0;
+ S = 0.0;
+ Scale = 0.0;
+ if (i<=M) {
+ for (k=i;k<=M;k++)
+ Scale += fabs(U[k][i]);
+ if (Scale!=0.0) {
+ for (k=i;k<=M;k++) {
+ U[k][i] /= Scale;
+ S += U[k][i]*U[k][i];
+ }
+ F = U[i][i];
+ G = -Sign(sqrt(S),F);
+ H = F*G-S;
+ U[i][i] = F-G;
+ if (i!=N)
+ for (j=l;j<=N;j++) {
+ S = 0.0;
+ for (k=i;k<=M;k++)
+ S += U[k][i]*U[k][j];
+ F = S/H;
+ for (k=i;k<=M;k++)
+ U[k][j] += F*U[k][i];
+ }
+ for (k=i;k<=M;k++)
+ U[k][i] *= Scale;
+ }
+ }
+
+ W[i] = Scale*G;
+ G = 0.0;
+ S = 0.0;
+ Scale = 0.0;
+
+ if ((i<=M) && (i!=N)) {
+ for (k=l;k<=N;k++)
+ Scale += fabs(U[i][k]);
+ if (Scale!=0.0) {
+ for (k=l;k<=N;k++) {
+ U[i][k] /= Scale;
+ S += U[i][k]*U[i][k];
+ }
+ F = U[i][l];
+ G = -Sign(sqrt(S),F);
+ H = F*G-S;
+ U[i][l] = F-G;
+ for (k=l;k<=N;k++)
+ RV1[k] = U[i][k]/H;
+ if (i!=M)
+ for (j=l;j<=M;j++) {
+ S = 0.0;
+ for (k=l;k<=N;k++)
+ S += U[j][k]*U[i][k];
+ for (k=l;k<=N;k++)
+ U[j][k] += S*RV1[k];
+ }
+ for (k=l;k<=N;k++)
+ U[i][k] *= Scale;
+ }
+ }
+
+ ANorm = RMax( ANorm,fabs(W[i])+fabs(RV1[i]) );
+
+ }
+
+ // Accumulation of the right-hand transformations
+
+ if (MatV)
+ for (i=N;i>=1;i--) {
+ if (i!=N) {
+ if (G!=0.0) {
+ for (j=l;j<=N;j++)
+ V[j][i] = (U[i][j]/U[i][l]) / G;
+ for (j=l;j<=N;j++) {
+ S = 0.0;
+ for (k=l;k<=N;k++)
+ S += U[i][k]*V[k][j];
+ for (k=l;k<=N;k++)
+ V[k][j] += S*V[k][i];
+ }
+ }
+ for (j=l;j<=N;j++) {
+ V[i][j] = 0.0;
+ V[j][i] = 0.0;
+ }
+ }
+
+ V[i][i] = 1.0;
+ G = RV1[i];
+ l = i;
+
+ }
+
+
+ // Accumulation of the left-hand transformations
+
+ if (MatU) {
+ mn = N;
+ if (M<N) mn = M;
+
+ for (i=mn;i>=1;i--) {
+ l = i+1;
+ G = W[i];
+ if (i!=N)
+ for (j=l;j<=N;j++)
+ U[i][j] = 0.0;
+ if (G!=0.0) {
+ if (i!=mn)
+ for (j=l;j<=N;j++) {
+ S = 0.0;
+ for (k=l;k<=M;k++)
+ S += U[k][i]*U[k][j];
+ F = (S/U[i][i]) / G;
+ for (k=i;k<=M;k++)
+ U[k][j] += F*U[k][i];
+ }
+ for (j=i;j<=M;j++)
+ U[j][i] /= G;
+ } else
+ for (j=i;j<=M;j++)
+ U[j][i] = 0.0;
+
+ U[i][i] += 1.0;
+
+ }
+ }
+
+ // Diagonalization of the two-diagonal form.
+
+ for (k=N;k>=1;k--) {
+ k1 = k-1;
+ its = 0;
+
+ do {
+ ExitKey = 0;
+ l = k+1;
+ while ((ExitKey==0) && (l>1)) {
+ l--;
+ l1 = l-1;
+ if (fabs(RV1[l])+ANorm==ANorm) ExitKey=1;
+ else if (l1>0) {
+ if (fabs(W[l1])+ANorm==ANorm) ExitKey=2;
+ }
+ }
+
+ // if (ExitKey!=1) { <-- this is original statement
+ if (ExitKey>1) { // <-- prevents from corruption due to l1<1.
+ // This is a rare case as RV1[1] should be
+ // always 0.0 . Apparently this logics is
+ // on the edge of float-point arithmetic,
+ // therefore extra precaution for the case
+ // of l1<1 was found necessary.
+ C = 0.0;
+ S = 1.0;
+ ExitKey = 0;
+ i = l;
+ while ((ExitKey==0) && (i<=k)) {
+ F = S*RV1[i];
+ RV1[i] = C*RV1[i];
+ if (fabs(F)+ANorm==ANorm) ExitKey = 1;
+ else {
+ G = W[i];
+ H = SrX2Y2(F,G);
+ W[i] = H;
+ C = G/H;
+ S = -F/H;
+ if (MatU)
+ for (j=1;j<=M;j++) {
+ Y = U[j][l1];
+ Z = U[j][i];
+ U[j][l1] = Y*C+Z*S;
+ U[j][i] = -Y*S+Z*C;
+ }
+ i++;
+ }
+ }
+ }
+
+ // Convergence Checking
+
+ Z = W[k];
+ if (l!=k) {
+ if (its>=ItnLimit) {
+ RetCode = k;
+ return;
+ }
+ its++;
+ X = W[l];
+ Y = W[k1];
+ G = RV1[k1];
+ H = RV1[k];
+ F = ((Y-Z)*(Y+Z) + (G-H)*(G+H)) / ( 2.0*H*Y );
+ if (fabs(F)<=1.0) GG = Sign(sqrt(F*F+1.0),F);
+ else GG = F*sqrt(1.0+1.0/F/F);
+ F = ((X-Z)*(X+Z) + H*(Y/(F+GG)-H)) / X;
+
+ // Next QR - Transformation
+
+ C = 1.0;
+ S = 1.0;
+ for (i1=l;i1<=k1;i1++) {
+ i = i1+1;
+ G = RV1[i];
+ Y = W[i];
+ H = S*G;
+ G = C*G;
+ Z = SrX2Y2(F,H);
+ RV1[i1] = Z;
+ C = F/Z;
+ S = H/Z;
+ F = X*C+G*S;
+ G = -X*S+G*C;
+ H = Y*S;
+ Y = Y*C;
+ if (MatV)
+ for (j=1;j<=N;j++) {
+ X = V[j][i1];
+ Z = V[j][i];
+ V[j][i1] = X*C+Z*S;
+ V[j][i] = -X*S+Z*C;
+ }
+
+ Z = SrX2Y2(F,H);
+ W[i1] = Z;
+ if (Z!=0.0) {
+ C = F/Z;
+ S = H/Z;
+ }
+ F = C*G+S*Y;
+ X = -S*G+C*Y;
+ if (MatU)
+ for (j=1;j<=M;j++) {
+ Y = U[j][i1];
+ Z = U[j][i];
+ U[j][i1] = Y*C+Z*S;
+ U[j][i] = -Y*S+Z*C;
+ }
+
+ }
+
+ RV1[l] = 0.0;
+ RV1[k] = F;
+ W[k] = X;
+
+ } else if (Z<0.0) {
+
+ W[k] = -Z;
+ if (MatV)
+ for (j=1;j<=N;j++)
+ V[j][k] = -V[j][k];
+ }
+
+ } while (l!=k);
+
+ }
+
+ }
+
+ // -----------------------------------------------------
+
+ void OrderSVD ( int M, int N, rmatrix U, rmatrix V,
+ rvector W, bool MatU, bool MatV ) {
+
+ int i,k,j;
+ realtype P;
+
+ // External loop of the re-ordering
+ for (i=1;i<N;i++) {
+ k = i;
+ P = W[i];
+
+ // Internal loop : finding of the index of greatest
+ // singular value over the remaining ones.
+ for (j=i+1;j<=N;j++)
+ if (W[j]>P) {
+ k = j;
+ P = W[j];
+ }
+
+ if (k!=i) {
+ // Swapping the singular value
+ W[k] = W[i];
+ W[i] = P;
+ // Swapping the U's columns ( if needed )
+ if (MatU)
+ for (j=1;j<=M;j++) {
+ P = U[j][i];
+ U[j][i] = U[j][k];
+ U[j][k] = P;
+ }
+ // Swapping the V's columns ( if needed )
+ if (MatV)
+ for (j=1;j<=N;j++) {
+ P = V[j][i];
+ V[j][i] = V[j][k];
+ V[j][k] = P;
+ }
+ }
+
+ }
+
+ }
+
+
+ /*
+
+ #ifndef __STDIO_H
+ #include <stdio.h>
+ #endif
+
+ int main ( int argc, char ** argv, char ** env ) {
+ // Test Jacobi
+ matrix A,T,A1;
+ vector Eigen,Aik;
+ realtype SR;
+ int N,i,j,k,Signal;
+
+ N = 4;
+
+ GetMatrixMemory ( A,N,N,1,1 );
+ GetMatrixMemory ( T,N,N,1,1 );
+ GetMatrixMemory ( A1,N,N,1,1 );
+ GetVectorMemory ( Eigen,N,1 );
+ GetVectorMemory ( Aik ,N,1 );
+
+ k = 1;
+ for (i=1;i<=N;i++)
+ for (j=i;j<=N;j++) {
+ A[i][j] = k++;
+ A[i][j] *= 1000.0;
+ A[j][i] = A[i][j];
+ }
+
+ printf ( " INITIAL MATRIX:\n" );
+ for (i=1;i<=N;i++) {
+ for (j=1;j<=N;j++)
+ printf ( " %10.4f",A[i][j] );
+ printf ( "\n" );
+ }
+
+ Jacobi ( N,A,T,Eigen,Aik,Signal );
+
+ printf ( "\n EIGEN VALUES AND EIGEN VECTORS:\n" );
+ for (i=1;i<=N;i++) {
+ printf ( " %10.4f ",Eigen[i] );
+ for (j=1;j<=N;j++)
+ printf ( " %10.4f",T[j][i] );
+ printf ( "\n" );
+ }
+ printf ( "\n measure: " );
+ for (i=1;i<=N;i++) {
+ SR = 0.0;
+ for (j=1;j<=N;j++)
+ SR += T[j][i]*T[j][i];
+ printf ( " %10.4f",sqrt(SR) );
+ }
+ printf ( "\n" );
+
+ for (i=1;i<=N;i++)
+ for (j=1;j<=N;j++) {
+ A1[i][j] = 0.0;
+ for (k=1;k<=N;k++)
+ A1[i][j] += T[i][k]*Eigen[k]*T[j][k];
+ }
+
+ printf ( "\n RESTORED INITIAL MATRIX:\n" );
+ for (i=1;i<=N;i++) {
+ for (j=1;j<=N;j++)
+ printf ( " %10.4f",A1[j][i] );
+ printf ( "\n" );
+ }
+
+ FreeMatrixMemory ( A,N,1,1 );
+ FreeMatrixMemory ( T,N,1,1 );
+ FreeMatrixMemory ( A1,N,1,1 );
+ FreeVectorMemory ( Eigen,1 );
+ FreeVectorMemory ( Aik ,1 );
+
+
+ }
+
+ */
+
+ }
+
+}
diff --git a/mmdb2/mmdb_math_linalg.h b/mmdb2/mmdb_math_linalg.h
new file mode 100644
index 0000000..b646166
--- /dev/null
+++ b/mmdb2/mmdb_math_linalg.h
@@ -0,0 +1,236 @@
+// $Id: mmdb_math_linalg.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : LinAlg <interface>
+// ~~~~~~~~~
+// **** Project : MMDB ( MacroMolecular Data Base )
+// ~~~~~~~~~
+//
+// (C) E.Krissinel 2000-2013
+//
+// =================================================================
+//
+//
+
+#ifndef __MMDB_MATH_LinAlg__
+#define __MMDB_MATH_LinAlg__
+
+#include "mmdb_mattype.h"
+
+namespace mmdb {
+
+ namespace math {
+
+ // ========================== Jacobi =============================
+
+
+ /// Diagonalization of symmetric matrices A[1..N][1..N]
+ /// by the method of Jacobi.
+ extern void Jacobi ( int N, //!< dimension of the matrix
+ rmatrix A, //!< matrix to diagonalize; the
+ /// lower triangle, except the
+ /// diagonal, will remain unchanged
+ rmatrix T, //!< eigenvectors placed as columns
+ rvector Eigen, //!< vector of eigenvalues, orderd
+ /// by increasing
+ rvector Aik, //!< working array
+ int & Signal //!< 0 <=> Ok, ItMax <=> iteration
+ /// limit exchausted.
+ );
+
+
+ // A5.5.2 : Perturbed Cholesky Decomposition
+ extern void PbCholDecomp ( int N,
+ rvector HDiag,
+ realtype MaxOff,
+ realtype MachEps,
+ rmatrix L,
+ realtype & MaxAdd );
+
+ // A3.2.3a : Cholesky's L - Solution of
+ // L*Y = B ( given B )
+ extern void LSolve ( int N, rmatrix L, rvector B, rvector Y );
+
+ // A3.2.3b : Cholesky's LT - Solution of
+ // LT*X = Y ( given Y )
+ extern void LTSolve ( int N, rmatrix L, rvector Y, rvector X );
+
+ // A3.2.3 : Solution of the equation L*LT*S = G
+ // by the Cholesky's method
+ extern void ChSolve ( int N, rmatrix L, rvector G, rvector S );
+
+
+ // ----------------------------------------------------
+
+ extern void FastInverse ( int N, rmatrix A, ivector J0,
+ //#D realtype & Det,
+ int & Signal );
+ //
+ // 13.09.90 <-- Last Modification Date
+ // ------------------------
+ //
+ // ================================================
+ //
+ // Fast Inversion of the matrix A
+ // by the method of GAUSS - JORDAN .
+ //
+ // ------------------------------------------------
+ //
+ // Input parameters are :
+ //
+ // N - dimension of the matrix
+ // A - the matrix [1..N][1..N] to be inverted.
+ // ------------------------------------------------
+ //
+ // J0 - integer vector [1..N] for temporal storage
+ //
+ // ------------------------------------------------
+ //
+ // Output parameters are :
+ //
+ // A - the inverted matrix
+ // Signal - the error key :
+ // = 0 <=> O'K
+ // else
+ // degeneration was found, and
+ // the rang of matrix is Signal-1.
+ //
+ // Variable Det may return the determinant
+ // of matrix A. To obtain it, remove all comments
+ // of form //#D.
+ //
+ // ================================================
+
+
+ // ----------------------------------------------------
+
+ extern void SVD ( int NA, int M, int N,
+ rmatrix A, rmatrix U, rmatrix V,
+ rvector W, rvector RV1,
+ bool MatU, bool MatV,
+ int & RetCode );
+ //
+ // 13.12.01 <-- Last Modification Date
+ // ------------------------
+ //
+ // ================================================
+ //
+ // The Singular Value Decomposition
+ // of the matrix A by the algorithm from
+ // G.Forsait, M.Malkolm, K.Mouler. Numerical
+ // methods of mathematical calculations //
+ // M., Mir, 1980.
+ //
+ // Matrix A is represented as
+ //
+ // A = U * W * VT
+ //
+ // ------------------------------------------------
+ //
+ // All dimensions are indexed from 1 on.
+ //
+ // ------------------------------------------------
+ //
+ // Input parameters:
+ //
+ // NA - number of lines in A. NA may be
+ // equal to M or N only. If NA=M
+ // then usual SVD will be made. If MA=N
+ // then matrix A is transposed before
+ // the decomposition, and the meaning of
+ // output parameters U and V is
+ // swapped (U accepts VT and VT accepts U).
+ // In other words, matrix A has physical
+ // dimension of M x N , same as U and V;
+ // however the logical dimension of it
+ // remains that of N x M .
+ // M - number of lines in U
+ // N - number of columns in U,V and length
+ // of W,RV1 . Always provide M >= N !
+ // A - matrix [1..M][1..N] or [1..N][1..M]
+ // to be decomposed. The matrix does not
+ // change, and it may coincide with U or
+ // V, if NA=M (in which case A does change)
+ // MatU - compute U , if set True
+ // MatV - compute V , if set True
+ // RV1 - temporary array [1..N].
+ // U - should be always supplied as an array of
+ // [1..M][1..N], M>=N .
+ // V - should be suuplied as an array of
+ // [1..N][1..N] if MatV is True .
+ //
+ // ------------------------------------------------
+ //
+ // Output parameters are :
+ //
+ // W - N non-ordered singular values,
+ // if RetCode=0. If RetCode<>0, the
+ // RetCode+1 ... N -th values are still
+ // valid
+ // U - matrix of right singular vectors
+ // (arranged in columns), corresponding
+ // to the singular values in W, if
+ // RetCode=0 and MatU is True. If MatU
+ // is False, U is still used as a
+ // temporary array. If RetCode<>0 then
+ // the RetCode+1 ... N -th vectors
+ // are valid
+ // V - matrix of left singular vectors
+ // (arranged in columns), corresponding
+ // to the singular values in W, if
+ // RetCode=0 and MatV is True. If MatV
+ // is False, V is not used and may be set
+ // to NULL. If RetCode<>0 then the
+ // RetCode+1 ... N -th vectors are valid
+ // RetCode - the error key :
+ // = 0 <=> O'K
+ // else
+ // = k, if the k-th singular value
+ // was not computed after 30 iterations.
+ //
+ // ------------------------------------------------
+ //
+ // Key Variables are :
+ //
+ // ItnLimit - the limit for iterations
+ //
+ // This routine does not use any machine-dependent
+ // constants.
+ //
+ // ================================================
+ //
+ //
+
+ extern void OrderSVD ( int M, int N, rmatrix U, rmatrix V,
+ rvector W, bool MatU, bool MatV );
+
+
+ }
+}
+
+#endif
diff --git a/mmdb2/mmdb_math_rand.cpp b/mmdb2/mmdb_math_rand.cpp
new file mode 100644
index 0000000..1122c89
--- /dev/null
+++ b/mmdb2/mmdb_math_rand.cpp
@@ -0,0 +1,241 @@
+// $Id: mmdb_math_rand.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : Rand <implementation>
+// ~~~~~~~~~
+// **** Classes : RandomNumber ( random number generator )
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 1997-2013
+//
+// =================================================================
+//
+
+#include <math.h>
+
+#include "mmdb_math_rand.h"
+
+
+namespace mmdb {
+
+ namespace math {
+
+ // =================== RandomNumber ==========================
+
+ RandomNumber::RandomNumber ( long IJ, long KL ) {
+ Init ( IJ,KL );
+ }
+
+ void RandomNumber::Init ( long IJ, long KL ) {
+ long i,j,k,l,m, ii,jj;
+ realtype s,t;
+
+ iset = 0;
+ gset = 0.0;
+
+ if ((IJ<0) || (IJ>_RN_MAX_IJ) ||
+ (KL<0) || (KL>_RN_MAX_KL)) return;
+
+ i = mod(IJ/177,177) + 2;
+ j = mod(IJ,177) + 2;
+ k = mod(KL/169,178) + 1;
+ l = mod(KL,169);
+
+ for (ii=0;ii<97;ii++) {
+ s = 0.0;
+ t = 0.5;
+ for (jj=1;jj<=24;jj++) {
+ m = mod(mod(i*j,179)*k,179);
+ i = j;
+ j = k;
+ k = m;
+ l = mod(53*l+1,169);
+ if (mod(l*m,64)>=32) s += t;
+ t *= 0.5;
+ }
+ U[ii] = s;
+ }
+
+ C = 362436.0 / 16777216.0;
+ CD = 7654321.0 / 16777216.0;
+ CM = 16777213.0 / 16777216.0;
+
+ I97 = 96;
+ J97 = 32;
+
+ }
+
+
+ // uniform [0..1] random number generator
+ realtype RandomNumber::random() {
+ realtype uni;
+
+ uni = U[I97] - U[J97];
+ if (uni<0.0) uni += 1.0;
+ U[I97] = uni;
+ I97--;
+ if (I97<0) I97 = 96;
+ J97--;
+ if (J97<0) J97 = 96;
+ C -= CD;
+ if (C<0.0) C += CM;
+ uni -= C;
+ if (uni<0.0) uni += 1.0;
+
+ return uni;
+
+ }
+
+
+ // uniform [-1..1] random number generator
+ realtype RandomNumber::srandom() {
+ realtype uni;
+
+ uni = U[I97] - U[J97];
+ if (uni<0.0) uni += 1.0;
+ U[I97] = uni;
+ I97--;
+ if (I97<0) I97 = 96;
+ J97--;
+ if (J97<0) J97 = 96;
+ C -= CD;
+ if (C<0.0) C += CM;
+ uni -= C;
+ if (uni<0.0) uni += 1.0;
+
+ return 2.0*uni - 1.0;
+
+ }
+
+ // gaussian random numbers
+ realtype RandomNumber::gauss_rnd() {
+ realtype v1,v2,r,fac;
+ if (iset==0) {
+ do {
+ v1 = srandom();
+ v2 = srandom();
+ r = v1*v1 + v2*v2;
+ } while ((r>=1.0) || (r==0.0));
+ fac = sqrt(-2.0*log(r)/r);
+ gset = v1*fac;
+ iset = 1;
+ return v2*fac;
+ } else {
+ iset = 0;
+ return gset;
+ }
+ }
+
+ void RandomNumber::write ( io::RFile f ) {
+ int Version=1;
+ f.WriteFile ( &Version,sizeof(Version) );
+ f.WriteFile ( &I97 ,sizeof(I97) );
+ f.WriteFile ( &J97 ,sizeof(J97) );
+ f.WriteFile ( U ,sizeof(U) );
+ f.WriteFile ( &C ,sizeof(C) );
+ f.WriteFile ( &CD ,sizeof(CD) );
+ f.WriteFile ( &CM ,sizeof(CM) );
+ f.WriteFile ( &gset ,sizeof(gset) );
+ f.WriteFile ( &iset ,sizeof(iset) );
+ }
+
+ void RandomNumber::read ( io::RFile f ) {
+ int Version;
+ f.ReadFile ( &Version,sizeof(Version) );
+ f.ReadFile ( &I97 ,sizeof(I97) );
+ f.ReadFile ( &J97 ,sizeof(J97) );
+ f.ReadFile ( U ,sizeof(U) );
+ f.ReadFile ( &C ,sizeof(C) );
+ f.ReadFile ( &CD ,sizeof(CD) );
+ f.ReadFile ( &CM ,sizeof(CM) );
+ f.ReadFile ( &gset ,sizeof(gset) );
+ f.ReadFile ( &iset ,sizeof(iset) );
+ }
+
+
+ } // namespace math
+
+} // namespace mmdb
+
+
+/*
+
+static int m1 = 259200;
+static int ia1 = 7141;
+static int ic1 = 54773;
+static realtype rm1 = 1.0/259200.0;
+
+static int m2 = 134456;
+static int ia2 = 8121;
+static int ic2 = 28411;
+static realtype rm2 = 1.0/134456.0;
+
+static int m3 = 243000;
+static int ia3 = 4561;
+static int ic3 = 51349;
+
+static int ix1 = 0;
+static int ix2 = 0;
+static int ix3 = 0;
+
+static realtype R[97];
+
+void randomize ( int iseed ) {
+int j;
+ RndInit = True;
+ ix1 = mod(ic1-iseed,m1);
+ ix1 = mod(ia1*ix1+ic1,m1);
+ ix2 = mod(ix1,m2);
+ ix1 = mod(ia1*ix1+ic1,m1);
+ ix3 = mod(ix1,m3);
+ for (j=0;j<97;j++) {
+ ix1 = mod(ia1*ix1+ic1,m1);
+ ix2 = mod(ia2*ix2+ic2,m2);
+ R[j] = (ix1+ix2*rm2)*rm1;
+ }
+}
+
+realtype rand() {
+int j;
+realtype rnd;
+ if (!RndInit) randomize();
+ ix1 = mod(ia1*ix1+ic1,m1);
+ ix2 = mod(ia2*ix2+ic2,m2);
+ ix3 = mod(ia3*ix3+ic3,m3);
+ j = 1 + (97*ix3)/m3;
+ j = IMax(j,1);
+ j = IMin(j,97);
+ rnd = R[j-1];
+ R[j] = (ix1+ix2*rm2)*rm1;
+ return rnd;
+}
+*/
+
+// ===========================================================
+
+// End of Random_N
diff --git a/mmdb/random_n.h b/mmdb2/mmdb_math_rand.h
old mode 100755
new mode 100644
similarity index 51%
rename from mmdb/random_n.h
rename to mmdb2/mmdb_math_rand.h
index 3a15a92..8fde4f1
--- a/mmdb/random_n.h
+++ b/mmdb2/mmdb_math_rand.h
@@ -1,18 +1,18 @@
-// $Id: random_n.h,v 1.19 2012/01/26 17:52:21 ekr Exp $
+// $Id: mmdb_math_rand.h $
// =================================================================
//
// CCP4 Coordinate Library: support of coordinate-related
// functionality in protein crystallography applications.
//
-// Copyright (C) Eugene Krissinel 2000-2008.
+// Copyright (C) Eugene Krissinel 2000-2013.
//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
// of the license to address the requirements of UK law.
//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
//
// This program is distributed in the hope that it will be useful,
@@ -22,50 +22,59 @@
//
// =================================================================
//
-// 05.02.03 <-- Date of Last Modification.
+// 12.09.13 <-- Date of Last Modification.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// -----------------------------------------------------------------
//
-// **** Module : Random_N <interface>
+// **** Module : Rand <interface>
// ~~~~~~~~~
-// **** Classes : CRandomNumber ( random number generator )
+// **** Classes : RandomNumber ( random number generator )
// ~~~~~~~~~
//
-// (C) E. Krissinel' 1997-2008
+// (C) E. Krissinel 1997-2013
//
// =================================================================
//
-#ifndef __Random_N__
-#define __Random_N__
+#ifndef __MMDB_MATH_Rand__
+#define __MMDB_MATH_Rand__
-#ifndef __File__
-#include "file_.h"
-#endif
+#include "mmdb_io_file.h"
+
+namespace mmdb {
+
+ namespace math {
+
+ // -------------------------------------------------------------
+
+ enum RN_MAX_SEED {
+ _RN_MAX_IJ = 31328,
+ _RN_MAX_KL = 30081
+ };
+
+ DefineClass(RandomNumber);
+ class RandomNumber {
+ public :
+ RandomNumber ( long IJ=0, long KL=0 );
+ void Init ( long IJ=0, long KL=0 );
+ realtype gauss_rnd(); //!< Gaussian random numbers
+ realtype random (); //!< Uniform [0..1] random number generator
+ realtype srandom (); //!< Uniform [-1..1] random number generator
-// -------------------------------------------------------------
+ void read ( io::RFile f );
+ void write ( io::RFile f );
-#define _RN_MAX_IJ 31328
-#define _RN_MAX_KL 30081
+ protected :
+ long I97,J97;
+ realtype U[97],C,CD,CM;
+ realtype gset;
+ long iset;
-DefineClass(CRandomNumber);
+ };
-class CRandomNumber {
- public :
- CRandomNumber ( long IJ=0, long KL=0 );
- void Init ( long IJ=0, long KL=0 );
- realtype gauss_rnd(); // Gaussian random numbers
- realtype random (); // Uniform [0..1] random number generator
- realtype srandom (); // Uniform [-1..1] random number generator
+ } // namespace math
- void read ( RCFile f );
- void write ( RCFile f );
- protected :
- long I97,J97;
- realtype U[97],C,CD,CM;
- realtype gset;
- long iset;
-};
+} // namespace mmdb
#endif
diff --git a/mmdb2/mmdb_mattype.cpp b/mmdb2/mmdb_mattype.cpp
new file mode 100644
index 0000000..83e4a59
--- /dev/null
+++ b/mmdb2/mmdb_mattype.cpp
@@ -0,0 +1,2087 @@
+// $Id: mmdb_mattype.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2008.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 10.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MatType_ <implementation>
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits>
+#include <stdio.h>
+
+#include "mmdb_mattype.h"
+
+
+namespace mmdb {
+
+ // -------------------------------------------------------
+
+ realtype MachEps;
+ realtype floatMachEps;
+ realtype LnMaxReal;
+ realtype LnMinReal;
+ static realtype LnMaxRealExp;
+ static realtype LnMinRealExp;
+
+ // Initialization. Some C++ enviroments do not do the
+ // following statements automatically, therefore it is
+ // always advisable to call InitMatType() explicitely
+ // from the top of main(). See body of InitMatType()
+ // in the very end of this file. It is completely
+ // harmless and cheap to call InitMatType() multiple
+ // times.
+
+ static bool MatTypeInit = InitMatType();
+
+
+ // -------------------------------------------------------
+
+
+#ifdef _WIN32
+ pstr strcasestr ( pstr s1, cpstr s2 ) {
+ pstr l1,l2,l;
+ l1 = NULL;
+ l2 = NULL;
+ CreateCopy ( l1,s1 );
+ CreateCopy ( l2,s2 );
+ LowerCase ( l1 );
+ LowerCase ( l2 );
+ l = strstr ( l1,l2 );
+ if (l)
+ l = s1 + (l-l1);
+ delete[] l1;
+ delete[] l2;
+ return l;
+ }
+#endif
+
+
+ // -------------------------------------------------------
+ bool GetVectorMemory ( rvector & V, word N, word Shift ) {
+ V = new realtype[N];
+ if (V!=NULL) V = V - Shift; // shift for abovementioned enumeration
+ return (V!=NULL);
+ }
+
+ bool GetVectorMemory ( ivector & I, word N, word Shift ) {
+ I = new int[N];
+ if (I!=NULL) I = I - Shift; // shift for abovementioned enumeration
+ return (I!=NULL);
+ }
+
+ bool GetVectorMemory ( wvector & W, word N, word Shift ) {
+ W = new word[N];
+ if (W!=NULL) W = W - Shift; // shift for abovementioned enumeration
+ return (W!=NULL);
+ }
+
+ bool GetVectorMemory ( bvector & B, word N, word Shift ) {
+ B = new byte[N];
+ if (B!=NULL) B = B - Shift; // shift for abovementioned enumeration
+ return (B!=NULL);
+ }
+
+ bool GetVectorMemory ( ovector & O, word N, word Shift ) {
+ O = new bool[N];
+ if (O!=NULL) O = O - Shift; // shift for abovementioned enumeration
+ return (O!=NULL);
+ }
+
+ bool GetVectorMemory ( lvector & L, word N, word Shift ) {
+ L = new long[N];
+ if (L!=NULL) L = L - Shift; // shift for abovementioned enumeration
+ return (L!=NULL);
+ }
+
+ bool GetVectorMemory ( lwvector & L, word N, word Shift ) {
+ L = new lword[N];
+ if (L!=NULL) L = L - Shift; // shift for abovementioned enumeration
+ return (L!=NULL);
+ }
+
+ bool GetVectorMemory ( psvector & P, word N, word Shift ) {
+ P = new pstr[N];
+ if (P!=NULL) P = P - Shift; // shift for abovementioned enumeration
+ return (P!=NULL);
+ }
+
+ void FreeVectorMemory ( rvector & V, word Shift ) {
+ if (V!=NULL) {
+ V = V + Shift; // back shift for the work of heap system
+ delete[] V;
+ V = NULL;
+ }
+ }
+
+ void FreeVectorMemory ( ivector & I, word Shift ) {
+ if (I!=NULL) {
+ I = I + Shift; // back shift for the work of heap system
+ delete[] I;
+ I = NULL;
+ }
+ }
+
+ void FreeVectorMemory ( wvector & W, word Shift ) {
+ if (W!=NULL) {
+ W = W + Shift; // back shift for the work of heap system
+ delete[] W;
+ W = NULL;
+ }
+ }
+
+ void FreeVectorMemory ( bvector & B, word Shift ) {
+ if (B!=NULL) {
+ B = B + Shift; // back shift for the work of heap system
+ delete[] B;
+ B = NULL;
+ }
+ }
+
+ void FreeVectorMemory ( ovector & O, word Shift ) {
+ if (O!=NULL) {
+ O = O + Shift; // back shift for the work of heap system
+ delete[] O;
+ O = NULL;
+ }
+ }
+
+ void FreeVectorMemory ( lvector & L, word Shift ) {
+ if (L!=NULL) {
+ L = L + Shift; // back shift for the work of heap system
+ delete[] L;
+ L = NULL;
+ }
+ }
+
+ void FreeVectorMemory ( lwvector & L, word Shift ) {
+ if (L!=NULL) {
+ L = L + Shift; // back shift for the work of heap system
+ delete[] L;
+ L = NULL;
+ }
+ }
+
+ void FreeVectorMemory ( psvector & P, word Shift ) {
+ if (P!=NULL) {
+ P = P + Shift; // back shift for the work of heap system
+ delete[] P;
+ P = NULL;
+ }
+ }
+
+ bool GetMatrixMemory ( rmatrix & A, word N, word M,
+ word ShiftN, word ShiftM ) {
+ A = new rvector[N];
+ if (A!=NULL) {
+ for (word i=0;i<N;i++)
+ GetVectorMemory ( A[i],M,ShiftM );
+ if (A[N-1]==NULL)
+ FreeMatrixMemory ( A,N,0,ShiftM );
+ else A = A - ShiftN; // shift for the enumeration with 1
+ }
+ return (A!=NULL);
+ }
+
+ bool GetMatrixMemory ( imatrix & A, word N, word M,
+ word ShiftN, word ShiftM ) {
+ A = new ivector[N];
+ if (A!=NULL) {
+ for (word i=0;i<N;i++)
+ GetVectorMemory ( A[i],M,ShiftM );
+ if (A[N-1]==NULL)
+ FreeMatrixMemory ( A,N,0,ShiftM );
+ else A = A - ShiftN; // shift for the enumeration with 1
+ }
+ return (A!=NULL);
+ }
+
+ bool GetMatrixMemory ( wmatrix & W, word N, word M,
+ word ShiftN, word ShiftM ) {
+ W = new wvector[N];
+ if (W!=NULL) {
+ for (word i=0;i<N;i++)
+ GetVectorMemory ( W[i],M,ShiftM );
+ if (W[N-1]==NULL)
+ FreeMatrixMemory ( W,N,0,ShiftM );
+ else W = W - ShiftN; // shift for the enumeration with 1
+ }
+ return (W!=NULL);
+ }
+
+ bool GetMatrixMemory ( bmatrix & B, word N, word M,
+ word ShiftN, word ShiftM ) {
+ B = new bvector[N];
+ if (B!=NULL) {
+ for (word i=0;i<N;i++)
+ GetVectorMemory ( B[i],M,ShiftM );
+ if (B[N-1]==NULL)
+ FreeMatrixMemory ( B,N,0,ShiftM );
+ else B = B - ShiftN; // shift for the enumeration with 1
+ }
+ return (B!=NULL);
+ }
+
+ bool GetMatrixMemory ( omatrix & O, word N, word M,
+ word ShiftN, word ShiftM ) {
+ O = new ovector[N];
+ if (O!=NULL) {
+ for (word i=0;i<N;i++)
+ GetVectorMemory ( O[i],M,ShiftM );
+ if (O[N-1]==NULL)
+ FreeMatrixMemory ( O,N,0,ShiftM );
+ else O = O - ShiftN; // shift for the enumeration with 1
+ }
+ return (O!=NULL);
+ }
+
+ bool GetMatrixMemory ( lmatrix & L, word N, word M,
+ word ShiftN, word ShiftM ) {
+ L = new lvector[N];
+ if (L!=NULL) {
+ for (word i=0;i<N;i++)
+ GetVectorMemory ( L[i],M,ShiftM );
+ if (L[N-1]==NULL)
+ FreeMatrixMemory ( L,N,0,ShiftM );
+ else L = L - ShiftN; // shift for the enumeration with 1
+ }
+ return (L!=NULL);
+ }
+
+ bool GetMatrixMemory ( lwmatrix & L, word N, word M,
+ word ShiftN, word ShiftM ) {
+ L = new lwvector[N];
+ if (L!=NULL) {
+ for (word i=0;i<N;i++)
+ GetVectorMemory ( L[i],M,ShiftM );
+ if (L[N-1]==NULL)
+ FreeMatrixMemory ( L,N,0,ShiftM );
+ else L = L - ShiftN; // shift for the enumeration with 1
+ }
+ return (L!=NULL);
+ }
+
+ bool GetMatrixMemory ( psmatrix & P, word N, word M,
+ word ShiftN, word ShiftM ) {
+ P = new psvector[N];
+ if (P!=NULL) {
+ for (word i=0;i<N;i++)
+ GetVectorMemory ( P[i],M,ShiftM );
+ if (P[N-1]==NULL)
+ FreeMatrixMemory ( P,N,0,ShiftM );
+ else P = P - ShiftN; // shift for the enumeration with 1
+ }
+ return (P!=NULL);
+ }
+
+ void FreeMatrixMemory ( rmatrix & A, word N,
+ word ShiftN, word ShiftM ) {
+ if (A!=NULL) {
+ A = A + ShiftN; // back shift for the work of heap system
+ for (word i=0;i<N;i++)
+ FreeVectorMemory ( A[i],ShiftM );
+ delete[] A;
+ A = NULL;
+ }
+ }
+
+ void FreeMatrixMemory ( imatrix & A, word N,
+ word ShiftN, word ShiftM ) {
+ if (A!=NULL) {
+ A = A + ShiftN; // back shift for the work of heap system
+ for (word i=0;i<N;i++)
+ FreeVectorMemory ( A[i],ShiftM );
+ delete[] A;
+ A = NULL;
+ }
+ }
+
+ void FreeMatrixMemory ( wmatrix & W, word N,
+ word ShiftN, word ShiftM ) {
+ if (W!=NULL) {
+ W = W + ShiftN; // back shift for the work of heap system
+ for (word i=0;i<N;i++)
+ FreeVectorMemory ( W[i],ShiftM );
+ delete[] W;
+ W = NULL;
+ }
+ }
+
+ void FreeMatrixMemory ( bmatrix & B, word N,
+ word ShiftN, word ShiftM ) {
+ if (B!=NULL) {
+ B = B + ShiftN; // back shift for the work of heap system
+ for (word i=0;i<N;i++)
+ FreeVectorMemory ( B[i],ShiftM );
+ delete[] B;
+ B = NULL;
+ }
+ }
+
+ void FreeMatrixMemory ( omatrix & O, word N,
+ word ShiftN, word ShiftM ) {
+ if (O!=NULL) {
+ O = O + ShiftN; // back shift for the work of heap system
+ for (word i=0;i<N;i++)
+ FreeVectorMemory ( O[i],ShiftM );
+ delete[] O;
+ O = NULL;
+ }
+ }
+
+ void FreeMatrixMemory ( lmatrix & L, word N,
+ word ShiftN, word ShiftM ) {
+ if (L!=NULL) {
+ L = L + ShiftN; // back shift for the work of heap system
+ for (word i=0;i<N;i++)
+ FreeVectorMemory ( L[i],ShiftM );
+ delete[] L;
+ L = NULL;
+ }
+ }
+
+ void FreeMatrixMemory ( lwmatrix & L, word N,
+ word ShiftN, word ShiftM ) {
+ if (L!=NULL) {
+ L = L + ShiftN; // back shift for the work of heap system
+ for (word i=0;i<N;i++)
+ FreeVectorMemory ( L[i],ShiftM );
+ delete[] L;
+ L = NULL;
+ }
+ }
+
+ void FreeMatrixMemory ( psmatrix & P, word N,
+ word ShiftN, word ShiftM ) {
+ if (P!=NULL) {
+ P = P + ShiftN; // back shift for the work of heap system
+ for (word i=0;i<N;i++)
+ FreeVectorMemory ( P[i],ShiftM );
+ delete[] P;
+ P = NULL;
+ }
+ }
+
+ bool GetMatrix3Memory ( rmatrix3 & A, word N, word M, word K,
+ word ShiftN, word ShiftM, word ShiftK ) {
+ A = new rmatrix[N];
+ if (A!=NULL) {
+ for (word i=0;i<N;i++)
+ GetMatrixMemory ( A[i],M,K,ShiftM,ShiftK );
+ if (A[N-1]==NULL)
+ FreeMatrix3Memory ( A,N,M,0,ShiftM,ShiftK );
+ else
+ A = A - ShiftN; // shift for the enumeration with 1
+ }
+ return (A!=NULL);
+ }
+
+ bool GetMatrix3Memory ( imatrix3 & A, word N, word M, word K,
+ word ShiftN, word ShiftM, word ShiftK ) {
+ A = new imatrix[N];
+ if (A!=NULL) {
+ for (word i=0;i<N;i++)
+ GetMatrixMemory ( A[i],M,K,ShiftM,ShiftK );
+ if (A[N-1]==NULL)
+ FreeMatrix3Memory ( A,N,M,0,ShiftM,ShiftK );
+ else
+ A = A - ShiftN; // shift for the enumeration with 1
+ }
+ return (A!=NULL);
+ }
+
+ bool GetMatrix3Memory ( wmatrix3 & A, word N, word M, word K,
+ word ShiftN, word ShiftM, word ShiftK ) {
+ A = new wmatrix[N];
+ if (A!=NULL) {
+ for (word i=0;i<N;i++)
+ GetMatrixMemory ( A[i],M,K,ShiftM,ShiftK );
+ if (A[N-1]==NULL)
+ FreeMatrix3Memory ( A,N,M,0,ShiftM,ShiftK );
+ else
+ A = A - ShiftN; // shift for the enumeration with 1
+ }
+ return (A!=NULL);
+ }
+
+ bool GetMatrix3Memory ( bmatrix3 &A, word N, word M, word K,
+ word ShiftN, word ShiftM, word ShiftK ) {
+ A = new bmatrix[N];
+ if (A!=NULL) {
+ for (word i=0;i<N;i++)
+ GetMatrixMemory ( A[i],M,K,ShiftM,ShiftK );
+ if (A[N-1]==NULL)
+ FreeMatrix3Memory ( A,N,M,0,ShiftM,ShiftK );
+ else
+ A = A - ShiftN; // shift for the enumeration with 1
+ }
+ return (A!=NULL);
+ }
+
+ bool GetMatrix3Memory ( omatrix3 &A, word N, word M, word K,
+ word ShiftN, word ShiftM, word ShiftK ) {
+ A = new omatrix[N];
+ if (A!=NULL) {
+ for (word i=0;i<N;i++)
+ GetMatrixMemory ( A[i],M,K,ShiftM,ShiftK );
+ if (A[N-1]==NULL)
+ FreeMatrix3Memory ( A,N,M,0,ShiftM,ShiftK );
+ else
+ A = A - ShiftN; // shift for the enumeration with 1
+ }
+ return (A!=NULL);
+ }
+
+ bool GetMatrix3Memory ( lmatrix3 & A, word N, word M, word K,
+ word ShiftN, word ShiftM, word ShiftK ) {
+ A = new lmatrix[N];
+ if (A!=NULL) {
+ for (word i=0;i<N;i++)
+ GetMatrixMemory ( A[i],M,K,ShiftM,ShiftK );
+ if (A[N-1]==NULL)
+ FreeMatrix3Memory ( A,N,M,0,ShiftM,ShiftK );
+ else
+ A = A - ShiftN; // shift for the enumeration with 1
+ }
+ return (A!=NULL);
+ }
+
+ bool GetMatrix3Memory ( lwmatrix3 & A, word N, word M, word K,
+ word ShiftN, word ShiftM, word ShiftK ) {
+ A = new lwmatrix[N];
+ if (A!=NULL) {
+ for (word i=0;i<N;i++)
+ GetMatrixMemory ( A[i],M,K,ShiftM,ShiftK );
+ if (A[N-1]==NULL)
+ FreeMatrix3Memory ( A,N,M,0,ShiftM,ShiftK );
+ else
+ A = A - ShiftN; // shift for the enumeration with 1
+ }
+ return (A!=NULL);
+ }
+
+ bool GetMatrix3Memory ( psmatrix3 & A, word N, word M, word K,
+ word ShiftN, word ShiftM, word ShiftK ) {
+ A = new psmatrix[N];
+ if (A!=NULL) {
+ for (word i=0;i<N;i++)
+ GetMatrixMemory ( A[i],M,K,ShiftM,ShiftK );
+ if (A[N-1]==NULL)
+ FreeMatrix3Memory ( A,N,M,0,ShiftM,ShiftK );
+ else
+ A = A - ShiftN; // shift for the enumeration with 1
+ }
+ return (A!=NULL);
+ }
+
+ void FreeMatrix3Memory ( rmatrix3 & A, word N, word M,
+ word ShiftN, word ShiftM, word ShiftK ) {
+ if (A!=NULL) {
+ A = A + ShiftN; // back shift for the work of heap system
+ for (word i=0;i<N;i++)
+ FreeMatrixMemory ( A[i],M,ShiftM,ShiftK );
+ delete[] A;
+ A = NULL;
+ }
+ }
+
+ void FreeMatrix3Memory ( imatrix3 & A, word N, word M,
+ word ShiftN, word ShiftM, word ShiftK ) {
+ if (A!=NULL) {
+ A = A + ShiftN; // back shift for the work of heap system
+ for (word i=0;i<N;i++)
+ FreeMatrixMemory ( A[i],M,ShiftM,ShiftK );
+ delete[] A;
+ A = NULL;
+ }
+ }
+
+ void FreeMatrix3Memory ( wmatrix3 & A, word N, word M,
+ word ShiftN, word ShiftM, word ShiftK ) {
+ if (A!=NULL) {
+ A = A + ShiftN; // back shift for the work of heap system
+ for (word i=0;i<N;i++)
+ FreeMatrixMemory ( A[i],M,ShiftM,ShiftK );
+ delete[] A;
+ A = NULL;
+ }
+ }
+
+ void FreeMatrix3Memory ( bmatrix3 & A, word N, word M,
+ word ShiftN, word ShiftM, word ShiftK ) {
+ if (A!=NULL) {
+ A = A + ShiftN; // back shift for the work of heap system
+ for (word i=0;i<N;i++)
+ FreeMatrixMemory ( A[i],M,ShiftM,ShiftK );
+ delete[] A;
+ A = NULL;
+ }
+ }
+
+ void FreeMatrix3Memory ( omatrix3 & A, word N, word M,
+ word ShiftN, word ShiftM, word ShiftK ) {
+ if (A!=NULL) {
+ A = A + ShiftN; // back shift for the work of heap system
+ for (word i=0;i<N;i++)
+ FreeMatrixMemory ( A[i],M,ShiftM,ShiftK );
+ delete[] A;
+ A = NULL;
+ }
+ }
+
+ void FreeMatrix3Memory ( lmatrix3 & A, word N, word M,
+ word ShiftN, word ShiftM, word ShiftK ) {
+ if (A!=NULL) {
+ A = A + ShiftN; // back shift for the work of heap system
+ for (word i=0;i<N;i++)
+ FreeMatrixMemory ( A[i],M,ShiftM,ShiftK );
+ delete[] A;
+ A = NULL;
+ }
+ }
+
+ void FreeMatrix3Memory ( lwmatrix3 & A, word N, word M,
+ word ShiftN, word ShiftM, word ShiftK ) {
+ if (A!=NULL) {
+ A = A + ShiftN; // back shift for the work of heap system
+ for (word i=0;i<N;i++)
+ FreeMatrixMemory ( A[i],M,ShiftM,ShiftK );
+ delete[] A;
+ A = NULL;
+ }
+ }
+
+ void FreeMatrix3Memory ( psmatrix3 & A, word N, word M,
+ word ShiftN, word ShiftM, word ShiftK ) {
+ if (A!=NULL) {
+ A = A + ShiftN; // back shift for the work of heap system
+ for (word i=0;i<N;i++)
+ FreeMatrixMemory ( A[i],M,ShiftM,ShiftK );
+ delete[] A;
+ A = NULL;
+ }
+ }
+
+ realtype MachinEps () {
+ // A1.3.1 : Calculation of the machine's epsilon
+ /*
+ realtype rMachEps = 1.0;
+ do
+ rMachEps /= 2.0;
+ while ((1.0+rMachEps)!=1.0);
+ return 2.0*rMachEps;
+ */
+ return std::numeric_limits<realtype>::epsilon();
+ }
+
+ realtype floatMachinEps() {
+ // A1.3.1 : Calculation of the machine's epsilon
+ /*
+ float fMachEps = 1.0;
+ do
+ fMachEps /= 2.0;
+ while (float(1.0+fMachEps)!=1.0);
+ return 2.0*fMachEps;
+ */
+ return std::numeric_limits<float>::epsilon();
+ }
+
+ realtype frac ( realtype R ) {
+ realtype i;
+ return modf ( R,&i );
+ }
+
+ long mod ( long x, long y ) {
+ long k=x/y;
+ long f=x-k*y;
+ while (f<0) f += y;
+ return f;
+ }
+
+ realtype Pow ( realtype X, int y ) {
+ int m,l;
+ realtype B;
+ if (y==0) return 1.0;
+ else if (X!=0.0) {
+ B = X;
+ m = 1;
+ if (y>=0) l = y;
+ else l = -y;
+ while (m++<l) B = B*X;
+ if (y>=0) return B;
+ else return 1.0/B;
+ } else return 0.0;
+ }
+
+ realtype Pow1 ( realtype X, realtype Y ) {
+ int k = mround(Y);
+ if (fabs(k-Y)<=100.0*MachEps) return Pow(X,k);
+ if (X==0.0) return 0.0;
+ else return pow(X,Y);
+ }
+
+ realtype Exp ( realtype X ) {
+ //realtype X1 = X;
+ //realtype B = 1.0;
+ if (X>=LnMaxRealExp) return MaxReal;
+ else if (X<=LnMinRealExp) return 0.0;
+ else {
+ return exp(X);
+ /*
+ while (X1>LnMaxReal) {
+ X1 -= LnMaxReal;
+ B *= MaxExponent;
+ }
+ while (X1<-LnMaxReal) {
+ X1 += LnMaxReal;
+ B /= MaxExponent;
+ }
+ return B*exp(X1);
+ */
+ }
+ }
+
+ bool Odd ( int i ) {
+ return (i & 1);
+ }
+
+
+ // ----------------------------------------------------
+
+ long HexValL ( cpstr S ) {
+ char C;
+ int i;
+ long z=0;
+ for (i=0;S[i];i++) {
+ z <<= 4;
+ C = (char)toupper(S[i]);
+ if (isdigit(C)) z += S[i]-'0';
+ else z += C-'A'+10;
+ }
+ return z;
+ }
+
+
+ // ----------------------------------------------------
+
+ long OctValL ( cpstr S ) {
+ int i;
+ long z=0;
+ for (i=0;S[i];i++) {
+ z <<= 3;
+ z += S[i]-'0';
+ }
+ return z;
+ }
+
+
+ // ----------------------------------------------------
+
+ long BinValL ( cpstr S ) {
+ int i;
+ long z=0;
+ for (i=0;S[i];i++) {
+ z <<= 1;
+ z += S[i]-'0';
+ }
+ return z;
+ }
+
+ pstr BinValS ( long L, pstr S ) {
+ int i;
+ long z;
+ z = long(1) << (8*sizeof(long)-1);
+ for (i=0;i<8*(int)sizeof(long);i++) {
+ if (L & z) S[i] = '1';
+ else S[i] = '0';
+ z >>= 1;
+ }
+ S[8*sizeof(long)] = char(0);
+ return S;
+ }
+
+
+
+ // ----------------------------------------------------
+
+ pstr ParamStr ( pstr D, cpstr S, realtype V, int M, cpstr S1 ) {
+ char VS[30];
+ strcat ( D,S );
+ sprintf ( VS,"%-.*g",M,V );
+ strcat ( D,VS );
+ return strcat(D,S1);
+ }
+
+
+ pstr ParamStr ( pstr D, cpstr S, realtype V, int M,
+ cpstr S1, realtype V2, int M2, cpstr S2 ) {
+ char VS[30];
+ ParamStr ( D,S,V,M,S1 );
+ sprintf ( VS,"%-.*g",M2,V2 );
+ strcat ( D,VS );
+ return strcat(D,S2);
+ }
+
+
+ pstr CreateCopy ( pstr & Dest, cpstr Source ) {
+ if (Dest) delete[] Dest;
+ if (Source) {
+ Dest = new char[strlen(Source)+1];
+ strcpy ( Dest,Source );
+ } else
+ Dest = NULL;
+ return Dest;
+ }
+
+ pstr CreateCopy_n ( pstr & Dest, cpstr Source, int n ) {
+ int l;
+ if (Dest) delete[] Dest;
+ if (Source) {
+ l = IMin ( strlen(Source),n );
+ Dest = new char[l+1];
+ strncpy ( Dest,Source,l );
+ Dest[l] = char(0);
+ } else
+ Dest = NULL;
+ return Dest;
+ }
+
+ pstr CreateCopCat ( pstr & Dest,
+ cpstr Source1, cpstr Source2,
+ cpstr Source3, cpstr Source4,
+ cpstr Source5 ) {
+ if (Dest) {
+ delete[] Dest;
+ Dest = NULL;
+ }
+ return CreateConcat ( Dest,Source1,Source2,Source3,Source4,Source5 );
+ }
+
+ pstr CreateCopCat ( pstr & Dest,
+ cpstr Source1, cpstr Source2,
+ cpstr Source3, cpstr Source4 ) {
+ if (Dest) {
+ delete[] Dest;
+ Dest = NULL;
+ }
+ return CreateConcat ( Dest,Source1,Source2,Source3,Source4 );
+ }
+
+ pstr CreateCopCat ( pstr & Dest,
+ cpstr Source1, cpstr Source2,
+ cpstr Source3 ) {
+ if (Dest) {
+ delete[] Dest;
+ Dest = NULL;
+ }
+ return CreateConcat ( Dest,Source1,Source2,Source3 );
+ }
+
+ pstr CreateCopCat ( pstr & Dest,
+ cpstr Source1, cpstr Source2 ) {
+ if (Dest) {
+ delete[] Dest;
+ Dest = NULL;
+ }
+ return CreateConcat ( Dest,Source1,Source2 );
+ }
+
+
+ pstr CreateConcat ( pstr & Dest,
+ cpstr Source1, cpstr Source2,
+ cpstr Source3, cpstr Source4,
+ cpstr Source5 ) {
+ pstr S;
+ int ld,ls;
+ if (Dest) ld = strlen(Dest);
+ else ld = 0;
+ ls = 0;
+ if (Source1) ls += strlen(Source1);
+ if (Source2) ls += strlen(Source2);
+ if (Source3) ls += strlen(Source3);
+ if (Source4) ls += strlen(Source4);
+ if (Source5) ls += strlen(Source5);
+ if (ls>0) {
+ S = new char[ls+ld+1];
+ if (Dest) {
+ strcpy ( S,Dest );
+ delete[] Dest;
+ } else
+ S[0] = char(0);
+ if (Source1) strcat ( S,Source1 );
+ if (Source2) strcat ( S,Source2 );
+ if (Source3) strcat ( S,Source3 );
+ if (Source4) strcat ( S,Source4 );
+ if (Source5) strcat ( S,Source5 );
+ Dest = S;
+ }
+ return Dest;
+ }
+
+
+ pstr CreateConcat ( pstr & Dest,
+ cpstr Source1, cpstr Source2,
+ cpstr Source3, cpstr Source4 ) {
+ pstr S;
+ int ld,ls;
+ if (Dest) ld = strlen(Dest);
+ else ld = 0;
+ ls = 0;
+ if (Source1) ls += strlen(Source1);
+ if (Source2) ls += strlen(Source2);
+ if (Source3) ls += strlen(Source3);
+ if (Source4) ls += strlen(Source4);
+ if (ls>0) {
+ S = new char[ls+ld+1];
+ if (Dest) {
+ strcpy ( S,Dest );
+ delete[] Dest;
+ } else
+ S[0] = char(0);
+ if (Source1) strcat ( S,Source1 );
+ if (Source2) strcat ( S,Source2 );
+ if (Source3) strcat ( S,Source3 );
+ if (Source4) strcat ( S,Source4 );
+ Dest = S;
+ }
+ return Dest;
+ }
+
+
+ pstr CreateConcat ( pstr & Dest,
+ cpstr Source1, cpstr Source2,
+ cpstr Source3 ) {
+ pstr S;
+ int ld,ls;
+ if (Dest) ld = strlen(Dest);
+ else ld = 0;
+ ls = 0;
+ if (Source1) ls += strlen(Source1);
+ if (Source2) ls += strlen(Source2);
+ if (Source3) ls += strlen(Source3);
+ if (ls>0) {
+ S = new char[ls+ld+1];
+ if (Dest) {
+ strcpy ( S,Dest );
+ delete[] Dest;
+ } else
+ S[0] = char(0);
+ if (Source1) strcat ( S,Source1 );
+ if (Source2) strcat ( S,Source2 );
+ if (Source3) strcat ( S,Source3 );
+ Dest = S;
+ }
+ return Dest;
+ }
+
+ pstr CreateConcat ( pstr & Dest,
+ cpstr Source1, cpstr Source2 ) {
+ pstr S;
+ int ld,ls;
+ if (Dest) ld = strlen(Dest);
+ else ld = 0;
+ ls = 0;
+ if (Source1) ls += strlen(Source1);
+ if (Source2) ls += strlen(Source2);
+ if (ls>0) {
+ S = new char[ls+ld+1];
+ if (Dest) {
+ strcpy ( S,Dest );
+ delete[] Dest;
+ } else
+ S[0] = char(0);
+ if (Source1) strcat ( S,Source1 );
+ if (Source2) strcat ( S,Source2 );
+ Dest = S;
+ }
+ return Dest;
+ }
+
+ pstr CreateConcat ( pstr & Dest, cpstr Source ) {
+ pstr S;
+ int ld,ls;
+ if (Dest) ld = strlen(Dest);
+ else ld = 0;
+ if (Source) ls = strlen(Source);
+ else ls = 0;
+ if (ls>0) {
+ S = new char[ls+ld+1];
+ if (Dest) {
+ strcpy ( S,Dest );
+ delete[] Dest;
+ } else
+ S[0] = char(0);
+ strcat ( S,Source );
+ Dest = S;
+ }
+ return Dest;
+ }
+
+
+ pstr LastOccurence ( cpstr S, char c ) {
+ pstr P=(pstr)S;
+ pstr R=NULL;
+ while (*P) {
+ if (*P==c) R = P;
+ P++;
+ }
+ return R;
+ }
+
+
+ pstr FirstOccurence ( cpstr S, char c ) {
+ pstr P=(pstr)S;
+ while (*P) {
+ if (*P==c) return P;
+ P++;
+ }
+ return NULL;
+ }
+
+ int indexOf ( cpstr S, char c ) {
+ int i=0;
+ while (S[i]) {
+ if (S[i]==c) return i;
+ i++;
+ }
+ return -1;
+ }
+
+ pstr FirstOccurence ( cpstr S, int Slen, cpstr Q, int Qlen ) {
+ int i,j,k,l;
+ l = Slen-Qlen;
+ for (i=0;i<=l;i++) {
+ j = 0;
+ k = i;
+ while (j<Qlen)
+ if (S[k++]!=Q[j]) break;
+ else j++;
+ if (j>=Qlen) return pstr(&(S[i]));
+ }
+ return NULL;
+ }
+
+ int indexOf ( cpstr S, int Slen, cpstr Q, int Qlen ) {
+ int i,j,k,l;
+ l = Slen-Qlen;
+ for (i=0;i<=l;i++) {
+ j = 0;
+ k = i;
+ while (j<Qlen)
+ if (S[k++]!=Q[j]) break;
+ else j++;
+ if (j>=Qlen) return i;
+ }
+ return -1;
+ }
+
+
+ pstr LowerCase ( pstr s ) {
+ pstr p=s;
+ while (*p) {
+ *p = char(tolower(int(*p)));
+ p++;
+ }
+ return s;
+ }
+
+ pstr UpperCase ( pstr s ) {
+ pstr p=s;
+ while (*p) {
+ *p = char(toupper(int(*p)));
+ p++;
+ }
+ return s;
+ }
+
+
+ void GetString ( pstr L, cpstr S, int M ) {
+ // Copies first M characters of string S into string L,
+ // appending the terminating null. If S contains less
+ // then M characters, L will be padded with spaces.
+ int i,j;
+ i = 0;
+ j = 0;
+ while (S[i] && (i<M))
+ L[j++] = S[i++];
+ while (j<M)
+ L[j++] = ' ';
+ L[j] = char(0);
+ }
+
+
+ void GetStrTer ( pstr L, cpstr S, int n, int LMax, int SMax ) {
+ // Copies at least n (or LMax if LMax<n) first symbols of
+ // string S into string L, then continues copying until first
+ // space or terminating null is found. If the terminating null
+ // is met among the first n characters or if SMax<n, the string
+ // L will be padded with spaces till the length of minimum of
+ // n and LMax and then terminated with the null.
+ // SMax are buffer lengths of L and S, respectively. Even if
+ // no space is found, the last character in L will be the
+ // terminating null.
+ int i,k,lm1,msl,mnsl;
+ lm1 = LMax-1;
+ msl = IMin(lm1,SMax);
+ mnsl = IMin(n,msl);
+ k = 0;
+ for (i=0;i<mnsl;i++)
+ if (S[i]) L[k++] = S[i];
+ else break;
+ if ((k>=SMax) || (!S[k])) {
+ lm1 = IMin(n,lm1);
+ while (k<lm1)
+ L[k++] = ' ';
+ } else {
+ lm1 = k;
+ for (i=lm1;i<msl;i++)
+ if (S[i] && (S[i]!=' ')) L[k++] = S[i];
+ else break;
+ }
+ L[k] = char(0);
+ }
+
+
+ void GetStrTerWin32File ( pstr L, cpstr S, int n, int LMax,
+ int SMax ) {
+ //
+ // Version of GetStrTer(..) allowing for spaces in the string.
+ //
+ // Copies at least n (or LMax if LMax<n) first symbols of
+ // string S into string L, then continues copying until first
+ // terminating null is found. If the terminating null
+ // is met among the first n characters or if SMax<n, the string
+ // L will be padded with spaces till the length of minimum of
+ // n and LMax and then terminated with the null.
+ // SMax are buffer lengths of L and S, respectively. The last
+ // character in L will be the terminating null.
+ //
+ int i,k,lm1,msl,mnsl;
+ lm1 = LMax-1;
+ msl = IMin(lm1,SMax);
+ mnsl = IMin(n,msl);
+ k = 0;
+ for (i=0;i<mnsl;i++)
+ if (S[i]) L[k++] = S[i];
+ else break;
+ if ((!S[k]) || (k>=SMax)) {
+ lm1 = IMin(n,lm1);
+ while (k<lm1)
+ L[k++] = ' ';
+ } else {
+ lm1 = k;
+ for (i=lm1;i<msl;i++)
+ if (S[i]) L[k++] = S[i];
+ else break;
+ }
+ L[k] = char(0);
+ }
+
+ void strcpy_n ( pstr d, cpstr s, int n ) {
+ // Copies at most n symbols from string s to d, but
+ // no more than strlen(s) (s must contain a terminating
+ // null). The terminating null IS NEITHER appended NOR
+ // copied to d.
+ int i;
+ i = 0;
+ while ((i<n) && (s[i])) {
+ d[i] = s[i];
+ i++;
+ }
+ }
+
+
+ void strcpy_n1 ( pstr d, cpstr s, int n ) {
+ // Copies at most n last symbols from string s to d, but
+ // no more than strlen(s) (s must contain a terminating null).
+ // The string in d is aligned to the right and added with
+ // spaces at the left, if necessary. The terminating null
+ // IS NEITHER appended NOR copied to d.
+ int i,k;
+ i = n-1;
+ k = strlen(s)-1;
+ while ((i>=0) && (k>=0))
+ d[i--] = s[k--];
+ while (i>=0)
+ d[i--] = ' ';
+ }
+
+ void strcpy_nr ( pstr d, cpstr s, int n ) {
+ // Copies at most n symbols from string s to d, but
+ // no more than strlen(s) (s must contain a terminating null).
+ // The string in d is aligned to the right and added with
+ // spaces at the left, if necessary. The terminating null
+ // IS NEITHER appended NOR copied to d.
+ int i,k;
+ i = n-1;
+ k = IMin(i,strlen(s)-1);
+ while ((i>=0) && (k>=0))
+ d[i--] = s[k--];
+ while (i>=0)
+ d[i--] = ' ';
+ }
+
+
+ void strcpy_ns ( pstr d, cpstr s, int n ) {
+ // Copies at most n symbols from string s to d, but
+ // no more than strlen(s) (s must contain a terminating
+ // null). The terminating null IS NEITHER appended NOR
+ // copied to d; rather, d is padded with spaces if
+ // strlen(s)<n.
+ int i;
+ i = 0;
+ while ((i<n) && (s[i])) {
+ d[i] = s[i];
+ i++;
+ }
+ while (i<n)
+ d[i++] = ' ';
+ }
+
+
+ pstr strcpy_cs ( pstr d, cpstr s ) {
+ // Copies string s to string d cutting all spaces at
+ // at the end. Thus, " abcde " will be copied like
+ // " abcde" (terminating null appended).
+ // The function returns d.
+ int i;
+ i = 0;
+ while (s[i]) {
+ d[i] = s[i];
+ i++;
+ }
+ i--;
+ while ((i>0) && (d[i]==' ')) i--;
+ if (d[i]==' ') d[i] = char(0);
+ else d[i+1] = char(0);
+ return d;
+ }
+
+
+ pstr strcpy_ncs ( pstr d, cpstr s, int n ) {
+ // Copies at most n characters from string s to string d
+ // cutting all spaces at at the end. Thus, " abcde " will
+ // be copied like " abc" at n=4 and like " abcde" at n>5
+ // (terminating null appended).
+ // The function returns d.
+ int i;
+ i = 0;
+ while (s[i] && (i<n)) {
+ d[i] = s[i];
+ i++;
+ }
+ i--;
+ while ((i>0) && (d[i]==' ')) i--;
+ if (d[i]==' ') d[i] = char(0);
+ else d[i+1] = char(0);
+ return d;
+ }
+
+ pstr strcpy_css ( pstr d, cpstr s ) {
+ // Copies string s to string d cutting all spaces at
+ // at the begining and at the end. Thus, " ab c de "
+ // will be copied like "ab c de" (terminating null
+ // appended).
+ // The function returns d.
+ int i,k;
+ i = 0;
+ while (s[i]==' ') i++;
+ k = 0;
+ while (s[i])
+ d[k++] = s[i++];
+ if (k>0) {
+ k--;
+ while ((k>0) && (d[k]==' ')) k--;
+ if (d[k]==' ') d[k] = char(0);
+ else d[k+1] = char(0);
+ } else
+ d[k] = char(0);
+ return d;
+ }
+
+ pstr strcpy_ncss ( pstr d, cpstr s, int n ) {
+ // Copies at most n characters from string s to string d cutting
+ // all spaces at the begining and at the end. Thus, " ab c de "
+ // will be copied like "ab" at n=3 (terminating null appended).
+ // The function returns d.
+ int i,k;
+ i = 0;
+ while ((s[i]==' ') && (i<n)) i++;
+ k = 0;
+ while (s[i] && (i<n))
+ d[k++] = s[i++];
+ if (k>0) {
+ k--;
+ while ((k>0) && (d[k]==' ')) k--;
+ if (d[k]==' ') d[k] = char(0);
+ else d[k+1] = char(0);
+ } else
+ d[k] = char(0);
+ return d;
+ }
+
+
+ pstr strcpy_n0 ( pstr d, cpstr s, int n ) {
+ // Copies at most n symbols from string s to d, but
+ // no more than strlen(s) (s must contain a terminating
+ // null). The terminating null IS appended to d.
+ // The function returns d.
+ int i;
+ i = 0;
+ while ((i<n) && (s[i])) {
+ d[i] = s[i];
+ i++;
+ }
+ d[i] = char(0);
+ return d;
+ }
+
+
+ int strlen_des ( cpstr s ) {
+ // strlen_des returns the length of a string as if all extra
+ // spaces from the latter have been deleted. Extra spaces
+ // include all leading and tracing spaces and any sequential
+ // spaces when more than one. The string does not change.
+ int i,l;
+ l = 0;
+ i = 0;
+ while (s[i]==' ') i++;
+ while (s[i]) {
+ if ((s[i]!=' ') || ((s[i+1]!=' ') && s[i+1]))
+ l++;
+ i++;
+ }
+ return l;
+ }
+
+ pstr strcpy_des ( pstr d, cpstr s ) {
+ // strcpy_des copies string s into string d removing all extra
+ // spaces from the latter. Extra spaces include all leading and
+ // tracing spaces and any sequential spaces when more than one.
+ int i,j;
+ j = 0;
+ i = 0;
+ while (s[i]==' ') i++;
+ while (s[i]) {
+ if ((s[i]!=' ') || ((s[i+1]!=' ') && s[i+1]))
+ d[j++] = s[i];
+ i++;
+ }
+ d[j] = char(0);
+ return d;
+ }
+
+ pstr strcat_des ( pstr d, cpstr s ) {
+ // strcpy_des appends string s to string d removing all extra
+ // spaces from the latter. Extra spaces include all leading and
+ // tracing spaces and any sequential spaces when more than one.
+ int i,j;
+ j = strlen(d);
+ i = 0;
+ while (s[i]==' ') i++;
+ while (s[i]) {
+ if ((s[i]!=' ') || ((s[i+1]!=' ') && s[i+1]))
+ d[j++] = s[i];
+ i++;
+ }
+ d[j] = char(0);
+ return d;
+ }
+
+
+ void PadSpaces ( pstr S, int len ) {
+ // Pads string S with spaces making its length equal to len.
+ // The terminating zero is added, so that S should reserve
+ // space of a minimum len+1 characters.
+ int i=strlen(S);
+ while (i<len) S[i++] = ' ';
+ S[i] = char(0);
+ }
+
+
+ pstr CutSpaces ( pstr S, int CutKey ) {
+ // Cuts spaces at the begining or end of string S
+ // according to the value of CutKey. THe function
+ // returns S;
+ int i,k;
+ i = 0;
+ k = 0;
+ if (CutKey & SCUTKEY_BEGIN)
+ while (S[i]==' ') i++;
+ if (k<i)
+ while (S[i])
+ S[k++] = S[i++];
+ else
+ k = strlen(S);
+ if ((CutKey & SCUTKEY_END) && (k>0)) {
+ k--;
+ while ((k>0) && (S[k]==' ')) k--;
+ if (S[k]!=' ') k++;
+ }
+ S[k] = char(0);
+ return S;
+ }
+
+
+ pstr DelSpaces ( pstr S, char c ) {
+ // Removes all spaces (or other symbols as specified by 'c')
+ // from the string. The string is then shrinked by the number
+ // of removed characters. Thus, " as ttt " becomes "asttt".
+ int i,j;
+ j = 0;
+ for (i=0;S[i];i++)
+ if (S[i]!=c) {
+ if (j<i) S[j] = S[i];
+ j++;
+ }
+ S[j] = char(0);
+ return S;
+ }
+
+ pstr EnforceSpaces ( pstr S ) {
+ int i,k;
+ i = 0;
+ while (S[i]) {
+ k = int(S[i]);
+ if ((k<32) && (k!=9) && (k!=10) && (k!=13)) S[i] = ' ';
+ i++;
+ }
+ return S;
+ }
+
+
+ // ----------------------------------------------------
+
+ #define _fbase 256
+ #define _rfbase 256.0
+ #define _fsign 0x80
+ #define _fsign1 0x7F
+
+ #ifdef UseDoubleFloat
+ # define _nfPowers 255
+ # define _nfPower0 127
+ # define _nfPower8 135
+ //# define _nfPower4 131
+ # define _nfPower4 130
+ #else
+ # define _nfPowers 31
+ # define _nfPower0 15
+ # define _nfPower8 19
+ # define _nfPower4 19
+ #endif
+
+ static realtype _fpower[_nfPowers+1];
+ static realtype _fpower8;
+ static realtype _fpower4;
+ static bool _old_float_unibin;
+
+ bool InitFPowers() {
+ int i;
+ _fpower[_nfPower0] = 1.0;
+ for (i=1;i<=_nfPower0;i++) {
+ _fpower[_nfPower0+i] = _fpower[_nfPower0+i-1]*_rfbase;
+ _fpower[_nfPower0-i] = _fpower[_nfPower0-i+1]/_rfbase;
+ }
+ _fpower[_nfPowers] = fMaxReal;
+ _fpower8 = _fpower[_nfPower8];
+ _fpower4 = _fpower[_nfPower4];
+ _old_float_unibin = false;
+ return true;
+ }
+
+ void __modify4() {
+ _fpower4 = _fpower[_nfPower4-1];
+ }
+
+ void set_new_float_unibin() {
+ _old_float_unibin = false;
+ }
+
+ bool is_new_float_unibin() {
+ return !_old_float_unibin;
+ }
+
+ void set_old_float_unibin() {
+ _old_float_unibin = true;
+ }
+
+ void int2UniBin ( int I, intUniBin iUB ) {
+ int n;
+ word j;
+ n = I;
+ for (j=0;j<sizeof(intUniBin);j++) {
+ iUB[j] = byte(n & 0xFF);
+ n >>= 8;
+ }
+ }
+
+ void short2UniBin ( short S, shortUniBin sUB ) {
+ int j,sh;
+ short n;
+ sh = 8*(sizeof(shortUniBin)-1);
+ for (j=sizeof(shortUniBin)-1;j>=0;j--) {
+ n = (S >> sh) & 0xFF;
+ sUB[j] = byte(n);
+ sh -= 8;
+ }
+ }
+
+ void long2UniBin ( long L, longUniBin lUB ) {
+ int j,sh;
+ long n;
+ sh = 8*(sizeof(longUniBin)-1);
+ for (j=sizeof(longUniBin)-1;j>=0;j--) {
+ n = (L >> sh) & 0xFF;
+ lUB[j] = byte(n);
+ sh -= 8;
+ }
+ }
+
+ void word2UniBin ( word W, wordUniBin wUB ) {
+ int j,sh;
+ word n;
+ sh = 8*(sizeof(wordUniBin)-1);
+ for (j=sizeof(wordUniBin)-1;j>=0;j--) {
+ n = (W >> sh) & 0xFF;
+ wUB[j] = byte(n);
+ sh -= 8;
+ }
+ }
+
+
+ void real2UniBin ( realtype R, realUniBin rUB ) {
+ int k1,k2,k;
+ realtype Q,L;
+ if (R>=0) Q = R;
+ else Q = -R;
+ k1 = 0;
+ k2 = _nfPowers;
+ do {
+ k = (k1+k2)/2;
+ if (Q>=_fpower[k]) k1 = k;
+ else k2 = k;
+ } while (k2>k1+1);
+ if (Q<=_fpower[0]) k2 = 0;
+ Q = (Q/_fpower[k2])*_fpower8;
+ rUB[0] = byte(k2);
+ for (k=sizeof(realUniBin)-1;k>0;k--) {
+ L = floor(Q/_rfbase);
+ rUB[k] = byte(int(Q-L*_rfbase));
+ Q = L;
+ }
+ if (R<0) rUB[1] |= _fsign;
+
+ }
+
+ void shortreal2UniBin ( shortreal R, shortrealUniBin srUB ) {
+ int k1,k2,k;
+ realtype Q,L;
+
+ if (R>=0) Q = R;
+ else Q = -R;
+ k1 = 0;
+ k2 = _nfPowers;
+ do {
+ k = (k1+k2)/2;
+ if (Q>=_fpower[k]) k1 = k;
+ else k2 = k;
+ } while (k2>k1+1);
+ if (Q<=_fpower[0]) k2 = 0;
+ Q = (Q/_fpower[k2])*_fpower4;
+ srUB[0] = byte(k2);
+ for (k=sizeof(shortrealUniBin)-1;k>0;k--) {
+ L = floor(Q/_rfbase);
+ srUB[k] = byte(int(Q-L*_rfbase));
+ Q = L;
+ }
+ if (R<0) srUB[1] |= _fsign;
+
+ }
+
+ /*
+ #undef _new_float_unibin
+
+ #ifdef _new_float_unibin
+
+ void float2UniBin ( realtype R, floatUniBin fUB ) {
+ int k1,k2,k;
+ realtype Q,L;
+
+ if (R>=0) Q = R;
+ else Q = -R;
+ k1 = 0;
+ k2 = _nfPowers;
+ do {
+ k = (k1+k2)/2;
+ if (Q>=_fpower[k]) k1 = k;
+ else k2 = k;
+ } while (k2>k1+1);
+ if (Q<=_fpower[0]) k2 = 0;
+ Q = (Q/_fpower[k2])*_fpower4;
+ fUB[0] = byte(k2);
+ for (k=sizeof(floatUniBin)-1;k>0;k--) {
+ L = floor(Q/_rfbase);
+ fUB[k] = byte(int(Q-L*_rfbase));
+ Q = L;
+ }
+ if (R<0) fUB[1] |= _fsign;
+
+ }
+
+ #else
+
+ void float2UniBin ( realtype R, floatUniBin fUB ) {
+ int k1,k2,k;
+ realtype Q,L;
+ if (R>=0) Q = R;
+ else Q = -R;
+ k1 = 0;
+ k2 = _nfPowers;
+ do {
+ k = (k1+k2)/2;
+ if (Q>=_fpower[k]) k1 = k;
+ else k2 = k;
+ } while (k2>k1+1);
+ if (Q<=_fpower[0]) k2 = 0;
+ Q = (Q/_fpower[k2])*_fpower8;
+ fUB[0] = byte(k2);
+ for (k=sizeof(realUniBin)-1;k>0;k--) {
+ L = floor(Q/_rfbase);
+ if (k<=sizeof(floatUniBin))
+ fUB[k] = byte(int(Q-L*_rfbase));
+ Q = L;
+ }
+ if (R<0) fUB[1] |= _fsign;
+
+ }
+
+ #endif
+ */
+
+ void float2UniBin ( realtype R, floatUniBin fUB ) {
+ int k1,k2,k;
+ realtype Q,L;
+
+ if (R>=0) Q = R;
+ else Q = -R;
+ k1 = 0;
+ k2 = _nfPowers;
+ do {
+ k = (k1+k2)/2;
+ if (Q>=_fpower[k]) k1 = k;
+ else k2 = k;
+ } while (k2>k1+1);
+ if (Q<=_fpower[0]) k2 = 0;
+ fUB[0] = byte(k2);
+
+ if (_old_float_unibin) {
+ // this is wrong but compatible with already existing files :(
+ // in the result, it gives errors in 6th digit at back conversion
+ Q = (Q/_fpower[k2])*_fpower8;
+ for (k=sizeof(realUniBin)-1;k>0;k--) {
+ L = floor(Q/_rfbase);
+ if (k<=(int)sizeof(floatUniBin))
+ fUB[k] = byte(int(Q-L*_rfbase));
+ Q = L;
+ }
+ } else {
+ // this is correct
+ Q = (Q/_fpower[k2])*_fpower4;
+ for (k=sizeof(floatUniBin)-1;k>0;k--) {
+ L = floor(Q/_rfbase);
+ fUB[k] = byte(int(Q-L*_rfbase));
+ Q = L;
+ }
+ }
+
+ //if (fUB[1] & _fsign) printf ( " error!\n" );
+
+ if (R<0) fUB[1] |= _fsign;
+
+ }
+
+
+ void UniBin2float ( floatUniBin fUB, realtype & R ) {
+ int j,s;
+
+ if (fUB[1] & _fsign) {
+ s = 1;
+ fUB[1] &= _fsign1;
+ } else
+ s = 0;
+
+ R = int(fUB[1]);
+
+ if (_old_float_unibin) {
+ // this is wrong and gives a conversion error in 6th digit :(
+ // we have to keep this for compatibility with already existing
+ // files
+ for (j=2;j<(int)sizeof(floatUniBin);j++)
+ R = R*_rfbase + int(fUB[j]);
+ for (j=sizeof(floatUniBin);j<(int)sizeof(realUniBin);j++)
+ R *= _rfbase;
+ R = (R/_fpower8)*_fpower[int(fUB[0])];
+ } else {
+ // this is correct
+ for (j=2;j<(int)sizeof(floatUniBin);j++)
+ R = R*_rfbase + int(fUB[j]);
+ R = (R/_fpower4)*_fpower[int(fUB[0])];
+ }
+ if (s) R = -R;
+ }
+
+
+ /* -------------------------------------------------------
+ This piece of code shows that float2Unibin - Unbin2float
+ pair does same-quality job as the native float - double
+ conversion:
+
+ InitMatType();
+ set_new_float_unibin();
+
+ floatUniBin fUB;
+ realUniBin rUB;
+ realtype maxsh = MaxShortReal/2.0; // max manageable /2!
+ float maxshf = maxsh;
+ realtype maxshr = maxshf;
+ realtype maxsh1;
+
+ float2UniBin ( maxsh,fUB );
+ UniBin2float ( fUB,maxsh1 );
+
+ printf ( " float\n %10.3f\n %10.3f\n %10.3f\n %10.3f\n",
+ maxsh,maxsh1,maxshf,maxshr );
+
+ maxsh = MaxShortReal;
+ real2UniBin ( maxsh,rUB );
+ UniBin2real ( rUB,maxsh1 );
+
+ printf ( " real\n %10.3f\n %10.3f\n",maxsh,maxsh1 );
+
+ ---- RESULTS:
+
+ float
+ 170099999999999990938343446679146987520.000
+ 170099999948540854500627141228603899904.000
+ 170100000027769017014891478822147850240.000
+ 170100000027769017014891478822147850240.000
+ real
+ 340199999999999981876686893358293975040.000
+ 340199999999999981876686893358293975040.000
+
+ -------------------------------------------------------------- */
+
+ /*
+ void shortreal2UniBin ( shortreal R, shortrealUniBin srUB ) {
+ int k1,k2,k;
+ realtype Q,L;
+
+ if (R>=0) Q = R;
+ else Q = -R;
+ k1 = 0;
+ k2 = _nfPowers;
+ do {
+ k = (k1+k2)/2;
+ if (Q>=_fpower[k]) k1 = k;
+ else k2 = k;
+ } while (k2>k1+1);
+ if (Q<=_fpower[0]) k2 = 0;
+ Q = (Q/_fpower[k2])*_fpower8;
+ srUB[0] = byte(k2);
+ for (k=sizeof(realUniBin)-1;k>0;k--) {
+ L = floor(Q/_rfbase);
+ if (k<=(int)sizeof(shortrealUniBin))
+ srUB[k] = byte(int(Q-L*_rfbase));
+ Q = L;
+ }
+ if (R<0) srUB[1] |= _fsign;
+
+ }
+
+ void float2UniBin ( realtype R, floatUniBin fUB ) {
+ int k1,k2,k;
+ realtype Q,L;
+
+ if (R>=0) Q = R;
+ else Q = -R;
+ k1 = 0;
+ k2 = _nfPowers;
+ do {
+ k = (k1+k2)/2;
+ if (Q>=_fpower[k]) k1 = k;
+ else k2 = k;
+ } while (k2>k1+1);
+ if (Q<=_fpower[0]) k2 = 0;
+ Q = (Q/_fpower[k2])*_fpower8;
+ fUB[0] = byte(k2);
+ for (k=sizeof(realUniBin)-1;k>0;k--) {
+ L = floor(Q/_rfbase);
+ if (k<=(int)sizeof(floatUniBin))
+ fUB[k] = byte(int(Q-L*_rfbase));
+ Q = L;
+ }
+ if (R<0) fUB[1] |= _fsign;
+
+ }
+ */
+
+ /*
+ void UniBin2int ( intUniBin iUB, int & I ) {
+ int j,n,sh;
+ sh = 8*sizeof(intUniBin);
+ I = 0x00;
+ for (j=sizeof(intUniBin)-1;j>=0;j--) {
+ sh -= 8;
+ n = byte(iUB[j]);
+ I = I | (n << sh);
+ }
+ }
+ */
+
+ void UniBin2int ( intUniBin iUB, int & I ) {
+ int j;
+ I = 0x00;
+ for (j=sizeof(intUniBin)-1;j>=0;j--) {
+ I <<= 8;
+ I |= int(iUB[j]);
+ }
+ }
+
+ void UniBin2short ( shortUniBin sUB, short & S ) {
+ int j,sh;
+ short n;
+ sh = 8*sizeof(shortUniBin);
+ S = 0x00;
+ for (j=sizeof(shortUniBin)-1;j>=0;j--) {
+ sh -= 8;
+ n = byte(sUB[j]);
+ S = S | (n << sh);
+ }
+ }
+
+ void UniBin2long ( longUniBin lUB, long & L ) {
+ int j,sh;
+ long n;
+ sh = 8*sizeof(longUniBin);
+ L = 0x00;
+ for (j=sizeof(longUniBin)-1;j>=0;j--) {
+ sh -= 8;
+ n = byte(lUB[j]);
+ L = L | (n << sh);
+ }
+ }
+
+ void UniBin2word ( wordUniBin wUB, word & W ) {
+ int j,sh;
+ word n;
+ sh = 8*sizeof(wordUniBin);
+ W = 0x00;
+ for (j=sizeof(wordUniBin)-1;j>=0;j--) {
+ sh -= 8;
+ n = byte(wUB[j]);
+ W = W | (n << sh);
+ }
+ }
+
+ void UniBin2real ( realUniBin rUB, realtype & R ) {
+ int j,s;
+ if (rUB[1] & _fsign) {
+ s = 1;
+ rUB[1] &= _fsign1;
+ } else
+ s = 0;
+ R = int(rUB[1]);
+ for (j=2;j<(int)sizeof(realUniBin);j++)
+ R = R*_rfbase + int(rUB[j]);
+ R = (R/_fpower8)*_fpower[int(rUB[0])];
+ if (s) R = -R;
+ }
+
+ void UniBin2shortreal ( shortrealUniBin srUB, shortreal & R ) {
+ int j,s;
+ if (srUB[1] & _fsign) {
+ s = 1;
+ srUB[1] &= _fsign1;
+ } else
+ s = 0;
+ R = int(srUB[1]);
+ for (j=2;j<(int)sizeof(shortrealUniBin);j++)
+ R = R*_rfbase + int(srUB[j]);
+ R = (R/_fpower4)*_fpower[int(srUB[0])];
+ if (s) R = -R;
+ }
+
+ /*
+ #ifdef _new_float_unibin
+
+ void UniBin2float ( floatUniBin fUB, realtype & R ) {
+ int j,s;
+ if (fUB[1] & _fsign) {
+ s = 1;
+ fUB[1] &= _fsign1;
+ } else
+ s = 0;
+ R = int(fUB[1]);
+ for (j=2;j<(int)sizeof(floatUniBin);j++)
+ R = R*_rfbase + int(fUB[j]);
+ R = (R/_fpower4)*_fpower[int(fUB[0])];
+ if (s) R = -R;
+ }
+
+ #else
+
+ void UniBin2float ( floatUniBin fUB, realtype & R ) {
+ int j,s;
+ if (fUB[1] & _fsign) {
+ s = 1;
+ fUB[1] &= _fsign1;
+ } else
+ s = 0;
+ R = int(fUB[1]);
+ for (j=2;j<sizeof(floatUniBin);j++)
+ R = R*_rfbase + int(fUB[j]);
+ for (j=sizeof(floatUniBin);j<sizeof(realUniBin);j++)
+ R *= _rfbase;
+ R = (R/_fpower8)*_fpower[int(fUB[0])];
+ if (s) R = -R;
+ }
+
+ #endif
+ */
+
+
+
+
+
+ /*
+ void UniBin2shortreal ( shortrealUniBin srUB, shortreal & R ) {
+ int j,s;
+ if (srUB[1] & _fsign) {
+ s = 1;
+ srUB[1] &= _fsign1;
+ } else
+ s = 0;
+ R = int(srUB[1]);
+ for (j=2;j<(int)sizeof(shortrealUniBin);j++)
+ R = R*_rfbase + int(srUB[j]);
+ for (j=sizeof(shortrealUniBin);j<(int)sizeof(realUniBin);j++)
+ R *= _rfbase;
+ R = (R/_fpower8)*_fpower[int(srUB[0])];
+ if (s) R = -R;
+ }
+
+ void UniBin2float ( floatUniBin fUB, realtype & R ) {
+ int j,s;
+ if (fUB[1] & _fsign) {
+ s = 1;
+ fUB[1] &= _fsign1;
+ } else
+ s = 0;
+ R = int(fUB[1]);
+ for (j=2;j<(int)sizeof(floatUniBin);j++)
+ R = R*_rfbase + int(fUB[j]);
+ for (j=sizeof(floatUniBin);j<(int)sizeof(realUniBin);j++)
+ R *= _rfbase;
+ R = (R/_fpower8)*_fpower[int(fUB[0])];
+ if (s) R = -R;
+ }
+ */
+
+
+ void mem_write ( int I, pstr S, int & l ) {
+ intUniBin iUB;
+ int2UniBin ( I,iUB );
+ memcpy ( &(S[l]),iUB,sizeof(intUniBin) );
+ l += sizeof(intUniBin);
+ S[l] = char(0);
+ }
+
+ void mem_write ( short I, pstr S, int & l ) {
+ shortUniBin sUB;
+ short2UniBin ( I,sUB );
+ memcpy ( &(S[l]),sUB,sizeof(shortUniBin) );
+ l += sizeof(shortUniBin);
+ S[l] = char(0);
+ }
+
+ void mem_write ( long I, pstr S, int & l ) {
+ longUniBin lUB;
+ long2UniBin ( I,lUB );
+ memcpy ( &(S[l]),lUB,sizeof(longUniBin) );
+ l += sizeof(longUniBin);
+ S[l] = char(0);
+ }
+
+ void mem_write ( word W, pstr S, int & l ) {
+ wordUniBin wUB;
+ word2UniBin ( W,wUB );
+ memcpy ( &(S[l]),wUB,sizeof(wordUniBin) );
+ l += sizeof(wordUniBin);
+ S[l] = char(0);
+ }
+
+ void mem_write ( realtype R, pstr S, int & l ) {
+ realUniBin rUB;
+ real2UniBin ( R,rUB );
+ memcpy ( &(S[l]),rUB,sizeof(realUniBin) );
+ l += sizeof(realUniBin);
+ S[l] = char(0);
+ }
+
+ void mem_write ( shortreal R, pstr S, int & l ) {
+ shortrealUniBin srUB;
+ shortreal2UniBin ( R,srUB );
+ memcpy ( &(S[l]),srUB,sizeof(shortrealUniBin) );
+ l += sizeof(shortrealUniBin);
+ S[l] = char(0);
+ }
+
+ void mem_write ( pstr L, int len, pstr S, int & l ) {
+ memcpy ( &(S[l]),L,len );
+ l += len;
+ S[l] = char(0);
+ }
+
+ void mem_write ( pstr L, pstr S, int & l ) {
+ int len;
+ if (L) len = strlen(L);
+ else len = 0;
+ mem_write ( len,S,l );
+ if (len>0) {
+ memcpy ( &(S[l]),L,len );
+ l += len;
+ S[l] = char(0);
+ }
+ }
+
+ void mem_write ( bool B, pstr S, int & l ) {
+ if (B) S[l++] = 'Y';
+ else S[l++] = 'N';
+ S[l] = char(0);
+ }
+
+ void mem_write_byte ( byte B, pstr S, int & l ) {
+ S[l++] = char(B);
+ S[l] = char(0);
+ }
+
+
+ void mem_read ( int & I, cpstr S, int & l ) {
+ intUniBin iUB;
+ memcpy ( iUB,&(S[l]),sizeof(intUniBin) );
+ l += sizeof(intUniBin);
+ UniBin2int ( iUB,I );
+ }
+
+ void mem_read ( short & I, cpstr S, int & l ) {
+ shortUniBin sUB;
+ memcpy ( sUB,&(S[l]),sizeof(shortUniBin) );
+ l += sizeof(shortUniBin);
+ UniBin2short ( sUB,I );
+ }
+
+ void mem_read ( long & I, cpstr S, int & l ) {
+ longUniBin lUB;
+ memcpy ( lUB,&(S[l]),sizeof(longUniBin) );
+ l += sizeof(longUniBin);
+ UniBin2long ( lUB,I );
+ }
+
+ void mem_read ( word & W, cpstr S, int & l ) {
+ wordUniBin wUB;
+ memcpy ( wUB,&(S[l]),sizeof(wordUniBin) );
+ l += sizeof(wordUniBin);
+ UniBin2word ( wUB,W );
+ }
+
+ void mem_read ( realtype & R, cpstr S, int & l ) {
+ realUniBin rUB;
+ memcpy ( rUB,&(S[l]),sizeof(realUniBin) );
+ l += sizeof(realUniBin);
+ UniBin2real ( rUB,R );
+ }
+
+ void mem_read ( shortreal & R, cpstr S, int & l ) {
+ shortrealUniBin srUB;
+ memcpy ( srUB,&(S[l]),sizeof(shortrealUniBin) );
+ l += sizeof(shortrealUniBin);
+ UniBin2shortreal ( srUB,R );
+ }
+
+ void mem_read ( pstr L, int len, cpstr S, int & l ) {
+ memcpy ( L,&(S[l]),len );
+ l += len;
+ }
+
+ void mem_read ( pstr & L, cpstr S, int & l ) {
+ int len;
+ if (L) {
+ delete[] L;
+ L = NULL;
+ }
+ mem_read ( len,S,l );
+ if (len>0) {
+ L = new char[len+1];
+ memcpy ( L,&(S[l]),len );
+ L[len] = char(0);
+ l += len;
+ }
+ }
+
+ void mem_read ( bool & B, cpstr S, int & l ) {
+ B = (S[l++]=='Y');
+ }
+
+ void mem_read_byte ( byte & B, cpstr S, int & l ) {
+ B = byte(S[l++]);
+ }
+
+ // -------------------------------------------------------
+
+ bool InitMatType() {
+ MachEps = MachinEps();
+ floatMachEps = floatMachinEps();
+ LnMaxReal = log(fMaxReal);
+ LnMinReal = log(fMinReal);
+ LnMaxRealExp = LnMaxReal;
+ LnMinRealExp = LnMinReal;
+ InitFPowers();
+ return true;
+ }
+
+}
+
+/* =================================================== */
+
+// *** end of <MatType>
diff --git a/mmdb2/mmdb_mattype.h b/mmdb2/mmdb_mattype.h
new file mode 100644
index 0000000..08cf55c
--- /dev/null
+++ b/mmdb2/mmdb_mattype.h
@@ -0,0 +1,652 @@
+// $Id: mmdb_mattype.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2008.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 10.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MatType_ <interface>
+// ~~~~~~~~~
+// **** Functions :
+// ~~~~~~~~~~~
+// GetString ( reads substring from a string )
+// GetStrTer ( reads substring and put term-ing null )
+// strcpy_n ( copies not more than n characters )
+// strcpy_ns ( like strcpy_ns and pads with spaces )
+// strcpy_n0 ( like strcpy_n and adds terminating 0 )
+// PadSpaces ( pads a string with spaces )
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+
+#ifndef __MMDB_MatType__
+#define __MMDB_MatType__
+
+#include <math.h>
+
+#define UseDoubleFloat
+
+#ifndef __ClassMacros
+
+# define __ClassMacros
+
+ // A Class definition macros
+# define DefineClass(ClassName) \
+ class ClassName; \
+ typedef ClassName * P##ClassName; \
+ typedef ClassName & R##ClassName; \
+ typedef P##ClassName * PP##ClassName; \
+ typedef P##ClassName & RP##ClassName;
+
+ // A Structure definition macros
+# define DefineStructure(StructureName) \
+ struct StructureName; \
+ typedef StructureName * P##StructureName; \
+ typedef StructureName & R##StructureName; \
+ typedef P##StructureName * PP##StructureName; \
+ typedef P##StructureName & RP##StructureName;
+
+#endif
+
+#define UNUSED_ARGUMENT(x) (void)x
+
+// -----------------------------------------------------
+
+namespace mmdb {
+
+#ifdef UseDoubleFloat
+
+ typedef double realtype;
+ const realtype MinReal = 2.2250e-307;
+ const realtype MaxReal = 1.7976e+308;
+ const realtype fMinReal = 2.2250e-307;
+ const realtype fMaxReal = 1.7976e+308;
+
+#else
+
+ typedef float realtype;
+ const realtype MinReal = 1.1755e-38;
+ const realtype MaxReal = 3.4020e+38;
+ const realtype fMinReal = 1.1755e-38;
+ const realtype fMaxReal = 3.4020e+38;
+
+#endif
+
+ typedef float shortreal;
+ const shortreal MinShortReal = 1.1755e-38;
+ const shortreal MaxShortReal = 3.4020e+38;
+
+#define strrchr LastOccurence
+#define fstrrchr LastOccurence
+#define strchr FirstOccurence
+#define fstrchr FirstOccurence
+
+ typedef char * pstr;
+ typedef const char * cpstr;
+ typedef unsigned int word;
+ typedef unsigned char byte;
+ typedef signed char short_int;
+// typedef byte Boolean;
+ typedef unsigned int word2;
+ typedef byte * byteptr;
+ typedef unsigned long lword;
+
+ typedef byte intUniBin [4];
+ typedef byte shortUniBin [2];
+ typedef byte longUniBin [4];
+ typedef byte wordUniBin [4];
+ typedef byte realUniBin [10];
+ typedef byte floatUniBin [5];
+ typedef byte shortrealUniBin[5];
+
+#ifdef _WIN32
+ pstr strcasestr ( pstr s1, cpstr s2 );
+#endif
+
+#ifdef _MSC_VER
+#define strncasecmp _strnicmp
+#define strcasecmp _stricmp
+#endif
+
+ const int MaxInt = 32767;
+ const int MinInt = -32768;
+ const word MaxWord = 65535L;
+ const long int MaxInt4 = 2147483647L;
+
+ // MinInt4 would have to be defined as -2147483648,
+ // however some compilers do not like that. To be on safe,
+ // we define it as -2147483647:
+ const long int MinInt4 = -2147483647;
+ const lword MaxWord4 = 4294967295UL;
+
+ const realtype Pi = 3.141592653589793238462643;
+ const realtype Eu = 2.718281828459045235360287;
+ const realtype ln10 = 2.3025850929940456840179915;
+
+ // *** vectors X[1..N] :
+ typedef realtype * rvector;
+ typedef int * ivector;
+ typedef word * wvector;
+ typedef byte * bvector;
+ typedef bool * ovector;
+ typedef long * lvector;
+ typedef lword * lwvector;
+ typedef pstr * psvector;
+
+ // *** matrices X[1..N][1..M] :
+ typedef rvector * rmatrix;
+ typedef ivector * imatrix;
+ typedef wvector * wmatrix;
+ typedef bvector * bmatrix;
+ typedef ovector * omatrix;
+ typedef lvector * lmatrix;
+ typedef lwvector * lwmatrix;
+ typedef psvector * psmatrix;
+
+ // *** matrices X[1..N][1..M][1..K] :
+ typedef rmatrix * rmatrix3;
+ typedef imatrix * imatrix3;
+ typedef wmatrix * wmatrix3;
+ typedef bmatrix * bmatrix3;
+ typedef omatrix * omatrix3;
+ typedef lmatrix * lmatrix3;
+ typedef lwmatrix * lwmatrix3;
+ typedef psmatrix * psmatrix3;
+
+
+ // ------------------------------------------------------------
+
+ // Initialization. Some C++ enviroments do not do call
+ // InitMatType() automatically, therefore it is always
+ // advisable to call InitMatType() explicitely from the top of
+ // main(). It is completely harmless and cheap (although
+ // unnecessary) to call InitMatType() multiple times.
+ extern bool InitMatType();
+
+ // ------------------------------------------------------------
+
+ inline int mround ( realtype X ) { return (int)floor(X+0.5); }
+ inline int ifloor ( realtype X ) { return (int)floor(X); }
+ inline int Abs ( int x ) { return ( x >= 0 ? x : -x ); }
+
+ inline void ISwap ( int & x, int & y )
+ { int b = x; x = y; y = b; }
+
+ inline void WSwap ( word & x, word & y )
+ { word b = x; x = y; y = b; }
+
+ inline void BSwap ( byte & x, byte & y )
+ { byte b = x; x = y; y = b; }
+
+ inline void OSwap ( bool & x, bool & y )
+ { bool b = x; x = y; y = b; }
+
+ inline void LSwap ( long & x, long & y )
+ { long b = x; x = y; y = b; }
+
+ inline void RSwap ( realtype & x, realtype & y )
+ { realtype b = x; x = y; y = b; }
+
+ inline realtype RMax ( const realtype x1, const realtype x2 )
+ { return ( x1 > x2 ? x1 : x2 ); }
+
+ inline long LMax ( const long x1, const long x2 )
+ { return ( x1 > x2 ? x1 : x2 ); }
+
+ inline word WMax ( const word x1, const word x2 )
+ { return ( x1 > x2 ? x1 : x2 ); }
+
+ inline int IMax ( const int x1, const int x2 )
+ { return ( x1 > x2 ? x1 : x2 ); }
+
+ inline realtype RMin ( const realtype x1, const realtype x2 )
+ { return ( x1 < x2 ? x1 : x2 ); }
+
+ inline long LMin ( const long x1, const long x2 )
+ { return ( x1 < x2 ? x1 : x2 ); }
+
+ inline word WMin ( const word x1, const word x2 )
+ { return ( x1 < x2 ? x1 : x2 ); }
+
+ inline int IMin ( const int x1, const int x2 )
+ { return ( x1 < x2 ? x1 : x2 ); }
+
+ inline realtype fsign ( const realtype x1, const realtype x2 ) {
+ realtype ax;
+ if (x1>=0.0) ax = x1;
+ else ax = -x1;
+ return ( x2 >= 0.0 ? ax : -ax );
+ }
+
+
+ // ------------------------------------------------------------
+
+ // Allocated vectors are enumerated as [Shift..Shift+N-1]
+ // rather than [0..N-1] !
+ // Get-functions return <true> if memory was allocated;
+ // if allocation attemt fails, vector is assigned with NULL
+
+ extern bool GetVectorMemory ( rvector & V, word N, word Shift=1 );
+ extern bool GetVectorMemory ( ivector & I, word N, word Shift=1 );
+ extern bool GetVectorMemory ( wvector & W, word N, word Shift=1 );
+ extern bool GetVectorMemory ( bvector & B, word N, word Shift=1 );
+ extern bool GetVectorMemory ( ovector & O, word N, word Shift=1 );
+ extern bool GetVectorMemory ( lvector & L, word N, word Shift=1 );
+ extern bool GetVectorMemory ( lwvector & L, word N, word Shift=1 );
+ extern bool GetVectorMemory ( psvector & P, word N, word Shift=1 );
+
+ // Shift at deallocation MUST be the same as that at allocation !
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ // Free-functions do nothing if vector has value NULL (e.g.
+ // after unsuccessful allocation).
+
+ extern void FreeVectorMemory ( rvector & V, word Shift=1 );
+ extern void FreeVectorMemory ( ivector & I, word Shift=1 );
+ extern void FreeVectorMemory ( wvector & W, word Shift=1 );
+ extern void FreeVectorMemory ( bvector & B, word Shift=1 );
+ extern void FreeVectorMemory ( ovector & O, word Shift=1 );
+ extern void FreeVectorMemory ( lvector & L, word Shift=1 );
+ extern void FreeVectorMemory ( lwvector & L, word Shift=1 );
+ extern void FreeVectorMemory ( psvector & P, word Shift=1 );
+
+ // -------------------------------------------------------------
+
+ // Allocated matrices are enumerated as
+ // [ShiftN..ShiftN+N-1, ShiftM..ShiftM+M-1]
+ // rather than [0..N-1,0..M-1] !
+ // Get-functions return <true> if memory was allocated;
+ // if allocation attemt fails, matrix is assigned with NULL
+ // Free-functions do nothing if matrix has value NULL (e.g.
+ // after unsuccessful allocation).
+
+ extern bool GetMatrixMemory
+ ( rmatrix & A, word N, word M, word ShiftN=1, word ShiftM=1 );
+ extern bool GetMatrixMemory
+ ( imatrix & A, word N, word M, word ShiftN=1, word ShiftM=1 );
+ extern bool GetMatrixMemory
+ ( wmatrix & W, word N, word M, word ShiftN=1, word ShiftM=1 );
+ extern bool GetMatrixMemory
+ ( bmatrix & B, word N, word M, word ShiftN=1, word ShiftM=1 );
+ extern bool GetMatrixMemory
+ ( omatrix & O, word N, word M, word ShiftN=1, word ShiftM=1 );
+ extern bool GetMatrixMemory
+ ( lmatrix & L, word N, word M, word ShiftN=1, word ShiftM=1 );
+ extern bool GetMatrixMemory
+ ( lwmatrix & L, word N, word M, word ShiftN=1, word ShiftM=1 );
+ extern bool GetMatrixMemory
+ ( psmatrix & P, word N, word M, word ShiftN=1, word ShiftM=1 );
+
+ // ShiftN and ShiftM at deallocation MUST be the same as those at
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ // allocation !
+ // ~~~~~~~~~~~~~
+
+ extern void FreeMatrixMemory ( rmatrix & A, word N,
+ word ShiftN=1, word ShiftM=1 );
+ extern void FreeMatrixMemory ( imatrix & A, word N,
+ word ShiftN=1, word ShiftM=1 );
+ extern void FreeMatrixMemory ( wmatrix & W, word N,
+ word ShiftN=1, word ShiftM=1 );
+ extern void FreeMatrixMemory ( bmatrix & B, word N,
+ word ShiftN=1, word ShiftM=1 );
+ extern void FreeMatrixMemory ( omatrix & O, word N,
+ word ShiftN=1, word ShiftM=1 );
+ extern void FreeMatrixMemory ( lmatrix & L, word N,
+ word ShiftN=1, word ShiftM=1 );
+ extern void FreeMatrixMemory ( lwmatrix & L, word N,
+ word ShiftN=1, word ShiftM=1 );
+ extern void FreeMatrixMemory ( psmatrix & P, word N,
+ word ShiftN=1, word ShiftM=1 );
+
+
+ // -------------------------------------------------------------
+ // 3D matrices
+
+ extern bool GetMatrix3Memory
+ ( rmatrix3 & A, word N, word M, word K,
+ word ShiftN=1, word ShiftM=1, word ShiftK=1 );
+ extern bool GetMatrix3Memory
+ ( imatrix3 & A, word N, word M, word K,
+ word ShiftN=1, word ShiftM=1, word ShiftK=1 );
+ extern bool GetMatrix3Memory
+ ( wmatrix3 & A, word N, word M, word K,
+ word ShiftN=1, word ShiftM=1, word ShiftK=1 );
+ extern bool GetMatrix3Memory
+ ( bmatrix3 & A, word N, word M, word K,
+ word ShiftN=1, word ShiftM=1, word ShiftK=1 );
+ extern bool GetMatrix3Memory
+ ( omatrix3 & A, word N, word M, word K,
+ word ShiftN=1, word ShiftM=1, word ShiftK=1 );
+ extern bool GetMatrix3Memory
+ ( lmatrix3 & A, word N, word M, word K,
+ word ShiftN=1, word ShiftM=1, word ShiftK=1 );
+ extern bool GetMatrix3Memory
+ ( lwmatrix3 & A, word N, word M, word K,
+ word ShiftN=1, word ShiftM=1, word ShiftK=1 );
+ extern bool GetMatrix3Memory
+ ( psmatrix3 & A, word N, word M, word K,
+ word ShiftN=1, word ShiftM=1, word ShiftK=1 );
+
+ //
+ // ShiftN, ShiftM and ShiftK at deallocation MUST be
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ // the same as those at allocation !
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ extern void FreeMatrix3Memory
+ ( rmatrix3 & A, word N, word M,
+ word ShiftN=1, word ShiftM=1, word ShiftK=1 );
+ extern void FreeMatrix3Memory
+ ( imatrix3 & A, word N, word M,
+ word ShiftN=1, word ShiftM=1, word ShiftK=1 );
+ extern void FreeMatrix3Memory
+ ( wmatrix3 & A, word N, word M,
+ word ShiftN=1, word ShiftM=1, word ShiftK=1 );
+ extern void FreeMatrix3Memory
+ ( bmatrix3 & A, word N, word M,
+ word ShiftN=1, word ShiftM=1, word ShiftK=1 );
+ extern void FreeMatrix3Memory
+ ( omatrix3 & A, word N, word M,
+ word ShiftN=1, word ShiftM=1, word ShiftK=1 );
+ extern void FreeMatrix3Memory
+ ( lmatrix3 & A, word N, word M,
+ word ShiftN=1, word ShiftM=1, word ShiftK=1 );
+ extern void FreeMatrix3Memory
+ ( lwmatrix3 & A, word N, word M,
+ word ShiftN=1, word ShiftM=1, word ShiftK=1 );
+ extern void FreeMatrix3Memory
+ ( psmatrix3 & A, word N, word M,
+ word ShiftN=1, word ShiftM=1, word ShiftK=1 );
+
+ // -------------------------------------------------------------
+
+ extern realtype MachEps;
+ extern realtype floatMachEps;
+ extern realtype LnMaxReal;
+ extern realtype LnMinReal;
+
+ extern realtype MachinEps ();
+ extern realtype floatMachinEps();
+ extern realtype frac ( realtype R );
+ extern long mod ( long x, long y );
+ extern realtype Pow ( realtype X, int y );
+ extern realtype Pow1 ( realtype X, realtype Y );
+ extern realtype Exp ( realtype X ); // use to avoid catastrophies
+ extern bool Odd ( int i );
+ extern long HexValL ( cpstr S );
+ extern long OctValL ( cpstr S );
+ extern long BinValL ( cpstr S );
+ extern pstr BinValS ( long L, pstr S ); // S[sizeof(long)+1] at least
+
+ extern pstr ParamStr ( pstr D, cpstr S, realtype V, int M=5,
+ cpstr S1=(pstr)"" );
+ extern pstr ParamStr ( pstr D, cpstr S, realtype V, int M,
+ cpstr S1, realtype V2, int M2=5,
+ cpstr S2=(pstr)"" );
+
+
+ // ---------- Strings
+
+ // CreateCopy(..) allocates Dest string and copies the contents of
+ // Source into it. If Dest is not NULL prior calling the function,
+ // it is attempted to deallocate first.
+
+ extern pstr CreateCopy ( pstr & Dest, cpstr Source );
+ extern pstr CreateCopy_n ( pstr & Dest, cpstr Source, int n );
+
+ extern pstr CreateConcat ( pstr & Dest, cpstr Source );
+ extern pstr CreateConcat ( pstr & Dest, cpstr Source1,
+ cpstr Source2 );
+ extern pstr CreateConcat ( pstr & Dest, cpstr Source1,
+ cpstr Source2,
+ cpstr Source3 );
+ extern pstr CreateConcat ( pstr & Dest, cpstr Source1,
+ cpstr Source2,
+ cpstr Source3,
+ cpstr Source4 );
+ extern pstr CreateConcat ( pstr & Dest, cpstr Source1,
+ cpstr Source2,
+ cpstr Source3,
+ cpstr Source4,
+ cpstr Source5 );
+
+ extern pstr CreateCopCat ( pstr & Dest, cpstr Source1,
+ cpstr Source2,
+ cpstr Source3,
+ cpstr Source4,
+ cpstr Source5 );
+ extern pstr CreateCopCat ( pstr & Dest, cpstr Source1,
+ cpstr Source2,
+ cpstr Source3,
+ cpstr Source4 );
+ extern pstr CreateCopCat ( pstr & Dest, cpstr Source1,
+ cpstr Source2,
+ cpstr Source3 );
+ extern pstr CreateCopCat ( pstr & Dest, cpstr Source1,
+ cpstr Source2 );
+
+ extern pstr LastOccurence ( cpstr S , char c );
+ extern pstr FirstOccurence ( cpstr S , char c );
+ extern int indexOf ( cpstr S , char c );
+ extern pstr FirstOccurence ( cpstr S, int Slen,
+ cpstr Q, int Qlen );
+ extern int indexOf ( cpstr S, int Slen,
+ cpstr Q, int Qlen );
+
+ extern pstr LowerCase ( pstr s );
+ extern pstr UpperCase ( pstr s );
+
+ // GetString(..) copies first M characters of string S into string
+ // L, appending the terminating null. If S contains less then M
+ // characters, L will be padded with spaces.
+ extern void GetString ( pstr L, cpstr S, int M );
+
+ // GetStrTer(..) copies at least n (or LMax if LMax<n) first symbols
+ // of string S into string L, then continues copying until first space
+ // or terminating null is found. If the terminating null is met among
+ // the first n characters or if SMax<n, the string L will be padded
+ // with spaces till the length of minimum of n and LMax and then
+ // terminated with the null.
+ // LMax and SMax are the buffer lengths of L and S,
+ // respectively. Even if no space is found, the last character
+ // in L will be the terminating null.
+ extern void GetStrTer ( pstr L, cpstr S, int n, int LMax,
+ int SMax );
+
+
+ // Version of GetStrTer(..) allowing for spaces in the string.
+ //
+ // Copies at least n (or LMax if LMax<n) first symbols of
+ // string S into string L, then continues copying until first
+ // terminating null is found. If the terminating null
+ // is met among the first n characters or if SMax<n, the string
+ // L will be padded with spaces till the length of minimum of
+ // n and LMax and then terminated with the null.
+ // SMax are buffer lengths of L and S, respectively. The last
+ // character in L will be the terminating null.
+ extern void GetStrTerWin32File ( pstr L, cpstr S, int n,
+ int LMax, int SMax );
+
+
+ // strcpy_n(..) copies at most n symbols from string s to d,
+ // but no more than strlen(s) (s must contain a terminating
+ // null). The terminating null IS NEITHER appended OR copied
+ // to d.
+ extern void strcpy_n ( pstr d, cpstr s, int n );
+
+ // strcpy_n1(..) copies at most n last symbols from string s
+ // to d, but no more than strlen(s) (s must contain a terminating
+ // null). The string in d is aligned to the right and added with
+ // spaces at the left, if necessary. The terminating null
+ // IS NEITHER appended OR copied to d.
+ extern void strcpy_n1 ( pstr d, cpstr s, int n );
+
+ // Copies at most n symbols from string s to d, but no
+ // more than strlen(s) (s must contain a terminating null).
+ // The string in d is aligned to the right and added with
+ // spaces at the left, if necessary. The terminating null
+ // IS NEITHER appended NOR copied to d.
+ extern void strcpy_nr ( pstr d, cpstr s, int n );
+
+ // strcpy_ns(..) copies at most n symbols from string s to d,
+ // but no more than strlen(s) (s must contain a terminating
+ // null). The terminating null IS NEITHER appended NOR copied
+ // to d; rather, d is padded with spaces up to the length of n
+ // if strlen(s)<n.
+ extern void strcpy_ns ( pstr d, cpstr s, int n );
+
+ // strcpy_cs(..) copies string s to string d cutting all
+ // spaces at the end. Thus, " abcde " will be copied
+ // like " abcde" (terminating null appended).
+ // The function returns d.
+ extern pstr strcpy_cs ( pstr d, cpstr s );
+
+ // strcpy_ncs(..) copies at most n characters from string s
+ // to string d cutting all spaces at at the end. Thus, " abcde "
+ // will be copied like " abc" at n=4 and like " abcde" at n>5
+ // (terminating null appended).
+ // The function returns d.
+ extern pstr strcpy_ncs ( pstr d, cpstr s, int n );
+
+ // strcpy_css(..) copies string s to string d cutting all
+ // spaces at the begining and at the end. Thus, " ab c de "
+ // will be copied like "ab c de" (terminating null appended).
+ // The function returns d.
+ extern pstr strcpy_css ( pstr d, cpstr s );
+
+ // strcpy_ncss(..) copies at most n characters from string s
+ // to string d cutting all spaces at the begining and at the end.
+ // Thus, " ab c de " will be copied like "ab" at n=3 (terminating
+ // null appended).
+ // The function returns d.
+ extern pstr strcpy_ncss ( pstr d, cpstr s, int n );
+
+ // strcpy_n0(..) copies at most n symbols from string s to d,
+ // but no more than strlen(s) (s must contain a terminating
+ // null). The terminating null IS appended to d.
+ // The function returns d.
+ extern pstr strcpy_n0 ( pstr d, cpstr s, int n );
+
+ // strlen_des returns the length of a string as if all extra
+ // spaces from the latter have been deleted. Extra spaces
+ // include all leading and tracing spaces and any sequential
+ // spaces when more than one. The string does not change.
+ extern int strlen_des ( cpstr s );
+
+ // strcpy_des copies string s into string d removing all extra
+ // spaces from the latter. Extra spaces include all leading and
+ // tracing spaces and any sequential spaces when more than one.
+ extern pstr strcpy_des ( pstr d, cpstr s );
+
+ // strcat_des appends string s to string d removing all extra
+ // spaces from the latter. Extra spaces include all leading and
+ // tracing spaces and any sequential spaces when more than one.
+ extern pstr strcat_des ( pstr d, cpstr s );
+
+ // PadSpaces(..) pads string S with spaces making its length
+ // equal to len. The terminating zero is added, so that S should
+ // reserve space of a minimum len+1 characters.
+ extern void PadSpaces ( pstr S, int len );
+
+ enum SCUTKEY {
+ SCUTKEY_BEGIN = 0x00000001,
+ SCUTKEY_END = 0x00000002,
+ SCUTKEY_BEGEND = 0x00000003
+ };
+
+ // CutSpaces(..) cuts spaces at the begining or end of
+ // string S according to the value of CutKey. The function
+ // returns S.
+ extern pstr CutSpaces ( pstr S, int CutKey );
+
+ // DelSpaces(..) removes all spaces (or other symbols as
+ // specified by 'c') from the string. The string is then
+ // shrinked by the number of removed characters. Thus,
+ // " as ttt " becomes "asttt".
+ extern pstr DelSpaces ( pstr S, char c=' ' );
+
+ // EnforceSpaces(..) replaces all unprintable characters,
+ // except <CR>, <LF>, <TAB> and some others, for spaces
+ extern pstr EnforceSpaces ( pstr S );
+
+ // -------------------------------------------------------------
+
+ /// This call will produce correct floats in universal binaries but
+ /// make them incompatible with old files. Without this call, float
+ /// read/write will result in error after 6th digit.
+ /// UniBin read/write of other types (realtype, shortreal, int etc)
+ /// is not affected by this call, and to the best of knowledge is
+ /// correct (no loss of precision).
+ extern void set_new_float_unibin();
+ extern bool is_new_float_unibin();
+ extern void set_old_float_unibin();
+
+ extern void __modify4();
+
+ extern void int2UniBin ( int I, intUniBin iUB );
+ extern void short2UniBin ( short S, shortUniBin sUB );
+ extern void long2UniBin ( long L, longUniBin lUB );
+ extern void word2UniBin ( word W, wordUniBin wUB );
+ extern void real2UniBin ( realtype R, realUniBin rUB );
+ extern void float2UniBin ( realtype R, floatUniBin fUB );
+ extern void shortreal2UniBin ( shortreal R, shortrealUniBin srUB );
+ extern void UniBin2int ( intUniBin iUB, int & I );
+ extern void UniBin2short ( shortUniBin sUB, short & S );
+ extern void UniBin2long ( longUniBin lUB, long & L );
+ extern void UniBin2word ( wordUniBin wUB, word & W );
+ extern void UniBin2real ( realUniBin rUB, realtype & R );
+ extern void UniBin2shortreal ( shortrealUniBin srUB, shortreal & R );
+ extern void UniBin2float ( floatUniBin fUB, realtype & R );
+
+ extern void mem_write ( int I, pstr S, int & l );
+ extern void mem_write ( short I, pstr S, int & l );
+ extern void mem_write ( long I, pstr S, int & l );
+ extern void mem_write ( word W, pstr S, int & l );
+ extern void mem_write ( realtype R, pstr S, int & l );
+ extern void mem_write ( shortreal R, pstr S, int & l );
+ extern void mem_write ( pstr L, int len, pstr S, int & l );
+ extern void mem_write ( pstr L, pstr S, int & l );
+ extern void mem_write ( bool B, pstr S, int & l );
+ extern void mem_write_byte ( byte B, pstr S, int & l );
+
+ extern void mem_read ( int & I, cpstr S, int & l );
+ extern void mem_read ( short & I, cpstr S, int & l );
+ extern void mem_read ( long & I, cpstr S, int & l );
+ extern void mem_read ( word & W, cpstr S, int & l );
+ extern void mem_read ( realtype & R, cpstr S, int & l );
+ extern void mem_read ( shortreal & R, cpstr S, int & l );
+ extern void mem_read ( pstr L, int len, cpstr S, int & l );
+ extern void mem_read ( pstr & L, cpstr S, int & l );
+ extern void mem_read ( bool & B, cpstr S, int & l );
+ extern void mem_read_byte ( byte & B, cpstr S, int & l );
+
+}
+
+#endif
+
+/* =================================================== */
+
diff --git a/mmdb2/mmdb_mmcif_.cpp b/mmdb2/mmdb_mmcif_.cpp
new file mode 100644
index 0000000..e5b962e
--- /dev/null
+++ b/mmdb2/mmdb_mmcif_.cpp
@@ -0,0 +1,3666 @@
+// $Id: mmdb_mmcif_.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_MMCIF <implementation>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::mmcif::Category ( mmCIF category )
+// ~~~~~~~~~ mmdb::mmcif::Struct ( mmCIF structure )
+// mmdb::mmcif::Loop ( mmCIF loop )
+// mmdb::mmcif::Data ( mmCIF data block )
+// mmdb::mmcif::File ( mmCIF file )
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "mmdb_mmcif_.h"
+
+namespace mmdb {
+
+ namespace mmcif {
+
+ // ====================== SortTags ===============================
+
+ void SortTags ( psvector tag, int len, ivector index ) {
+ int i,k,l,l1,l2;
+ if (len==1) {
+ index[0] = 0;
+ return;
+ }
+ if (strcasecmp(tag[0],tag[1])<0) {
+ index[0] = 0;
+ index[1] = 1;
+ } else {
+ index[0] = 1;
+ index[1] = 0;
+ }
+ for (k=2;k<len;k++) {
+ l2 = k-1;
+ if (strcasecmp(tag[k],tag[index[0]])<0) l2 = 0;
+ else if (strcasecmp(tag[k],tag[index[l2]])>0) l2 = k;
+ else {
+ l1 = 0;
+ while (l1<l2-1) {
+ l = (l1+l2)/2;
+ if (strcasecmp(tag[k],tag[index[l]])<0) l2 = l;
+ else l1 = l;
+ }
+ }
+ for (i=k;i>l2;i--)
+ index[i] = index[i-1];
+ index[l2] = k;
+ }
+ }
+
+
+ // ====================== Category ==========================
+
+ const int CIF_NODATA_DOT = 0;
+ const int CIF_NODATA_QUESTION = 1;
+ cpstr CIF_NODATA_DOT_FIELD = pstr("\x02" ".");
+ cpstr CIF_NODATA_QUESTION_FIELD = pstr("\x02" "?");
+
+ Category::Category() : io::Stream() {
+ InitCategory();
+ }
+
+ Category::Category ( cpstr N ) : io::Stream() {
+ InitCategory();
+ SetCategoryName ( N );
+ }
+
+ Category::Category ( io::RPStream Object ) : io::Stream(Object) {
+ InitCategory();
+ }
+
+ Category::~Category() {
+ FreeMemory();
+ }
+
+ void Category::InitCategory() {
+ name = NULL;
+ nTags = 0;
+ tag = NULL;
+ index = NULL;
+ nAllocTags = 0;
+ }
+
+ void Category::FreeMemory() {
+ int i;
+ if (name) delete[] name;
+ name = NULL;
+ for (i=0;i<nAllocTags;i++)
+ if (tag[i]) delete[] tag[i];
+ FreeVectorMemory ( tag ,0 );
+ FreeVectorMemory ( index,0 );
+ nTags = 0;
+ nAllocTags = 0;
+ }
+
+ void Category::SetCategoryName ( cpstr N ) {
+ if (N[0]) CreateCopy ( name,N );
+ else {
+ CreateCopy ( name,pstr(" ") );
+ name[0] = char(1); // no category name
+ }
+ }
+
+ void Category::ExpandTags ( int nTagsNew ) {
+ int i,nAT;
+ psvector tag1;
+ ivector index1;
+ if (nTagsNew>nAllocTags) {
+ nAT = nTagsNew + IMin(nAllocTags/2+1,20);
+ GetVectorMemory ( tag1 ,nAT,0 );
+ GetVectorMemory ( index1,nAT,0 );
+ for (i=0;i<nAllocTags;i++) {
+ tag1 [i] = tag [i];
+ index1[i] = index[i];
+ }
+ for (i=nAllocTags;i<nAT;i++) {
+ tag1 [i] = NULL;
+ index1[i] = i;
+ }
+ FreeVectorMemory ( tag ,0 );
+ FreeVectorMemory ( index,0 );
+ tag = tag1;
+ index = index1;
+ nAllocTags = nAT;
+ }
+ }
+
+ pstr Category::GetTag ( int tagNo ) {
+ if ((tagNo>=0) && (tagNo<nTags)) return tag[tagNo];
+ return NULL;
+ }
+
+ void Category::Sort() {
+ // Sorts tags for easing the search
+ int i,k;
+ if (nAllocTags>0) {
+ k = 0;
+ if (!index)
+ GetVectorMemory ( index,nAllocTags,0 );
+ for (i=0;i<nTags;i++)
+ if (tag[i]) {
+ if (k<i) {
+ tag[k] = tag[i];
+ tag[i] = NULL;
+ }
+ k++;
+ }
+ nTags = k;
+ SortTags ( tag,nTags,index );
+ }
+ }
+
+ void Category::Optimize() {
+ int i,k;
+ psvector tag1;
+ k = 0;
+ for (i=0;i<nTags;i++)
+ if (tag[i]) k++;
+ if (k<=0) FreeMemory();
+ else if (k!=nAllocTags) {
+ GetVectorMemory ( tag1,k,0 );
+ FreeVectorMemory ( index,0 );
+ k = 0;
+ for (i=0;i<nTags;i++)
+ if (tag[i])
+ tag1[k++] = tag[i];
+ FreeVectorMemory ( tag,0 );
+ tag = tag1;
+ nTags = k;
+ nAllocTags = nTags;
+ Sort();
+ }
+ }
+
+ int Category::GetTagNo ( cpstr ttag ) {
+ // Binary search for index of tag ttag in tag[].
+ // Return:
+ // >=0 : position of the tag found
+ // <0 : the tag was not found, it could be inserted before
+ // (-RC-1)th element, where RC is the return value
+ int l1,l2,l,k;
+
+ if (!tag) return -1;
+
+ if (!index) Sort();
+
+ l = 0;
+ l1 = 0;
+ l2 = nTags-1;
+ k = 1;
+ while (l1<l2-1) {
+ l = (l1+l2)/2;
+ k = strcasecmp ( ttag,tag[index[l]] );
+ if (k<0) l2 = l;
+ else if (k>0) l1 = l;
+ else {
+ l1 = l;
+ break;
+ }
+ }
+
+ if (k==0) return index[l]; // is at RCth position
+ k = strcasecmp ( ttag,tag[index[l1]] );
+ if (k==0) return index[l1]; // is at RCth position
+ if (k<0) return -1; // would be at (-RC-1)th position
+ if (l2!=l1) {
+ k = strcasecmp ( ttag,tag[index[l2]] );
+ if (k==0) return index[l2]; // is at RCth position
+ if (k>0) return -2-l2; // would be at l2+1=(-RC-1)th position
+ }
+
+ return -2-l1; // would be at l1+1=(-RC-1)th position
+
+ }
+
+ int Category::AddTag ( cpstr ttag ) {
+ // return -1: the tag has been added on the top of array;
+ // index is added and sorted automatically
+ // >=0: the tag is already in the array -- its position
+ // is returned
+ int i1,i;
+ if (!tag) {
+ ExpandTags ( 3 ); // get space for first 3 tags
+ CreateCopy ( tag[0],ttag );
+ nTags = 1;
+ return -nTags; // the tag has been added on the top of array
+ }
+ i1 = GetTagNo ( ttag );
+ if (i1>=0) return i1; // non-negative returns mean that
+ // the tag is already in the array
+ i1 = -i1-1; // otherwise the tag has to be added and indexed at here
+ // put new tag on the top of array and update index
+ ExpandTags ( nTags+1 );
+ CreateCopy ( tag[nTags],ttag );
+ for (i=nTags;i>i1;i--)
+ index[i] = index[i-1];
+ index[i1] = nTags;
+ nTags++;
+ return -nTags; // the tag has been added on the top of array
+ }
+
+ void Category::PrintTags() {
+ int i;
+ Sort();
+ printf ( " Unsorted tags:\n" );
+ for (i=0;i<nTags;i++)
+ if (tag[i])
+ printf ( " %s.%s\n",name,tag[i] );
+ if (index) {
+ printf ( " Sorted tags:\n" );
+ for (i=0;i<nTags;i++)
+ if (tag[index[i]])
+ printf ( " %s.%s\n",name,tag[index[i]] );
+ }
+ }
+
+ bool Category::CheckTags ( cpstr * tagList ) {
+ int i;
+ i = 0;
+ while (tagList[i][0]) {
+ if (GetTagNo(tagList[i])<0) return false;
+ i++;
+ }
+ return true;
+ }
+
+ void Category::PutCategoryName ( cpstr newName ) {
+ CreateCopy ( name,newName );
+ }
+
+ void Category::Copy ( PCategory Category ) {
+ int i;
+ FreeMemory();
+ if (Category) {
+ CreateCopy ( name,Category->name );
+ nTags = Category->nTags;
+ nAllocTags = nTags;
+ if (nTags>0) {
+ GetVectorMemory ( tag ,nAllocTags,0 );
+ GetVectorMemory ( index,nAllocTags,0 );
+ for (i=0;i<nTags;i++) {
+ tag[i] = NULL;
+ CreateCopy ( tag[i],Category->tag[i] );
+ index[i] = Category->index[i];
+ }
+ }
+ }
+ }
+
+
+ void Category::write ( io::RFile f ) {
+ int i;
+ if (!index) Sort();
+ f.CreateWrite ( name );
+ f.WriteInt ( &nTags );
+ for (i=0;i<nTags;i++)
+ f.CreateWrite ( tag[i] );
+ f.WriteVector ( index,nTags,0 );
+ }
+
+ void Category::read ( io::RFile f ) {
+ int i;
+ FreeMemory ();
+ f.CreateRead ( name );
+ f.ReadInt ( &nTags );
+ nAllocTags = nTags;
+ if (nTags>0) {
+ GetVectorMemory ( tag,nTags,0 );
+ for (i=0;i<nTags;i++) {
+ tag[i] = NULL;
+ f.CreateRead ( tag[i] );
+ }
+ }
+ f.CreateReadVector ( index,0 );
+ }
+
+ MakeStreamFunctions(Category)
+
+
+
+ // ====================== Struct ===========================
+
+
+ Struct::Struct() : Category() {
+ InitStruct();
+ }
+
+ Struct::Struct ( cpstr N ) : Category(N) {
+ InitStruct();
+ }
+
+ Struct::Struct ( io::RPStream Object ) : Category(Object) {
+ InitStruct();
+ }
+
+ Struct::~Struct() {
+ FreeMemory();
+ }
+
+ void Struct::FreeMemory() {
+ int i;
+ for (i=0;i<nAllocTags;i++)
+ if (field[i]) delete[] field[i];
+ FreeVectorMemory ( field,0 );
+ Category::FreeMemory();
+ }
+
+ void Struct::InitStruct() {
+ field = NULL;
+ }
+
+ void Struct::Optimize() {
+ int i,k;
+ psvector f1;
+ k = 0;
+ for (i=0;i<nTags;i++)
+ if (!tag[i]) {
+ if (field[i]) delete[] field[i];
+ field[i] = NULL;
+ } else if (!field[i]) {
+ delete[] tag[i];
+ tag[i] = NULL;
+ } else
+ k++;
+ if (k<=0) FreeMemory();
+ else if (k!=nAllocTags) {
+ f1 = new pstr[k];
+ k = 0;
+ for (i=0;i<nTags;i++)
+ if (tag[i])
+ f1[k++] = field[i];
+ FreeVectorMemory ( field,0 );
+ field = f1;
+ Category::Optimize();
+ }
+ }
+
+ void Struct::AddField ( cpstr F, cpstr T, bool Concatenate ) {
+ psvector field1;
+ int i,nAT;
+ pstr nf;
+
+ nAT = nAllocTags;
+ i = AddTag ( T );
+
+ if (i<0) {
+ // The tag was not in the list, but has been added on the top
+ // of list. Now expand the field list and put new field on
+ // the top of it.
+ if (nAllocTags>nAT) {
+ GetVectorMemory ( field1,nAllocTags,0 );
+ for (i=0;i<nTags-1;i++)
+ field1[i] = field[i];
+ for (i=nTags-1;i<nAllocTags;i++)
+ field1[i] = NULL;
+ FreeVectorMemory ( field,0 );
+ field = field1;
+ }
+ i = nTags-1;
+ field[i] = NULL;
+ }
+
+ if (!F) {
+ if ((!Concatenate) || (!field[i])) {
+ CreateCopy ( field[i],pstr(" ?") );
+ field[i][0] = char(2);
+ }
+ } else if ((!Concatenate) || (!field[i]))
+ CreateCopy ( field[i],F );
+ else {
+ nf = new char[strlen(field[i])+strlen(F)+1];
+ strcpy ( nf,field[i] );
+ strcat ( nf,F );
+ delete[] field[i];
+ field[i] = nf;
+ }
+
+ }
+
+ pstr Struct::GetField ( int tagNo ) {
+ if ((tagNo>=0) && (tagNo<nTags)) return field[tagNo];
+ return NULL;
+ }
+
+ int Struct::GetString ( pstr & S, cpstr TName,
+ bool Remove ) {
+ int k = GetTagNo ( TName );
+ if (S) delete[] S;
+ S = NULL;
+ if (!field) return CIFRC_NoField;
+ if (k<0) return CIFRC_NoTag;
+ if (!field[k]) return CIFRC_NoField;
+ if (field[k][0]==char(2)) {
+ if (Remove) {
+ delete[] field[k];
+ field[k] = NULL;
+ }
+ } else if (Remove) {
+ S = field[k];
+ field[k] = NULL;
+ } else
+ CreateCopy ( S,field[k] );
+ return 0;
+ }
+
+ pstr Struct::GetString ( cpstr TName, int & RC ) {
+ int k = GetTagNo ( TName );
+ if (k<0) {
+ RC = CIFRC_NoTag;
+ return NULL;
+ }
+ if (!field) {
+ RC = CIFRC_NoField;
+ return NULL;
+ }
+ if (!field[k]) {
+ RC = CIFRC_NoField;
+ return NULL;
+ }
+ RC = 0;
+ if (field[k][0]==char(2)) return NULL;
+ return field[k];
+ }
+
+ int Struct::DeleteField ( cpstr TName ) {
+ int k = GetTagNo ( TName );
+ if ((k>=0) && (field)) {
+ if (field[k]) delete[] field[k];
+ field[k] = NULL;
+ }
+ return k;
+ }
+
+ int Struct::GetReal ( realtype & R, cpstr TName,
+ bool Remove ) {
+ pstr endptr;
+ int RC;
+ int k = GetTagNo ( TName );
+ R = 0.0;
+ if (!field) return CIFRC_NoField;
+ if (k<0) return CIFRC_NoTag;
+ if (!field[k]) return CIFRC_NoField;
+ if (field[k][0]==char(2)) return CIFRC_NoData;
+ R = strtod ( field[k],&endptr );
+ if (endptr==field[k]) RC = CIFRC_WrongFormat;
+ else {
+ RC = 0;
+ if (Remove) {
+ delete[] field[k];
+ field[k] = NULL;
+ }
+ }
+ return RC;
+ }
+
+ int Struct::GetInteger ( int & I, cpstr TName,
+ bool Remove ) {
+ pstr endptr;
+ int RC;
+ int k = GetTagNo ( TName );
+ I = 0;
+ if (!field) return CIFRC_NoField;
+ if (k<0) return CIFRC_NoTag;
+ if (!field[k]) return CIFRC_NoField;
+ if (field[k][0]==char(2)) {
+ if (field[k][1]=='.') I = MinInt4;
+ return CIFRC_NoData;
+ }
+ I = mround ( strtod(field[k],&endptr) );
+ if (endptr==field[k]) RC = CIFRC_WrongFormat;
+ else {
+ RC = 0;
+ if (Remove) {
+ delete[] field[k];
+ field[k] = NULL;
+ }
+ }
+ return RC;
+ }
+
+
+ void Struct::PutString ( cpstr S, cpstr T,
+ bool NonBlankOnly ) {
+ pstr p;
+ if (!S) PutNoData ( CIF_NODATA_QUESTION,T );
+ else {
+ p = pstr(S);
+ if (NonBlankOnly)
+ while (*p==' ') p++;
+ if (!(*p)) PutNoData ( CIF_NODATA_DOT,T );
+ else AddField ( S,T,false );
+ }
+ }
+
+ void Struct::PutDate ( cpstr T ) {
+ time_t t;
+ tm * tstruct;
+ char S[100];
+ t = time ( NULL );
+ tstruct = localtime(&t);
+ if (tstruct)
+ sprintf ( S,"%4i-%02i-%02i",
+ tstruct->tm_year+1900,tstruct->tm_mon+1,tstruct->tm_mday );
+ else strcpy ( S,"YYYY-MM-DD" );
+ AddField ( S,T,false );
+ }
+
+
+ void Struct::PutNoData ( int NoDataType, cpstr T ) {
+ char S[10];
+ S[0] = char(2);
+ if (NoDataType==CIF_NODATA_DOT) S[1] = '.';
+ else S[1] = '?';
+ S[2] = char(0);
+ AddField ( S,T,false );
+ }
+
+
+ void Struct::PutReal ( realtype R, cpstr T, int prec ) {
+ char rS[100];
+ sprintf ( rS,"%.*g",prec,R );
+ AddField ( rS,T,false );
+ }
+
+ void Struct::PutReal ( realtype R, cpstr T, cpstr format ) {
+ char rS[100];
+ sprintf ( rS,format,R );
+ AddField ( DelSpaces(rS,' '),T,false );
+ }
+
+ void Struct::PutInteger ( int I, cpstr T ) {
+ char iS[100];
+ if (I>MinInt4) {
+ sprintf ( iS,"%i",I );
+ AddField ( iS,T,false );
+ } else
+ PutNoData ( CIF_NODATA_DOT,T );
+ }
+
+
+
+ #define NODATA_Q pstr("?")
+ #define NODATA_P pstr(".")
+
+ bool Struct::WriteMMCIFStruct ( cpstr FName,
+ io::GZ_MODE gzipMode ) {
+ io::File f;
+ f.assign ( FName,true,false,gzipMode );
+ if (f.rewrite()) {
+ WriteMMCIF ( f );
+ f.shut();
+ return true;
+ } else
+ return false;
+ }
+
+ #define _max_output_line_width 256
+
+ void Struct::WriteMMCIF ( io::RFile f ) {
+ int i,j,k,l,m,n;
+ pstr F;
+
+ // calculate maximal length of tags
+ l = 0;
+ for (i=0;i<nTags;i++)
+ l = IMax(l,strlen(tag[i]));
+ l += 1; // add one space separator
+
+ // calculate maximal space left for data
+ m = _max_output_line_width - l;
+ // subtract category name width
+ if (name[0]!=char(1)) m -= strlen(name);
+
+ // start outout
+ f.LF();
+ for (i=0;i<nTags;i++) { // for each tag
+
+ // print category name, if not hidden, and dot
+ if (name[0]!=char(1)) {
+ f.Write ( name );
+ f.Write ( pstr(".") );
+ }
+
+ // print tag, checking for duplicate tag flag
+ F = strchr ( tag[i],'\1' );
+ if (F) {
+ *F = char(0);
+ f.Write ( tag[i] );
+ *F = '\1';
+ } else
+ f.Write ( tag[i] );
+
+ // print field
+ if (field[i]) { // field is defined
+ F = field[i];
+ if (strchr(F,'\n') || strstr(F,"\" ")) {
+ f.Write ( pstr("\n;") );
+ f.Write ( F );
+ f.Write ( pstr("\n;\n") );
+ } else {
+ n = strlen(F);
+ if (n>m) // wrap around if field is too long
+ f.Write ( pstr("\n ") );
+ else {
+ k = l-strlen(tag[i]);
+ for (j=0;j<k;j++)
+ f.Write ( pstr(" ") );
+ }
+ if ((((F[0]=='.') || (F[0]=='?')) && (!F[1])) ||
+ strchr(F,' ')) {
+ f.Write ( pstr("\"") );
+ f.Write ( field[i] );
+ f.Write ( pstr("\"\n") );
+ } else if (field[i][0]==char(2)) {
+ f.WriteLine ( &(field[i][1]) );
+ } else if (!field[i][0]) {
+ f.WriteLine ( NODATA_P );
+ } else
+ f.WriteLine ( field[i] );
+ }
+
+ } else { // field if not defined, put question mark
+
+ k = l-strlen(tag[i]);
+ for (j=0;j<k;j++)
+ f.Write ( pstr(" ") );
+ f.WriteLine ( NODATA_Q );
+
+ }
+
+ }
+
+ }
+
+ void Struct::Copy ( PCategory Struct ) {
+ int i;
+ Category::Copy ( Struct );
+ if (nTags>0) {
+ GetVectorMemory ( field,nTags,0 );
+ for (i=0;i<nTags;i++) {
+ field[i] = NULL;
+ CreateCopy ( field[i],PStruct(Struct)->field[i] );
+ }
+ }
+ }
+
+ void Struct::write ( io::RFile f ) {
+ int i;
+ Category::write ( f );
+ for (i=0;i<nTags;i++)
+ f.CreateWrite ( field[i] );
+ }
+
+ void Struct::read ( io::RFile f ) {
+ int i;
+ Category::read ( f );
+ if (nTags>0) {
+ GetVectorMemory ( field,nTags,0 );
+ for (i=0;i<nTags;i++) {
+ field[i] = NULL;
+ f.CreateRead ( field[i] );
+ }
+ }
+ }
+
+
+ MakeStreamFunctions(Struct)
+
+
+
+ // ====================== Loop ==============================
+
+
+ Loop::Loop() : Category() {
+ InitLoop();
+ }
+
+ Loop::Loop ( cpstr N ) : Category(N) {
+ InitLoop();
+ }
+
+ Loop::Loop ( io::RPStream Object ) : Category(Object) {
+ InitLoop();
+ }
+
+ Loop::~Loop() {
+ FreeMemory();
+ }
+
+ void Loop::InitLoop() {
+ nRows = 0;
+ field = NULL;
+ iColumn = 0;
+ nAllocRows = 0;
+ }
+
+ void Loop::FreeMemory() {
+ DeleteFields();
+ Category::FreeMemory();
+ }
+
+ void Loop::Optimize() {
+ int i,j,nT,nR,k,m;
+ bool empty;
+ psmatrix f1;
+
+ if (!field) {
+ Category::Optimize(); // optimize tags
+ return;
+ }
+
+ // first check for empty columns
+ nT = 0;
+ for (i=0;i<nTags;i++)
+ if (!tag[i]) {
+ for (j=0;j<nRows;j++) // delete ith column of field
+ if (field[j]) {
+ if (field[j][i])
+ delete[] field[j][i];
+ field[j][i] = NULL;
+ }
+ } else {
+ empty = true;
+ j = 0;
+ while ((j<nRows) && empty) { // check if ith column is empty
+ if (field[j])
+ empty = !field[j][i];
+ j++;
+ }
+ if (empty) { // if ith column is empty, delete its tag
+ delete[] tag[i];
+ tag[i] = NULL;
+ } else // otherwise count ith tag
+ nT++;
+ }
+
+ // now check for empty rows
+ nR = 0;
+ for (j=0;j<nRows;j++)
+ if (field[j]) {
+ i = 0;
+ while ((i<nTags) && (!field[j][i])) i++;
+ if (i>=nTags) {
+ delete[] field[j]; // delete empty row
+ field[j] = NULL;
+ } else
+ nR++; // count non-empty row
+ }
+ if ((nT<=0) || (nR<=0))
+ FreeMemory(); // the loop is completely empty
+ else if ((nT!=nTags) || (nR!=nAllocRows)) {
+ f1 = new psvector[nR];
+ m = 0;
+ for (j=0;j<nRows;j++)
+ if (field[j]) {
+ f1[m] = new pstr[nT];
+ k = 0;
+ for (i=0;i<nTags;i++)
+ if (tag[i])
+ f1[m][k++] = field[j][i];
+ m++;
+ delete[] field[j];
+ }
+ if (field) delete[] field;
+ field = f1;
+ nRows = nR;
+ nAllocRows = nRows;
+ Category::Optimize(); // optimize tags
+ }
+
+ }
+
+ void Loop::DeleteFields() {
+ int i,j;
+ if (field) {
+ for (i=0;i<nAllocRows;i++)
+ if (field[i]) {
+ for (j=0;j<nTags;j++)
+ if (field[i][j]) delete[] field[i][j];
+ delete[] field[i];
+ }
+ delete[] field;
+ field = NULL;
+ nRows = 0;
+ nAllocRows = 0;
+ }
+ }
+
+ void Loop::AddLoopTag ( cpstr T, bool Remove ) {
+ psmatrix f1;
+ int i,j,nT1;
+ if (Remove) {
+ DeleteFields();
+ AddTag ( T );
+ } else {
+ f1 = field;
+ field = NULL;
+ i = AddTag ( T );
+ if ((f1) && (i<0)) {
+ // The tag was added on the top of tag array. Create
+ // and fill new fields.
+ field = new psvector[nAllocRows];
+ nT1 = nTags-1;
+ for (i=0;i<nAllocRows;i++)
+ if (f1[i]) {
+ field[i] = new pstr[nTags];
+ for (j=0;j<nT1;j++)
+ field[i][j] = f1[i][j];
+ field[i][nT1] = NULL;
+ f1[i] = NULL;
+ } else
+ field[i] = NULL;
+ delete[] f1;
+ } else
+ // The tag was already in the category. Just restore fields.
+ field = f1;
+ }
+ }
+
+
+ void Loop::ExpandRows ( int nRowsNew ) {
+ int nAR,i;
+ psmatrix field1;
+ if (nRowsNew>nAllocRows) {
+ nAR = nRowsNew + IMin(nAllocRows/2+10,2000);
+ field1 = new psvector[nAR];
+ for (i=0;i<nAllocRows;i++)
+ field1[i] = field[i];
+ for (i=nAllocRows;i<nAR;i++)
+ field1[i] = NULL;
+ if (field) delete[] field;
+ field = field1;
+ nAllocRows = nAR;
+ }
+ }
+
+ void Loop::AddString ( cpstr S, bool NonBlankOnly ) {
+ int i;
+ pstr p;
+ if (!S) AddNoData ( CIF_NODATA_QUESTION );
+ else {
+ p = pstr(S);
+ if (NonBlankOnly)
+ while (*p==' ') p++;
+ if (!(*p)) AddNoData ( CIF_NODATA_DOT );
+ else {
+ if (iColumn==0) { // start a new row
+ ExpandRows ( nRows+1 );
+ field[nRows] = new pstr[nTags];
+ for (i=0;i<nTags;i++)
+ field[nRows][i] = NULL;
+ nRows++;
+ }
+ CreateCopy ( field[nRows-1][iColumn],S );
+ iColumn++;
+ if (iColumn>=nTags) iColumn = 0;
+ }
+ }
+ }
+
+ void Loop::AddNoData ( int NoDataType ) {
+ char S[10];
+ S[0] = char(2);
+ if (NoDataType==CIF_NODATA_DOT) S[1] = '.';
+ else S[1] = '?';
+ S[2] = char(0);
+ AddString ( S );
+ }
+
+ void Loop::AddReal ( realtype R, int prec ) {
+ char rS[100];
+ sprintf ( rS,"%.*g",prec,R );
+ AddString ( rS );
+ }
+
+ void Loop::AddReal ( realtype R, cpstr format ) {
+ char rS[100];
+ sprintf ( rS,format,R );
+ AddString ( DelSpaces(rS,' ') );
+ }
+
+ void Loop::AddInteger ( int I ) {
+ char iS[100];
+ if (I>MinInt4) {
+ sprintf ( iS,"%i",I );
+ AddString ( iS );
+ } else
+ AddNoData ( CIF_NODATA_DOT );
+ }
+
+
+ pstr Loop::GetField ( int rowNo, int tagNo ) {
+ if ((tagNo>=0) && (tagNo<nTags) &&
+ (rowNo>=0) && (rowNo<nRows)) {
+ if (field[rowNo]) return field[rowNo][tagNo];
+ }
+ return NULL;
+ }
+
+ int Loop::GetString ( pstr & S, cpstr TName, int nrow,
+ bool Remove) {
+ int k = GetTagNo ( TName );
+ if (S) delete[] S;
+ S = NULL;
+ if (k<0) return CIFRC_NoTag;
+ if ((nrow<0) || (nrow>=nRows)) return CIFRC_WrongIndex;
+ if (!field[nrow]) return CIFRC_NoField;
+ if (!field[nrow][k]) return CIFRC_NoField;
+ if (field[nrow][k][0]==char(2)) {
+ if (Remove) {
+ delete[] field[nrow][k];
+ field[nrow][k] = NULL;
+ }
+ } else if (Remove) {
+ S = field[nrow][k];
+ field[nrow][k] = NULL;
+ } else
+ CreateCopy ( S,field[nrow][k] );
+ return 0;
+ }
+
+ pstr Loop::GetString ( cpstr TName, int nrow, int & RC ) {
+ int k = GetTagNo ( TName );
+ if (k<0) {
+ RC = CIFRC_NoTag;
+ return NULL;
+ }
+ if ((nrow<0) || (nrow>=nRows)) {
+ RC = CIFRC_WrongIndex;
+ return NULL;
+ }
+ if (!field[nrow]) {
+ RC = CIFRC_NoField;
+ return NULL;
+ }
+ if (!field[nrow][k]) {
+ RC = CIFRC_NoField;
+ return NULL;
+ }
+ RC = 0;
+ // char(2) means the field was either '.' or '?'
+ if (field[nrow][k][0]==char(2)) return NULL;
+ return field[nrow][k];
+ }
+
+ // CopyString() does nothing if RC is not 0
+ void Loop::CopyString ( pstr buf, int maxlength,
+ cpstr TName, int nrow, int & RC ) {
+ pstr p;
+ int k;
+
+ if (RC) return;
+
+ k = GetTagNo ( TName );
+ if (k<0) {
+ RC = CIFRC_NoTag;
+ buf[0] = char(0);
+ return;
+ }
+ if ((nrow<0) || (nrow>=nRows)) {
+ RC = CIFRC_WrongIndex;
+ buf[0] = char(0);
+ return;
+ }
+ if (!field[nrow]) {
+ RC = CIFRC_NoField;
+ buf[0] = char(0);
+ return;
+ }
+ p = field[nrow][k];
+ if (!p) {
+ RC = CIFRC_NoField;
+ buf[0] = char(0);
+ return;
+ }
+
+ // char(2) means the field was either '.' or '?'
+ if (p[0]==char(2)) {
+ buf[0] = p[0];
+ buf[1] = char(0);
+ } else
+ strncpy ( buf,p,IMin(maxlength,strlen(p)+1) );
+
+ }
+
+
+
+ int Loop::DeleteField ( cpstr TName, int nrow ) {
+ int k = GetTagNo ( TName );
+ if (k<0) return CIFRC_NoTag;
+ if ((nrow<0) || (nrow>=nRows))
+ return CIFRC_WrongIndex;
+ if (field[nrow]) {
+ if (field[nrow][k]) delete[] field[nrow][k];
+ field[nrow][k] = NULL;
+ }
+ return k;
+ }
+
+ int Loop::DeleteRow ( int nrow ) {
+ int i;
+ if ((nrow<0) || (nrow>=nRows))
+ return CIFRC_WrongIndex;
+ if (field[nrow]) {
+ for (i=0;i<nTags;i++)
+ if (field[nrow][i]) {
+ delete[] field[nrow][i];
+ field[nrow][i] = NULL;
+ }
+ delete[] field[nrow];
+ field[nrow] = NULL;
+ }
+ return 0;
+ }
+
+ int Loop::GetReal ( realtype & R, cpstr TName, int nrow,
+ bool Remove ) {
+ pstr endptr;
+ int k = GetTagNo ( TName );
+ if (k<0) return CIFRC_NoTag;
+ if ((nrow<0) || (nrow>=nRows))
+ return CIFRC_WrongIndex;
+ R = 0.0;
+ if (!field[nrow]) return CIFRC_NoField;
+ if (!field[nrow][k]) return CIFRC_NoField;
+ if (field[nrow][k][0]==char(2)) return CIFRC_NoField;
+ R = strtod ( field[nrow][k],&endptr );
+ if (endptr==field[nrow][k]) return CIFRC_WrongFormat;
+ if (Remove) {
+ delete[] field[nrow][k];
+ field[nrow][k] = NULL;
+ }
+ return 0;
+ }
+
+ void Loop::CopyReal ( realtype & R, cpstr TName, int nrow,
+ int & RC ) {
+ pstr endptr;
+ int k;
+
+ if (RC) return;
+
+ // R = 0.0;
+ k = GetTagNo ( TName );
+
+ if (k<0) RC = CIFRC_NoTag;
+ else if ((nrow<0) || (nrow>=nRows)) RC = CIFRC_WrongIndex;
+ else if (!field[nrow]) RC = CIFRC_NoField;
+ else if (!field[nrow][k]) RC = CIFRC_NoField;
+ else if (field[nrow][k][0]==char(2)) RC = CIFRC_NoField;
+ else {
+ R = strtod ( field[nrow][k],&endptr );
+ if (endptr==field[nrow][k]) RC = CIFRC_WrongFormat;
+ }
+
+ }
+
+ void Loop::CopyInteger ( int & I, cpstr TName, int nrow,
+ int & RC ) {
+ pstr endptr;
+ int k;
+
+ if (RC) return;
+
+ I = 0;
+ k = GetTagNo ( TName );
+
+ if (k<0) RC = CIFRC_NoTag;
+ else if ((nrow<0) || (nrow>=nRows)) RC = CIFRC_WrongIndex;
+ else if (!field[nrow]) RC = CIFRC_NoField;
+ else if (!field[nrow][k]) RC = CIFRC_NoField;
+ else if (field[nrow][k][0]==char(2)) RC = CIFRC_NoField;
+ else {
+ I = mround ( strtod ( field[nrow][k],&endptr ) );
+ if (endptr==field[nrow][k]) RC = CIFRC_WrongFormat;
+ }
+
+ }
+
+ int Loop::GetInteger ( int & I, cpstr TName, int nrow,
+ bool Remove ) {
+ pstr endptr;
+ int k = GetTagNo ( TName );
+ if (k<0) return CIFRC_NoTag;
+ if ((nrow<0) || (nrow>=nRows))
+ return CIFRC_WrongIndex;
+ I = 0;
+ if (!field[nrow]) return CIFRC_NoField;
+ if (!field[nrow][k]) return CIFRC_NoField;
+ if (field[nrow][k][0]==char(2)) {
+ if (field[nrow][k][1]=='.') I = MinInt4;
+ return CIFRC_NoField;
+ }
+ I = mround ( strtod(field[nrow][k],&endptr) );
+ if (endptr==field[nrow][k]) return CIFRC_WrongFormat;
+ if (Remove) {
+ delete[] field[nrow][k];
+ field[nrow][k] = NULL;
+ }
+ return 0;
+ }
+
+
+ int Loop::GetSVector ( psvector & S, cpstr TName,
+ int i1, int i2, bool Remove ) {
+ int j,k,r1,r2;
+ r1 = IMin(i1,i2);
+ r2 = IMin(IMax(i1,i2),nRows-1);
+ if ((r1<0) || (r1>=nRows) || (r2<0)) return CIFRC_WrongIndex;
+ k = GetTagNo ( TName );
+ if (k<0) return CIFRC_NoTag;
+ if (!S)
+ GetVectorMemory ( S,r2-r1+1,r1 );
+ if (Remove) {
+ for (j=r1;j<=r2;j++)
+ if (field[j]) {
+ S[j] = field[j][k];
+ field[j][k] = NULL;
+ if (S[j]) {
+ if (S[j][0]==char(2)) {
+ delete[] S[j];
+ S[j] = NULL;
+ }
+ }
+ } else
+ S[j] = NULL;
+ } else {
+ for (j=r1;j<=r2;j++) {
+ S[j] = NULL;
+ if (field[j]) {
+ if (field[j][k]) {
+ if (field[j][k][0]!=char(2))
+ CreateCopy ( S[j],field[j][k] );
+ }
+ }
+ }
+ }
+ return 0;
+ }
+
+ int Loop::GetRVector ( rvector & R, cpstr TName,
+ int i1, int i2, bool Remove ) {
+ int j,k,r1,r2,RC;
+ pstr endptr;
+ r1 = IMin(i1,i2);
+ r2 = IMin(IMax(i1,i2),nRows-1);
+ if ((r1<0) || (r1>=nRows) || (r2<0)) return CIFRC_WrongIndex;
+ k = GetTagNo ( TName );
+ if (k<0) return CIFRC_NoTag;
+ if (!R)
+ GetVectorMemory ( R,r2-r1+1,r1 );
+ RC = 0;
+ for (j=r1;j<=r2;j++) {
+ R[j] = 0.0;
+ if (field[j]) {
+ if (field[j][k]) {
+ R[j] = strtod ( field[j][k],&endptr );
+ if (endptr==field[j][k]) RC = CIFRC_WrongFormat;
+ if (Remove) {
+ delete[] field[j][k];
+ field[j][k] = NULL;
+ }
+ }
+ }
+ }
+ return RC;
+ }
+
+ int Loop::GetIVector ( ivector & I, cpstr TName,
+ int i1, int i2, bool Remove ) {
+ int j,k,r1,r2,RC;
+ pstr endptr;
+ r1 = IMin(i1,i2);
+ r2 = IMin(IMax(i1,i2),nRows-1);
+ if ((r1<0) || (r1>=nRows) || (r2<0)) return CIFRC_WrongIndex;
+ k = GetTagNo ( TName );
+ if (k<0) return CIFRC_NoTag;
+ if (!I)
+ GetVectorMemory ( I,r2-r1+1,r1 );
+ RC = 0;
+ for (j=r1;j<=r2;j++) {
+ I[j] = 0;
+ if (field[j]) {
+ if (field[j][k]) {
+ I[j] = mround ( strtod(field[j][k],&endptr) );
+ if (endptr==field[j][k]) RC = CIFRC_WrongFormat;
+ if (Remove) {
+ delete[] field[j][k];
+ field[j][k] = NULL;
+ }
+ }
+ }
+ }
+ return RC;
+ }
+
+
+ void Loop::PutString ( cpstr S, cpstr T, int nrow ) {
+ psmatrix field1;
+ int nT,nR,iT,i,j;
+ nT = nTags;
+ nR = nRows;
+ iT = AddTag ( T );
+ if (iT<0) iT = nTags-1;
+ if (nTags>nT) {
+ // a new tag has been added; all field must be reallocated.
+ nRows = IMax(nR,nrow+1); // nrow is indexed like 0,1,...
+ nAllocRows = IMax(nR,nrow+IMin(nR/2+1,2000));
+ field1 = new psvector[nAllocRows];
+ for (i=0;i<nR;i++)
+ if (field[i]) {
+ field1[i] = new pstr[nTags];
+ for (j=0;j<nT;j++)
+ field1[i][j] = field[i][j];
+ for (j=nT;j<nTags;j++)
+ field1[i][j] = NULL;
+ delete[] field[i];
+ } else
+ field1[i] = NULL;
+ for (i=nR;i<nRows;i++)
+ field1[i] = NULL;
+ if (field) delete[] field;
+ field = field1;
+ } else if (nrow>=nR) {
+ // only new rows are to be added
+ ExpandRows ( nrow+1 );
+ nRows++;
+ }
+ if (!field[nrow]) {
+ field[nrow] = new pstr[nTags];
+ for (j=0;j<nTags;j++)
+ field[nrow][j] = NULL;
+ }
+ CreateCopy ( field[nrow][iT],S );
+ iColumn = iT+1;
+ if (iColumn>=nTags) iColumn = 0;
+ }
+
+
+ void Loop::PutNoData ( int NoDataType, cpstr T, int nrow ) {
+ char S[10];
+ S[0] = char(2);
+ if (NoDataType==CIF_NODATA_DOT) S[1] = '.';
+ else S[1] = '?';
+ S[2] = char(0);
+ PutString ( S,T,nrow );
+ }
+
+
+ void Loop::PutReal ( realtype R, cpstr T, int nrow, int prec ) {
+ char rS[100];
+ sprintf ( rS,"%.*g",prec,R );
+ PutString ( rS,T,nrow );
+ }
+
+ void Loop::PutReal ( realtype R, cpstr T, int nrow,
+ cpstr format ) {
+ char rS[100];
+ sprintf ( rS,format,R );
+ PutString ( DelSpaces(rS,' '),T,nrow );
+ }
+
+ void Loop::PutInteger ( int I, cpstr T, int nrow ) {
+ char iS[100];
+ if (I>MinInt4) {
+ sprintf ( iS,"%i",I );
+ PutString ( iS,T,nrow );
+ } else
+ PutNoData ( CIF_NODATA_DOT,T,nrow );
+ }
+
+ void Loop::PutSVector ( psvector S, cpstr T, int i1, int i2 ) {
+ int i,j,k;
+ PutString ( S[i2],T,i2 );
+ if (iColumn==0) k = nTags-1;
+ else k = iColumn-1;
+ for (i=i2-1;i>=i1;i--) {
+ if (!field[i]) {
+ field[i] = new pstr[nTags];
+ for (j=0;j<nTags;j++)
+ field[i][j] = NULL;
+ }
+ CreateCopy ( field[i][k],S[i] );
+ }
+ }
+
+ void Loop::PutRVector ( rvector R, cpstr T,
+ int i1, int i2, int prec ) {
+ int i,j,k;
+ char rS[100];
+ PutReal ( R[i2],T,i2,prec );
+ if (iColumn==0) k = nTags-1;
+ else k = iColumn-1;
+ for (i=i2-1;i>=i1;i--) {
+ if (!field[i]) {
+ field[i] = new pstr[nTags];
+ for (j=0;j<nTags;j++)
+ field[i][j] = NULL;
+ }
+ sprintf ( rS,"%.*g",prec,R[i] );
+ CreateCopy ( field[i][k],rS );
+ }
+ }
+
+ void Loop::PutIVector ( ivector I, cpstr T,
+ int i1, int i2 ) {
+ int l,j,k;
+ char iS[100];
+ PutInteger ( I[i2],T,i2 );
+ if (iColumn==0) k = nTags-1;
+ else k = iColumn-1;
+ for (l=i2-1;l>=i1;l--) {
+ if (!field[l]) {
+ field[l] = new pstr[nTags];
+ for (j=0;j<nTags;j++)
+ field[l][j] = NULL;
+ }
+ sprintf ( iS,"%i",I[l] );
+ CreateCopy ( field[l][k],iS );
+ }
+ }
+
+ bool Loop::WriteMMCIFLoop ( cpstr FName, io::GZ_MODE gzipMode ) {
+ io::File f;
+ f.assign ( FName,true,false,gzipMode );
+ if (f.rewrite()) {
+ WriteMMCIF ( f );
+ f.shut();
+ return true;
+ } else
+ return false;
+ }
+
+ void Loop::WriteMMCIF ( io::RFile f ) {
+ int i,j,k,m,n;
+ ivector l;
+ pstr F;
+
+ // write loop keyword
+ f.Write ( pstr("\nloop_\n") );
+
+ GetVectorMemory ( l,nTags,0 );
+ k = 0;
+ for (i=0;i<nTags;i++) {
+ if (name[0]!=char(1)) {
+ f.Write ( name );
+ f.Write ( pstr(".") );
+ }
+ F = strchr ( tag[i],'\1' );
+ if (F) {
+ *F = char(0);
+ f.WriteLine ( tag[i] );
+ *F = '\1';
+ } else
+ f.WriteLine ( tag[i] );
+ l[i] = 0;
+ for (j=0;j<nRows;j++)
+ if (field[j]) {
+ if (field[j][i]) {
+ F = field[j][i];
+ if (strchr(F,'\n') || strstr(F,"\" "))
+ l[i] = 10001;
+ else if (F[0]==char(2)) l[i] = IMax(l[i],1);
+ else if (((F[0]=='.') || (F[0]=='?')) &&
+ (!F[1])) l[i] = IMax(l[i],3);
+ else {
+ if (strchr(F,' ')) m = 2;
+ else m = 0;
+ l[i] = IMax(l[i],strlen(F)+m);
+ }
+ }
+ }
+ l[i] = IMax(l[i],1);
+ k += l[i]+1;
+ if (k>_max_output_line_width) {
+ l[i] = -l[i];
+ k = 0;
+ }
+ }
+ for (i=0;i<nRows;i++) {
+ m = 0; // counts symbols in the string
+ k = 0; // rest of left-aligned fields to fill with spaces
+ for (j=0;j<nTags;j++) {
+ n = k;
+ k = l[j]; // length of the field
+ if (k<0) k = -k;
+ m += k+1;
+ if (m>_max_output_line_width) {
+ f.LF();
+ m = k+1;
+ } else
+ while (n>0) {
+ f.Write ( pstr(" ") );
+ n--;
+ }
+ if (field[i]) {
+ if (field[i][j]) {
+ F = field[i][j];
+ if (k>10000) {
+ if (F[0]==char(2)) {
+ f.Write ( pstr(" ") );
+ f.WriteLine ( &(F[1]) );
+ } else if (!F[0]) {
+ f.Write ( pstr(" ") );
+ f.WriteLine ( NODATA_P );
+ } else {
+ f.Write ( pstr(";") );
+ f.WriteLine ( F );
+ f.WriteLine ( pstr(";") );
+ }
+ m = 0;
+ k = 0;
+ } else if ((((F[0]=='.') || (F[0]=='?')) && (!F[1])) ||
+ strchr(F,' ')) {
+ f.Write ( pstr(" \"") );
+ f.Write ( F );
+ f.Write ( pstr("\"") );
+ k -= strlen(F)+2;
+ } else if (F[0]==char(2)) {
+ f.Write ( pstr(" ") );
+ f.Write ( &(F[1]) );
+ k--;
+ } else if (!F[0]) {
+ f.Write ( pstr(" ") );
+ f.Write ( NODATA_P );
+ k--;
+ } else {
+ f.Write ( pstr(" ") );
+ f.Write ( F );
+ k -= strlen(F);
+ }
+ } else {
+ f.Write ( pstr(" ") );
+ f.Write ( NODATA_Q );
+ k--;
+ }
+ } else {
+ f.Write ( pstr(" ") );
+ f.Write ( NODATA_Q );
+ k--;
+ }
+ }
+ if (m) f.LF();
+ }
+
+ }
+
+
+ void Loop::Copy ( PCategory Loop ) {
+ int i,j;
+ Category::Copy ( Loop );
+ nRows = PLoop(Loop)->nRows;
+ nAllocRows = nRows;
+ if ((nTags>0) && (nRows>0)) {
+ field = new psvector[nRows];
+ for (i=0;i<nRows;i++) {
+ if (PLoop(Loop)->field[i]) {
+ field[i] = new pstr[nTags];
+ for (j=0;j<nTags;j++) {
+ field[i][j] = NULL;
+ CreateCopy ( field[i][j],PLoop(Loop)->field[i][j] );
+ }
+ } else
+ field[i] = NULL;
+ }
+ }
+ iColumn = PLoop(Loop)->iColumn;
+ }
+
+
+ void Loop::write ( io::RFile f ) {
+ int i,j;
+ Category::write ( f );
+ f.WriteInt ( &nRows );
+ if ((nTags>0) && (nRows>0))
+ for (i=0;i<nRows;i++)
+ if (field[i]) {
+ j = 1;
+ f.WriteInt ( &j );
+ for (j=0;j<nTags;j++)
+ f.CreateWrite ( field[i][j] );
+ } else {
+ j = 0;
+ f.WriteInt ( &j );
+ }
+ f.WriteInt ( &iColumn );
+ }
+
+ void Loop::read ( io::RFile f ) {
+ int i,j;
+ Category::read ( f );
+ f.ReadInt ( &nRows );
+ nAllocRows = nRows;
+ if ((nTags>0) && (nRows>0)) {
+ field = new psvector[nRows];
+ for (i=0;i<nRows;i++) {
+ f.ReadInt ( &j );
+ if (j) {
+ field[i] = new pstr[nTags];
+ for (j=0;j<nTags;j++) {
+ field[i][j] = NULL;
+ f.CreateRead ( field[i][j] );
+ }
+ } else
+ field[i] = NULL;
+ }
+ }
+ f.ReadInt ( &iColumn );
+ }
+
+
+ MakeStreamFunctions(Loop)
+
+
+
+ // ====================== Data =============================
+
+
+ Data::Data() : io::Stream() {
+ InitData();
+ }
+
+ Data::Data ( cpstr N ) : io::Stream() {
+ InitData();
+ CreateCopy ( name,N );
+ }
+
+ Data::Data ( io::RPStream Object ) : io::Stream(Object) {
+ InitData();
+ }
+
+ Data::~Data() {
+ FreeMemory(0);
+ }
+
+ void Data::InitData() {
+ name = NULL;
+ nCategories = 0;
+ Category = NULL;
+ index = NULL;
+ flags = 0;
+ Warning = 0;
+ loopNo = 0;
+ tagNo = 0;
+ WrongCat = NULL;
+ WrongTag = NULL;
+ nWrongFields = 0;
+ }
+
+ void Data::FreeMemory ( int key ) {
+ int i;
+ if (name) delete[] name;
+ name = NULL;
+ if (Category) {
+ for (i=0;i<nCategories;i++)
+ if (Category[i]) delete Category[i];
+ delete[] Category;
+ Category = NULL;
+ }
+ nCategories = 0;
+ FreeVectorMemory ( index,0 );
+ if (key==0) FreeWrongFields();
+ }
+
+ void Data::FreeWrongFields() {
+ int i;
+ if (WrongCat) {
+ for (i=0;i<nWrongFields;i++)
+ if (WrongCat[i]) delete[] WrongCat[i];
+ delete[] WrongCat;
+ }
+ if (WrongTag) {
+ for (i=0;i<nWrongFields;i++)
+ if (WrongTag[i]) delete[] WrongTag[i];
+ delete[] WrongTag;
+ }
+ WrongCat = NULL;
+ WrongTag = NULL;
+ nWrongFields = 0;
+ }
+
+
+ void Data::SetPrintWarnings ( bool SPW ) {
+ if (SPW) SetFlag ( CIFFL_PrintWarnings );
+ else RemoveFlag ( CIFFL_PrintWarnings );
+ }
+
+ void Data::SetStopOnWarning ( bool SOW ) {
+ if (SOW) SetFlag ( CIFFL_StopOnWarnings );
+ else RemoveFlag ( CIFFL_StopOnWarnings );
+ }
+
+ void Data::SetFlag ( CIF_FLAG F ) {
+ flags |= F;
+ }
+
+ void Data::RemoveFlag ( CIF_FLAG F ) {
+ flags &= ~F;
+ }
+
+ void Data::SetWrongFields ( cpstr *cats, cpstr *tags ) {
+ int i,lc,lt;
+ FreeWrongFields();
+ if ((!cats) || (!tags)) return;
+ lc = 0;
+ while (cats[lc]) lc++;
+ lt = 0;
+ while (tags[lt]) lt++;
+ nWrongFields = IMax(lc,lt);
+ if (nWrongFields>0) {
+ WrongCat = new pstr[nWrongFields];
+ WrongTag = new pstr[nWrongFields];
+ for (i=0;i<nWrongFields;i++) {
+ WrongCat[i] = NULL;
+ WrongTag[i] = NULL;
+ if (cats[i]) {
+ if (cats[i][0]) CreateCopy ( WrongCat[i],cats[i] );
+ }
+ if (!WrongCat[i]) {
+ CreateCopy ( WrongCat[i],pstr(" ") );
+ WrongCat[i][0] = char(1);
+ }
+ if (tags[i]) CreateCopy ( WrongTag[i],tags[i] );
+ else CreateCopy ( WrongTag[i],pstr("") );
+ }
+ }
+ }
+
+ bool Data::CheckWrongField ( cpstr C, cpstr T ) {
+ int i;
+ for (i=0;i<nWrongFields;i++)
+ if ((!strcasecmp(C,WrongCat[i])) &&
+ (!strcasecmp(T,WrongTag[i]))) return true;
+ return false;
+ }
+
+ #define _max_buf_len 500
+
+ static char _err_string[_max_buf_len+1];
+ static int _err_line;
+
+
+ int Data::ReadMMCIFData ( cpstr FName, io::GZ_MODE gzipMode ) {
+ io::File f;
+ char S[_max_buf_len+1];
+ int RC,lcount;
+ f.assign ( FName,true,false,gzipMode );
+ if (f.reset(true)) {
+ S[0] = char(0);
+ lcount = 0;
+ RC = ReadMMCIFData ( f,S,lcount );
+ f.shut();
+ return RC;
+ } else {
+ _err_string[0] = char(0);
+ _err_line = 0;
+ Warning = CIFRC_CantOpenFile;
+ return CIFRC_CantOpenFile;
+ }
+ }
+
+
+ // --------------- General I/O functions
+
+ int Data::ReadMMCIFData ( io::RFile f, pstr S, int & lcount ) {
+ pstr p;
+ int i,llen;
+ pstr L;
+
+ FreeMemory(1);
+ Warning = 0;
+ loopNo = 0;
+ tagNo = 0;
+
+ // 1. Look for 'data_' tag
+ do {
+ p = &(S[0]);
+ while ((*p==' ') || (*p==char(9))) p++;
+ if (strncmp(p,"data_",5)) {
+ f.ReadLine ( S,_max_buf_len );
+ lcount++;
+ p = NULL;
+ }
+ } while ((!p) && (!f.FileEnd()));
+
+ if (!p) {
+ strcpy ( _err_string,S );
+ _err_line = lcount;
+ if (flags & CIFFL_PrintWarnings)
+ printf ( "\n **** mmCIF READ ERROR "
+ "<<line %i: no 'data_XXXX' tag found>>\n",lcount );
+ return CIFRC_NoDataLine;
+ }
+
+ llen = _max_buf_len;
+ L = new char[llen];
+ i = 0;
+ p += 5;
+ while ((*p) && (*p!=' ') && (*p!=char(9))) {
+ L[i++] = *p;
+ p++;
+ }
+ L[i] = char(0);
+ CreateCopy ( name,L );
+
+
+ // 2. Loop over tags until next 'data_' or end of file
+
+ while (p) {
+
+ // skip spaces
+ while ((*p==' ') || (*p==char(9))) p++;
+
+ if ((*p) && (*p!='#')) { // this is not a comment, continue
+ if (*p=='_')
+ GetDataItem ( f,S,L,p,lcount,llen );
+ else if (!strncmp(p,"loop_",5))
+ GetLoop ( f,S,L,p,lcount,llen );
+ else if (!strncmp(p,"data_",5)) {
+ p = NULL;
+ break;
+ } else {
+ // if got to here, the file is corrupted
+ strcpy ( _err_string,S );
+ _err_line = lcount;
+ Warning |= CIFW_UnrecognizedItems;
+ if (flags & CIFFL_PrintWarnings)
+ printf ( "\n **** mmCIF READ WARNING "
+ "<<line %i: unrecognized string>>\n%s\n",
+ lcount,S );
+ while ((*p) && (*p!=' ') && (*p!=char(9)))
+ if (*p=='#') *p = char(0);
+ else p++;
+ }
+ } else
+ *p = char(0);
+
+ if (Warning && (flags & CIFFL_StopOnWarnings)) {
+ if (L) delete[] L;
+ return Warning;
+ }
+
+ if (!(*p)) {
+ if (!f.FileEnd()) {
+ f.ReadLine ( S,_max_buf_len );
+ lcount++;
+ p = &(S[0]);
+ } else
+ p = NULL;
+ }
+
+ }
+
+ if (L) delete[] L;
+
+ Optimize(); // get rid of over-allocated fields.
+
+ return Warning;
+
+ }
+
+
+ void Data::GetDataItem ( io::RFile f, pstr S, pstr & L,
+ pstr & p, int & lcount, int & llen ) {
+ PStruct cifStruct;
+ char T[100];
+ int RC,i;
+
+ i = 0;
+ while ((*p) && (*p!=' ') && (*p!=char(9)) && (*p!='.')) {
+ if (i<(int)sizeof(T)-1) T[i++] = *p;
+ p++;
+ }
+ T[i] = char(0);
+
+ if (*p!='.') { // category name missing
+ strcpy ( L,T ); // item name
+ T[0] = char(1); // special
+ T[1] = char(0); // category name
+ }
+
+ // look for category
+ i = AddCategory ( T );
+ if (i<0) {
+ // negative value means that the category was not in the list,
+ // but a place for it has been provided and index updated
+ cifStruct = new Struct ( T );
+ Category[nCategories-1] = cifStruct;
+ } else {
+ cifStruct = PStruct(Category[i]);
+ if (cifStruct->GetCategoryID()!=MMCIF_Struct) {
+ strcpy ( _err_string,S );
+ _err_line = lcount;
+ Warning |= CIFW_NotAStructure;
+ if (flags & CIFFL_PrintWarnings)
+ printf ( "\n **** mmCIF READ WARNING "
+ "<<line %i: %s was a loop -- replaced>>\n%s\n",
+ lcount,T,S );
+ delete Category[i];
+ cifStruct = new Struct ( T );
+ Category[i] = cifStruct;
+ }
+ }
+
+ if (*p=='.') { // get item name
+ i = 0;
+ p++; // skip period
+ while ((*p) && (*p!=' ') && (*p!=char(9))) {
+ T[i++] = *p;
+ p++;
+ }
+ T[i] = char(0);
+ } else
+ strcpy ( T,L );
+
+ if (nWrongFields>0) {
+ if (CheckWrongField(cifStruct->name,T)) {
+ GetField ( f,S,L,p,lcount,llen );
+ cifStruct->DeleteField ( T );
+ return;
+ }
+ }
+
+ RC = GetField ( f,S,L,p,lcount,llen );
+
+ if (RC) {
+ strcpy ( _err_string,S );
+ _err_line = lcount;
+ Warning |= CIFW_MissingField;
+ if (flags & CIFFL_PrintWarnings)
+ printf ( "\n **** mmCIF READ WARNING "
+ "<<line %i: expected data field missing>>\n%s\n",
+ lcount,S );
+ }
+
+ while ((*p==' ') || (*p==char(9))) p++;
+ if (*p=='#') *p = char(0);
+
+ i = cifStruct->GetTagNo ( T );
+ if (i>=0) {
+ if (flags & CIFFL_SuggestTags) {
+ tagNo++;
+ ParamStr ( T,pstr("\1"),tagNo );
+ } else {
+ strcpy ( _err_string,S );
+ _err_line = lcount;
+ Warning |= CIFW_DuplicateTag;
+ if (flags & CIFFL_PrintWarnings)
+ printf ( "\n **** mmCIF READ WARNING "
+ "<<line %i: duplicated tag>>\n%s\n",lcount,S );
+ }
+ }
+ cifStruct->AddField ( L,T );
+
+ }
+
+ void Data::GetLoop ( io::RFile f, pstr S, pstr & L,
+ pstr & p, int & lcount, int & llen ) {
+ PLoop cifLoop;
+ pstr p1;
+ char T[100];
+ bool Repeat,WrongField;
+ int RC,i,nC;
+
+ RC = 0;
+
+ p += 5; // skip 'loop_' tag
+
+ loopNo++;
+ cifLoop = NULL;
+ nC = -1; // undefined category number
+ do {
+
+ while ((*p==' ') || (*p==char(9))) p++;
+ p1 = p;
+
+ if (*p=='_') {
+
+ // get category name
+ i = 0;
+ while ((*p) && (*p!=' ') && (*p!=char(9)) && (*p!='.')) {
+ if (i<(int)sizeof(T)-1) T[i++] = *p;
+ p++;
+ }
+ T[i] = char(0);
+
+ if (*p!='.') { // category name missing
+ strcpy ( L,T ); // item name
+ if (flags & CIFFL_SuggestCategories)
+ sprintf ( T,"X%i",loopNo );
+ else strcpy ( T,"X" );
+ T[0] = char(1); // special category name
+ }
+
+ if (cifLoop) {
+ if (strcmp(cifLoop->GetCategoryName(),T)) {
+ // loop ended, empty
+ p = p1; // play back to last category
+ cifLoop = NULL;
+ }
+ } else {
+ // look for category
+ i = AddCategory ( T );
+ if ((i!=nC) && (nC>=0)) { // empty loop; most probably
+ // a corrupted file
+ p = p1; // play back to last category
+ strcpy ( _err_string,S );
+ _err_line = lcount;
+ Warning |= CIFW_EmptyLoop;
+ if (flags & CIFFL_PrintWarnings)
+ printf ( "\n **** mmCIF READ WARNING "
+ "<<line %i: empty loop>>\n%s\n",lcount,S );
+ // AddCategory(..) has added a NULL-Category on the top of
+ // category list; remove it now
+ DeleteCategory ( nCategories-1 );
+ cifLoop = NULL;
+ // return;
+ }
+ if (i<0) {
+ // negative value means that the category was not in the list,
+ // but a place for it has been provided and index updated
+ cifLoop = new Loop ( T );
+ Category[nCategories-1] = cifLoop;
+ nC = nCategories-1;
+ }
+ }
+ /*
+ else if (Loop) {
+ if (!strcmp(Loop->GetCategoryName(),
+ Category[i]->GetCategoryName())) {
+ if (Loop->GetCategoryID()!=MMCIF_Loop) {
+ Warning |= CIFW_NotALoop;
+ if (flags & CIFFL_PrintWarnings)
+ printf ( "\n **** mmCIF READ WARNING "
+ "<<line %i: %s was a structure --"
+ " replaced>>\n%s\n",lcount,T,S );
+ delete Category[i];
+ Loop = new Loop ( T );
+ Category[i] = Loop;
+ }
+ } else
+ Loop = NULL;
+ }
+ */
+ if (cifLoop) {
+
+ if (*p=='.') { // get item name
+ i = 0;
+ p++; // skip period
+ while ((*p) && (*p!=' ') && (*p!=char(9))) {
+ T[i++] = *p;
+ p++;
+ }
+ T[i] = char(0);
+ } else
+ strcpy ( T,L );
+
+ if (nWrongFields>0)
+ WrongField = CheckWrongField ( cifLoop->name,T );
+ else WrongField = false;
+
+ if (!WrongField) {
+ if (cifLoop->AddTag(T)>=0) {
+ if (flags & CIFFL_SuggestTags) {
+ tagNo++;
+ ParamStr ( T,pstr("\1"),tagNo );
+ cifLoop->AddTag(T);
+ } else {
+ strcpy ( _err_string,S );
+ _err_line = lcount;
+ Warning |= CIFW_DuplicateTag;
+ if (flags & CIFFL_PrintWarnings)
+ printf ( "\n **** mmCIF READ WARNING "
+ "<<line %i: duplicate tag>>\n%s\n",lcount,S );
+ }
+ }
+ }
+ Repeat = true;
+
+ } else {
+
+ p = p1;
+ Repeat = false;
+
+ }
+
+ } else if (!(*p) || (*p=='#')) {
+ Repeat = !f.FileEnd();
+ if (Repeat) {
+ f.ReadLine ( S,_max_buf_len );
+ lcount++;
+ p = &(S[0]);
+ } else {
+ strcpy ( _err_string,S );
+ _err_line = lcount;
+ Warning |= CIFW_UnexpectedEOF;
+ if (flags & CIFFL_PrintWarnings)
+ printf ( "\n **** mmCIF READ WARNING "
+ "<<line %i: unexpected end of file>>\n%s\n",
+ lcount,S );
+ }
+ } else
+ Repeat = false;
+
+ } while (Repeat);
+
+ if (cifLoop) {
+ do {
+ while ((*p==' ') || (*p==char(9))) p++;
+ if (!(*p) || (*p=='#')) {
+ Repeat = !f.FileEnd();
+ if (Repeat) {
+ f.ReadLine ( S,_max_buf_len );
+ lcount++;
+ p = &(S[0]);
+ }
+ } else if (*p=='_') Repeat = false;
+ else if (!strncmp(p,"loop_",5)) Repeat = false;
+ else if (!strncmp(p,"data_",5)) Repeat = false;
+ else if (!strncmp(p,"stop_",5)) {
+ p += 5;
+ Repeat = false;
+ } else {
+ RC = GetField ( f,S,L,p,lcount,llen );
+ if (!RC) {
+ cifLoop->AddString ( L );
+ Repeat = true;
+ } else
+ Repeat = false;
+ }
+ } while (Repeat);
+ if ((cifLoop->iColumn!=0) || (RC)) {
+ strcpy ( _err_string,S );
+ _err_line = lcount;
+ Warning |= CIFW_LoopFieldMissing;
+ if (flags & CIFFL_PrintWarnings)
+ printf ( "\n **** mmCIF READ WARNING "
+ "<<line %i: expected loop field missing>>\n%s\n",
+ lcount,S );
+ }
+ }
+
+ }
+
+ int Data::GetField ( io::RFile f, pstr S, pstr & L,
+ pstr & p, int & lcount, int & llen ) {
+ bool Repeat;
+ pstr L1;
+ int i,flen;
+ char c;
+
+ flen = 0;
+ L[flen] = char(0);
+
+ do {
+
+ // skip all spaces before the field
+ while ((*p==' ') || (*p==char(9))) p++;
+
+ if ((*p=='#') || (!(*p))) {
+ // comment or end of line met; the field should be
+ // found on the next line
+ Repeat = !f.FileEnd();
+ if (Repeat) {
+ // take the next line
+ f.ReadLine ( S,_max_buf_len );
+ lcount++;
+ p = &(S[0]);
+ Repeat = (*p!=';');
+ } else {
+ // end of file and the field is not taken
+ L[0] = char(0);
+ return 1;
+ }
+ } else
+ // first symbol of a field is found
+ Repeat = false;
+
+ } while (Repeat);
+
+
+ if (*p==';') { // this is a multiline field
+ p++;
+ strcpy ( L,p ); // take first line of the field
+ flen = strlen(L);
+ while (!f.FileEnd()) {
+ f.ReadLine ( S,_max_buf_len );
+ lcount++;
+ p = &(S[0]);
+ if (*p==';') { // multiline field terminated
+ p++;
+ while ((*p==' ') || (*p==char(9))) p++;
+ return 0;
+ } else { // multiline field continues -- take next line
+ flen += strlen(S)+2;
+ if (flen>=llen) {
+ llen = flen + IMin(2000,llen);
+ L1 = new char[llen];
+ strcpy ( L1,L );
+ delete[] L;
+ L = L1;
+ }
+ strcat ( L,"\n" );
+ strcat ( L,S );
+ }
+ }
+
+ // end of file -- take the last line of the multiline field
+ p = &(S[strlen(S)]);
+
+ } else {
+
+ i = 0;
+ if (*p!='_') {
+ if ((*p=='\'') || (*p=='"')) {
+ c = *p;
+ // field in quotation marks
+ do {
+ p++;
+ // stop taking characters either on end of line
+ // or the quotation mark
+ while ((*p) && (*p!=c)) {
+ L[i++] = *p;
+ p++;
+ }
+ while (*p==c) {
+ // it was a quotation mark -- check that it is followed
+ // by end of line or space
+ p++;
+ if ((*p) && (*p!=' ') && (*p!=char(9))) {
+ // the quotation mark is not a field terminator and
+ // belongs to the field.
+ L[i++] = c; // take the quotation mark
+ if (*p!=c) // take the non-space character
+ L[i++] = *p; // but check for field terminator
+ }
+ }
+ // terminate the loop only on space or end of line
+ } while ((*p) && (*p!=' ') && (*p!=char(9)));
+ if (*p) p++;
+ L[i] = char(0);
+ } else {
+ // a simplest field without spaces
+ while ((*p) && (*p!=' ') && (*p!=char(9))) {
+ L[i++] = *p;
+ p++;
+ }
+ L[i] = char(0);
+ if (((L[0]=='.') || (L[0]=='?')) && (!L[1])) {
+ // "no data" tokens
+ L[1] = L[0];
+ L[0] = char(2);
+ L[2] = char(0);
+ }
+ }
+ }
+
+ }
+
+ return 0;
+
+ }
+
+ void Data::Sort() {
+ int i,k;
+ psvector cnames;
+
+ k = 0;
+ for (i=0;i<nCategories;i++)
+ if (Category[i]) {
+ if (k<i) Category[k] = Category[i];
+ k++;
+ }
+ for (i=k;i<nCategories;i++)
+ Category[i] = NULL;
+ nCategories = k;
+
+ FreeVectorMemory ( index ,0 );
+ GetVectorMemory ( cnames,nCategories,0 );
+ GetVectorMemory ( index ,nCategories,0 );
+
+ for (i=0;i<nCategories;i++) {
+ Category[i]->Sort();
+ cnames[i] = NULL;
+ CreateCopy ( cnames[i],Category[i]->name );
+ }
+
+ SortTags ( cnames,nCategories,index );
+
+ for (i=0;i<nCategories;i++)
+ if (cnames[i]) delete[] cnames[i];
+
+ if (cnames) delete[] cnames;
+
+ }
+
+ int Data::GetCategoryNo ( cpstr cname ) {
+ // Binary search for index of category cname in Category[].
+ // Return:
+ // >=0 : position of the category found
+ // <0 : the category was not found, it could be inserted before
+ // (-RC-1)th element, where RC is the return value
+ int l1,l2,l,k;
+
+ if ((!Category) || (nCategories<1)) return -1;
+
+ if (!index) Sort();
+
+ if (cname[0]) {
+ l = 0;
+ l1 = 0;
+ l2 = nCategories-1;
+ k = 1;
+ while (l1<l2-1) {
+ l = (l1+l2)/2;
+ k = strcasecmp ( cname,Category[index[l]]->name );
+ if (k<0) l2 = l;
+ else if (k>0) l1 = l;
+ else {
+ l1 = l;
+ break;
+ }
+ }
+ if (k==0) return index[l]; // is at RCth position
+ k = strcasecmp(cname,Category[index[l1]]->name);
+ if (k==0) return index[l1]; // is at RCth position
+ if (k<0) return -1; // would be at (-RC-1)th position
+ if (l2!=l1) {
+ k = strcasecmp(cname,Category[index[l2]]->name);
+ if (k==0) return index[l2]; // is at RCth position
+ if (k>0) return -2-l2; // would be at l2+1=(-RC-1)th position
+ }
+ return -2-l1; // would be at l1+1=(-RC-1)th position
+ } else
+ // 'root' category should be always on top
+ if (Category[index[0]]->name[0]==char(1)) return index[0];
+
+ return -1;
+
+ }
+
+ int Data::AddCategory ( cpstr cname ) {
+ // return -1: a place for category has been added on the top of array;
+ // index is added and sorted automatically
+ // >=0: the category is already in the array -- its position
+ // is returned
+ int l1,l;
+ PPCategory Category1;
+ ivector index1;
+
+
+ if (!Category) {
+ Category = new PCategory[1];
+ Category[0] = NULL;
+ GetVectorMemory ( index,1,0 );
+ index[0] = 0;
+ nCategories = 1;
+ return -nCategories; // the category has been added on the top of array
+ }
+ l1 = GetCategoryNo ( cname );
+ if (l1>=0) return l1; // non-negative returns mean that
+ // the category is already in the array
+ l1 = -l1-1; // otherwise the category has to be added and indexed at here
+ // put new NULL-category on the top of array and update the index
+ Category1 = new PCategory[nCategories+1];
+ GetVectorMemory ( index1,nCategories+1,0 );
+ for (l=0;l<nCategories;l++)
+ Category1[l] = Category[l];
+ Category1[nCategories] = NULL;
+ for (l=0;l<l1;l++)
+ index1[l] = index[l];
+ index1[l1] = nCategories;
+ for (l=l1+1;l<=nCategories;l++)
+ index1[l] = index[l-1];
+ delete[] Category;
+ FreeVectorMemory ( index,0 );
+ Category = Category1;
+ index = index1;
+ nCategories++;
+ return -nCategories; // the category has been added on
+ // the top of array
+ }
+
+ bool Data::WriteMMCIFData ( cpstr FName, io::GZ_MODE gzipMode ) {
+ io::File f;
+ f.assign ( FName,true,false,gzipMode );
+ if (f.rewrite()) {
+ WriteMMCIF ( f );
+ f.shut();
+ return true;
+ } else
+ return false;
+ }
+
+ void Data::WriteMMCIF ( io::RFile f ) {
+ int i;
+
+ if (name) {
+ f.Write ( pstr("\ndata_") );
+ f.WriteLine ( name );
+ } else
+ f.WriteLine ( pstr("\ndata_") );
+
+ for (i=0;i<nCategories;i++)
+ if (Category[i])
+ Category[i]->WriteMMCIF ( f );
+
+ }
+
+
+ // --------------- Retrieving data
+
+ int Data::DeleteCategory ( cpstr CName ) {
+ int k;
+ k = GetCategoryNo ( CName );
+ if (k<0) return CIFRC_NoCategory;
+ return DeleteCategory ( k );
+ }
+
+ int Data::DeleteCategory ( int CatNo ) {
+ int i;
+ if (Category[CatNo]) delete Category[CatNo];
+ for (i=CatNo+1;i<nCategories;i++)
+ Category[i-1] = Category[i];
+ i = 0;
+ while ((i<nCategories) && (index[i]!=CatNo)) {
+ if (index[i]>CatNo) index[i]--;
+ i++;
+ }
+ i++;
+ while (i<nCategories) {
+ if (index[i]>CatNo) index[i]--;
+ index[i-1] = index[i];
+ i++;
+ }
+ nCategories--;
+ index [nCategories] = 0;
+ Category[nCategories] = NULL;
+ return 0;
+ }
+
+ int Data::DeleteStructure ( cpstr CName ) {
+ int k;
+ k = GetCategoryNo ( CName );
+ if (k<0) return CIFRC_NoCategory;
+ if (Category[k]->GetCategoryID()==MMCIF_Struct)
+ return DeleteCategory ( k );
+ else return CIFRC_NotAStructure;
+ }
+
+ int Data::DeleteLoop ( cpstr CName ) {
+ int k;
+ k = GetCategoryNo ( CName );
+ if (k<0) return CIFRC_NoCategory;
+ if (Category[k]->GetCategoryID()==MMCIF_Loop)
+ return DeleteCategory ( k );
+ else return CIFRC_NotALoop;
+ }
+
+ PCategory Data::GetCategory ( int categoryNo ) {
+ if ((categoryNo>=0) && (categoryNo<nCategories))
+ return Category[categoryNo];
+ return NULL;
+ }
+
+ PStruct Data::GetStructure ( cpstr CName ) {
+ int i;
+ i = GetCategoryNo ( CName );
+ if (i<0) return NULL;
+ if (Category[i]->GetCategoryID()==MMCIF_Struct)
+ return PStruct(Category[i]);
+ else return NULL;
+ }
+
+ PLoop Data::GetLoop ( cpstr CName ) {
+ int i;
+ i = GetCategoryNo ( CName );
+ if (i<0) return NULL;
+ if (Category[i]->GetCategoryID()==MMCIF_Loop)
+ return PLoop(Category[i]);
+ else return NULL;
+ }
+
+ PLoop Data::FindLoop ( cpstr * tagList ) {
+ int i;
+ for (i=0;i<nCategories;i++)
+ if (Category[i]) {
+ if (Category[i]->GetCategoryID()==MMCIF_Loop) {
+ if (Category[i]->CheckTags(tagList))
+ return PLoop(Category[i]);
+ }
+ }
+ return NULL;
+ }
+
+ void Data::GetDataName ( pstr & dname, bool Remove ) {
+ if (Remove) {
+ if (dname) delete[] dname;
+ dname = name;
+ name = NULL;
+ } else
+ CreateCopy ( dname,name );
+ }
+
+ int Data::CheckData ( cpstr CName, cpstr TName ) {
+ // CheckData(..) returns positive value if the field is in the
+ // file:
+ // CIFRC_Structure category CName is a structure
+ // CIFRC_Loop category CName is a loop
+ // Negative returns mean:
+ // CIFRC_StructureNoTag category CName is present,
+ // it is a structure, but it does not
+ // have tag TName
+ // CIFRC_LoopNoTag category CName is present,
+ // it is a loop, but it does not have
+ // tag TName
+ // CIFRC_NoCategory category CName is not present.
+ // If TName is set to NULL then only the CName is checked and
+ // possible returns are CIFRC_Structure, CIFRC_Loop and
+ // CIFRC_NoCategory.
+ int i,k;
+ i = GetCategoryNo ( CName );
+ if (i<0) return CIFRC_NoCategory;
+ if (Category[i]->GetCategoryID()==MMCIF_Struct)
+ k = CIFRC_Structure;
+ else k = CIFRC_Loop;
+ if (TName) {
+ if (Category[i]->GetTagNo(TName)<0) {
+ if (k==CIFRC_Structure)
+ k = CIFRC_StructureNoTag;
+ else k = CIFRC_LoopNoTag;
+ }
+ }
+ return k;
+ }
+
+ void Data::Optimize() {
+ int i,k;
+ PPCategory C1;
+ k = 0;
+ for (i=0;i<nCategories;i++)
+ if (Category[i]) {
+ Category[i]->Optimize();
+ if (Category[i]->nTags<=0) {
+ delete Category[i];
+ Category[i] = NULL;
+ } else
+ k++;
+ }
+ if (k>0) {
+ if (k!=nCategories) {
+ C1 = new PCategory[k];
+ k = 0;
+ for (i=0;i<nCategories;i++)
+ if (Category[i])
+ C1[k++] = Category[i];
+ if (Category) delete[] Category;
+ Category = C1;
+ nCategories = k;
+ FreeVectorMemory ( index,0 );
+ Sort();
+ }
+ } else {
+ if (Category) delete[] Category;
+ Category = NULL;
+ nCategories = 0;
+ }
+ }
+
+ int Data::GetString ( pstr & Dest, cpstr CName,
+ cpstr TName, bool Remove ) {
+ // GetString(..), GetReal(..) and GetInteger(..) return 0 if the
+ // requested field was found and successfully converted. Negative
+ // returns mean:
+ // CIFRC_WrongFormat the field was found but failed to convert
+ // due to improper numeric format
+ // CIFRC_NoTag category CName was found, but it does not
+ // have tag TName
+ // CIFRC_NoCategory category CName was not found
+ // CIFRC_NotAStructure category CName was found, but it is a loop
+ // rather than a structure.
+ // GetString(..) will try to dispose Dest unless it is assugned
+ // NULL value before the call. The string will be then dynamically
+ // allocated and copied.
+ int i = GetCategoryNo ( CName );
+ if (i<0) return CIFRC_NoCategory;
+ if (Category[i]->GetCategoryID()!=MMCIF_Struct)
+ return CIFRC_NotAStructure;
+ return PStruct(Category[i])->GetString ( Dest,TName,Remove );
+ }
+
+ pstr Data::GetString ( cpstr CName, cpstr TName, int & RC ) {
+ int i = GetCategoryNo ( CName );
+ if (i<0) {
+ RC = CIFRC_NoCategory;
+ return NULL;
+ }
+ if (Category[i]->GetCategoryID()!=MMCIF_Struct) {
+ RC = CIFRC_NotAStructure;
+ return NULL;
+ }
+ return PStruct(Category[i])->GetString ( TName,RC );
+ }
+
+ int Data::DeleteField ( cpstr CName, cpstr TName ) {
+ int i = GetCategoryNo ( CName );
+ if (i<0) return CIFRC_NoCategory;
+ if (Category[i]->GetCategoryID()!=MMCIF_Struct)
+ return CIFRC_NotAStructure;
+ return PStruct(Category[i])->DeleteField ( TName );
+ }
+
+ int Data::GetReal ( realtype & R, cpstr CName,
+ cpstr TName, bool Remove ) {
+ int i = GetCategoryNo ( CName );
+ if (i<0) return CIFRC_NoCategory;
+ if (Category[i]->GetCategoryID()!=MMCIF_Struct)
+ return CIFRC_NotAStructure;
+ return PStruct(Category[i])->GetReal ( R,TName,Remove );
+ }
+
+ int Data::GetInteger ( int & I, cpstr CName,
+ cpstr TName, bool Remove ) {
+ int j = GetCategoryNo ( CName );
+ if (j<0) return CIFRC_NoCategory;
+ if (Category[j]->GetCategoryID()!=MMCIF_Struct)
+ return CIFRC_NotAStructure;
+ return PStruct(Category[j])->GetInteger ( I,TName,Remove );
+ }
+
+ int Data::GetLoopLength ( cpstr CName ) {
+ // GetLoopLength(..) returns CIFRC_NotALoop if the category CName
+ // is not a loop, CIFRC_NoCategory if the category CName is not
+ // found. Non-negative returns give the length of the loop (may be
+ // 0 if the loop is empty).
+ int i;
+ i = GetCategoryNo ( CName );
+ if (i<0) return CIFRC_NoCategory;
+ if (Category[i]->GetCategoryID()!=MMCIF_Loop)
+ return CIFRC_NotALoop;
+ return PLoop(Category[i])->nRows;
+ }
+
+ int Data::GetLoopString ( pstr & Dest, cpstr CName,
+ cpstr TName, int nrow,
+ bool Remove ) {
+ // GetLoopString(..), GetLoopReal(..) and GetLoopInteger(..) act
+ // like GetString(..), GetReal(..) and GetInteger(..) above for
+ // nrow-th element of the 'loop_' (indexed like 0..N-1 where N
+ // is obtained through GetLoopLength(..)). They will return
+ // CIFRC_WrongIndex if nrow is out of range.
+ int i = GetCategoryNo ( CName );
+ if (i<0) return CIFRC_NoCategory;
+ if (Category[i]->GetCategoryID()!=MMCIF_Loop)
+ return CIFRC_NotALoop;
+ return PLoop(Category[i])->GetString ( Dest,TName,nrow,Remove );
+ }
+
+ pstr Data::GetLoopString ( cpstr CName, cpstr TName,
+ int nrow, int & RC ) {
+ int i = GetCategoryNo ( CName );
+ if (i<0) {
+ RC = CIFRC_NoCategory;
+ return NULL;
+ }
+ if (Category[i]->GetCategoryID()!=MMCIF_Loop) {
+ RC = CIFRC_NotALoop;
+ return NULL;
+ }
+ return PLoop(Category[i])->GetString ( TName,nrow,RC );
+ }
+
+ int Data::DeleteLoopField ( cpstr CName, cpstr TName,
+ int nrow ) {
+ int i = GetCategoryNo ( CName );
+ if (i<0) return CIFRC_NoCategory;
+ if (Category[i]->GetCategoryID()!=MMCIF_Loop)
+ return CIFRC_NotALoop;
+ return PLoop(Category[i])->DeleteField ( TName,nrow );
+ }
+
+ int Data::GetLoopReal ( realtype & R, cpstr CName,
+ cpstr TName, int nrow,
+ bool Remove ) {
+ int i = GetCategoryNo ( CName );
+ if (i<0) return CIFRC_NoCategory;
+ if (Category[i]->GetCategoryID()!=MMCIF_Loop)
+ return CIFRC_NotALoop;
+ return PLoop(Category[i])->GetReal ( R,TName,nrow,Remove );
+ }
+
+ int Data::GetLoopInteger ( int & I, cpstr CName,
+ cpstr TName, int nrow,
+ bool Remove ) {
+ int j = GetCategoryNo ( CName );
+ if (j<0) return CIFRC_NoCategory;
+ if (Category[j]->GetCategoryID()!=MMCIF_Loop)
+ return CIFRC_NotALoop;
+ return PLoop(Category[j])->GetInteger ( I,TName,nrow,Remove );
+ }
+
+
+ int Data::GetLoopSVector ( psvector & S, cpstr CName,
+ cpstr TName, int i1, int i2,
+ bool Remove ) {
+ // GetLoopSVector(..), GetLoopRVector(..) and GetLoopIVector(..)
+ // read CIF 'loop_' data into allocated vectors of strings, reals and
+ // integers, correspondingly. The vectors may be deallocated prior
+ // to call and assigned NULL, in which case they will be allocated
+ // with offsets of i1, which is also the lower index of the 'loop_'
+ // data transferred into it. The upper vector index is given by i2 or
+ // by the loop's length whichever is less. If vectors are not assigned
+ // NULL prior the call, it is assumed that they are properly (i1-offset,
+ // i2-i1+1 length) allocated.
+ // The return codes are same as those of GetLoopString(..),
+ // GetLoopReal(..) and GetLoopInteger(..).
+ int i;
+ i = GetCategoryNo ( CName );
+ if (i<0) return CIFRC_NoCategory;
+ if (Category[i]->GetCategoryID()!=MMCIF_Loop)
+ return CIFRC_NotALoop;
+ return PLoop(Category[i])->GetSVector ( S,TName,i1,i2,Remove );
+ }
+
+ int Data::GetLoopRVector ( rvector & R, cpstr CName,
+ cpstr TName, int i1, int i2,
+ bool Remove ) {
+ int i;
+ i = GetCategoryNo ( CName );
+ if (i<0) return CIFRC_NoCategory;
+ if (Category[i]->GetCategoryID()!=MMCIF_Loop)
+ return CIFRC_NotALoop;
+ return PLoop(Category[i])->GetRVector ( R,TName,i1,i2,Remove );
+ }
+
+ int Data::GetLoopIVector ( ivector & I, cpstr CName,
+ cpstr TName, int i1, int i2,
+ bool Remove ) {
+ int j;
+ j = GetCategoryNo ( CName );
+ if (j<0) return CIFRC_NoCategory;
+ if (Category[j]->GetCategoryID()!=MMCIF_Loop)
+ return CIFRC_NotALoop;
+ return PLoop(Category[j])->GetIVector ( I,TName,i1,i2,Remove );
+ }
+
+
+ // --------------- Storing data
+
+ void Data::PutDataName ( cpstr dname ) {
+ // stores name for 'data_' record
+ CreateCopy ( name,dname );
+ }
+
+ int Data::PutNoData ( int NoDataType, cpstr CName, cpstr TName ) {
+ PStruct cifStruct;
+ int i,RC;
+
+ RC = CIFRC_Ok;
+
+ // look for category
+ i = AddCategory ( CName );
+ if (i<0) {
+ // negative value means that the category was not in the list,
+ // but a place for it has been provided and index updated
+ cifStruct = new Struct ( CName );
+ Category[nCategories-1] = cifStruct;
+ } else {
+ cifStruct = PStruct(Category[i]);
+ if (cifStruct->GetCategoryID()!=MMCIF_Struct) {
+ RC = CIFRC_NotAStructure;
+ delete Category[i];
+ cifStruct = new Struct ( CName );
+ Category[i] = cifStruct;
+ }
+ }
+
+ cifStruct->PutNoData ( NoDataType,TName );
+
+ return RC;
+
+ }
+
+ int Data::PutString ( cpstr S, cpstr CName,
+ cpstr TName, bool Concatenate ) {
+ // PutString(..), PutReal(..) and PutInteger(..) will put the
+ // values given into the specified category (CName) under the
+ // specified tag (TName). The category, tag and field are created
+ // automatically; the field will be replaced silently if identical
+ // CName.TName is specified in two calls. Calls of these functions
+ // may follow in random order; however CIF file will have all tags
+ // grouped by categories and catgories will follow in the order
+ // of first appearance in PutString(..), PutReal(..) or
+ // PutInteger(..).
+ // Return code - one of CIFRC_Ok or CIFRC_NotAStruct
+ PStruct cifStruct;
+ int i,RC;
+
+ RC = CIFRC_Ok;
+
+ // look for category
+ i = AddCategory ( CName );
+ if (i<0) {
+ // negative value means that the category was not in the list,
+ // but a place for it has been provided and index updated
+ cifStruct = new Struct ( CName );
+ Category[nCategories-1] = cifStruct;
+ } else {
+ cifStruct = PStruct(Category[i]);
+ if (cifStruct->GetCategoryID()!=MMCIF_Struct) {
+ RC = CIFRC_NotAStructure;
+ delete Category[i];
+ cifStruct = new Struct ( CName );
+ Category[i] = cifStruct;
+ }
+ }
+
+ cifStruct->AddField ( S,TName,Concatenate );
+
+ return RC;
+
+ }
+
+ int Data::PutDate ( cpstr CName, cpstr TName ) {
+ PStruct cifStruct;
+ int i,RC;
+
+ RC = CIFRC_Ok;
+
+ // look for category
+ i = AddCategory ( CName );
+ if (i<0) {
+ // negative value means that the category was not in the list,
+ // but a place for it has been provided and index updated
+ cifStruct = new Struct ( CName );
+ Category[nCategories-1] = cifStruct;
+ } else {
+ cifStruct = PStruct(Category[i]);
+ if (cifStruct->GetCategoryID()!=MMCIF_Struct) {
+ RC = CIFRC_NotAStructure;
+ delete Category[i];
+ cifStruct = new Struct ( CName );
+ Category[i] = cifStruct;
+ }
+ }
+
+ cifStruct->PutDate ( TName );
+
+ return RC;
+
+ }
+
+ int Data::PutReal ( realtype R, cpstr CName,
+ cpstr TName, int prec ) {
+ char rS[100];
+ sprintf ( rS,"%.*g",prec,R );
+ return PutString ( rS,CName,TName,false );
+ }
+
+ int Data::PutInteger ( int I, cpstr CName,
+ cpstr TName ) {
+ char iS[100];
+ if (I>MinInt4) sprintf ( iS,"%i",I );
+ else {
+ iS[0] = char(2);
+ iS[1] = '.';
+ iS[2] = char(0);
+ }
+ return PutString ( iS,CName,TName,false );
+ }
+
+
+ int Data::AddLoop ( cpstr CName, PLoop & cifLoop ) {
+ int i,RC;
+
+ RC = CIFRC_Ok;
+
+ // look for category
+ i = AddCategory ( CName );
+ if (i<0) {
+ // negative value means that the category was not in the list,
+ // but a place for it has been provided and index updated
+ cifLoop = new Loop ( CName );
+ Category[nCategories-1] = cifLoop;
+ RC = CIFRC_Created;
+ } else {
+ cifLoop = PLoop(Category[i]);
+ if (cifLoop->GetCategoryID()!=MMCIF_Loop) {
+ RC = CIFRC_NotALoop;
+ delete Category[i];
+ cifLoop = new Loop ( CName );
+ Category[i] = cifLoop;
+ }
+ }
+
+ return RC;
+
+ }
+
+ int Data::AddStructure ( cpstr CName, PStruct & cifStruct ) {
+ int i,RC;
+
+ RC = CIFRC_Ok;
+
+ // look for category
+ i = AddCategory ( CName );
+ if (i<0) {
+ // negative value means that the category was not in the list,
+ // but a place for it has been provided and index updated
+ cifStruct = new Struct ( CName );
+ Category[nCategories-1] = cifStruct;
+ RC = CIFRC_Created;
+ } else {
+ cifStruct = PStruct(Category[i]);
+ if (cifStruct->GetCategoryID()!=MMCIF_Struct) {
+ RC = CIFRC_NotAStructure;
+ delete Category[i];
+ cifStruct = new Struct ( CName );
+ Category[i] = cifStruct;
+ }
+ }
+
+ return RC;
+
+ }
+
+
+ int Data::PutLoopNoData ( int NoDataType, cpstr CName,
+ cpstr TName, int nrow ) {
+ PLoop cifLoop;
+ int i,RC;
+
+ RC = CIFRC_Ok;
+
+ // look for category
+ i = AddCategory ( CName );
+ if (i<0) {
+ // negative value means that the category was not in the list,
+ // but a place for it has been provided and index updated
+ cifLoop = new Loop ( CName );
+ Category[nCategories-1] = cifLoop;
+ } else {
+ cifLoop = PLoop(Category[i]);
+ if (cifLoop->GetCategoryID()!=MMCIF_Loop) {
+ RC = CIFRC_NotALoop;
+ delete Category[i];
+ cifLoop = new Loop ( CName );
+ Category[i] = cifLoop;
+ }
+ }
+
+ cifLoop->PutNoData ( NoDataType,TName,nrow );
+
+ return RC;
+
+ }
+
+
+ int Data::PutLoopString ( cpstr S, cpstr CName,
+ cpstr TName, int nrow ) {
+ // PutLoopString(..), PutLoopReal(..) and PutLoopInteger(..) act
+ // like PutString(..), PutReal(..) and PutInteger(..) above for
+ // nrow-th element of the 'loop_' CName (indexed begining from 0).
+ // In consequitive calls, given values of nrow does not have to be
+ // ordered; the most efficient way is to start with HIGHEST value
+ // for nrow in the loop and move down to 0. The least efficient way
+ // is to start with nrow=0 and move up.
+ PLoop cifLoop;
+ int i,RC;
+
+ RC = CIFRC_Ok;
+
+ // look for category
+ i = AddCategory ( CName );
+ if (i<0) {
+ // negative value means that the category was not in the list,
+ // but a place for it has been provided and index updated
+ cifLoop = new Loop ( CName );
+ Category[nCategories-1] = cifLoop;
+ } else {
+ cifLoop = PLoop(Category[i]);
+ if (cifLoop->GetCategoryID()!=MMCIF_Loop) {
+ RC = CIFRC_NotALoop;
+ delete Category[i];
+ cifLoop = new Loop ( CName );
+ Category[i] = cifLoop;
+ }
+ }
+
+ cifLoop->PutString ( S,TName,nrow );
+
+ return RC;
+
+ }
+
+ int Data::PutLoopReal ( realtype R, cpstr CName,
+ cpstr TName, int nrow, int prec ) {
+ char rS[100];
+ sprintf ( rS,"%.*g",prec,R );
+ return PutLoopString ( rS,CName,TName,nrow );
+ }
+
+ int Data::PutLoopInteger ( int I, cpstr CName,
+ cpstr TName, int nrow ) {
+ char iS[100];
+ sprintf ( iS,"%i",I );
+ return PutLoopString ( iS,CName,TName,nrow );
+ }
+
+
+ int Data::PutLoopSVector ( psvector S, cpstr CName,
+ cpstr TName, int i1, int i2 ) {
+ // PutLoopSVector(..), PutLoopRVector(..) and PutLoopIVector(..)
+ // put vectors of values into specified loop fields. Parameters i1
+ // and i2 give the range of indices of values which are to be
+ // transfered. To transfer an entire vector allocated as [0..N-1]
+ // i1 shoudl be set to 0 and i2 - to N-1. Note that the loop is
+ // always indexed as starting form 0 on, therefore negative i1 and
+ // i2 are not allowed, and specifying i1>0 will leave first i1
+ // elements of the CIF loop for the corresponding tag undefined
+ // (will be output like '?').
+ PLoop cifLoop;
+ int i,RC;
+
+ RC = CIFRC_Ok;
+
+ // look for category
+ i = AddCategory ( CName );
+ if (i<0) {
+ // negative value means that the category was not in the list,
+ // but a place for it has been provided and index updated
+ cifLoop = new Loop ( CName );
+ Category[nCategories-1] = cifLoop;
+ } else {
+ cifLoop = PLoop(Category[i]);
+ if (cifLoop->GetCategoryID()!=MMCIF_Loop) {
+ RC = CIFRC_NotALoop;
+ delete Category[i];
+ cifLoop = new Loop ( CName );
+ Category[i] = cifLoop;
+ }
+ }
+
+ cifLoop->PutSVector ( S,TName,i1,i2 );
+
+ return RC;
+
+ }
+
+ int Data::PutLoopRVector ( rvector R, cpstr CName,
+ cpstr TName,
+ int i1, int i2, int prec ) {
+ PLoop cifLoop;
+ int i,RC;
+
+ RC = CIFRC_Ok;
+
+ // look for category
+ i = AddCategory ( CName );
+ if (i<0) {
+ // negative value means that the category was not in the list,
+ // but a place for it has been provided and index updated
+ cifLoop = new Loop ( CName );
+ Category[nCategories-1] = cifLoop;
+ } else {
+ cifLoop = PLoop(Category[i]);
+ if (cifLoop->GetCategoryID()!=MMCIF_Loop) {
+ RC = CIFRC_NotALoop;
+ delete Category[i];
+ cifLoop = new Loop ( CName );
+ Category[i] = cifLoop;
+ }
+ }
+
+ cifLoop->PutRVector ( R,TName,i1,i2,prec );
+
+ return RC;
+
+ }
+
+ int Data::PutLoopIVector ( ivector I, cpstr CName,
+ cpstr TName,
+ int i1, int i2 ) {
+ PLoop cifLoop;
+ int j,RC;
+
+ RC = CIFRC_Ok;
+
+ // look for category
+ j = AddCategory ( CName );
+ if (j<0) {
+ // negative value means that the category was not in the list,
+ // but a place for it has been provided and index updated
+ cifLoop = new Loop ( CName );
+ Category[nCategories-1] = cifLoop;
+ } else {
+ cifLoop = PLoop(Category[j]);
+ if (cifLoop->GetCategoryID()!=MMCIF_Loop) {
+ RC = CIFRC_NotALoop;
+ delete Category[j];
+ cifLoop = new Loop ( CName );
+ Category[j] = cifLoop;
+ }
+ }
+
+ cifLoop->PutIVector ( I,TName,i1,i2 );
+
+ return RC;
+
+ }
+
+
+ int Data::RenameCategory ( cpstr CName,
+ cpstr newCName ) {
+ int i,RC;
+ i = GetCategoryNo ( CName );
+ if (i>=0) {
+ Category[i]->PutCategoryName ( newCName );
+ Sort();
+ RC = CIFRC_Ok;
+ } else
+ RC = CIFRC_NoCategory;
+ return RC;
+ }
+
+
+ void Data::Copy ( PData Data ) {
+ int i;
+ FreeMemory(0);
+ CreateCopy ( name,Data->name );
+ nCategories = Data->nCategories;
+ if (nCategories>0) {
+ Category = new PCategory[nCategories];
+ GetVectorMemory ( index,nCategories,0 );
+ for (i=0;i<nCategories;i++) {
+ if (Data->Category[i]) {
+ if (Data->Category[i]->GetCategoryID()==MMCIF_Struct)
+ Category[i] = new Struct();
+ else Category[i] = new Loop();
+ Category[i]->Copy ( Data->Category[i] );
+ } else
+ Category[i] = NULL;
+ index[i] = Data->index[i];
+ }
+ }
+ flags = Data->flags;
+ Warning = Data->Warning;
+ }
+
+
+ int Data::CopyCategory ( PData Data, cpstr CName,
+ cpstr newCName ) {
+ PCategory Cat;
+ int i,di,dc,RC;
+
+ di = Data->GetCategoryNo ( CName );
+
+ if (di>=0) {
+
+ RC = CIFRC_Ok;
+ dc = Data->Category[di]->GetCategoryID();
+
+ // look for category
+ i = AddCategory ( CName );
+ if (i<0) {
+ // negative value means that the category was not in the list,
+ // but a place for it has been provided and index updated
+ if (dc==MMCIF_Loop) Cat = new Loop ( CName );
+ else Cat = new Struct ( CName );
+ Category[nCategories-1] = Cat;
+ } else {
+ Cat = Category[i];
+ if (Cat->GetCategoryID()!=dc) {
+ RC = CIFRC_NotAStructure;
+ delete Category[i];
+ if (dc==MMCIF_Loop) Cat = new Loop ( CName );
+ else Cat = new Struct ( CName );
+ Category[i] = Cat;
+ }
+ }
+
+ Cat->Copy ( Data->Category[di] );
+ if (newCName) {
+ Cat->PutCategoryName ( newCName );
+ Sort();
+ }
+
+ } else
+ RC = CIFRC_NoCategory;
+
+ return RC;
+
+ }
+
+ void Data::PrintCategories() {
+ // for debuging only
+ int i;
+ printf ( " Total %i categories:\n",nCategories );
+ for (i=0;i<nCategories;i++)
+ if (Category[i]) {
+ printf ( " %5i. ",i+1 );
+ if (Category[i]->GetCategoryID()==MMCIF_Loop)
+ printf ( "Loop %s\n",Category[i]->name );
+ else printf ( "Structure %s\n",Category[i]->name );
+ }
+ }
+
+
+ void Data::write ( io::RFile f ) {
+ int i,k;
+ if (!index) Sort();
+ f.CreateWrite ( name );
+ f.WriteInt ( &nCategories );
+ for (i=0;i<nCategories;i++) {
+ if (Category[i]) {
+ k = Category[i]->GetCategoryID();
+ f.WriteInt ( &k );
+ Category[i]->write ( f );
+ } else {
+ k = -1;
+ f.WriteInt ( &k );
+ }
+ f.WriteInt ( &(index[i]) );
+ }
+ f.WriteInt ( &flags );
+ f.WriteInt ( &Warning );
+ }
+
+
+ void Data::read ( io::RFile f ) {
+ int i,k;
+ FreeMemory(0);
+ f.CreateRead ( name );
+ f.ReadInt ( &nCategories );
+ if (nCategories>0) {
+ Category = new PCategory[nCategories];
+ GetVectorMemory ( index,nCategories,0 );
+ for (i=0;i<nCategories;i++) {
+ f.ReadInt ( &k );
+ if (k>=0) {
+ if (k==MMCIF_Struct) Category[i] = new Struct();
+ else Category[i] = new Loop();
+ Category[i]->read ( f );
+ } else
+ Category[i] = NULL;
+ f.ReadInt ( &(index[i]) );
+ }
+ }
+ f.ReadInt ( &flags );
+ f.ReadInt ( &Warning );
+ }
+
+
+ MakeStreamFunctions(Data)
+
+
+
+ // ====================== File =============================
+
+
+ File::File() : io::Stream() {
+ InitFile();
+ }
+
+ File::File ( cpstr FName, io::GZ_MODE gzipMode ) : io::Stream() {
+ InitFile ();
+ ReadMMCIFFile ( FName,gzipMode );
+ }
+
+ File::File ( io::RPStream Object ) : io::Stream(Object) {
+ InitFile();
+ }
+
+ File::~File() {
+ FreeMemory();
+ }
+
+ void File::InitFile() {
+ nData = 0;
+ nAllocData = 0;
+ data = NULL;
+ index = NULL;
+ PrintWarnings = false;
+ StopOnWarning = false;
+ }
+
+ void File::FreeMemory() {
+ int i;
+ for (i=0;i<nData;i++)
+ if (data[i]) delete data[i];
+ if (data) delete[] data;
+ data = NULL;
+ FreeVectorMemory ( index,0 );
+ nData = 0;
+ nAllocData = 0;
+ }
+
+
+ pstr GetMMCIFInputBuffer ( int & LineNo ) {
+ LineNo = _err_line;
+ _err_string[sizeof(_err_string)-1] = char(0);
+ return _err_string;
+ }
+
+ int File::ReadMMCIFFile ( cpstr FName, io::GZ_MODE gzipMode ) {
+ io::File f;
+ PData CIF;
+ char S[500];
+ int RC,lcount;
+
+ FreeMemory();
+
+ CIF = NULL;
+ f.assign ( FName,true,false,gzipMode );
+ if (f.reset(true)) {
+ S[0] = char(0);
+ lcount = 0;
+ RC = 0;
+ while ((!RC) && (!f.FileEnd())) {
+ if (!CIF) CIF = new Data();
+ CIF->SetPrintWarnings ( PrintWarnings );
+ CIF->SetStopOnWarning ( StopOnWarning );
+ RC = CIF->ReadMMCIFData ( f,S,lcount );
+ if (!RC) {
+ ExpandData ( nData+1 );
+ data[nData] = CIF;
+ nData++;
+ CIF = NULL;
+ }
+ }
+ if (CIF) delete CIF;
+ f.shut();
+ if (RC==CIFRC_NoDataLine) {
+ if (nData>0) RC = 0;
+ }
+ Sort();
+ return RC;
+ } else
+ return CIFRC_CantOpenFile;
+
+ }
+
+ int File::WriteMMCIFFile ( cpstr FName, io::GZ_MODE gzipMode ) {
+ io::File f;
+ f.assign ( FName,true,false,gzipMode );
+ if (f.rewrite()) {
+ WriteMMCIF ( f );
+ f.shut();
+ return 0;
+ } else
+ return CIFRC_CantOpenFile;
+ }
+
+ void File::WriteMMCIF ( io::RFile f ) {
+ int i;
+ for (i=0;i<nData;i++)
+ if (data[i])
+ data[i]->WriteMMCIF ( f );
+ }
+
+
+ void File::Sort() {
+ psvector tag;
+ int i;
+ if (nData>0) {
+ FreeVectorMemory ( index,0 );
+ GetVectorMemory ( index,nData,0 );
+ GetVectorMemory ( tag ,nData,0 );
+ for (i=0;i<nData;i++) {
+ tag[i] = NULL;
+ CreateCopy ( tag[i],data[i]->name );
+ }
+ SortTags ( tag,nData,index );
+ for (i=0;i<nData;i++)
+ if (tag[i]) {
+ delete[] tag[i];
+ tag[i] = NULL;
+ }
+ FreeVectorMemory ( tag,0 );
+ }
+ }
+
+ int File::GetCIFDataNo ( cpstr DName ) {
+ // Binary search for index of DName ttag in data[].
+ // Return:
+ // >=0 : position of the DName found
+ // <0 : the DName was not found, it could be inserted before
+ // (-RC-1)th element, where RC is the return value
+ int l1,l2,l,k;
+
+ if (!data) return -1;
+ if (!index) Sort();
+
+ l = 0;
+ l1 = 0;
+ l2 = nData-1;
+ k = 1;
+ while (l1<l2-1) {
+ l = (l1+l2)/2;
+ k = strcasecmp ( DName,data[index[l]]->name );
+ if (k<0) l2 = l;
+ else if (k>0) l1 = l;
+ else {
+ l1 = l;
+ break;
+ }
+ }
+
+ if (k==0) return index[l]; // is at RCth position
+ k = strcasecmp ( DName,data[index[l1]]->name );
+ if (k==0) return index[l1]; // is at RCth position
+ if (k<0) return -1; // would be at (-RC-1)th position
+ if (l2!=l1) {
+ k = strcasecmp ( DName,data[index[l2]]->name );
+ if (k==0) return index[l2]; // is at RCth position
+ if (k>0) return -2-l2; // would be at l2+1=(-RC-1)th position
+ }
+
+ return -2-l1; // would be at l1+1=(-RC-1)th position
+
+ }
+
+ PData File::GetCIFData ( int dataNo ) {
+ if ((dataNo>=0) && (dataNo<nData)) return data[dataNo];
+ else return NULL;
+ }
+
+ PData File::GetCIFData ( cpstr DName ) {
+ int l;
+ l = GetCIFDataNo ( DName );
+ if (l>=0) return data[l];
+ else return NULL;
+ }
+
+ void File::ExpandData ( int nDataNew ) {
+ int i,nAD;
+ PPData data1;
+ ivector index1;
+ if (nDataNew>nAllocData) {
+ nAD = nDataNew + IMin(nAllocData/2+1,100);
+ data1 = new PData[nAD];
+ GetVectorMemory ( index1,nAD,0 );
+ for (i=0;i<nAllocData;i++) {
+ data1 [i] = data [i];
+ index1[i] = index[i];
+ }
+ for (i=nAllocData;i<nAD;i++) {
+ data1 [i] = NULL;
+ index1[i] = i;
+ }
+ if (data) delete[] data;
+ FreeVectorMemory ( index,0 );
+ data = data1;
+ index = index1;
+ nAllocData = nAD;
+ }
+ }
+
+ int File::AddCIFData ( cpstr DName ) {
+ // return -1: the CIF data structure has been added on the
+ // top of data array; the index is added and sorted
+ // automatically
+ // >=0: the CIF data structure is already in the array
+ // -- its position is returned
+ int i1,i;
+ if (!data) {
+ ExpandData ( 3 ); // get space for first 3 CIF data structures
+ data[0] = new Data ( DName );
+ nData = 1;
+ return -nData; // the CIF data structure has been added
+ // "on the top" of array
+ }
+ i1 = GetCIFDataNo ( DName );
+ if (i1>=0) return i1; // non-negative returns mean that the CIF
+ // data structure is already in the array
+ i1 = -i1-1; // otherwise the data has to be added and indexed at here
+ // put new CIF data structure on the top of array and update index
+ ExpandData ( nData+1 );
+ data[nData] = new Data ( DName );
+ for (i=nData;i>i1;i--)
+ index[i] = index[i-1];
+ index[i1] = nData;
+ nData++;
+ return -nData; // the tag has been added on the top of array
+ }
+
+
+ int File::DeleteCIFData ( cpstr DName ) {
+ int dataNo = GetCIFDataNo ( DName );
+
+ if (dataNo>=0) return DeleteCIFData ( dataNo );
+ return dataNo;
+
+ }
+
+ int File::DeleteCIFData ( int dataNo ) {
+ int i;
+
+ if ((0<=dataNo) && (dataNo<nData)) {
+
+ if (data[dataNo]) delete data[dataNo];
+ for (i=dataNo+1;i<nData;i++)
+ data[i-1] = data[i];
+ nData--;
+
+ Sort();
+
+ return 0;
+
+ }
+
+ return -nData;
+
+ }
+
+ void File::Copy ( PFile File ) {
+ int i;
+ FreeMemory();
+ nData = File->nData;
+ nAllocData = nData;
+ if (nData>0) {
+ data = new PData[nData];
+ for (i=0;i<nData;i++) {
+ if (File->data[i]) {
+ data[i] = new Data();
+ data[i]->Copy ( File->data[i] );
+ } else
+ data[i] = NULL;
+ }
+ }
+ }
+
+
+ void File::write ( io::RFile f ) {
+ int i,k;
+ f.WriteInt ( &nData );
+ for (i=0;i<nData;i++)
+ if (data[i]) {
+ k = 1;
+ f.WriteInt ( &k );
+ data[i]->write ( f );
+ } else {
+ k = 0;
+ f.WriteInt ( &k );
+ }
+ }
+
+ void File::read ( io::RFile f ) {
+ int i,k;
+ FreeMemory();
+ f.ReadInt ( &nData );
+ nAllocData = nData;
+ if (nData>0) {
+ data = new PData[nData];
+ for (i=0;i<nData;i++) {
+ f.ReadInt ( &k );
+ if (k) {
+ data[i] = new Data();
+ data[i]->read ( f );
+ } else
+ data[i] = NULL;
+ }
+ }
+ }
+
+
+ MakeStreamFunctions(File)
+
+
+ int isCIF ( cpstr FName, io::GZ_MODE gzipMode ) {
+ io::File f;
+ int rc;
+
+ f.assign ( FName,true,false,gzipMode );
+ if (f.reset(true)) {
+ rc = isCIF ( f );
+ f.shut();
+ } else
+ rc = -1;
+
+ return rc;
+
+ }
+
+ int isCIF ( io::RFile f ) {
+ char S[_max_buf_len+1];
+ bool Done;
+ pstr p;
+
+ f.ReadLine ( S,_max_buf_len );
+ S[_max_buf_len] = char(0);
+ Done = false;
+ while (!Done) {
+ p = &(S[0]);
+ while ((*p==' ') || (*p==char(9))) p++;
+ Done = !strncmp(p,"data_",5);
+ if (!Done) {
+ if (f.FileEnd()) {
+ Done = true;
+ p = NULL;
+ } else {
+ f.ReadLine ( S,_max_buf_len );
+ S[_max_buf_len] = char(0);
+ }
+ }
+ }
+
+ if (!p) return 1;
+ if (!strncmp(p,"data_",5)) return 0;
+ else return 1;
+
+ }
+
+
+ pstr GetCIFMessage ( pstr M, int RC ) {
+ int LineNo;
+ pstr InputLine;
+
+ InputLine = GetMMCIFInputBuffer ( LineNo );
+
+ if (RC>10) {
+ if (RC & CIFW_UnrecognizedItems)
+ sprintf ( M,"unrecognized items found on %ith line\n%s",
+ LineNo,InputLine );
+ else if (RC & CIFW_MissingField)
+ sprintf ( M,"expected data field not found; line %i reads\n%s",
+ LineNo,InputLine );
+ else if (RC & CIFW_EmptyLoop)
+ sprintf ( M,"empty loop ('loop_') on %ith line\n%s",
+ LineNo,InputLine );
+ else if (RC & CIFW_UnexpectedEOF)
+ sprintf ( M,"unexpected end of file; line %i reads\n%s",
+ LineNo,InputLine );
+ else if (RC & CIFW_LoopFieldMissing)
+ sprintf ( M,"expected data field in a loop not found; "
+ "line %i reads\n%s", LineNo,InputLine );
+ else if (RC & CIFW_LoopFieldMissing)
+ sprintf ( M,"expected data field in a loop not found; "
+ "line %i reads\n%s", LineNo,InputLine );
+ else if (RC & CIFW_NotAStructure)
+ sprintf ( M,"a loop is used as a structure on line %i\n%s",
+ LineNo,InputLine );
+ else if (RC & CIFW_NotALoop)
+ sprintf ( M,"a structure is used as a loop on line %i\n%s",
+ LineNo,InputLine );
+ else if (RC & CIFW_DuplicateTag)
+ sprintf ( M,"duplicate tag was found on line %i\n%s",
+ LineNo,InputLine );
+ else
+ sprintf ( M,"undocumented warning issued for line %i\n%s",
+ LineNo,InputLine );
+ } else if (RC<0)
+ switch (RC) {
+ case CIFRC_StructureNoTag : strcpy(M,"tag of a structure not "
+ "found");
+ break;
+ case CIFRC_LoopNoTag : strcpy(M,"tag of a loop not found");
+ break;
+ case CIFRC_NoCategory : strcpy(M,"category not found");
+ break;
+ case CIFRC_WrongFormat : strcpy(M,"wrong format of a number");
+ break;
+ case CIFRC_NoTag : strcpy(M,"tag not found");
+ break;
+ case CIFRC_NotAStructure : strcpy(M,"category is not a "
+ "structure");
+ break;
+ case CIFRC_NotALoop : strcpy(M,"category is not a loop");
+ break;
+ case CIFRC_WrongIndex : strcpy(M,"index outside the loop's "
+ "limits");
+ break;
+ case CIFRC_NoField : strcpy(M,"data is absent");
+ break;
+ case CIFRC_Created : strcpy(M,"category created");
+ break;
+ case CIFRC_CantOpenFile : strcpy(M,"can't open CIF file");
+ break;
+ case CIFRC_NoDataLine : strcpy(M,"'data_' tag not found." );
+ break;
+ default : strcpy(M,"undocumented return code");
+ }
+
+ return M;
+
+ }
+
+ } // namespace mmcif
+
+} // namespace mmdb
diff --git a/mmdb2/mmdb_mmcif_.h b/mmdb2/mmdb_mmcif_.h
new file mode 100644
index 0000000..388a24f
--- /dev/null
+++ b/mmdb2/mmdb_mmcif_.h
@@ -0,0 +1,2146 @@
+// $Id: mmdb_mmcif_.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_MMCIF <interface>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::mmcif::Category ( mmCIF category )
+// ~~~~~~~~~ mmdb::mmcif::Struct ( mmCIF structure )
+// mmdb::mmcif::Loop ( mmCIF loop )
+// mmdb::mmcif::Data ( mmCIF data block )
+// mmdb::mmcif::File ( mmCIF file )
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+
+#ifndef __MMDB_MMCIF__
+#define __MMDB_MMCIF__
+
+
+#include "mmdb_io_stream.h"
+
+namespace mmdb {
+
+ namespace mmcif {
+
+
+ // ====================== Category ==========================
+
+ enum MMCIF_ITEM {
+ MMCIF_Category = 0,
+ MMCIF_Struct = 1,
+ MMCIF_Loop = 2,
+ MMCIF_Data = 3
+ };
+
+ DefineClass(Category);
+ DefineStreamFunctions(Category);
+
+ /// \brief mmcif::Category is a base class for mmcif::Struct and
+ /// mmcif::Loop, implementations of mmCIF's "structure" and
+ /// "loop" categories.
+ /*!
+ This class is not instantiated independently in any applications,
+ however, it provides a few public functions which work for
+ both mmcif::Struct and mmcif::Loop.
+
+ All data in mmCIF hierarchy is addressed using construct
+ "category.tag" plus row number (>=0) for loops. Category names
+ should always start from underscore, while tags normally start
+ with a letter, e.g. "_barrel.id".
+
+ See general principles of working with mmCIF files and mmCIF
+ hierarchies in Section \"\ref mmcif_handler\".
+ */
+
+ class Category : public io::Stream {
+
+ friend class Data;
+
+ public :
+
+ /// \brief Basic constructor.
+ Category ();
+
+ /// \brief Constructor that assigns category name.
+ /// \param[in] N category name (must start with underscore).
+ Category ( cpstr N );
+
+ /// \brief Constructor for MMDB data streaming functions.
+ Category ( io::RPStream Object );
+
+ /// \brief Destructor.
+ ~Category();
+
+ /// \brief Returns category name.
+ /// \return NULL if name was not set
+ /// \return pointer to character string if name was set
+ inline pstr GetCategoryName() { return name; }
+
+ /// \brief Sets category name.
+ /// \param N new category name
+ void SetCategoryName ( cpstr N );
+
+ /// \brief Returns category type.
+ /// This function may be used when retrieving categories
+ /// (structures and loops) from data blocks (mmcif::Data).
+ /// \return MMCIF_Category for mmcif::Category
+ /// \return MMCIF_Struct for mmcif::Struct
+ /// \return MMCIF_Loop for mmcif::Loop
+ virtual MMCIF_ITEM GetCategoryID() { return MMCIF_Category; }
+
+ /// \brief Virtual function for writing category's content
+ /// into mmCIF file.
+ /// Default implementation does nothing.
+ virtual void WriteMMCIF ( io::RFile ) {}
+
+ /// \brief Virtual function for optimizig data structures.
+ /// Optimized data structures take less RAM and their indexes
+ /// are sorted for quicker access. Sorting is done automatically
+ /// as new data is added to the category. If the
+ /// category is edited (fields/data removed), it may need
+ /// optimization and re-sorting for efficiency.\n\n
+ /// The sorting preserves the order of actual appearance of
+ /// tags in mmCIF file. If a category is created
+ /// programmatically, the order of tags in mmCIF file will be
+ /// the same as order of adding them to the category.
+ virtual void Optimize();
+
+ /// \brief Sorts category's data for quicker access.
+ /// The sorting is essentially re-indexing of data for quicker
+ /// access. It does not change the order of data in both mmCIF
+ /// hierarchy and mmCIF file. E.g., if tag "serial_no" was 2nd
+ /// one in given category before sorting, it will remain on 2nd
+ /// place after it, therefore no change in tag number passed
+ /// to functions in mmcif::Struct, mmcif::Loop and mmcif::Data.
+ void Sort();
+
+ /// \brief Returns serial number of a tag in the category.
+ /// \param[in] ttag tag (or name of a field in category)
+ /// \return \b >=0 : the tag is in given position
+ /// \return \b <0 : the tag was not found, but it could be
+ /// inserted before tag with (-rc-1)th index, where
+ /// 'rc' is the return.
+ int GetTagNo ( cpstr ttag );
+
+ /// \brief Adds a tag to the category.
+ /// Adding a tag in mmcif::Category does not reserve any
+ /// placeholder for the corresponding value. All tags get
+ /// automatically sorted (reindexed) for quicker access.
+ /// Tags will appear in mmCIF file in order of their addition
+ /// to the category.
+ /// \param[in] ttag tag to be added.
+ /// \return \b >=0 the tag is already in the category, and return
+ /// is its serial number. No changes to the category
+ /// is done
+ /// \return \b <0 the tag was added to the list of tags, and
+ /// return is minus total number of tags in the
+ /// category.
+ int AddTag ( cpstr ttag );
+
+ /// \brief Returns the total number of tags in the category
+ int GetNofTags() { return nTags; }
+
+ /// \brief Returns tag with the specified serial number.
+ /// The tags are enumerated as 0..GetNofTags()-1.
+ /// \param tagNo tag's serial number
+ /// \return \b NULL: tagNo is outside the range
+ /// of 0..GetNofTags()-1
+ /// \return \b not \b NULL: tag in tagNo'th position
+ pstr GetTag ( int tagNo ); // 0..nTags-1
+
+ /// \brief Prints list of tags to stdout.
+ /// Both sorted and unsorted tags are printed to standard
+ /// output. This function may be used for debugging.
+ void PrintTags();
+
+ /// \brief Returns true if all tags from the list are found
+ /// in the category.
+ /// The size of the list of tags may be less than the number
+ /// of tags in the category, and order of tags is disregarded.
+ /// \param[in] tagList list of tags to be checked for presence
+ /// in the category. The list must end with NULL
+ /// pointer, or your program will crash.
+ /// \return \b true if all tags from the list were found in the
+ /// category
+ /// \return \b false if one or more tags from the list were not
+ /// found in the category.
+ ///
+ /// Example:
+ /// \code
+ /// cpstr tagList[] = {"id","type","date",NULL};
+ /// mmcif::Struct cifStruct;
+ /// if (cifStruct.CheckTags(tagList))
+ /// printf ( " all tags are found in category %s\n",
+ /// cifStruct.GetCategoryName() );
+ /// \endcode
+ /// This function is useful for finding categories in
+ /// "dirty cifs", where category name is not given.
+ bool CheckTags ( cpstr * tagList );
+
+ /// \brief Deep copy of categories.
+ /// Deep copy duplicates all data and memory allocations,
+ /// producing a genuine clone of the original. Only deep copy
+ /// should be used for copying MMDB objects, a mere assignment
+ /// operator will fail you.
+ /// \param[in] Category a pointer to mmcif::Category, the content of
+ /// which is copied into 'this' category.
+ virtual void Copy ( PCategory Category );
+
+ /// \brief MMDB stream writer.
+ void write ( io::RFile f );
+
+ /// \brief MMDB stream reader.
+ void read ( io::RFile f );
+
+ protected:
+ int nTags;
+ pstr name;
+ psvector tag;
+ ivector index;
+ int nAllocTags;
+
+ void InitCategory ();
+ virtual void FreeMemory ();
+ void ExpandTags ( int nTagsNew );
+ void PutCategoryName ( cpstr newName );
+
+ };
+
+
+
+ // ====================== Struct ============================
+
+ DefineClass(Struct);
+ DefineStreamFunctions(Struct);
+
+ /// \brief Constants used to specify mmCIF's \"data not given\" and
+ /// \"data not available\" data types.
+ extern const int CIF_NODATA_DOT;
+ extern const int CIF_NODATA_QUESTION;
+ extern cpstr CIF_NODATA_DOT_FIELD;
+ extern cpstr CIF_NODATA_QUESTION_FIELD;
+
+ /// \brief mmcif::Struct represents mmCIF's \"structure\" category,
+ /// where data follows directly the corresponding tag.
+ /*!
+ mmCIF's \"structure\" category has the following form:
+ \code
+ _structure_name.tag0 value0
+ _structure_name.tag1 value1
+ ...........
+ _structure_name.tagN valueN
+ \endcode
+ mmcif::Struct represents this construct by keeping category name
+ (\"_structure_name\") and associated lists of tags
+ (\"tag0,tag1...tagN\") and their values (\"value0,value1...valueN\").
+
+ The structure is created automatically when an mmCIF file is read,
+ or it may be created programatically and then pushed into file.
+
+ Access to data is provided via tags. Internally, all values are kept
+ as character fields, and it is only on the retrieval stage that they
+ are converted to other data types (integers, floats or strings).
+ If conversion is not possible, an error code is returned by the
+ corresponding functions, which should be checked by the application.
+
+ See general principles of working with mmCIF files and mmCIF
+ hierarchies, as well as some code samples, in Section
+ \"\ref mmcif_handler\".
+ */
+
+ class Struct : public Category {
+
+ public :
+
+ /// \brief Basic constructor
+ Struct ();
+
+ /// \brief Constructor that assigns structure name.
+ /// \param[in] N structure name (must start with underscore).
+ Struct ( cpstr N );
+
+ /// \brief Constructor for MMDB data streaming functions
+ Struct ( io::RPStream Object );
+
+ /// \brief Destructor
+ ~Struct();
+
+ /// \brief Adds field to the structure.
+ /// \param[in] F field value
+ /// \param[in] T tag name
+ /// \param[in] Concatenate flag to concatenate existing field
+ /// with the value of \b F. If tag \b T is already in
+ /// the structure and \b Concatenate=true, then
+ /// value of \b F is appended to the existing field.
+ /// Otherwise, the field is replaced with the value
+ /// of \b F
+ void AddField ( cpstr F, cpstr T, bool Concatenate=false );
+
+ /// \brief Returns category type \b MMCIF_Struct.
+ MMCIF_ITEM GetCategoryID() { return MMCIF_Struct; }
+
+ /// \brief Optimizes structure for RAM and data access speed.
+ /// Optimized data structures take less RAM and their indexes
+ /// are sorted for quicker access. Sorting is done automatically
+ /// as new data is added to the category. If the structure
+ /// is edited (fields/data removed), it may need
+ /// optimization and re-sorting for efficiency.\n\n
+ /// The sorting preserves the order of actual appearance of
+ /// tags in mmCIF file. If a structure is created
+ /// programmatically, the order of tags in mmCIF file will be
+ /// the same as order of adding them to the structure.
+ void Optimize();
+
+ /// \brief Returns value of field corresponding to tag in the
+ /// specified position.
+ /// Tag positions are defined by the order of their appearance in
+ /// mmCIF file (if structure was read from a file), or by the
+ /// order of their addition to the structure (if structure was
+ /// created programmatically). Tags are numbered as
+ /// 0...GetNofTags()-1.
+ /// \param[in] tagNo tag number (position in the structure)
+ /// \return \b NULL: tag does not exist
+ /// \return \b CIF_NODATA_DOT_FIELD the field contains
+ /// \"data not given\" value
+ /// \return \b CIF_NODATA_QUESTION_FIELD the field contains
+ /// \"data not available\" value
+ /// \return \b not \b NULL: string value of the field
+ pstr GetField ( int tagNo ); // 0..nTags-1
+
+ /// \brief Fetches value, corresponding to the given tag, as
+ /// a string
+ /// \param[out] S pointer to string, which will point to newly
+ /// allocated character string, containing value
+ /// associated with tag \b TName. If tag or value
+ /// is not found, or if value corresponds to
+ /// mmCIF's \"data not given\" or
+ /// \"data not available\", \b S returns NULL.
+ /// \param[in] TName character string with tag name
+ /// \param[in] Remove flag to remove the tag and its value from
+ /// structure after it is read.
+ /// \return \b CIFRC_NoTag: tag is not found
+ /// \return \b CIFRC_NoField: value is not found
+ /// \return \b CIFRC_Ok: success. If \b S returns NULL, then
+ /// the value corresponds to either
+ /// \"data not available\" or
+ /// \"data not given\".
+ /// \remarks If \b S!=NULL at time of call, the function will
+ /// try to dispose the string it points on. This allows a slick
+ /// re-use of the same pointer in consequitive calls. This also
+ /// means that one should never pass unallocated pointer to
+ /// this function. Safe use assumes the following patern:
+ /// \code
+ /// mmcif::Struct mmCIFStruct;
+ /// pstr S; // this is merely "char *S"
+ /// int rc;
+ ///
+ /// S = NULL; // null pointer before first use
+ /// rc = mmCIFStruct.GetString ( S,"id" );
+ /// if (rc) CreateCopy ( S,"*** data not found" );
+ /// if (!S) CreateCopy ( S,"*** data not given or not available" );
+ /// printf ( " rc=%i, S='%s'\n",rc,S );
+ ///
+ /// rc = mmCIFStruct.GetString ( S,"property" );
+ /// if (rc) CreateCopy ( S,"*** data not found" );
+ /// if (!S) CreateCopy ( S,"*** data not given or not available" );
+ /// printf ( " rc=%i, S='%s'\n",rc,S );
+ ///
+ /// // etc etc etc
+ ///
+ /// delete[] S; // application is responsible for final
+ /// // disposal of memory
+ /// \endcode
+ int GetString ( pstr & S, cpstr TName, bool Remove=false );
+
+ /// \brief Returns pointer to value associated with given tag.
+ /// \param[in] TName character string with tag name
+ /// \param[out] RC return code:
+ /// \arg \b CIFRC_NoTag: tag is not found
+ /// \arg \b CIFRC_NoField: value is not found
+ /// \arg \b CIFRC_Ok: success. If function returns NULL, then
+ /// the value corresponds to either
+ /// \"data not available\" or
+ /// \"data not given\".
+ /// \return \b NULL: either tag or value is not found, or the
+ /// value is \"data not available\" or \"data not given\".
+ /// Read return code \b RC in order to interpret NULL return.
+ /// \return \b not \b NULL: pointer (\c char \c *) to value
+ /// associated with \b TName.
+ /// \remarks Never try to dispose memory pointed by the return
+ /// value, or your program will crash.
+ pstr GetString ( cpstr TName, int & RC ); // NULL if TName
+ // is not there
+
+ /// \brief Deletes field associated with given tag.
+ /// \param[in] TName character string with tag name
+ /// \return \b >=0: field deleted
+ /// \return \b <0: either field or tag is not found
+ int DeleteField ( cpstr TName ); // <0 the field was not there
+
+ /// \brief Fetches value, corresponding to the given tag, as
+ /// a real number.
+ /// \param[out] R reference to real number to accept the value.
+ /// In case of failure, \b R returns zero.
+ /// \param[in] TName character string with tag name
+ /// \param[in] Remove flag to remove the tag and its value from
+ /// structure after it is read.
+ /// \return \b CIFRC_NoTag: tag is not found
+ /// \return \b CIFRC_NoField: field is not found
+ /// \return \b CIFRC_WrongFormat: value is not a real or integer
+ /// number.
+ /// \return \b CIFRC_NoData: value is either
+ /// \"data not available\" or
+ /// \"data not given\".
+ /// \return \b CIFRC_Ok: success.
+ int GetReal ( realtype & R, cpstr TName, bool Remove=false );
+
+ /// \brief Fetches value, corresponding to the given tag, as
+ /// an integer number.
+ /// \param[out] I reference to integer number to accept the
+ /// value. In case of failure, \b I returns zero, except
+ /// when value is \"data not available\" or
+ /// \"data not given\", when I returns \c MinInt4.
+ /// \param[in] TName character string with tag name
+ /// \param[in] Remove flag to remove the tag and its value from
+ /// structure after it is read.
+ /// \return \arg \b CIFRC_NoTag: tag is not found
+ /// \return \b CIFRC_NoField: field is not found
+ /// \return \b CIFRC_WrongFormat: value is not an integer number.
+ /// \return \b CIFRC_NoData: value is either
+ /// \"data not available\" or
+ /// \"data not given\".
+ /// \return \b CIFRC_Ok: success.
+ int GetInteger ( int & I, cpstr TName, bool Remove=false );
+
+ /// \brief Sets string value for given tag.
+ /// \param[in] S character string with value to be set.
+ /// If \b S==NULL, the \"data not given\" value
+ /// will be set. If \b S==\"\" (empty string), the
+ /// \"data not available\" value is stored.
+ /// \param[in] TName character string with tag name. If tag
+ /// is not found, it will be added to the structure.
+ /// \param[in] NonBlankOnly flag to treat white-space-only
+ /// strings:
+ /// \arg \b false: set as is
+ /// \arg \b true: set \"data not available\" value instead.
+ void PutString ( cpstr S, cpstr TName,
+ bool NonBlankOnly=false );
+
+ /// \brief Sets current date in format YYYY-MM-DD as a value
+ /// for given tag.
+ /// \param[in] T character string with tag name. If tag
+ /// is not found, it will be added to the structure.
+ void PutDate ( cpstr T );
+
+ /// \brief Sets \"data not given\" or \"data not available\"
+ /// values for given tag.
+ /// \param[in] NoDataType can be either
+ /// \arg \b CIF_NODATA_DOT for \"data not given\"
+ /// \arg \b CIF_NODATA_QUESTION for \"data not available\"
+ /// \param[in] T character string with tag name. If tag
+ /// is not found, it will be added to the structure.
+ void PutNoData ( int NoDataType, cpstr T );
+
+ /// \brief Sets float-point value for given tag.
+ /// \param[in] R real number with value to be set.
+ /// \param[in] TName character string with tag name. If tag
+ /// is not found, it will be added to the structure.
+ /// \param[in] prec float-point precision; g-format with given
+ /// precision will be used
+ void PutReal ( realtype R, cpstr TName, int prec=8 );
+
+ /// \brief Sets float-point value for given tag.
+ /// \param[in] R real number with value to be set.
+ /// \param[in] TName character string with tag name. If tag
+ /// is not found, it will be added to the structure.
+ /// \param[in] format format string to convert \b R.
+ void PutReal ( realtype R, cpstr TName, cpstr format );
+
+ /// \brief Sets integer value for given tag.
+ /// \param[in] I integer number with value to be set.
+ /// \param[in] TName character string with tag name. If tag
+ /// is not found, it will be added to the structure.
+ void PutInteger ( int I, cpstr TName );
+
+ /// \brief Writes structure data in mmCIF format into file.
+ /// \param[in] FName character string with file name.
+ /// \param[in] gzipMode flag to controll compression of files:
+ /// \arg \b GZM_NONE: do not compress
+ /// \arg \b GZM_CHECK: check file name suffix and compress
+ /// (or not) accordingly
+ /// \arg \b GZM_ENFORCE_GZIP: force gzip compression despite
+ /// suffix
+ /// \arg \b GZM_ENFORCE_COMPRESS: force using compress despite
+ /// suffix
+ /// \return \b true: success
+ /// \return \b false: can not open file for writing.
+ /// \remarks This function does not create a valid mmCIF file
+ /// as \"data_XXX\" record will be missing. It may be used for
+ /// debugging though.
+ bool WriteMMCIFStruct ( cpstr FName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+
+ /// \brief Writes structure into given file.
+ /// \param f reference to MMDB's file class. The file should be
+ /// opened and closed by application.
+ /// \remarks There is a very limited use of this function on
+ /// application level. It is primarily used by mmcif::Data class.
+ void WriteMMCIF ( io::RFile f );
+
+ /// \brief Deep copy of structures.
+ /// Deep copy duplicates all data and memory allocations,
+ /// producing a genuine clone of the original. Only deep copy
+ /// should be used for copying MMDB objects, a mere assignment
+ /// operator will fail you.
+ /// \param[in] Struct a pointer to mmcif::Struct, the content of
+ /// which is copied into 'this' structure.
+ void Copy ( PCategory Struct );
+
+ /// \brief MMDB stream writer.
+ void write ( io::RFile f );
+
+ /// \brief MMDB stream reader.
+ void read ( io::RFile f );
+
+ protected:
+ psvector field;
+
+ void InitStruct();
+ void FreeMemory();
+
+ };
+
+
+
+ // ====================== Loop ==============================
+
+ DefineClass(Loop);
+ DefineStreamFunctions(Loop);
+
+ /// \brief mmcif::Loop represents mmCIF's \"loop\" category, which keeps
+ /// rows of data values associated with tags.
+ /*!
+ mmCIF's \"loop\" category has the following form:
+ \code
+ loop_
+ _loop_name.tag0 value0
+ _loop_name.tag1 value1
+ ...........
+ _loop_name.tagN valueN
+ value00 value10 ... valueN0
+ value01 value11 ... valueN1
+ ...........
+ value0M value1M ... valueNM
+ \endcode
+ mmcif::Loop represents this construct by keeping category name
+ (\"_loop_name\") and associated lists of tags
+ (\"tag0,tag1...tagN\") and data vectors
+ (\"[value00...value0M],[value10...value1M]...[valueN0...valueNM]\").
+
+ The loop object is created automatically when an mmCIF file is read,
+ or it may be created programatically and then pushed into file.
+
+ Access to data is provided via tags and data indexes. Internally,
+ all values are kept as character fields, and it is only on the
+ retrieval stage that they are converted to other data types
+ (integers, floats or strings). If conversion is not possible, an
+ error code is returned by the corresponding functions, which should
+ be checked by the application.
+
+ The following code gives an example of creating mmCIF loop category
+ and populating it with data:
+ \code
+ mmcif::Loop loop;
+ char S[100];
+ int i;
+
+ // Specify loop name:
+ loop.SetCategoryName ( "_sample_loop" );
+
+ // Create loop structure, i.e., list of tags first:
+ loop.AddLoopTag ( "id" );
+ loop.AddLoopTag ( "name" );
+ loop.AddLoopTag ( "value" );
+
+ // Now populate it with data. This my be done in 2 ways.
+ // Here is how you write loop data in stream fashion,
+ // value-after-value:
+ for (i=0;i<3;i++) {
+ loop.AddInteger ( i );
+ sprintf ( S,"1st_way-%i",i );
+ loop.AddString ( S );
+ loop.AddReal ( 2.5*(i+1) );
+ }
+
+ // Here is how you populate loop data using direct-access
+ // functions:
+ for (i=3;i<6;i++) {
+ loop.PutReal ( 2.5*(i+1),"value",i );
+ loop.PutInteger ( i,"id" );
+ sprintf ( S,"2nd way: %i",i );
+ loop.PutString ( S,"name" );
+ }
+
+ loop.WriteMMCIFLoop ( "sample_loop.cif" );
+
+ \endcode
+
+ The resulting file \b sample_loop.cif will contain:
+
+ \code
+
+ loop_
+ _sample_loop.id
+ _sample_loop.name
+ _sample_loop.value
+ 0 1st_way-0 2.5
+ 1 1st_way-1 5.0
+ 2 1st_way-2 7.5
+ 3 "2nd way: 3" 10.0
+ 4 "2nd way: 4" 12.5
+ 5 "2nd way: 5" 15.0
+
+ \endcode
+
+ See general principles of working with mmCIF files and mmCIF
+ hierarchies, as well as some code samples, in Section
+ \"\ref mmcif_handler\".
+ */
+
+ class Loop : public Category {
+
+ friend class Data;
+
+ public :
+
+ /// \brief Basic constructor
+ Loop ();
+
+ /// \brief Constructor that assigns structure name.
+ /// \param[in] N structure name (must start with underscore).
+ Loop ( cpstr N );
+
+ /// \brief Constructor for MMDB data streaming functions
+ Loop ( io::RPStream Object );
+
+ /// \brief Destructor
+ ~Loop();
+
+ /// \brief Adds tag to the loop.
+ /// The tag is appended to the list of existing tags. The order
+ /// of tags cannot be changed.
+ /// \param[in] T tag name
+ /// \param[in] Remove flag to remove all fields in the loop.
+ void AddLoopTag ( cpstr T, bool Remove=true );
+
+ /// \brief Sets string value at current loop position.
+ /// When \b mmcif::Loop::Add[Data] functions use internal loop
+ /// pointer. When category is created or cleared (by using
+ /// \b mmcif::Loop::AddLoopTag ( T,true )) the pointer is set to
+ /// 0th row and 0th column (tag). After each call to
+ /// \b mmcif::Loop::Add[Data] function, internal pointer advances
+ /// to next column (tag), and wraps over to next row, 0th tag,
+ /// if list of tags is exhausted. Any remaining fields in last
+ /// row will be populated with \"data not given\" value.
+ /// \param[in] S character string with value to be set.
+ /// If \b S==NULL, the \"data not given\" value
+ /// will be set. If \b S==\"\" (empty string), the
+ /// \"data not available\" value is stored.
+ /// \param[in] NonBlankOnly flag to treat white-space-only
+ /// strings:
+ /// \arg \b false: set as is
+ /// \arg \b true: set \"data not available\" value instead.
+ void AddString ( cpstr S, bool NonBlankOnly=false );
+
+ /// \brief Sets \"data not given\" or \"data not available\" at
+ /// current loop position.
+ /// When \b mmcif::Loop::Add[Data] functions use internal loop
+ /// pointer. When category is created or cleared (by using
+ /// \b mmcif::Loop::AddLoopTag ( T,true )) the pointer is set to
+ /// 0th row and 0th column (tag). After each call to
+ /// \b mmcif::Loop::Add[Data] function, internal pointer advances
+ /// to next column (tag), and wraps over to next row, 0th tag,
+ /// if list of tags is exhausted. Any remaining fields in last
+ /// row will be populated with \"data not given\" value.
+ /// \param[in] NoDataType integer key specifying which type of
+ /// data absence should be set as a value:
+ /// \arg \b CIF_NODATA_DOT for \"data not given\"
+ /// \arg \b CIF_NODATA_QUESTION for \"data not available\"
+ void AddNoData ( int NoDataType );
+
+ /// \brief Sets float-point value at current loop position.
+ /// When \b mmcif::Loop::Add[Data] functions use internal loop
+ /// pointer. When category is created or cleared (by using
+ /// \b mmcif::Loop::AddLoopTag ( T,true )) the pointer is set to
+ /// 0th row and 0th column (tag). After each call to
+ /// \b mmcif::Loop::Add[Data] function, internal pointer advances
+ /// to next column (tag), and wraps over to next row, 0th tag,
+ /// if list of tags is exhausted. Any remaining fields in last
+ /// row will be populated with \"data not given\" value.
+ /// \param[in] R real number with value to be set.
+ /// \param[in] prec float-point precision; g-format with given
+ /// precision will be used
+ void AddReal ( realtype R, int prec=8 );
+
+ /// \brief Sets float-point value at current loop position in
+ /// given format.
+ /// When \b mmcif::Loop::Add[Data] functions use internal loop
+ /// pointer. When category is created or cleared (by using
+ /// \b mmcif::Loop::AddLoopTag ( T,true )) the pointer is set to
+ /// 0th row and 0th column (tag). After each call to
+ /// \b mmcif::Loop::Add[Data] function, internal pointer advances
+ /// to next column (tag), and wraps over to next row, 0th tag,
+ /// if list of tags is exhausted. Any remaining fields in last
+ /// row will be populated with \"data not given\" value.
+ /// \brief Sets float-point value for given tag.
+ /// \param[in] R real number with value to be set.
+ /// \param[in] format format string to convert \b R.
+ void AddReal ( realtype R, cpstr format );
+
+ /// \brief Sets integer value at current loop position in given
+ /// format.
+ /// When \b mmcif::Loop::Add[Data] functions use internal loop
+ /// pointer. When category is created or cleared (by using
+ /// \b mmcif::Loop::AddLoopTag ( T,true )) the pointer is set to
+ /// 0th row and 0th column (tag). After each call to
+ /// \b mmcif::Loop::Add[Data] function, internal pointer advances
+ /// to next column (tag), and wraps over to next row, 0th tag,
+ /// if list of tags is exhausted. Any remaining fields in last
+ /// row will be populated with \"data not given\" value.
+ /// \param[in] I integer number with value to be set.
+ void AddInteger ( int I );
+
+ /// \brief Returns current length of the loop (i.e. the number
+ /// of rows).
+ /// \return number of data rows in the loop.
+ int GetLoopLength() { return nRows; }
+
+ /// \brief Returns string pointer on the field corresponding to
+ /// tag in the specified position, in the specified row.
+ /// Tag positions are defined by the order of their appearance in
+ /// mmCIF file (if loop was read from a file), or by the
+ /// order of their addition to the loop (if loop was
+ /// created programmatically).
+ /// \param[in] rowNo row number (0...GetLoopLength()-1)
+ /// \param[in] tagNo tag number (0...GetNofTags()-1)
+ /// \return \b NULL: tag or row do not exist
+ /// \return \b CIF_NODATA_DOT_FIELD the field contains
+ /// \"data not given\" value
+ /// \return \b CIF_NODATA_QUESTION_FIELD the field contains
+ /// \"data not available\" value
+ /// \return \b not \b NULL: string value of the field
+ /// \remarks Never try to dispose memory pointed by the return
+ /// value, or your program will crash.
+ pstr GetField ( int rowNo, int tagNo );
+
+ /// \brief Fetches value, corresponding to the given tag, in
+ /// the given row, as a string
+ /// \param[out] S pointer to string, which will point to newly
+ /// allocated character string, containing value
+ /// associated with tag \b TName and row \b nrow.
+ /// If tag, row or value
+ /// is not found, or if value corresponds to
+ /// mmCIF's \"data not given\" or
+ /// \"data not available\", \b S returns NULL.
+ /// \param[in] TName character string with tag name
+ /// \param[in] nrow row number (0...GetLoopLength()-1)
+ /// \param[in] Remove flag to remove the field from
+ /// structure after it is read.
+ /// \return \b CIFRC_NoTag: tag is not found
+ /// \return \b CIFRC_WrongIndex: row is not found
+ /// \return \b CIFRC_NoField: value is not found
+ /// \return \b CIFRC_Ok: success. If \b S returns NULL, then
+ /// the value corresponds to either
+ /// \"data not available\" or
+ /// \"data not given\".
+ /// \remarks If \b S!=NULL at time of call, the function will
+ /// try to dispose the string it points on. This allows a slick
+ /// re-use of the same pointer in consequitive calls. This also
+ /// means that one should never pass unallocated pointer to
+ /// this function. Safe use assumes the following patern:
+ /// \code
+ /// mmcif::Loop mmCIFLoop;
+ /// pstr S; // this is merely "char *S"
+ /// int rc;
+ ///
+ /// S = NULL; // null pointer before first use
+ /// rc = mmCIFLoop.GetString ( S,"id",1 );
+ /// if (rc) CreateCopy ( S,"*** data not found" );
+ /// if (!S) CreateCopy ( S,"*** data not given or not available" );
+ /// printf ( " rc=%i, S='%s'\n",rc,S );
+ ///
+ /// rc = mmCIFLoop.GetString ( S,"property",0 );
+ /// if (rc) CreateCopy ( S,"*** data not found" );
+ /// if (!S) CreateCopy ( S,"*** data not given or not available" );
+ /// printf ( " rc=%i, S='%s'\n",rc,S );
+ ///
+ /// // etc etc etc
+ ///
+ /// delete[] S; // application is responsible for final
+ /// // disposal of memory
+ /// \endcode
+ int GetString ( pstr & S, cpstr TName, int nrow,
+ bool Remove=false );
+
+ /// \brief Returns pointer to value associated with given tag,
+ /// in the given row of the loop.
+ /// \param[in] TName character string with tag name
+ /// \param[in] nrow row number (0...GetLoopLength()-1)
+ /// \param[out] RC return code:
+ /// \arg \b CIFRC_NoTag: tag is not found
+ /// \arg \b CIFRC_WrongIndex: row is not found
+ /// \arg \b CIFRC_NoField: value is not found
+ /// \arg \b CIFRC_Ok: success. If function returns NULL, then
+ /// the value corresponds to either
+ /// \"data not available\" or
+ /// \"data not given\".
+ /// \return \b NULL: either tag, row or value is not found, or the
+ /// value is \"data not available\" or \"data not given\".
+ /// Read return code \b RC in order to interpret NULL return.
+ /// \return \b not \b NULL: pointer (\c char \c *) to value
+ /// associated with \b TName.
+ /// \remarks Never try to dispose memory pointed by the return
+ /// value, or your program will crash.
+ pstr GetString ( cpstr TName, int nrow, int & RC );
+
+ /// \brief Copies value, associated with given tag,
+ /// in the given row, into specified buffer.
+ /// Terminating NULL character is appended.
+ /// \param[out] buf character string to accept the value
+ /// \param[in] maxlength maximum number of bytes to copy
+ /// \param[in] TName character string with tag name
+ /// \param[in] nrow row number (0...GetLoopLength()-1)
+ /// \param[out] RC return code:
+ /// \arg \b CIFRC_NoTag: tag is not found
+ /// \arg \b CIFRC_WrongIndex: row is not found
+ /// \arg \b CIFRC_NoField: value is not found
+ /// \arg \b CIFRC_Ok: success.
+ /// \remarks Destination string \b buf is not modified if
+ /// \b RC!=CIFRC_Ok .
+ void CopyString ( pstr buf, int maxlength,
+ cpstr TName, int nrow, int & RC );
+
+ /// \brief Deletes field associated with given tag in
+ /// the given row.
+ /// \param[in] TName character string with tag name
+ /// \param[in] nrow row number (0...GetLoopLength()-1)
+ /// \return \b >=0: field deleted
+ /// \return \b <0: either field or tag is not found
+ int DeleteField ( cpstr TName, int nrow );
+
+ /// \brief Deletes all fields in given row.
+ /// \param[in] nrow row number (0...GetLoopLength()-1)
+ /// \return \b CIFRC_Ok: fields deleted
+ /// \return \b CIFRC_WrongIndex: row not found
+ /// \remarks Note that this function delets just the fields, but
+ /// not the row. If you wish the row to be deleted, call
+ /// mmcif::Loop::Optimize() function after this one.
+ int DeleteRow ( int nrow );
+
+ /// \brief Fetches value, corresponding to the given tag,
+ /// in the given row, as a real number.
+ /// \param[out] R reference to real number to accept the value.
+ /// In case of failure, \b R returns zero.
+ /// \param[in] TName character string with tag name
+ /// \param[in] nrow row number (0...GetLoopLength()-1)
+ /// \param[in] Remove flag to remove the field from
+ /// the loop after it is read.
+ /// \return \b CIFRC_NoTag: tag is not found
+ /// \return \b CIFRC_WrongIndex: row not found
+ /// \return \b CIFRC_NoField: field is not found
+ /// \return \b CIFRC_WrongFormat: value is not a real or integer
+ /// number.
+ /// \return \b CIFRC_NoData: value is either
+ /// \"data not available\" or
+ /// \"data not given\".
+ /// \return \b CIFRC_Ok: success.
+ int GetReal ( realtype & R, cpstr TName, int nrow,
+ bool Remove=false );
+
+ /// \brief Copies value, associated with given tag,
+ /// in the given row, into specified destination as
+ /// a real number.
+ /// \param[out] R reference to real number to accept the value
+ /// \param[in] TName character string with tag name
+ /// \param[in] nrow row number (0...GetLoopLength()-1)
+ /// \param[out] RC return code:
+ /// \arg \b CIFRC_NoTag: tag is not found
+ /// \arg \b CIFRC_WrongIndex: row is not found
+ /// \arg \b CIFRC_NoField: value is not found
+ /// \arg \b CIFRC_Ok: success.
+ /// \remarks Destination \b R is set 0 if \b RC!=CIFRC_Ok.
+ void CopyReal ( realtype & R, cpstr TName, int nrow, int & RC );
+
+ /// \brief Copies value, associated with given tag,
+ /// in the given row, into specified destination as
+ /// an integer number.
+ /// \param[out] I reference to integer number to accept the value
+ /// \param[in] TName character string with tag name
+ /// \param[in] nrow row number (0...GetLoopLength()-1)
+ /// \param[out] RC return code:
+ /// \arg \b CIFRC_NoTag: tag is not found
+ /// \arg \b CIFRC_WrongIndex: row is not found
+ /// \arg \b CIFRC_NoField: value is not found
+ /// \arg \b CIFRC_Ok: success.
+ /// \remarks Destination \b I is set 0 if \b RC!=CIFRC_Ok.
+ void CopyInteger ( int & I, cpstr TName, int nrow, int & RC );
+
+ /// \brief Fetches value, corresponding to the given tag,
+ /// in the given row, as an integer number.
+ /// \param[out] I reference to integer number to accept the value.
+ /// In case of failure, \b R returns zero.
+ /// \param[in] TName character string with tag name
+ /// \param[in] nrow row number (0...GetLoopLength()-1)
+ /// \param[in] Remove flag to remove the field from
+ /// the loop after it is read.
+ /// \return \b CIFRC_NoTag: tag is not found
+ /// \return \b CIFRC_WrongIndex: row not found
+ /// \return \b CIFRC_NoField: field is not found
+ /// \return \b CIFRC_WrongFormat: value is not a real or integer
+ /// number.
+ /// \return \b CIFRC_NoData: value is either
+ /// \"data not available\" or
+ /// \"data not given\".
+ /// \return \b CIFRC_Ok: success.
+ int GetInteger ( int & I, cpstr TName, int nrow,
+ bool Remove=false );
+
+ /// \brief Fetches set of values, corresponding to the given
+ /// tag, in the given range of rows, as a vector of
+ /// strings.
+ /// \param[out] S reference to string vector to accept
+ /// the values. if \b S==NULL , the vector will be
+ /// allocated with starting index of \b i1.
+ /// \param[in] TName character string with tag name
+ /// \param[in] i1 minimum row number to fetch, the actual
+ /// index will be calculated as \b max(0,min(i1,i2))
+ /// \param[in] i2 maximum row number to fetch, the actual
+ /// index will be calculated as
+ /// \b min(GetLoopLength()-1,max(i1,i2))
+ /// \param[in] Remove flag to remove fetched fields from
+ /// the loop after they are read.
+ /// \return \b CIFRC_NoTag: tag is not found
+ /// \return \b CIFRC_WrongIndex: invalid range of rows
+ /// \return \b CIFRC_Ok: success.
+ ///
+ /// For safe use, \b S should be pre-allocated by calling
+ /// process. Only elements \b S[i1] to \b S[i2] will contain
+ /// fetched data, others remain untouched. The calling
+ /// process is responsible for the disposal of \b S. Example:
+ /// \code
+ /// mmcif::Loop loop;
+ /// psvector S; // equivalent to char **S
+ /// int i,i1,i2,rc,n;
+ ///
+ /// // ... get loop data
+ ///
+ /// n = loop.GetLoopLength();
+ /// i1 = 5; i2 = n - 5; // could be wrong!
+ ///
+ /// // allocate vector of strings
+ /// GetVectorMemory ( S,n,0 ); // "0" for starting index
+ /// for (i=0;i<n;i++)
+ /// S[i] = NULL; // initialize NULL string pointers
+ ///
+ /// loop.GetSVector ( S,"name",i1,i2 );
+ /// printf ( " Fetched with return code rc=%i\n",rc );
+ /// // you may want a more thorough treatment of
+ /// // the return code here
+ /// for (i=i1;i<=i2;i++)
+ /// if (S[i]) printf ( " %4i. name='%s'\n",i,S[i] );
+ /// else printf ( " %4i. name is not available\n",i );
+ ///
+ /// // S[] may be re-used for as many fetches as necessary
+ /// // without cleaning or disposals
+ ///
+ /// // dispose of vector of strings
+ /// for (i=0;i<n;i++)
+ /// if (S[i]) delete[] S[i];
+ /// FreeVectorMemory ( S,0 ); // "0" for starting index
+ ///
+ /// \endcode
+ int GetSVector ( psvector & S, cpstr TName,
+ int i1=0, int i2=MaxInt4,
+ bool Remove=false );
+
+ /// \brief Fetches set of values, corresponding to the given
+ /// tag, in the given range of rows, as a vector of
+ /// float-point numbers.
+ /// \param[out] R reference to float-point vector to accept
+ /// the values. if \b R==NULL , the vector will be
+ /// allocated with starting index of \b i1.
+ /// \param[in] TName character string with tag name
+ /// \param[in] i1 minimum row number to fetch, the actual
+ /// index will be calculated as \b max(0,min(i1,i2))
+ /// \param[in] i2 maximum row number to fetch, the actual
+ /// index will be calculated as
+ /// \b min(GetLoopLength()-1,max(i1,i2))
+ /// \param[in] Remove flag to remove fetched fields from
+ /// the loop after they are read.
+ /// \return \b CIFRC_NoTag: tag is not found
+ /// \return \b CIFRC_WrongIndex: invalid range of rows
+ /// \return \b CIFRC_Ok: success.
+ ///
+ /// For safe use, \b R should be pre-allocated by calling
+ /// process. Only elements \b R[i1] to \b R[i2] will contain
+ /// fetched data, others remain untouched. The calling
+ /// process is responsible for the disposal of \b R. Example:
+ /// \code
+ /// mmcif::Loop loop;
+ /// rvector R; // equivalent to realtype *R
+ /// int i,i1,i2,rc,n;
+ ///
+ /// // ... get loop data
+ ///
+ /// n = loop.GetLoopLength();
+ /// i1 = 5; i2 = n - 5; // could be wrong!
+ ///
+ /// // allocate a vector of real numbers
+ /// GetVectorMemory ( R,n,0 ); // "0" for starting index
+ /// // no need to initiaize unless required for the
+ /// // application
+ ///
+ /// rc = loop.GetRVector ( R,"value",i1,i2 );
+ /// printf ( " Fetched with return code rc=%i\n",rc );
+ /// // you may want a more thorough treatment of
+ /// // the return code here
+ /// for (i=i1;i<=i2;i++)
+ /// printf ( " value[%4i] = %15.7g\n",i,R[i] );
+ ///
+ /// // R[] may be re-used for as many fetches as necessary
+ /// // without cleaning or disposals
+ ///
+ /// // dispose of the vector
+ /// FreeVectorMemory ( R,0 ); // "0" for starting index
+ ///
+ /// \endcode
+ int GetRVector ( rvector & R, cpstr TName,
+ int i1=0, int i2=MaxInt4,
+ bool Remove=false );
+
+ /// \brief Fetches set of values, corresponding to the given
+ /// tag, in the given range of rows, as a vector of
+ /// integer numbers.
+ /// \param[out] I reference to float-point vector to accept
+ /// the values. if \b I==NULL , the vector will be
+ /// allocated with starting index of \b i1.
+ /// \param[in] TName character string with tag name
+ /// \param[in] i1 minimum row number to fetch, the actual
+ /// index will be calculated as \b max(0,min(i1,i2))
+ /// \param[in] i2 maximum row number to fetch, the actual
+ /// index will be calculated as
+ /// \b min(GetLoopLength()-1,max(i1,i2))
+ /// \param[in] Remove flag to remove fetched fields from
+ /// the loop after they are read.
+ /// \return \b CIFRC_NoTag: tag is not found
+ /// \return \b CIFRC_WrongIndex: invalid range of rows
+ /// \return \b CIFRC_Ok: success.
+ ///
+ /// For safe use, \b I should be pre-allocated by calling
+ /// process. Only elements \b I[i1] to \b I[i2] will contain
+ /// fetched data, others remain untouched. The calling
+ /// process is responsible for the disposal of \b I.
+ /// See example in mmcif::Loop::GetRVector documentation
+ /// for details.
+ int GetIVector ( ivector & I, cpstr TName,
+ int i1=0, int i2=MaxInt4,
+ bool Remove=false );
+
+ /// \brief Sets string value for given tag and row.
+ /// \param[in] S character string with value to be set.
+ /// If \b S==NULL, the \"data not given\" value
+ /// will be set. If \b S==\"\" (empty string), the
+ /// \"data not available\" value is stored.
+ /// \param[in] T character string with tag name. If tag
+ /// is not found, it will be added, and all data in
+ /// the loop will be reindexed accordingly.
+ /// \param[in] nrow row number. If the row does not exist then
+ /// it will be created, along with all other rows
+ /// between GetLoopLength()-1 and \b nrow as
+ /// necessary. All newly created fields will be
+ /// initialised with \"data not given\" value.
+ void PutString ( cpstr S, cpstr T, int nrow );
+
+ /// \brief Sets \"data not given\" or \"data not available\"
+ /// values for given tag and row.
+ /// \param[in] NoDataType can be either
+ /// \arg \b CIF_NODATA_DOT for \"data not given\"
+ /// \arg \b CIF_NODATA_QUESTION for \"data not available\"
+ /// \param[in] T character string with tag name. If tag
+ /// is not found, it will be added, and all data in
+ /// the loop will be reindexed accordingly.
+ /// \param[in] nrow row number. If the row does not exist then
+ /// it will be created, along with all other rows
+ /// between GetLoopLength()-1 and \b nrow as
+ /// necessary. All newly created fields will be
+ /// initialised with \"data not given\" value.
+ void PutNoData ( int NoDataType, cpstr T, int nrow );
+
+ /// \brief Sets float-point value for given tag and row.
+ /// \param[in] R real number with value to be set.
+ /// \param[in] T character string with tag name. If tag
+ /// is not found, it will be added, and all data in
+ /// the loop will be reindexed accordingly.
+ /// \param[in] nrow row number. If the row does not exist then
+ /// it will be created, along with all other rows
+ /// between GetLoopLength()-1 and \b nrow as
+ /// necessary. All newly created fields will be
+ /// initialised with \"data not given\" value.
+ /// \param[in] prec float-point precision; g-format with given
+ /// precision will be used
+ void PutReal ( realtype R, cpstr T, int nrow, int prec=8 );
+
+ /// \brief Sets float-point value for given tag and row.
+ /// \param[in] R real number with value to be set.
+ /// \param[in] T character string with tag name. If tag
+ /// is not found, it will be added, and all data in
+ /// the loop will be reindexed accordingly.
+ /// \param[in] nrow row number. If the row does not exist then
+ /// it will be created, along with all other rows
+ /// between GetLoopLength()-1 and \b nrow as
+ /// necessary. All newly created fields will be
+ /// initialised with \"data not given\" value.
+ /// \param[in] format format string to convert \b R.
+ void PutReal ( realtype R, cpstr T, int nrow, cpstr format );
+
+ /// \brief Sets integer value for given tag.
+ /// \param[in] I integer number with value to be set.
+ /// \param[in] T character string with tag name. If tag
+ /// is not found, it will be added, and all data in
+ /// the loop will be reindexed accordingly.
+ /// \param[in] nrow row number. If the row does not exist then
+ /// it will be created, along with all other rows
+ /// between GetLoopLength()-1 and \b nrow as
+ /// necessary. All newly created fields will be
+ /// initialised with \"data not given\" value.
+ void PutInteger ( int I, cpstr T, int nrow );
+
+ /// \brief Sets a set of string values for the given tag and
+ /// range of rows.
+ /// \param[in] S string vector with values to store in the loop
+ /// \param[in] T character string with tag name. If tag
+ /// is not found, it will be added, and all data in
+ /// the loop will be reindexed accordingly.
+ /// \param[in] i1 minimum data index in \b S to set in the loop
+ /// \param[in] i2 maximum data index in \b S to set in the loop.
+ ///
+ /// The data will be set in rows \b i1 to \b i2 (inclusive) in
+ /// the loop. If range \b [i1,i2] is not contained in the loop,
+ /// all missing rows will be created and initialised to
+ /// \"data not given\" value. Example:
+ /// \code
+ /// mmcif::Loop loop("_sample_loop");
+ /// pstr S[100];
+ /// int i;
+ ///
+ /// // initialize vector of strings
+ /// for (i=0;i<100;i++) {
+ /// S[i] = new char[20];
+ /// sprintf ( S[i],"value i=%i",i );
+ /// }
+ ///
+ /// // put data in loop
+ /// loop.PutSVector ( S,"made_up_string_value",0,99 );
+ ///
+ /// // dispose of vector of strings
+ /// for (i=0;i<100;i++)
+ /// if (S[i]) delete[] S[i];
+ ///
+ /// \endcode
+ void PutSVector ( psvector S, cpstr T, int i1, int i2 );
+
+ /// \brief Sets a set of float-point values for the given tag and
+ /// range of rows.
+ /// \param[in] R vector of real numbers to store in the loop
+ /// \param[in] T character string with tag name. If tag
+ /// is not found, it will be added, and all data in
+ /// the loop will be reindexed accordingly.
+ /// \param[in] i1 minimum data index in \b S to set in the loop
+ /// \param[in] i2 maximum data index in \b S to set in the loop
+ /// \param[in] prec float-point precision; g-format with given
+ /// precision will be used.
+ ///
+ /// The data will be set in rows \b i1 to \b i2 (inclusive) in
+ /// the loop. If range \b [i1,i2] is not contained in the loop,
+ /// all missing rows will be created and initialised to
+ /// \"data not given\" value.
+ void PutRVector ( rvector R, cpstr T, int i1, int i2,
+ int prec=8 );
+
+ /// \brief Sets a set of integer values for the given tag and
+ /// range of rows.
+ /// \param[in] I vector of integers to store in the loop
+ /// \param[in] T character string with tag name. If tag
+ /// is not found, it will be added, and all data in
+ /// the loop will be reindexed accordingly.
+ /// \param[in] i1 minimum data index in \b S to set in the loop
+ /// \param[in] i2 maximum data index in \b S to set in the loop.
+ ///
+ /// The data will be set in rows \b i1 to \b i2 (inclusive) in
+ /// the loop. If range \b [i1,i2] is not contained in the loop,
+ /// all missing rows will be created and initialised to
+ /// \"data not given\" value.
+ void PutIVector ( ivector I, cpstr T, int i1, int i2 );
+
+ /// \brief Returns category type \b MMCIF_Loop.
+ MMCIF_ITEM GetCategoryID() { return MMCIF_Loop; }
+
+ /// \brief Optimizes loop for RAM and data access speed.
+ /// Optimized data structures take less RAM and their indexes
+ /// are sorted for quicker access. Sorting is done automatically
+ /// as new data is added to the category. If the structure
+ /// is edited (fields/data removed), it may need
+ /// optimization and re-sorting for efficiency.\n\n
+ /// The sorting preserves the order of actual appearance of
+ /// tags and rows in mmCIF file. If a loop is created
+ /// programmatically, the order of tags and rows in mmCIF file
+ /// will be the same as order of adding them to the loop.
+ void Optimize();
+
+ /// \brief Writes loop data in mmCIF format into file.
+ /// \param[in] FName character string with file name.
+ /// \param[in] gzipMode flag to controll compression of files:
+ /// \arg \b GZM_NONE: do not compress
+ /// \arg \b GZM_CHECK: check file name suffix and compress
+ /// (or not) accordingly
+ /// \arg \b GZM_ENFORCE_GZIP: force gzip compression despite
+ /// suffix
+ /// \arg \b GZM_ENFORCE_COMPRESS: force using compress despite
+ /// suffix
+ /// \return \b true: success
+ /// \return \b false: can not open file for writing.
+ /// \remarks This function does not create a valid mmCIF file
+ /// as \"data_XXX\" record will be missing. It may be used for
+ /// debugging though.
+ bool WriteMMCIFLoop ( cpstr FName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+
+ /// \brief Writes loop data into given file.
+ /// \param f reference to MMDB's file class. The file should be
+ /// opened and closed by application.
+ /// \remarks There is a very limited use of this function on
+ /// application level. It is primarily used by mmcif::Data class.
+ void WriteMMCIF ( io::RFile f );
+
+ /// \brief Deep copy of loops.
+ /// Deep copy duplicates all data and memory allocations,
+ /// producing a genuine clone of the original. Only deep copy
+ /// should be used for copying MMDB objects, a mere assignment
+ /// operator will fail you.
+ /// \param[in] Loop a pointer to mmcif::Loop, the content of
+ /// which is copied into 'this' loop.
+ void Copy ( PCategory Loop );
+
+ /// \brief MMDB stream writer.
+ void write ( io::RFile f );
+
+ /// \brief MMDB stream reader.
+ void read ( io::RFile f );
+
+ protected:
+ int nRows;
+ psmatrix field;
+ int iColumn,nAllocRows;
+
+ void InitLoop ();
+ void FreeMemory ();
+ void DeleteFields ();
+ void ExpandRows ( int nRowsNew );
+
+ };
+
+
+
+ // ====================== Data =============================
+
+
+ // CIFW are warnings which may be issued on reading the CIF file.
+ // Each of them means actually a CIF syntax error.
+
+ enum CIF_WARNING {
+ CIFW_UnrecognizedItems = 0x00000020,
+ CIFW_MissingField = 0x00000040,
+ CIFW_EmptyLoop = 0x00000080,
+ CIFW_UnexpectedEOF = 0x00000100,
+ CIFW_LoopFieldMissing = 0x00000200,
+ CIFW_NotAStructure = 0x00000400,
+ CIFW_NotALoop = 0x00000800,
+ CIFW_DuplicateTag = 0x00001000
+ };
+
+ // CIFRC are return codes from procedures of extracting data from
+ // the read CIF file. Negative returns reflect unsuccessful and
+ // not accomplished operation.
+ enum CIF_RC {
+ CIFRC_Loop = 2,
+ CIFRC_Structure = 1,
+ CIFRC_Ok = 0,
+ CIFRC_StructureNoTag = -1,
+ CIFRC_LoopNoTag = -2,
+ CIFRC_NoCategory = -3,
+ CIFRC_WrongFormat = -4,
+ CIFRC_NoTag = -5,
+ CIFRC_NotAStructure = -6,
+ CIFRC_NotALoop = -7,
+ CIFRC_WrongIndex = -8,
+ CIFRC_NoField = -9,
+ CIFRC_Created = -12,
+ CIFRC_CantOpenFile = -13,
+ CIFRC_NoDataLine = -14,
+ CIFRC_NoData = -15
+ };
+
+ //
+ // Functional flags:
+ // ~~~~~~~~~~~~~~~~~
+ //
+ // CIFFL_PrintWarnings when reading CIF file, all warning
+ // messages will be printed. If the flag
+ // is off, the warnings will be bit-encoded
+ // in the return code
+ // CIFFL_StopOnWarnings reading CIF file will stop at first
+ // warning issued
+ // CIFFL_SuggestCategories allows reading CIF file with loops having
+ // no categories. Hidden category names
+ // will be automatically generated for
+ // internal consistency of the system.
+ // These names will not appear in output.
+ // As these names are hidden, they cannot
+ // be used to access data. It is therefore
+ // assumed that all tags in all loops without
+ // categories are unique. Simply specify ""
+ // for category when accessing such data
+ // (it cannot be accessed through mmcif::Loop,
+ // but only through mmcif::Data functions
+ // taking both Category and Tag; note that
+ // CIFFL_SuggestCategories flag must be on
+ // while accessing such data).
+ // CIFFL_SuggestTags allows for identical tags in a category
+ // (including a hidden category). Hidden
+ // suffixes to tag names will be generated
+ // for internal consistency. At present,
+ // only data for first non-unique tag may be
+ // accessed.
+ //
+ enum CIF_FLAG {
+ CIFFL_PrintWarnings = 0x00000001,
+ CIFFL_StopOnWarnings = 0x00000002,
+ CIFFL_SuggestCategories = 0x00000004,
+ CIFFL_SuggestTags = 0x00000008
+ };
+
+ DefineClass(Data);
+ DefineStreamFunctions(Data);
+
+
+ /// \brief mmcif::Data represents mmCIF's \"data\" category, which keeps
+ /// structures and loops and is mandatory element of mmCIF file.
+ /*!
+ mmCIF's \"data\" category has the following form:
+ \code
+ data_DataName
+
+ _structure1.tag1 value1
+ ..........
+
+ loop_
+ ..........
+
+ \endcode
+ In the above example, all structures and loops that follow \b data_
+ keyword until next \b data_ or end of file are part of data category
+ with name \b DataName.
+
+ mmcif::Data represents this construct by keeping a list of mmcif::Struct
+ and mmcif::Loop class instances associated with the corresponding
+ categories in the data block.
+
+ The data object is created automatically when an mmCIF file is read,
+ or it may be created programatically and then pushed into file.
+
+ Access to data is provided via category (structures and loops) names,
+ tags and data indexes (in case of loops). Alternatively, pointers to
+ contained structures and loops may be obtained first, an used for
+ fetching data using mmcif::Struct's and mmcif::Loop's interface
+ functions.
+
+ The following code gives an example of creating mmCIF's data category
+ and populating it:
+ \code
+ mmcif::Data data;
+
+ // Specify data name:
+ data.PutDataName ( "Sample_Data" );
+
+ // the following statement:
+ data.PutInteger ( 12345,"_category1","id" );
+ // creates structure "_category1" with tag "id" and assigns it
+ // the integer value of 12345.
+
+ data.PutString ( "a name","_category1","name" );
+
+ // Loops may be created quite similarly:
+ data.PutLoopInteger ( 12345 ,"_loop1","id" ,2 );
+ data.PutLoopInteger ( "a name","_loop1","name",0 );
+
+ // push data into a file
+ data.WriteMMCIFData ( "sample.cif" );
+
+ \endcode
+
+ The resulting file \b sample.cif will contain:
+
+ \code
+ data_Sample_Data
+
+ _category1.id 12345
+ _category1.name "a name"
+
+ loop_
+ _loop1.id
+ _loop1.name
+ . "a name"
+ . .
+ 12345 .
+ \endcode
+
+ The same result may be achieved differently:
+
+ \code
+ mmcif::Data data;
+ mmcif::PStruct mmCIFStruct; // equivalent to mmcif::Struct *mmCIFStruct
+ mmcif::PLoop mmCIFLoop; // equivalent to mmcif::Loop *mmCIFLoop
+
+ // Specify data name:
+ data.PutDataName ( "Sample_Data" );
+
+ // create new mmCIF's structure in the data block:
+ data.AddStructure ( "_category1",mmCIFStruct );
+ if (mmCIFStruct) {
+ mmCIFStruct->PutInteger ( 12345 ,"id" );
+ mmCIFStruct->PutString ( "a name","name" );
+ }
+
+ // similarly for the loop:
+ data.AddLoop ( "_loop1",mmCIFLoop );
+ if (mmCIFLoop) {
+ mmCIFLoop->PutInteger ( 12345 ,"id" ,2 );
+ mmCIFLoop->PutString ( "a name","name",0 );
+ }
+
+ // push data into a file
+ data.WriteMMCIFData ( "sample.cif" );
+
+ \endcode
+
+ See general principles of working with mmCIF files and mmCIF
+ hierarchies, as well as some code samples, in Section
+ \"\ref mmcif_handler\".
+ */
+
+ class Data : public io::Stream {
+
+ friend class File;
+
+ public :
+
+ /// \brief Basic constructor.
+ Data ();
+
+ /// \brief Constructor that assigns data block name.
+ /// \param[in] N data block name.
+ Data ( cpstr N );
+
+ /// \brief Constructor for MMDB data streaming functions.
+ Data ( io::RPStream Object );
+
+ /// \brief Destructor.
+ ~Data();
+
+
+ // -------- General I/O functions
+
+ /// \brief Sets flag to print warnings on reading mmCIF files.
+ /// \param[in] SPW flag to print warnings:
+ /// \arg \b true : warnings will be printed to stdout
+ /// \arg \b false : warnings will not be printed but returned
+ /// in return code (default)
+ void SetPrintWarnings ( bool SPW );
+
+ /// \brief Sets flag to stop on warning when reading an mmCIF file.
+ /// \param[in] SOW flag to stop on warning:
+ /// \arg \b true : reading will stop on first warning encountered
+ /// \arg \b false : warnings will not stop reading (default)
+ void SetStopOnWarning ( bool SOW );
+
+ /// \brief Sets optional flag(s) for reading mmCIF files.
+ /// By default, no flags are set.
+ /// \param[in] F flag or logical \"or\" of several flags to be set:
+ /// \arg \b CIFFL_PrintWarnings toggles printing warning messages
+ /// at reading an mmCIF file, in stdout. If this
+ /// flag is not set (default), the warnings will
+ /// be returned in the bit-encoded return code
+ /// \arg \b CIFFL_StopOnWarnings if set, reading an mmCIF file
+ /// will stop at first warning issued
+ /// \arg \b CIFFL_SuggestCategories allows for reading of mmCIF
+ /// files with loops and structures having no
+ /// category names (\"dirty CIFs\"). If this flag is
+ /// set, then hidden category names will be
+ /// automatically generated. These names will not
+ /// appear in the output. As these names are hidden,
+ /// they cannot be used to access data. In order to
+ /// access data in such categories, consider whether
+ /// they are structures or loops. In case of a
+ /// unnamed structure, simply specify \"\" (empty
+ /// string) for structure name in all access
+ /// functions ( note that \b CIFFL_SuggestCategories
+ /// flag must be on while accessing such data). In
+ /// case of a loop, first use the mmcif::Data::FindLoop
+ /// function to retrieve pointer on the hidden loop,
+ /// and then use mmcif::Loop's interface function to
+ /// fetch data from the loop.
+ /// \arg \b CIFFL_SuggestTags allows for duplicate tags in a
+ /// category (structure or loop, including hidden
+ /// categories). This may help reading \"dirty CIFs\".
+ /// At present, only data for first non-unique tag
+ /// may be accessed.
+ void SetFlag ( CIF_FLAG F );
+
+ /// \brief Removes optional flag(s) for reading mmCIF files.
+ /// By default, no flags are set.
+ /// \param[in] F flag or logical \"or\" of several flags to be
+ /// removed (unset):
+ /// \arg \b CIFFL_PrintWarnings no wornings will be printed in
+ /// stdout, but rather returned in the bit-encoded
+ /// return code
+ /// \arg \b CIFFL_StopOnWarnings warnings will not stop reading
+ /// \arg \b CIFFL_SuggestCategories loops without names will
+ /// count as errors and stop reading
+ /// \arg \b CIFFL_SuggestTags duplicate tags in structures and
+ /// loops will count as errors and stop reading.
+ ///
+ /// See more detail flag description in mmcif::Data::SetFlag().
+ void RemoveFlag ( CIF_FLAG F );
+
+ /// \brief Returns bit-encoded warnings issued at last file read.
+ /// \return an integer number, which is an or-superposition of
+ /// warning flags:
+ /// \arg \b CIFW_UnrecognizedItems: unrecognized items were found
+ /// \arg \b CIFW_MissingField: expected data field not found
+ /// \arg \b CIFW_EmptyLoop: loop category was defined but has no
+ /// data
+ /// \arg \b CIFW_UnexpectedEOF: mmCIF construct finished prematurely
+ /// \arg \b CIFW_LoopFieldMissing: loop category has wrong number
+ /// of data fields
+ /// \arg \b CIFW_NotAStructure: attempt to use a category name,
+ /// which was once defined as a structure,
+ /// as a loop
+ /// \arg \b CIFW_NotALoop: attempt to use a category name, which was
+ /// once defined as a loop, as a structure
+ /// \arg \b CIFW_DuplicateTag: duplicate tag was found in a
+ /// structure or loop
+ inline int GetWarnings() { return Warning; }
+
+ /// \brief Sets category names and tags that are to be ignored
+ /// on file read.
+ /// \param[in] cats list of categories, terminated by NULL
+ /// \param[in] tags list of tags, terminated by NULL.
+ ///
+ /// This special function is to aid reading corrupt mmCIF files.
+ /// The input lists should be of equal length 'n', and specify
+ /// 'n' \"wrong fields\" that should be ignored on input. E.g.,
+ /// ith \"wrong field\" is identified as \"cats[i].taga[i]\".
+ /// If \"wrong field\" belongs to a loop, then all the corresponding
+ /// column is assumed to be absent. This corrects for mmCIF errors
+ /// when defined tags in loops or structures do not have actual data
+ /// associated with them.
+ ///
+ /// In order to remove settings, call SetWrongFields(NULL,NULL).
+ ///
+ /// Example:
+ /*!
+ \code
+ // assume data for "_category.item1" and "_category.item2"
+ // missed in a file to-be-read
+ mmcif::Data data;
+ cpstr cats[] = { "_category", "_category", NULL };
+ cpstr tags[] = { "item1" , "item2" , NULL };
+
+ data.SetWrongFields ( cats,tags );
+ data.ReadMMCIFData ( "corrupt.cif" );
+ \endcode
+ */
+ void SetWrongFields ( cpstr *cats, cpstr *tags );
+
+ /// \brief Reads mmCIF data block from file.
+ /// \param FName character null-terminated string with file name
+ /// \param gzipMode flag to read compressed files:
+ /// \arg \b GZM_NONE: do not assume any compression
+ /// \arg \b GZM_CHECK: check compression type by file extension
+ /// \arg \b GZM_ENFORCE: same as \b GZM_ENFORCE_GZIP
+ /// \arg \b GZM_ENFORCE_GZIP: assume gzip compression (*.gz files)
+ /// \arg \b GZM_ENFORCE_COMPRESS: assume compression with 'compress'
+ /// (*.Z files).
+ /// \return \b CIFRC_Ok: no errors
+ /// \return \b negative: there were errors
+ /// \return \b positive: there were warnings.
+ ///
+ /// This function will read 1st data block from the specified file.
+ /// In case of non-zero return, use GetCIFMessage() function to
+ /// print the corresponding error message or warning:
+ /*!
+ \code
+ mmcif::Data data;
+ char errLog[500];
+ int rc;
+ rc = data.ReadMMCIFData ( "myfile.cif" );
+ if (rc<0)
+ printf ( " There was an error:\n %s\n",
+ GetCIFMessage(errLog,rc) );
+ else if (rc>0)
+ printf ( " There were warnings:\n %s\n",
+ GetCIFMessage(errLog,rc) );
+ else
+ printf ( " mmCIF file has be read in successfully.\n" );
+ \endcode
+ */
+ int ReadMMCIFData ( cpstr FName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+
+ /// \brief Reads sequential mmCIF data blocks from file.
+ /// \param RCFile reference to a CFile object opened on a file
+ /// \param S buffer string which represent a sliding read window.
+ /// The string should be at least 500 characters long,
+ /// initialized with empty-string value before first read,
+ /// and passed unchanged between the reads
+ /// \param lcount line counter, should be set zero before first
+ /// read and passed unchanged between the reads.
+ /// \return \b CIFRC_Ok: no errors
+ /// \return \b negative: there were errors
+ /// \return \b positive: there were warnings.
+ ///
+ /// This function will read 1st data block from the current position
+ /// of the file. The function is useful if a file contains more than
+ /// a single data block, which should be read sequentially.
+ ///
+ /// \note Alternatively, files with multiple data blocks can be
+ /// read using mmcif::File class.
+ ///
+ /// In case of non-zero return, use GetCIFMessage() function to
+ /// print the corresponding error message or warning:
+ /*!
+ \code
+ mmcif::Data mmCIFData;
+ CFile f;
+ char S[1000];
+ int rc,lcount;
+
+ // open file first
+ f.assign ( "/path/example.cif" );
+ if (!f.reset(true)) {
+ printf ( " *** cannot open file '%s' for reading.\n",
+ f.FileName() );
+ return -1;
+ }
+
+ lcount = 0; // global line counter through the file
+ S[0] = char(0); // buffer string
+ while (!f.FileEnd()) {
+
+ rc = mmCIFData.ReadMMCIFData ( f,S,lcount );
+
+ if (rc!=CIFRC_Ok) { // error or warning
+ if ((rc<0) && (!f.FileEnd())) { // error
+ printf ( " *** error reading file %s:\n"
+ " %s\n",f.FileName(),GetCIFMessage(S,rc) );
+ return rc;
+ } else if (rc>0) { // warning
+ printf ( " ... warning on reading file %s:\n"
+ " %s\n",f.FileName(),GetCIFMessage(S,rc) );
+ }
+ } else {
+ // fetch needful values from the data block
+ // ........
+ }
+
+ }
+
+ f.shut(); // close file
+
+ // NOTE: do not delete mmcif::Struct/mmcif::Loop
+ // classes obtained from mmcif::Data. If you do, get a crash.
+ // All these structures are containers that dispose their
+ // content automatically.
+ \endcode
+ */
+ int ReadMMCIFData ( io::RFile f, pstr S, int & lcount );
+
+ /// \brief Writes mmCIF data block into file.
+ /// \param FName character null-terminated string with file name
+ /// \param gzipMode flag to read compressed files:
+ /// \arg \b GZM_NONE: do not compress
+ /// \arg \b GZM_CHECK: compress according to file extension
+ /// \arg \b GZM_ENFORCE: same as \b GZM_ENFORCE_GZIP
+ /// \arg \b GZM_ENFORCE_GZIP: compress with gzip
+ /// \arg \b GZM_ENFORCE_COMPRESS: compression with 'compress'.
+ /// \return \b true: no errors
+ /// \return \b false: file cannot be open for writing.
+ bool WriteMMCIFData ( cpstr FName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+
+ /// \brief Writes (next) mmCIF data block into file.
+ /// \param RCFile reference to a CFile object opened on a file.
+ ///
+ /// This function allows for sequential write of mmCIF data blocks
+ /// into a file.
+ ///
+ /// \note Alternatively, files with multiple data blocks can be
+ /// created using mmcif::File class.
+ ///
+ /// Example:
+ /*!
+ \code
+ io::File f;
+ mmcif::Data cifData;
+
+ // open file first
+ f.assign ( "/path/example.cif" );
+ if (!f.rewrite()) {
+ printf ( " *** cannot open file '%s' for writing.\n",
+ f.FileName() );
+ return -1;
+ }
+
+ cifData.PutDataName ( "name1" );
+ // fill cifData with all data needed
+ cifData.WriteMMCIF ( f ); // first data block written
+
+ cifData.FreeMemory ( 0 ); // reset data block to empty
+ cifData.PutDataName ( "name2" );
+ // fill cifData with all data needed
+ cifData.WriteMMCIF ( f ); // second data block written
+
+ // add as many data blocks as needed
+
+ // now close the file
+ f.shut();
+
+ \endcode
+
+ */
+ void WriteMMCIF ( io::RFile f );
+
+
+ // -------- Retrieving data
+
+ /// \brief Returns the number of categories (structures and loops)
+ /// in data block.
+ inline int GetNumberOfCategories () { return nCategories; }
+
+ /// \brief Retrieves pointer to category (a structure or a loop) by
+ /// category number.
+ /// \param categoryNo category number to retrieve. Categories are
+ /// numbered from 0 to GetNumberOfCategories()-1.
+ /// \return pointer to category, if \b categoryNo is in the right
+ /// range, or \b NULL otherwise.
+ ///
+ /// \note The category type (structure or loop) is returned by
+ /// function mmcif::Category::GetCategoryID().
+ /// \note The application should never attempt to deallocate
+ /// the category returned. It will be properly disposed of by
+ /// mmcif::Data's destructor.
+ PCategory GetCategory ( int categoryNo ); // 0..nCategories-1
+
+ /// \brief Retrieves mmCIF structure with given name.
+ /// \param CName character string with name of the structure (must
+ /// start with underscore).
+ /// \return pointer to structure if structure with given name was
+ /// found, and \b NULL otherwise.
+ /// \note The application should never attempt to deallocate
+ /// the structure returned. It will be properly disposed of by
+ /// mmcif::Data's destructor.
+ PStruct GetStructure ( cpstr CName );
+
+ /// \brief Retrieves mmCIF loop with given name.
+ /// \param CName character string with name of the loop (must
+ /// start with underscore).
+ /// \return pointer to loop if loop with given name was
+ /// found, and \b NULL otherwise.
+ /// \note The application should never attempt to deallocate
+ /// the loop returned. It will be properly disposed of by
+ /// mmcif::Data's destructor.
+ PLoop GetLoop ( cpstr CName );
+
+ /// \brief Finds loop containing all tags from the tag list
+ /// provided.
+ /// \param tagList list of tags to be looked for. The list should
+ /// be terminated by empty string \"\". The order of tags
+ /// is not significant.
+ /// \return pointer to loop if loop with given tags was found, and
+ /// \b NULL otherwise.
+ ///
+ /// The function will look for first loop that includes all tags
+ /// from the list. The list does not have to include all tags for
+ /// that loop in order for function to succeed. This function is
+ /// useful for reading \"dirty cifs\" that may contain loops without
+ /// a name.
+ PLoop FindLoop ( cpstr * tagList );
+
+ /// \brief Retrieves data block name into dynamically-allocated
+ /// string.
+ /// \param dname pointer reference to a string that accepts data
+ /// block name. If \b dname is not \b NULL, it is treated
+ /// as a pre-allocated string, which is disposed before
+ /// copying. The application is responsible for deallocating
+ /// \b dname.
+ /// \param Remove flag to remove name from the data block.
+ void GetDataName ( pstr & dname, bool Remove=false );
+
+ /// \brief Returns data block name.
+ inline pstr GetDataName() { return name; }
+
+ // CheckData(..) returns positive value if the field is in the
+ // file:
+ // CIFRC_Structure category CName is a structure
+ // CIFRC_Loop category CName is a loop
+ // Negative returns mean:
+ // CIFRC_StructureNoTag category CName is present,
+ // it is a structure, but it does not
+ // have tag TName
+ // CIFRC_LoopNoTag category CName is present,
+ // it is a loop, but it does not have
+ // tag TName
+ // CIFRC_NoCategory category CName is not present.
+ // If TName is set to NULL then only the CName is checked and
+ // possible returns are CIFRC_Structure, CIFRC_Loop and
+ // CIFRC_NoCategory.
+ int CheckData ( cpstr CName, cpstr TName );
+
+ int DeleteCategory ( cpstr CName );
+ int DeleteStructure ( cpstr CName );
+ int DeleteLoop ( cpstr CName );
+
+ // Optimize() optimizes the CIF data in memory allocation. It is
+ // a good idea to call it once after extraction of data (GetXXXXXX
+ // functions) with Remove flag set on has been completed.
+ void Optimize();
+
+ // GetString(..), GetReal(..) and GetInteger(..) return 0 if the
+ // requested field was found and successfully converted. Negative
+ // returns mean:
+ // CIFRC_WrongFormat the field was found but failed to convert
+ // due to improper numeric format
+ // CIFRC_NoTag category CName was found, but it does not
+ // have tag TName
+ // CIFRC_NoCategory category CName was not found
+ // CIFRC_NotAStructure category CName was found, but it is
+ // a loop rather than a structure.
+ // GetString(..) will try to dispose Dest unless it is assigned
+ // NULL value before the call. The string will be then dynamically
+ // allocated and copied.
+ // If Remove is set to true, the field will be removed after
+ // extraction.
+ int GetString ( pstr & Dest, cpstr CName, cpstr TName,
+ bool Remove=false );
+ pstr GetString ( cpstr CName, cpstr TName, int & RC );
+ int DeleteField ( cpstr CName, cpstr TName );
+ int GetReal ( realtype & R, cpstr CName,
+ cpstr TName, bool Remove=false );
+ int GetInteger ( int & I, cpstr CName, cpstr TName,
+ bool Remove=false );
+
+ // GetLoopLength(..) returns CIFRC_NotALoop if the category CName
+ // is not a loop, CIFRC_NoCategory if the category CName is not
+ // found. Non-negative returns give the length of the loop (may be
+ // 0 if the loop is empty).
+ int GetLoopLength ( cpstr CName );
+
+ // GetLoopString(..), GetLoopReal(..) and GetLoopInteger(..) act
+ // like GetString(..), GetReal(..) and GetInteger(..) above for
+ // nrow-th element of the 'loop_' (indexed like 0..N-1 where N
+ // is obtained through GetLoopLength(..)). They will return
+ // CIFRC_WrongIndex if nrow is out of range.
+ // If Remove is set to true, the field will be removed after
+ // extraction.
+ int GetLoopString ( pstr & Dest, cpstr CName,
+ cpstr TName, int nrow,
+ bool Remove=false );
+ pstr GetLoopString ( cpstr CName, cpstr TName,
+ int nrow, int & RC );
+ int DeleteLoopField ( cpstr CName, cpstr TName,
+ int nrow );
+ int GetLoopReal ( realtype & R, cpstr CName,
+ cpstr TName, int nrow,
+ bool Remove=false );
+ int GetLoopInteger ( int & I, cpstr CName,
+ cpstr TName, int nrow,
+ bool Remove=false );
+
+ // GetLoopSVector(..), GetLoopRVector(..) and GetLoopIVector(..)
+ // read CIF 'loop_' data into allocated vectors of strings, reals
+ // and integers, correspondingly. The vectors may be deallocated
+ // prior to call and assigned NULL, in which case they will be
+ // allocated with offsets of i1, which is also the lower index of
+ // the 'loop_' data transferred into it. The upper vector index is
+ // given by i2 or by the loop's length whichever is less. If
+ // vectors are not assigned NULL prior the call, it is assumed
+ // that they are properly (i1-offset, i2-i1+1 length) allocated.
+ // The return codes are same as those of GetLoopString(..),
+ // GetLoopReal(..) and GetLoopInteger(..).
+ int GetLoopSVector ( psvector & S, cpstr CName,
+ cpstr TName, int i1=0, int i2=MaxInt4,
+ bool Remove=false );
+ int GetLoopRVector ( rvector & R, cpstr CName,
+ cpstr TName, int i1=0, int i2=MaxInt4,
+ bool Remove=false );
+ int GetLoopIVector ( ivector & I, cpstr CName,
+ cpstr TName, int i1=0, int i2=MaxInt4,
+ bool Remove=false );
+
+
+ // -------- Storing data
+
+ // Unless the data are to be added to the existing CIF structure,
+ // FreeMemory() should be called once before creating a new
+ // CIF data set.
+ void FreeMemory ( int key );
+
+ void PutDataName ( cpstr dname ); // stores name for 'data_'
+ // record
+
+ // PutString(..), PutReal(..) and PutInteger(..) will put the
+ // values given into the specified category (CName) under the
+ // specified tag (TName). The category, tag and field are created
+ // automatically; the field will be replaced silently if identical
+ // CName.TName is specified in two calls. Calls of these functions
+ // may follow in random order; however CIF file will have all tags
+ // grouped by categories and catgories will follow in the order
+ // of first appearance in PutString(..), PutReal(..) or
+ // PutInteger(..).
+ // Return code - one of CIFRC_Ok or CIFRC_NotAStruct
+ int PutNoData ( int NoDataType, cpstr CName,
+ cpstr TName );
+ int PutString ( cpstr S, cpstr CName,
+ cpstr TName, bool Concatenate=false );
+ int PutDate ( cpstr CName, cpstr TName );
+ int PutReal ( realtype R, cpstr CName, cpstr TName,
+ int prec=8 );
+ int PutInteger ( int I, cpstr CName, cpstr TName );
+
+ // If loop category CName is not present in the CIF data
+ // structure, AddLoop(..) creates an empty one and returns
+ // its pointer in Loop. If loop category CName is already in
+ // the CIF data structure, its pointer is returned, and any
+ // data which might be contained in it, remains untouched.
+ // To stuff the loop with data, first the data tags have to
+ // be specified by calling Loop->AddLoopTag(..). After all
+ // tags are given, the data comes as a stream of calls
+ // Loop->AddString(..), Loop->AddReal(..) and
+ // Loop->AddInteger(..) which should provide data for every
+ // tag in sequence in strictly the same order as the tags
+ // were given. This essentially reflects reading a CIF loop
+ // from a file.
+ // Alternatively, the loop data may be stored with PutLoopXXX()
+ // functions given below, although this way may be less
+ // efficient (but more flexible).
+ // AddLoop(..) may return
+ // CIFRC_Ok category was present
+ // CIFRC_Created category was not present but it has
+ // been created; the category is empty
+ // CIFRC_NotALoop category was present as a structure, but
+ // has been replaced for a loop;
+ // the category is empty.
+ int AddLoop ( cpstr CName, PLoop & cifLoop );
+ int AddStructure ( cpstr CName, PStruct & cifStruct );
+
+ // PutLoopString(..), PutLoopReal(..) and PutLoopInteger(..) act
+ // like PutString(..), PutReal(..) and PutInteger(..) above for
+ // nrow-th element of the 'loop_' CName (indexed begining from 0).
+ // In consequitive calls, given values of nrow does not have to be
+ // ordered; the most efficient way is to start with HIGHEST value
+ // for nrow in the loop and move down to 0. The least efficient way
+ // is to start with nrow=0 and move up.
+ // These functions allow to form loops in arbitrary way.
+ // The functions may return CIFRC_Ok or CIFRC_NotALoop.
+ int PutLoopNoData ( int NoDataType, cpstr CName,
+ cpstr TName, int nrow );
+ int PutLoopString ( cpstr S, cpstr CName,
+ cpstr TName, int nrow );
+ int PutLoopReal ( realtype R, cpstr CName,
+ cpstr TName, int nrow,
+ int prec=8 );
+ int PutLoopInteger ( int I, cpstr CName, cpstr TName,
+ int nrow );
+
+ // PutLoopSVector(..), PutLoopRVector(..) and PutLoopIVector(..)
+ // put vectors of values into specified loop fields. Parameters i1
+ // and i2 give the range of indices of values which are to be
+ // transfered. To transfer an entire vector allocated as [0..N-1]
+ // i1 shoudl be set to 0 and i2 - to N-1. Note that the loop is
+ // always indexed as starting form 0 on, therefore negative i1 and
+ // i2 are not allowed, and specifying i1>0 will leave first i1
+ // elements of the CIF loop for the corresponding tag undefined
+ // (will be output like '?').
+ // These functions allow to form loops in arbitrary way.
+ int PutLoopSVector ( psvector S, cpstr CName,
+ cpstr TName, int i1, int i2 );
+ int PutLoopRVector ( rvector R, cpstr CName,
+ cpstr TName, int i1, int i2,
+ int prec=8 );
+ int PutLoopIVector ( ivector I, cpstr CName,
+ cpstr TName, int i1, int i2 );
+
+ int RenameCategory ( cpstr CName, cpstr newCName );
+
+ // --------
+
+ void Copy ( PData Data );
+ int CopyCategory ( PData Data, cpstr CName,
+ cpstr newCName=NULL );
+
+ void PrintCategories(); // for debuging only
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected:
+ pstr name;
+ int nCategories;
+ PPCategory Category;
+ ivector index;
+ int flags;
+ int Warning;
+ int loopNo; // used locally for suggesting categories
+ int tagNo; // used locally for suggesting tags
+ psvector WrongCat;
+ psvector WrongTag;
+ int nWrongFields;
+
+ void InitData ();
+ void FreeWrongFields ();
+ bool CheckWrongField ( cpstr C, cpstr T );
+ void Sort ();
+
+ // GetCategoryNo searches for index of category cname
+ // in Category[]. Return:
+ // >=0 : position of the category found
+ // <0 : the category was not found, it could be inserted before
+ // (-RC-1)th element, where RC is the return value
+ int GetCategoryNo ( cpstr cname );
+ int AddCategory ( cpstr cname );
+ int DeleteCategory ( int CatNo );
+
+ void GetDataItem ( io::RFile f, pstr S, pstr & L, pstr & p,
+ int & lcount, int & llen );
+ void GetLoop ( io::RFile f, pstr S, pstr & L, pstr & p,
+ int & lcount, int & llen );
+ int GetField ( io::RFile f, pstr S, pstr & L, pstr & p,
+ int & lcount, int & llen );
+
+ };
+
+
+
+ // ======================== File =============================
+
+ DefineClass(File);
+ DefineStreamFunctions(File);
+
+ class File : public io::Stream {
+
+ public :
+ int nData;
+ ivector index;
+ PPData data;
+
+ File ();
+ File ( cpstr FName, io::GZ_MODE gzipMode=io::GZM_CHECK );
+ File ( io::RPStream Object );
+ ~File();
+
+ void SetPrintWarnings ( bool SPW ) { PrintWarnings = SPW; }
+ void SetStopOnWarning ( bool SOW ) { StopOnWarning = SOW; }
+
+ int ReadMMCIFFile ( cpstr FName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+ int WriteMMCIFFile ( cpstr FName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+
+ int GetNofData() { return nData; }
+ PData GetCIFData ( int dataNo ); // 0..nData-1
+ PData GetCIFData ( cpstr DName );
+ int AddCIFData ( cpstr DName );
+ int DeleteCIFData ( cpstr DName );
+ int DeleteCIFData ( int dataNo );
+ int GetCIFDataNo ( cpstr DName );
+
+ void WriteMMCIF ( io::RFile f );
+
+ void Copy ( PFile File );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected:
+ int nAllocData;
+ bool PrintWarnings;
+ bool StopOnWarning;
+
+ void InitFile ();
+ void FreeMemory ();
+ void Sort ();
+ void ExpandData ( int nDataNew );
+
+ };
+
+
+ extern pstr GetMMCIFInputBuffer ( int & LineNo );
+
+ // isCIF will return
+ // -1 if file FName does not exist
+ // 0 if file FName is likely a CIF file ( 'data_' is present )
+ // 1 if file FName is not a CIF file ( 'data_' is absent )
+ extern int isCIF ( cpstr FName, io::GZ_MODE gzipMode=io::GZM_CHECK );
+ extern int isCIF ( io::RFile f );
+
+ pstr GetCIFMessage ( pstr M, int RC );
+
+
+ } // namespace mmcif
+
+} // namespace mmdb
+
+
+#endif
+
+
diff --git a/mmdb2/mmdb_model.cpp b/mmdb2/mmdb_model.cpp
new file mode 100644
index 0000000..ca1d537
--- /dev/null
+++ b/mmdb2/mmdb_model.cpp
@@ -0,0 +1,5332 @@
+// $Id: mmdb_model.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_Model <implementation>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::HetCompound ( description of het compounds )
+// ~~~~~~~~~ mmdb::HetCompounds (HETNAM, HETSYN, FORMULA records)
+// mmdb::SSContainer (container for helixes and turns)
+// mmdb::Helix ( helix info )
+// mmdb::Strand ( strand info )
+// mmdb::Sheet ( sheet info )
+// mmdb::Sheets ( container for sheets )
+// mmdb::Turn ( turn info )
+// mmdb::LinkContainer ( container for link data )
+// mmdb::Link ( link data )
+// mmdb::LinkRContainer ( container for refmac link )
+// mmdb::LinkR ( link data )
+// mmdb::CisPepContainer ( container for CisPep data )
+// mmdb::CisPep ( CisPep data )
+// mmdb::Model ( PDB model )
+//
+// Copyright (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "mmdb_model.h"
+#include "mmdb_manager.h"
+#include "mmdb_cifdefs.h"
+
+namespace mmdb {
+
+ // =================== HetCompound =========================
+
+ HetCompound::HetCompound ( cpstr HetName ) : io::Stream() {
+ InitHetCompound ( HetName );
+ }
+
+ HetCompound::HetCompound ( io::RPStream Object ) : io::Stream(Object) {
+ InitHetCompound ( pstr("---") );
+ }
+
+ HetCompound::~HetCompound() {
+ FreeMemory();
+ }
+
+ void HetCompound::InitHetCompound ( cpstr HetName ) {
+ strcpy_n0 ( hetID,HetName,sizeof(ResName) );
+ comment = NULL;
+ nSynonyms = 0;
+ hetSynonym = NULL;
+ compNum = MinInt4;
+ wc = ' ';
+ Formula = NULL;
+ }
+
+ void HetCompound::FreeMemory() {
+ int i;
+ if (comment) {
+ delete[] comment;
+ comment = NULL;
+ }
+ if (hetSynonym) {
+ for (i=0;i<nSynonyms;i++)
+ if (hetSynonym[i]) delete[] hetSynonym[i];
+ delete[] hetSynonym;
+ hetSynonym = NULL;
+ }
+ nSynonyms = 0;
+ if (Formula) {
+ delete[] Formula;
+ Formula = NULL;
+ }
+ }
+
+ void HetCompound::AddKeyWord ( cpstr W, bool Closed ) {
+ psvector HS1;
+ int i;
+ if (Closed || (!hetSynonym)) {
+ // first synonym orthe previous synonym was closed by semicolon
+ // -- add a new one
+ HS1 = new pstr[nSynonyms+1];
+ for (i=0;i<nSynonyms;i++)
+ HS1[i] = hetSynonym[i];
+ if (hetSynonym) delete[] hetSynonym;
+ hetSynonym = HS1;
+ hetSynonym[nSynonyms] = NULL;
+ CreateCopy ( hetSynonym[nSynonyms],W );
+ nSynonyms++;
+ } else {
+ // just add W to the last synonym
+ CreateConcat ( hetSynonym[nSynonyms-1],pstr(" "),W );
+ }
+ }
+
+
+ void HetCompound::HETNAM_PDBDump ( io::RFile f ) {
+ char S[100];
+ pstr p1,p2;
+ char c;
+ int N,i;
+
+ if (!comment) return;
+
+ c = ' ';
+ N = 0;
+ p1 = comment;
+ do {
+ N++;
+ if (N==1) sprintf ( S,"HETNAM %3s " ,hetID );
+ else sprintf ( S,"HETNAM %2i %3s ",N,hetID );
+ while (*p1==' ') p1++;
+ p2 = strchr(p1,'\n');
+ if (p2) {
+ c = *p2;
+ *p2 = char(0);
+ } else if (strlen(p1)>53) {
+ i = 0;
+ while (p1[i] && (i<53) && (p1[i]!=' ')) i++;
+ p2 = &(p1[i]);
+ c = *p2;
+ *p2 = char(0);
+ }
+ if (*p1) {
+ strcat ( S,p1 );
+ PadSpaces ( S,80 );
+ f.WriteLine ( S );
+ } else
+ N--;
+ if (p2) {
+ *p2 = c;
+ if (c) p1 = p2+1;
+ else p2 = NULL;
+ }
+ } while (p2);
+
+ }
+
+
+ void HetCompound::HETSYN_PDBDump ( io::RFile f ) {
+ char S[100];
+ pstr p;
+ char c;
+ int N,k,i,l;
+ if (!hetSynonym) return;
+ N = 0;
+ k = 0;
+ p = &(hetSynonym[0][0]);
+ do {
+ N++;
+ if (N==1) sprintf ( S,"HETSYN %3s " ,hetID );
+ else sprintf ( S,"HETSYN %2i %3s ",N,hetID );
+ i = 0;
+ do {
+ l = strlen(p)+2;
+ if (i+l<54) {
+ strcat ( S,p );
+ if (k<nSynonyms-1) strcat ( S,"; " );
+ k++;
+ i += l;
+ if (k<nSynonyms) p = &(hetSynonym[k][0]);
+ else i = 60; // break loop
+ } else {
+ if (i==0) {
+ // too long synonym, has to be split over several lines
+ i = l-3;
+ while (i>51) {
+ i--;
+ while ((i>0) && (p[i]!=' ')) i--;
+ }
+ if (i<2) i = 51; // no spaces!
+ c = p[i];
+ p[i] = char(0);
+ strcat ( S,p );
+ p[i] = c;
+ p = &(p[i]);
+ while (*p==' ') p++;
+ }
+ i = 60; // break loop
+ }
+ } while (i<54);
+ PadSpaces ( S,80 );
+ f.WriteLine ( S );
+ } while (k<nSynonyms);
+ }
+
+
+ void HetCompound::FORMUL_PDBDump ( io::RFile f ) {
+ char S[100];
+ pstr p1,p2;
+ char c;
+ int N,i;
+ if (!Formula) return;
+ N = 0;
+ p1 = Formula;
+ do {
+ N++;
+ if (compNum>MinInt4) {
+ if (N==1) sprintf ( S,"FORMUL %2i %3s " ,compNum,hetID );
+ else sprintf ( S,"FORMUL %2i %3s %2i ",compNum,hetID,N );
+ } else {
+ if (N==1) sprintf ( S,"FORMUL %3s " ,hetID );
+ else sprintf ( S,"FORMUL %3s %2i ",hetID,N );
+ }
+ S[18] = wc;
+ p2 = strchr(p1,'\n');
+ if (p2) {
+ c = *p2;
+ *p2 = char(0);
+ } else if (strlen(p1)>50) {
+ while (*p1==' ') p1++;
+ i = 0;
+ while (p1[i] && (i<50) && (p1[i]!=' ')) i++;
+ p2 = &(p1[i]);
+ c = *p2;
+ *p2 = char(0);
+ }
+ strcat ( S,p1 );
+ if (p2) {
+ *p2 = c;
+ p1 = p2+1;
+ }
+ PadSpaces ( S,80 );
+ f.WriteLine ( S );
+ } while (p2);
+ }
+
+
+ void HetCompound::FormComString ( pstr & F ) {
+ pstr p;
+ int i;
+ if (F) {
+ delete[] F;
+ F = NULL;
+ }
+ if (comment) {
+ CreateCopy ( F,comment );
+ i = 0;
+ p = comment;
+ while (*p) {
+ p++;
+ if (*p=='\n') i = 0;
+ else i++;
+ if (i>68) {
+ F[i] = char(0);
+ CreateConcat ( F,pstr("\n"),p );
+ i = 0;
+ }
+ }
+ }
+ }
+
+
+ void HetCompound::FormSynString ( pstr & F ) {
+ pstr p;
+ char c;
+ int i,k,l;
+ if (F) {
+ delete[] F;
+ F = NULL;
+ }
+ if (hetSynonym) {
+ CreateCopy ( F,pstr(" ") );
+ k = 0;
+ p = &(hetSynonym[0][0]);
+ do {
+ l = strlen(p)+2;
+ if (l<=60) {
+ if (k<nSynonyms-1) CreateConcat ( F,p,pstr(";\n ") );
+ else CreateConcat ( F,p );
+ k++;
+ if (k<nSynonyms) p = &(hetSynonym[k][0]);
+ } else {
+ // too long synonym, has to be split over several lines
+ i = l-3;
+ while (i>60) {
+ i--;
+ while ((i>0) && (p[i]!=' ')) i--;
+ }
+ if (i<2) i = 60; // no spaces!
+ c = p[i];
+ p[i] = char(0);
+ CreateConcat ( F,p,pstr("\n ") );
+ p[i] = c;
+ p = &(p[i]);
+ while (*p==' ') p++;
+ }
+ } while (k<nSynonyms);
+ }
+ }
+
+ void HetCompound::FormForString ( pstr & F ) {
+ pstr p;
+ int i;
+ if (F) {
+ delete[] F;
+ F = NULL;
+ }
+ if (Formula) {
+ CreateCopy ( F,Formula );
+ i = 0;
+ p = &(Formula[0]);
+ while (*p) {
+ p++;
+ if (*p=='\n') i = 0;
+ else i++;
+ if (i>68) {
+ F[i] = char(0);
+ CreateConcat ( F,pstr("\n"),p );
+ i = 0;
+ }
+ }
+ }
+ }
+
+
+ void HetCompound::Copy ( PHetCompound hetCompound ) {
+ int i;
+ FreeMemory ();
+ strcpy ( hetID ,hetCompound->hetID );
+ CreateCopy ( comment,hetCompound->comment );
+ nSynonyms = hetCompound->nSynonyms;
+ if (nSynonyms>0) {
+ hetSynonym = new pstr[nSynonyms];
+ for (i=0;i<nSynonyms;i++) {
+ hetSynonym[i] = NULL;
+ CreateCopy ( hetSynonym[i],hetCompound->hetSynonym[i] );
+ }
+ }
+ compNum = hetCompound->compNum;
+ wc = hetCompound->wc;
+ CreateCopy ( Formula,hetCompound->Formula );
+ }
+
+ void HetCompound::write ( io::RFile f ) {
+ int i;
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteTerLine ( hetID,false );
+ f.CreateWrite ( comment );
+ f.WriteInt ( &nSynonyms );
+ for (i=0;i<nSynonyms;i++)
+ f.CreateWrite ( hetSynonym[i] );
+ f.WriteInt ( &compNum );
+ f.WriteFile ( &wc,sizeof(wc) );
+ f.CreateWrite ( Formula );
+ }
+
+ void HetCompound::read ( io::RFile f ) {
+ int i;
+ byte Version;
+ FreeMemory();
+ f.ReadByte ( &Version );
+ f.ReadTerLine ( hetID,false );
+ f.CreateRead ( comment );
+ f.ReadInt ( &nSynonyms );
+ if (nSynonyms>0) {
+ hetSynonym = new pstr[nSynonyms];
+ for (i=0;i<nSynonyms;i++) {
+ hetSynonym[i] = NULL;
+ f.CreateRead ( hetSynonym[i] );
+ }
+ }
+ f.ReadInt ( &compNum );
+ f.ReadFile ( &wc,sizeof(wc) );
+ f.CreateRead ( Formula );
+ }
+
+ MakeStreamFunctions(HetCompound)
+
+
+ // ==================== HetCompounds =======================
+
+
+ HetCompounds::HetCompounds() : io::Stream() {
+ InitHetCompounds();
+ }
+
+ HetCompounds::HetCompounds ( io::RPStream Object )
+ : io::Stream(Object) {
+ InitHetCompounds();
+ }
+
+ HetCompounds::~HetCompounds() {
+ FreeMemory();
+ }
+
+ void HetCompounds::InitHetCompounds() {
+ nHets = 0;
+ hetCompound = NULL;
+ Closed = false;
+ }
+
+ void HetCompounds::FreeMemory() {
+ int i;
+ if (hetCompound) {
+ for (i=0;i<nHets;i++)
+ if (hetCompound[i]) delete hetCompound[i];
+ delete[] hetCompound;
+ hetCompound = NULL;
+ }
+ nHets = 0;
+ }
+
+ void HetCompounds::ConvertHETNAM ( cpstr S ) {
+ ResName hetID;
+ char L[100];
+ int l,i;
+ l = strlen(S);
+ if (l>12) {
+ strcpy_n0 ( hetID,&(S[11]),3 );
+ i = AddHetName ( hetID );
+ if (l>15) {
+ if (hetCompound[i]->comment) strcpy ( L,"\n" );
+ else L[0] = char(0);
+ strcat ( L,&(S[15]) );
+ CutSpaces ( L,SCUTKEY_END );
+ CreateConcat ( hetCompound[i]->comment,L );
+ }
+ }
+ }
+
+ void HetCompounds::ConvertHETSYN ( cpstr S ) {
+ ResName hetID;
+ char L[100];
+ int l,i,j,k;
+ l = strlen(S);
+ if (l>12) {
+ strcpy_n0 ( hetID,&(S[11]),3 );
+ i = AddHetName ( hetID );
+ if (l>15) {
+ j = 15;
+ do {
+ while (S[j]==' ') j++;
+ k = 0;
+ if (S[j]) {
+ while (S[j] && (S[j]!=';'))
+ L[k++] = S[j++];
+ L[k--] = char(0);
+ while ((k>0) && (L[k]==' ')) L[k--] = char(0);
+ if (L[0]) {
+ hetCompound[i]->AddKeyWord ( L,Closed );
+ Closed = (S[j]==';');
+ }
+ if (S[j]) j++;
+ }
+ } while (S[j]);
+ /*
+ p1 = &(S[15]);
+ do {
+ p2 = strchr ( p1,';' );
+ if (p2) {
+ c = *p2;
+ *p2 = char(0);
+ }
+ strcpy_css ( L,p1 );
+ if (L[0])
+ hetCompound[i]->AddKeyWord ( L,Closed );
+ if (p2) {
+ if (L[0]) Closed = true;
+ *p2 = c;
+ p1 = p2+1;
+ } else if (L[0])
+ Closed = false;
+ } while (p2);
+ */
+ }
+ }
+ }
+
+ void HetCompounds::ConvertFORMUL ( cpstr S ) {
+ ResName hetID;
+ char L[100];
+ int l,i;
+ l = strlen(S);
+ if (l>13) {
+ strcpy_n0 ( hetID,&(S[12]),3 );
+ i = AddHetName ( hetID );
+ if (l>18) {
+ GetInteger ( hetCompound[i]->compNum,&(S[9]),2 );
+ hetCompound[i]->wc = S[18];
+ if (strlen(S)>19) {
+ if (hetCompound[i]->Formula) strcpy ( L,"\n" );
+ else L[0] = char(0);
+ strcat ( L,&(S[19]) );
+ CutSpaces ( L,SCUTKEY_END );
+ CreateConcat ( hetCompound[i]->Formula,L );
+ }
+ }
+ }
+ }
+ int HetCompounds::AddHetName ( cpstr H ) {
+ PPHetCompound HC1;
+ int i;
+ i = 0;
+ while (i<nHets) {
+ if (hetCompound[i]) {
+ if (!strcmp(hetCompound[i]->hetID,H)) break;
+ }
+ i++;
+ }
+ if (i>=nHets) {
+ HC1 = new PHetCompound[nHets+1];
+ for (i=0;i<nHets;i++)
+ HC1[i] = hetCompound[i];
+ if (hetCompound) delete[] hetCompound;
+ hetCompound = HC1;
+ hetCompound[nHets] = new HetCompound ( H );
+ i = nHets;
+ nHets++;
+ }
+ return i;
+ }
+
+ void HetCompounds::PDBASCIIDump ( io::RFile f ) {
+ int i;
+
+ for (i=0;i<nHets;i++)
+ if (hetCompound[i])
+ hetCompound[i]->HETNAM_PDBDump ( f );
+
+ for (i=0;i<nHets;i++)
+ if (hetCompound[i])
+ hetCompound[i]->HETSYN_PDBDump ( f );
+
+ for (i=0;i<nHets;i++)
+ if (hetCompound[i])
+ hetCompound[i]->FORMUL_PDBDump ( f );
+
+ }
+
+
+ void HetCompounds::MakeCIF ( mmcif::PData CIF ) {
+ mmcif::PLoop Loop;
+ pstr F;
+ int RC;
+ int i;
+
+ if (!hetCompound) return;
+
+ RC = CIF->AddLoop ( CIFCAT_CHEM_COMP,Loop );
+ if (RC!=mmcif::CIFRC_Ok) {
+ Loop->AddLoopTag ( CIFTAG_ID );
+ Loop->AddLoopTag ( CIFTAG_NAME );
+ Loop->AddLoopTag ( CIFTAG_NDB_SYNONYMS );
+ Loop->AddLoopTag ( CIFTAG_NDB_COMPONENT_NO );
+ Loop->AddLoopTag ( CIFTAG_FORMULA );
+ }
+
+ F = NULL;
+ for (i=0;i<nHets;i++)
+ if (hetCompound[i]) {
+ Loop->AddString ( hetCompound[i]->hetID );
+ hetCompound[i]->FormComString ( F );
+ Loop->AddString ( F );
+ hetCompound[i]->FormSynString ( F );
+ Loop->AddString ( F );
+ if (hetCompound[i]->compNum>MinInt4)
+ Loop->AddInteger ( hetCompound[i]->compNum );
+ else Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION );
+ hetCompound[i]->FormForString ( F );
+ Loop->AddString ( F );
+ }
+
+ if (F) delete[] F;
+
+ }
+
+ ERROR_CODE HetCompounds::GetCIF ( mmcif::PData CIF ) {
+ mmcif::PLoop Loop;
+ char L[100];
+ ResName hetID;
+ pstr F,p1,p2;
+ char c;
+ int RC,i,l,k;
+
+ FreeMemory();
+ c = char(0); // only to supress compiler warnings
+
+ Loop = CIF->GetLoop ( CIFCAT_CHEM_COMP );
+ if (!Loop) return Error_NoError;
+
+ l = Loop->GetLoopLength();
+ F = NULL;
+
+ for (i=0;i<l;i++) {
+ CIFGetString ( hetID,Loop,CIFTAG_ID,i,sizeof(hetID),
+ pstr("---") );
+ k = AddHetName ( hetID );
+ Loop->GetString ( hetCompound[k]->comment,CIFTAG_NAME,i,true );
+ RC = Loop->GetInteger ( hetCompound[k]->compNum,
+ CIFTAG_NDB_COMPONENT_NO,i,true );
+ if (RC) hetCompound[i]->compNum = MinInt4;
+ Loop->GetString ( hetCompound[k]->Formula,CIFTAG_FORMULA,i,true );
+ RC = Loop->GetString ( F,CIFTAG_NDB_SYNONYMS,i,true );
+ if ((!RC) && F ) {
+ p1 = &(F[0]);
+ while (*p1) {
+ if (*p1=='\n') *p1 = ' ';
+ p1++;
+ }
+ p1 = &(F[0]);
+ do {
+ p2 = strchr ( p1,';' );
+ if (p2) {
+ c = *p2;
+ *p2 = char(0);
+ }
+ strcpy_css ( L,p1 );
+ hetCompound[i]->AddKeyWord ( L,true );
+ if (p2) {
+ *p2 = c;
+ p1 = p2+1;
+ }
+ } while (p2);
+ }
+ hetCompound[i]->wc = ' ';
+ }
+
+ // CIF->DeleteLoop ( CIFCAT_CHEM_COMP );
+
+ if (F) delete[] F;
+
+ return Error_NoError;
+
+ }
+
+ void HetCompounds::Copy ( PHetCompounds HetCompounds ) {
+ int i;
+ FreeMemory();
+ nHets = HetCompounds->nHets;
+ if (nHets>0) {
+ hetCompound = new PHetCompound[nHets];
+ for (i=0;i<nHets;i++) {
+ hetCompound[i] = new HetCompound ( "" );
+ hetCompound[i]->Copy ( HetCompounds->hetCompound[i] );
+ }
+ }
+ }
+
+ void HetCompounds::write ( io::RFile f ) {
+ int i;
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &nHets );
+ for (i=0;i<nHets;i++)
+ hetCompound[i]->write ( f );
+ }
+
+ void HetCompounds::read ( io::RFile f ) {
+ int i;
+ byte Version;
+ FreeMemory();
+ f.ReadByte ( &Version );
+ f.ReadInt ( &nHets );
+ if (nHets>0) {
+ hetCompound = new PHetCompound[nHets];
+ for (i=0;i<nHets;i++) {
+ hetCompound[i] = new HetCompound ( "---" );
+ hetCompound[i]->read ( f );
+ }
+ }
+ }
+
+ MakeStreamFunctions(HetCompounds)
+
+
+
+ // ==================== SSContainer =========================
+
+ PContainerClass SSContainer::MakeContainerClass ( int ClassID ) {
+ switch (ClassID) {
+ default :
+ case ClassID_Template : return
+ ClassContainer::MakeContainerClass(ClassID);
+ case ClassID_Helix : return new Helix();
+ case ClassID_Turn : return new Turn ();
+ }
+ }
+
+ MakeStreamFunctions(SSContainer)
+
+
+ // ================ Helix ===================
+
+ Helix::Helix() : ContainerClass() {
+ InitHelix();
+ }
+
+ Helix::Helix ( cpstr S ) : ContainerClass() {
+ InitHelix();
+ ConvertPDBASCII ( S );
+ }
+
+ Helix::Helix ( io::RPStream Object ) : ContainerClass(Object) {
+ InitHelix();
+ }
+
+ Helix::~Helix() {
+ if (comment) delete[] comment;
+ }
+
+ void Helix::InitHelix() {
+
+ serNum = 0; // serial number
+ strcpy ( helixID ,"---" ); // helix ID
+ strcpy ( initResName,"---" ); // name of the helix's initial residue
+ strcpy ( initChainID,"" ); // chain ID for the chain
+ // containing the helix
+ initSeqNum = 0; // sequence number of the initial
+ // residue
+ strcpy ( initICode ,"" ); // insertion code of the initial
+ // residue
+ strcpy ( endResName ,"---" ); // name of the helix's terminal residue
+ strcpy ( endChainID ,"" ); // chain ID for the chain
+ // containing the helix
+ endSeqNum = 0; // sequence number of the terminal
+ // residue
+ strcpy ( endICode ,"" ); // insertion code of the terminal
+ // residue
+ helixClass = 0; // helix class
+ comment = NULL; // comment about the helix
+ length = 0; // length of the helix
+
+ }
+
+ void Helix::PDBASCIIDump ( pstr S, int N ) {
+ UNUSED_ARGUMENT(N);
+ // makes the ASCII PDB OBSLTE line number N
+ // from the class' data
+ strcpy ( S,"HELIX" );
+ PadSpaces ( S,80 );
+ PutInteger ( &(S[7]) ,serNum ,3 );
+ strcpy_n1 ( &(S[11]),helixID ,3 );
+ strcpy_n1 ( &(S[15]),initResName,3 );
+ if (initChainID[0]) S[19] = initChainID[0];
+ PutIntIns ( &(S[21]),initSeqNum ,4,initICode );
+ strcpy_n1 ( &(S[27]),endResName ,3 );
+ if (endChainID[0]) S[31] = endChainID[0];
+ PutIntIns ( &(S[33]),endSeqNum ,4,endICode );
+ PutInteger ( &(S[38]),helixClass ,2 );
+ if (comment)
+ strcpy_n ( &(S[40]),comment ,30 );
+ PutInteger ( &(S[71]),length ,5 );
+ }
+
+ void AddStructConfTags ( mmcif::PLoop Loop ) {
+ Loop->AddLoopTag ( CIFTAG_CONF_TYPE_ID );
+ Loop->AddLoopTag ( CIFTAG_ID );
+ Loop->AddLoopTag ( CIFTAG_PDB_ID );
+ Loop->AddLoopTag ( CIFTAG_BEG_LABEL_COMP_ID );
+ Loop->AddLoopTag ( CIFTAG_BEG_LABEL_ASYM_ID );
+ Loop->AddLoopTag ( CIFTAG_BEG_LABEL_SEQ_ID );
+ Loop->AddLoopTag ( CIFTAG_NDB_BEG_LABEL_INS_CODE_PDB );
+ Loop->AddLoopTag ( CIFTAG_END_LABEL_COMP_ID );
+ Loop->AddLoopTag ( CIFTAG_END_LABEL_ASYM_ID );
+ Loop->AddLoopTag ( CIFTAG_END_LABEL_SEQ_ID );
+ Loop->AddLoopTag ( CIFTAG_NDB_END_LABEL_INS_CODE_PDB );
+ Loop->AddLoopTag ( CIFTAG_NDB_HELIX_CLASS_PDB );
+ Loop->AddLoopTag ( CIFTAG_DETAILS );
+ Loop->AddLoopTag ( CIFTAG_NDB_LENGTH );
+ }
+
+ #define HelixTypeID "HELX_P"
+
+ void Helix::MakeCIF ( mmcif::PData CIF, int N ) {
+ UNUSED_ARGUMENT(N);
+ mmcif::PLoop Loop;
+ int RC;
+ RC = CIF->AddLoop ( CIFCAT_STRUCT_CONF,Loop );
+ if (RC!=mmcif::CIFRC_Ok)
+ // the category was (re)created, provide tags
+ AddStructConfTags ( Loop );
+ Loop->AddString ( pstr(HelixTypeID) );
+ Loop->AddInteger ( serNum );
+ Loop->AddString ( helixID );
+ Loop->AddString ( initResName );
+ Loop->AddString ( initChainID );
+ Loop->AddInteger ( initSeqNum );
+ Loop->AddString ( initICode,true );
+ Loop->AddString ( endResName );
+ Loop->AddString ( endChainID );
+ Loop->AddInteger ( endSeqNum );
+ Loop->AddString ( endICode ,true );
+ Loop->AddInteger ( helixClass );
+ Loop->AddString ( comment );
+ Loop->AddInteger ( length );
+ }
+
+ ERROR_CODE Helix::ConvertPDBASCII ( cpstr S ) {
+ char L[100];
+ GetInteger ( serNum ,&(S[7]) ,3 );
+ strcpy_ncss ( helixID ,&(S[11]),3 );
+ strcpy_ncss ( initResName,&(S[15]),3 );
+ strcpy_ncss ( initChainID,&(S[19]),1 );
+ GetIntIns ( initSeqNum,initICode,&(S[21]),4 );
+ strcpy_ncss ( endResName ,&(S[27]),3 );
+ strcpy_ncss ( endChainID ,&(S[31]),1 );
+ GetIntIns ( endSeqNum ,endICode ,&(S[33]),4 );
+ GetInteger ( helixClass ,&(S[38]),2 );
+ strcpy_ncss ( L ,&(S[40]),30 );
+ CreateCopy ( comment ,L );
+ GetInteger ( length ,&(S[71]),5 );
+ return Error_NoError;
+ }
+
+ ERROR_CODE Helix::GetCIF ( mmcif::PData CIF, int & n ) {
+ mmcif::PLoop Loop;
+ int RC,l;
+ pstr F;
+ bool Done;
+ ERROR_CODE rc;
+
+ Loop = CIF->GetLoop ( CIFCAT_STRUCT_CONF );
+ if (!Loop) {
+ n = -1; // signal to finish processing of this structure
+ return Error_EmptyCIF;
+ }
+
+ l = Loop->GetLoopLength();
+ Done = n>=l;
+ while (!Done) {
+ F = Loop->GetString ( CIFTAG_CONF_TYPE_ID,n,RC );
+ if ((!RC) && F) Done = (strcmp(F,HelixTypeID)==0);
+ else Done = false;
+ if (!Done) {
+ n++;
+ Done = n>=l;
+ }
+ }
+
+ if (n>=l) {
+ n = -1; // finish processing of Helix
+ return Error_EmptyCIF;
+ }
+
+ Loop->DeleteField ( CIFTAG_CONF_TYPE_ID,n );
+
+ rc = CIFGetInteger ( serNum,Loop,CIFTAG_ID,n );
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+
+ CIFGetString ( helixID ,Loop,CIFTAG_PDB_ID,
+ n,sizeof(helixID),pstr(" ") );
+
+ CIFGetString ( initResName,Loop,CIFTAG_BEG_LABEL_COMP_ID,
+ n,sizeof(initResName),pstr(" ") );
+ CIFGetString ( initChainID,Loop,CIFTAG_BEG_LABEL_ASYM_ID,
+ n,sizeof(initChainID),pstr("") );
+ CIFGetString ( initICode ,Loop,CIFTAG_NDB_BEG_LABEL_INS_CODE_PDB,
+ n,sizeof(initICode),pstr("") );
+ if (CIFGetInteger(initSeqNum,Loop,CIFTAG_BEG_LABEL_SEQ_ID,n))
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+
+ CIFGetString ( endResName,Loop,CIFTAG_END_LABEL_COMP_ID,
+ n,sizeof(endResName),pstr(" ") );
+ CIFGetString ( endChainID,Loop,CIFTAG_END_LABEL_ASYM_ID,
+ n,sizeof(endChainID),pstr("") );
+ CIFGetString ( endICode ,Loop,CIFTAG_NDB_END_LABEL_INS_CODE_PDB,
+ n,sizeof(endICode),pstr("") );
+ rc = CIFGetInteger(endSeqNum,Loop,CIFTAG_END_LABEL_SEQ_ID,n );
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+
+ rc = CIFGetInteger(helixClass,Loop,CIFTAG_NDB_HELIX_CLASS_PDB,n );
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+
+ CreateCopy ( comment,Loop->GetString(CIFTAG_DETAILS,n,RC));
+ Loop->DeleteField ( CIFTAG_DETAILS,n );
+ rc = CIFGetInteger ( length,Loop,CIFTAG_NDB_LENGTH,n );
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+
+ n++;
+
+ return Error_NoError;
+
+ }
+
+ void Helix::Copy ( PContainerClass Helix ) {
+ serNum = PHelix(Helix)->serNum;
+ initSeqNum = PHelix(Helix)->initSeqNum;
+ endSeqNum = PHelix(Helix)->endSeqNum;
+ helixClass = PHelix(Helix)->helixClass;
+ length = PHelix(Helix)->length;
+ strcpy ( helixID ,PHelix(Helix)->helixID );
+ strcpy ( initResName,PHelix(Helix)->initResName );
+ strcpy ( initChainID,PHelix(Helix)->initChainID );
+ strcpy ( initICode ,PHelix(Helix)->initICode );
+ strcpy ( endResName ,PHelix(Helix)->endResName );
+ strcpy ( endChainID ,PHelix(Helix)->endChainID );
+ strcpy ( endICode ,PHelix(Helix)->endICode );
+ CreateCopy ( comment,PHelix(Helix)->comment );
+ }
+
+ void Helix::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &serNum );
+ f.WriteInt ( &initSeqNum );
+ f.WriteInt ( &endSeqNum );
+ f.WriteInt ( &helixClass );
+ f.WriteInt ( &length );
+ f.WriteTerLine ( helixID ,false );
+ f.WriteTerLine ( initResName,false );
+ f.WriteTerLine ( initChainID,false );
+ f.WriteTerLine ( initICode ,false );
+ f.WriteTerLine ( endResName ,false );
+ f.WriteTerLine ( endChainID ,false );
+ f.WriteTerLine ( endICode ,false );
+ f.CreateWrite ( comment );
+ }
+
+ void Helix::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ f.ReadInt ( &serNum );
+ f.ReadInt ( &initSeqNum );
+ f.ReadInt ( &endSeqNum );
+ f.ReadInt ( &helixClass );
+ f.ReadInt ( &length );
+ f.ReadTerLine ( helixID ,false );
+ f.ReadTerLine ( initResName,false );
+ f.ReadTerLine ( initChainID,false );
+ f.ReadTerLine ( initICode ,false );
+ f.ReadTerLine ( endResName ,false );
+ f.ReadTerLine ( endChainID ,false );
+ f.ReadTerLine ( endICode ,false );
+ f.CreateRead ( comment );
+ }
+
+ MakeStreamFunctions(Helix)
+
+
+
+ // ================ Strand =====================
+
+ Strand::Strand () : io::Stream() {
+ InitStrand();
+ }
+
+ Strand::Strand ( io::RPStream Object ) : io::Stream(Object) {
+ InitStrand();
+ }
+
+ Strand::~Strand() {
+ }
+
+ void Strand::InitStrand() {
+ initSeqNum = MinInt4;
+ endSeqNum = MinInt4;
+ sense = 0;
+ curResSeq = MinInt4;
+ prevResSeq = MinInt4;
+ strandNo = 0;
+ strcpy ( sheetID ,"sheet_0" );
+ strcpy ( initResName," " );
+ strcpy ( initChainID,"" );
+ strcpy ( initICode ,"" );
+ strcpy ( endResName ," " );
+ strcpy ( endChainID ,"" );
+ strcpy ( endICode ,"" );
+ strcpy ( curAtom ," " );
+ strcpy ( curResName ," " );
+ strcpy ( curChainID ,"" );
+ strcpy ( curICode ,"" );
+ strcpy ( prevAtom ," " );
+ strcpy ( prevResName," " );
+ strcpy ( prevChainID,"" );
+ strcpy ( prevICode ,"" );
+ }
+
+ void Strand::PDBASCIIDump ( pstr S ) {
+ // Finishes making the ASCII PDB SHEET line number N
+ // from the class' data. Making is initiated by Sheet.
+
+ strcpy_n1 ( &(S[17]),initResName,3 );
+ if (initChainID[0]) S[21] = initChainID[0];
+ PutIntIns ( &(S[22]),initSeqNum ,4,initICode );
+
+ strcpy_n1 ( &(S[28]),endResName ,3 );
+ if (endChainID[0]) S[32] = endChainID[0];
+ PutIntIns ( &(S[33]),endSeqNum ,4,endICode );
+
+ PutInteger ( &(S[38]),sense ,2 );
+
+ strcpy_n1 ( &(S[41]),curAtom ,4 );
+ strcpy_n1 ( &(S[45]),curResName ,3 );
+ if (curChainID[0]) S[49] = curChainID[0];
+ PutIntIns ( &(S[50]),curResSeq ,4,curICode );
+
+ strcpy_n1 ( &(S[56]),prevAtom ,4 );
+ strcpy_n1 ( &(S[60]),prevResName,3 );
+ if (prevChainID[0]) S[64] = prevChainID[0];
+ PutIntIns ( &(S[65]),prevResSeq ,4,prevICode );
+
+ }
+
+
+ void Strand::MakeCIF ( mmcif::PData CIF ) {
+ mmcif::PLoop Loop;
+ int RC;
+
+ RC = CIF->AddLoop ( CIFCAT_STRUCT_SHEET_RANGE,Loop );
+ if (RC!=mmcif::CIFRC_Ok) {
+ // the category was (re)created, provide tags
+ Loop->AddLoopTag ( CIFTAG_SHEET_ID );
+ Loop->AddLoopTag ( CIFTAG_ID );
+ Loop->AddLoopTag ( CIFTAG_BEG_LABEL_COMP_ID );
+ Loop->AddLoopTag ( CIFTAG_BEG_LABEL_ASYM_ID );
+ Loop->AddLoopTag ( CIFTAG_BEG_LABEL_SEQ_ID );
+ Loop->AddLoopTag ( CIFTAG_NDB_BEG_LABEL_INS_CODE_PDB );
+ Loop->AddLoopTag ( CIFTAG_END_LABEL_COMP_ID );
+ Loop->AddLoopTag ( CIFTAG_END_LABEL_ASYM_ID );
+ Loop->AddLoopTag ( CIFTAG_END_LABEL_SEQ_ID );
+ Loop->AddLoopTag ( CIFTAG_NDB_END_LABEL_INS_CODE_PDB );
+ }
+ Loop->AddString ( sheetID );
+ Loop->AddInteger ( strandNo );
+ Loop->AddString ( initResName );
+ Loop->AddString ( initChainID );
+ Loop->AddInteger ( initSeqNum );
+ Loop->AddString ( initICode,true );
+ Loop->AddString ( endResName );
+ Loop->AddString ( endChainID );
+ Loop->AddInteger ( endSeqNum );
+ Loop->AddString ( endICode ,true );
+
+ }
+
+
+ ERROR_CODE Strand::ConvertPDBASCII ( cpstr S ) {
+
+ GetInteger ( strandNo ,&(S[7]) ,3 );
+ strcpy_ncss ( sheetID ,&(S[11]) ,3 );
+
+ strcpy_ncss ( initResName,&(S[17]) ,3 );
+ strcpy_ncss ( initChainID,&(S[21]) ,1 );
+ GetIntIns ( initSeqNum ,initICode,&(S[22]),4 );
+
+ strcpy_ncss ( endResName ,&(S[28]) ,3 );
+ strcpy_ncss ( endChainID ,&(S[32]) ,1 );
+ GetIntIns ( endSeqNum ,endICode ,&(S[33]),4 );
+
+ GetInteger ( sense ,&(S[38]) ,2 );
+
+ GetString ( curAtom ,&(S[41]) ,4 );
+ strcpy_ncss ( curResName ,&(S[45]) ,3 );
+ strcpy_ncss ( curChainID ,&(S[49]) ,1 );
+ GetIntIns ( curResSeq ,curICode ,&(S[50]),4 );
+
+ GetString ( prevAtom ,&(S[56]) ,4 );
+ strcpy_ncss ( prevResName,&(S[60]) ,3 );
+ strcpy_ncss ( prevChainID,&(S[64]) ,1 );
+ GetIntIns ( prevResSeq ,prevICode,&(S[65]),4 );
+
+ return Error_NoError;
+
+ }
+
+ int Strand::GetCIF ( mmcif::PData CIF, cpstr sheet_id ) {
+ mmcif::PLoop Loop;
+ int RC,l,i,sNo;
+ pstr F;
+
+ Loop = CIF->GetLoop ( CIFCAT_STRUCT_SHEET_RANGE );
+ if (Loop) {
+ l = Loop->GetLoopLength();
+ i = 0;
+ while (i<l) {
+ F = Loop->GetString ( CIFTAG_SHEET_ID,i,RC );
+ if (F && (!RC)) {
+ if (!strcmp(F,sheet_id)) {
+ strcpy ( sheetID,sheet_id );
+ if (CIFGetInteger(sNo,Loop,CIFTAG_ID,i)) return i;
+ if (sNo==strandNo) {
+ CIFGetString ( initResName,Loop,CIFTAG_BEG_LABEL_COMP_ID,
+ i,sizeof(initResName),pstr(" ") );
+ CIFGetString ( initChainID,Loop,CIFTAG_BEG_LABEL_ASYM_ID,
+ i,sizeof(initChainID),pstr("") );
+ CIFGetString ( initICode,Loop,
+ CIFTAG_NDB_BEG_LABEL_INS_CODE_PDB,
+ i,sizeof(initICode),pstr("") );
+ if (CIFGetInteger(initSeqNum,Loop,
+ CIFTAG_BEG_LABEL_SEQ_ID,i))
+ return i;
+ CIFGetString ( endResName,Loop,CIFTAG_END_LABEL_COMP_ID,
+ i,sizeof(endResName),pstr(" ") );
+ CIFGetString ( endChainID,Loop,CIFTAG_END_LABEL_ASYM_ID,
+ i,sizeof(endChainID),pstr("") );
+ CIFGetString ( endICode ,Loop,
+ CIFTAG_NDB_END_LABEL_INS_CODE_PDB,
+ i,sizeof(endICode),pstr("") );
+ if (CIFGetInteger(endSeqNum,Loop,
+ CIFTAG_END_LABEL_SEQ_ID,i))
+ return i;
+ Loop->DeleteRow ( i );
+ i = l+100; // break the loop
+ }
+ }
+ }
+ i++;
+ }
+ }
+
+ return 0;
+
+ }
+
+ void Strand::Copy ( PStrand Strand ) {
+ initSeqNum = Strand->initSeqNum;
+ endSeqNum = Strand->endSeqNum;
+ sense = Strand->sense;
+ curResSeq = Strand->curResSeq;
+ prevResSeq = Strand->prevResSeq;
+ strcpy ( initResName,Strand->initResName );
+ strcpy ( initChainID,Strand->initChainID );
+ strcpy ( initICode ,Strand->initICode );
+ strcpy ( endResName ,Strand->endResName );
+ strcpy ( endChainID ,Strand->endChainID );
+ strcpy ( endICode ,Strand->endICode );
+ strcpy ( curAtom ,Strand->curAtom );
+ strcpy ( curResName ,Strand->curResName );
+ strcpy ( curChainID ,Strand->curChainID );
+ strcpy ( curICode ,Strand->curICode );
+ strcpy ( prevAtom ,Strand->prevAtom );
+ strcpy ( prevResName,Strand->prevResName );
+ strcpy ( prevChainID,Strand->prevChainID );
+ strcpy ( prevICode ,Strand->prevICode );
+ }
+
+ void Strand::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &initSeqNum );
+ f.WriteInt ( &endSeqNum );
+ f.WriteInt ( &sense );
+ f.WriteInt ( &curResSeq );
+ f.WriteInt ( &prevResSeq );
+ f.WriteTerLine ( initResName,false );
+ f.WriteTerLine ( initChainID,false );
+ f.WriteTerLine ( initICode ,false );
+ f.WriteTerLine ( endResName ,false );
+ f.WriteTerLine ( endChainID ,false );
+ f.WriteTerLine ( endICode ,false );
+ f.WriteTerLine ( curAtom ,false );
+ f.WriteTerLine ( curResName ,false );
+ f.WriteTerLine ( curChainID ,false );
+ f.WriteTerLine ( curICode ,false );
+ f.WriteTerLine ( prevAtom ,false );
+ f.WriteTerLine ( prevResName,false );
+ f.WriteTerLine ( prevChainID,false );
+ f.WriteTerLine ( prevICode ,false );
+ }
+
+ void Strand::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ f.ReadInt ( &initSeqNum );
+ f.ReadInt ( &endSeqNum );
+ f.ReadInt ( &sense );
+ f.ReadInt ( &curResSeq );
+ f.ReadInt ( &prevResSeq );
+ f.ReadTerLine ( initResName,false );
+ f.ReadTerLine ( initChainID,false );
+ f.ReadTerLine ( initICode ,false );
+ f.ReadTerLine ( endResName ,false );
+ f.ReadTerLine ( endChainID ,false );
+ f.ReadTerLine ( endICode ,false );
+ f.ReadTerLine ( curAtom ,false );
+ f.ReadTerLine ( curResName ,false );
+ f.ReadTerLine ( curChainID ,false );
+ f.ReadTerLine ( curICode ,false );
+ f.ReadTerLine ( prevAtom ,false );
+ f.ReadTerLine ( prevResName,false );
+ f.ReadTerLine ( prevChainID,false );
+ f.ReadTerLine ( prevICode ,false );
+ }
+
+ MakeStreamFunctions(Strand)
+
+
+
+
+ // ================ Sheet ===================
+
+ Sheet::Sheet() : io::Stream() {
+ InitSheet();
+ }
+
+ Sheet::Sheet ( io::RPStream Object ) : io::Stream(Object) {
+ InitSheet();
+ }
+
+ Sheet::~Sheet() {
+ FreeMemory();
+ }
+
+ void Sheet::InitSheet() {
+ nStrands = 0;
+ sheetID[0] = char(0);
+ strand = NULL;
+ }
+
+ void Sheet::FreeMemory() {
+ int i;
+ if (strand) {
+ for (i=0;i<nStrands;i++)
+ if (strand[i]) delete strand[i];
+ delete[] strand;
+ strand = NULL;
+ }
+ nStrands = 0;
+ sheetID[0] = char(0);
+ }
+
+ void Sheet::PDBASCIIDump ( io::RFile f ) {
+ char S[100];
+ int i;
+ if (strand)
+ for (i=0;i<nStrands;i++)
+ if (strand[i]) {
+ strcpy ( S,"SHEET" );
+ PadSpaces ( S,80 );
+ PutInteger ( &(S[7]) ,i+1 ,3 );
+ strcpy_n1 ( &(S[11]),sheetID ,3 );
+ PutInteger ( &(S[14]),nStrands,2 );
+ strand[i]->PDBASCIIDump ( S );
+ f.WriteLine ( S );
+ }
+ }
+
+ void Sheet::OrderSheet() {
+ int i,k;
+ PPStrand strand1;
+ k = 0;
+ for (i=0;i<nStrands;i++)
+ if (strand[i]) k++;
+ if (k<nStrands) {
+ strand1 = new PStrand[k];
+ k = 0;
+ for (i=0;i<nStrands;i++)
+ if (strand[i]) strand1[k++] = strand[i];
+ if (strand) delete[] strand;
+ strand = strand1;
+ nStrands = k;
+ }
+ }
+
+ void Sheet::MakeCIF ( mmcif::PData CIF ) {
+ mmcif::PLoop Loop;
+ int RC;
+ int i;
+ bool isSense;
+
+ OrderSheet();
+
+ RC = CIF->AddLoop ( CIFCAT_STRUCT_SHEET,Loop );
+ if (RC!=mmcif::CIFRC_Ok) {
+ // the category was (re)created, provide tags
+ Loop->AddLoopTag ( CIFTAG_SHEET_ID );
+ Loop->AddLoopTag ( CIFTAG_NUMBER_STRANDS );
+ }
+ Loop->AddString ( sheetID );
+ Loop->AddInteger ( nStrands );
+
+ for (i=0;i<nStrands;i++) {
+ strand[i]->MakeCIF ( CIF );
+ if (strand[i]->sense!=0) isSense = true;
+ }
+
+ if (nStrands>1) {
+
+ if (isSense) {
+ RC = CIF->AddLoop ( CIFCAT_STRUCT_SHEET_ORDER,Loop );
+ if (RC!=mmcif::CIFRC_Ok) {
+ // the category was (re)created, provide tags
+ Loop->AddLoopTag ( CIFTAG_SHEET_ID );
+ Loop->AddLoopTag ( CIFTAG_RANGE_ID_1 );
+ Loop->AddLoopTag ( CIFTAG_RANGE_ID_2 );
+ Loop->AddLoopTag ( CIFTAG_SENSE );
+ }
+ for (i=1;i<nStrands;i++) {
+ Loop->AddString ( sheetID );
+ Loop->AddInteger ( strand[i-1]->strandNo );
+ Loop->AddInteger ( strand[i] ->strandNo );
+ if (strand[i]->sense>0)
+ Loop->AddString ( pstr("parallel") );
+ else Loop->AddString ( pstr("anti-parallel") );
+ }
+ }
+
+ RC = CIF->AddLoop ( CIFCAT_STRUCT_SHEET_HBOND,Loop );
+ if (RC!=mmcif::CIFRC_Ok) {
+ // the category was (re)created, provide tags
+ Loop->AddLoopTag ( CIFTAG_SHEET_ID );
+ Loop->AddLoopTag ( CIFTAG_RANGE_ID_1 );
+ Loop->AddLoopTag ( CIFTAG_RANGE_ID_2 );
+ Loop->AddLoopTag ( CIFTAG_RANGE_1_BEG_LABEL_ATOM_ID );
+ Loop->AddLoopTag ( CIFTAG_NDB_RANGE_1_BEG_LABEL_COMP_ID );
+ Loop->AddLoopTag ( CIFTAG_NDB_RANGE_1_BEG_LABEL_ASYM_ID );
+ Loop->AddLoopTag ( CIFTAG_RANGE_1_BEG_LABEL_SEQ_ID );
+ Loop->AddLoopTag ( CIFTAG_NDB_RANGE_1_BEG_LABEL_INS_CODE );
+ Loop->AddLoopTag ( CIFTAG_RANGE_1_END_LABEL_ATOM_ID );
+ Loop->AddLoopTag ( CIFTAG_NDB_RANGE_1_END_LABEL_COMP_ID );
+ Loop->AddLoopTag ( CIFTAG_NDB_RANGE_1_END_LABEL_ASYM_ID );
+ Loop->AddLoopTag ( CIFTAG_RANGE_1_END_LABEL_SEQ_ID );
+ Loop->AddLoopTag ( CIFTAG_NDB_RANGE_1_END_LABEL_INS_CODE );
+ }
+ for (i=1;i<nStrands;i++) {
+ Loop->AddString ( sheetID );
+ Loop->AddInteger ( strand[i-1]->strandNo );
+ Loop->AddInteger ( strand[i]->strandNo );
+ Loop->AddString ( strand[i]->curAtom );
+ Loop->AddString ( strand[i]->curResName );
+ Loop->AddString ( strand[i]->curChainID );
+ Loop->AddInteger ( strand[i]->curResSeq );
+ Loop->AddString ( strand[i]->curICode ,true );
+ Loop->AddString ( strand[i]->prevAtom );
+ Loop->AddString ( strand[i]->prevResName );
+ Loop->AddString ( strand[i]->prevChainID );
+ Loop->AddInteger ( strand[i]->prevResSeq );
+ Loop->AddString ( strand[i]->prevICode,true );
+ }
+ }
+
+ }
+
+
+ ERROR_CODE Sheet::ConvertPDBASCII ( cpstr S ) {
+ int i,k,ns;
+ SheetID SID;
+ PPStrand strand1;
+
+ GetInteger ( k ,&(S[7]) ,3 );
+ strcpy_ncss ( SID,&(S[11]),3 );
+ GetInteger ( ns ,&(S[14]),2 );
+
+ // if (!SID[0]) return Error_NoSheetID;
+ if (!sheetID[0]) strcpy ( sheetID,SID );
+ else if (strcmp(sheetID,SID))
+ return Error_WrongSheetID;
+
+ if (k<=0) return Error_WrongStrandNo;
+
+ ns = IMax(k,ns);
+ if (!strand) {
+ strand = new PStrand[ns];
+ for (i=0;i<ns;i++)
+ strand[i] = NULL;
+ } else if (ns>nStrands) {
+ strand1 = new PStrand[ns];
+ for (i=0;i<nStrands;i++)
+ strand1[i] = strand[i];
+ for (i=nStrands;i<ns;i++)
+ strand1[i] = NULL;
+ if (strand) delete[] strand;
+ strand = strand1;
+ }
+ nStrands = ns;
+
+ k--;
+ if (!strand[k]) strand[k] = new Strand();
+
+ return strand[k]->ConvertPDBASCII ( S );
+
+ }
+
+ void Sheet::TryStrand ( int strand_no ) {
+ int i,k;
+ PPStrand strand1;
+ k = -1;
+ for (i=0;(i<nStrands) && (k<0);i++)
+ if (strand[i])
+ if (strand[i]->strandNo==strand_no) k = i;
+ if (k<0) {
+ strand1 = new PStrand[nStrands+1];
+ for (i=0;i<nStrands;i++)
+ strand1[i] = strand[i];
+ if (strand) delete[] strand;
+ strand = strand1;
+ strand[nStrands] = new Strand();
+ strand[nStrands]->strandNo = strand_no;
+ nStrands++;
+ }
+ }
+
+
+ void Sheet::CIFFindStrands ( mmcif::PData CIF, cpstr Category ) {
+ // just look for all strands mentioned for the sheet
+ mmcif::PLoop Loop;
+ pstr F;
+ int RC,i,l,sNo;
+ Loop = CIF->GetLoop ( Category );
+ if (Loop) {
+ l = Loop->GetLoopLength();
+ for (i=0;i<l;i++) {
+ F = Loop->GetString ( CIFTAG_SHEET_ID,i,RC );
+ if (F && (!RC)) {
+ if (!strcmp(F,sheetID)) {
+ if (!Loop->GetInteger(sNo,CIFTAG_ID,i))
+ TryStrand ( sNo );
+ if (!Loop->GetInteger(sNo,CIFTAG_RANGE_ID_1,i))
+ TryStrand ( sNo );
+ if (!Loop->GetInteger(sNo,CIFTAG_RANGE_ID_2,i))
+ TryStrand ( sNo );
+ }
+ }
+ }
+ }
+ }
+
+ int Sheet::GetStrand ( int strand_no ) {
+ int i;
+ for (i=0;i<nStrands;i++)
+ if (strand[i]) {
+ if (strand[i]->strandNo==strand_no)
+ return i;
+ }
+ return -1;
+ }
+
+ int Sheet::GetCIF ( mmcif::PData CIF ) {
+ mmcif::PLoop Loop;
+ int i,ns,l,k,k2,RC,sNo;
+ pstr F;
+ ivector pair;
+ bool Ok;
+
+ pair = NULL;
+
+ // First find all strands and create
+ // the corresponding classes. The CIF fields
+ // are not removed at this stage.
+
+ CIFFindStrands ( CIF,CIFCAT_STRUCT_SHEET_ORDER );
+ CIFFindStrands ( CIF,CIFCAT_STRUCT_SHEET_RANGE );
+ CIFFindStrands ( CIF,CIFCAT_STRUCT_SHEET_HBOND );
+
+ // Check number of strands
+ Loop = CIF->GetLoop ( CIFCAT_STRUCT_SHEET );
+ if (Loop) {
+ l = Loop->GetLoopLength();
+ i = 0;
+ while (i<l) {
+ F = Loop->GetString ( CIFTAG_SHEET_ID,i,RC );
+ if (F && (!RC)) {
+ if (!strcmp(F,sheetID)) {
+ RC = CIFGetInteger1 ( ns,Loop,CIFTAG_NUMBER_STRANDS,i );
+ if ((!RC) && (ns!=nStrands))
+ return Error_WrongNumberOfStrands;
+ Loop->DeleteRow ( i );
+ i = l+100; // break loop
+ }
+ }
+ i++;
+ }
+ }
+
+ // Read each strand
+ RC = 0;
+ for (i=0;(i<nStrands) && (!RC);i++)
+ RC = strand[i]->GetCIF ( CIF,sheetID );
+
+ if (RC) return RC;
+
+ if (nStrands>1) {
+
+ GetVectorMemory ( pair,nStrands,0 );
+ for (i=0;i<nStrands;i++)
+ pair[i] = -1;
+
+ Loop = CIF->GetLoop ( CIFCAT_STRUCT_SHEET_ORDER );
+ if (Loop) {
+ Ok = true;
+ l = Loop->GetLoopLength();
+ for (i=0;(i<l) && Ok;i++) {
+ F = Loop->GetString ( CIFTAG_SHEET_ID,i,RC );
+ if (F && (!RC)) {
+ if (!strcmp(F,sheetID)) {
+ if (!Loop->GetInteger(sNo,CIFTAG_RANGE_ID_1,i)) {
+ k = GetStrand ( sNo );
+ if ((k>=0) &&
+ (!Loop->GetInteger(sNo,CIFTAG_RANGE_ID_2,i))) {
+ pair[k] = GetStrand ( sNo );
+ if (pair[k]>=0) {
+ F = Loop->GetString ( CIFTAG_SENSE,i,RC );
+ if (F && (!RC)) {
+ if (!strcasecmp(F,"anti-parallel"))
+ strand[pair[k]]->sense = -1;
+ else if (!strcasecmp(F,"parallel"))
+ strand[pair[k]]->sense = 1;
+ }
+ Loop->DeleteRow ( i );
+ } else
+ Ok = false;
+ } else
+ Ok = false;
+ } else
+ Ok = false;
+ }
+ }
+ }
+ if (!Ok) {
+ FreeVectorMemory ( pair,0 );
+ return Error_WrongSheetOrder;
+ }
+ }
+
+ Loop = CIF->GetLoop ( CIFCAT_STRUCT_SHEET_HBOND );
+ if (Loop) {
+ Ok = true;
+ l = Loop->GetLoopLength();
+ for (i=0;(i<l) && Ok;i++) {
+ F = Loop->GetString ( CIFTAG_SHEET_ID,i,RC );
+ if (F && (!RC)) {
+ if (!strcmp(F,sheetID)) {
+ if (!Loop->GetInteger(sNo,CIFTAG_RANGE_ID_1,i)) {
+ k = GetStrand ( sNo );
+ if ((k>=0) &&
+ (!Loop->GetInteger(sNo,CIFTAG_RANGE_ID_1,i))) {
+ k2 = GetStrand ( sNo );
+ if (k2>=0) {
+ if (pair[k]==k2) {
+ CIFGetString ( strand[k2]->curAtom,Loop,
+ CIFTAG_RANGE_1_BEG_LABEL_ATOM_ID,
+ i,sizeof(strand[k2]->curAtom),
+ pstr(" ") );
+ CIFGetString ( strand[k2]->curResName,Loop,
+ CIFTAG_NDB_RANGE_1_BEG_LABEL_COMP_ID,
+ i,sizeof(strand[k2]->curResName),
+ pstr(" ") );
+ CIFGetString ( strand[k2]->curChainID,Loop,
+ CIFTAG_NDB_RANGE_1_BEG_LABEL_ASYM_ID,
+ i,sizeof(strand[k2]->curChainID),
+ pstr(" ") );
+ if (CIFGetInteger(strand[k2]->curResSeq,Loop,
+ CIFTAG_RANGE_1_BEG_LABEL_SEQ_ID,i)) {
+ FreeVectorMemory ( pair,0 );
+ return i;
+ }
+ CIFGetString ( strand[k2]->curICode,Loop,
+ CIFTAG_NDB_RANGE_1_BEG_LABEL_INS_CODE,
+ i,sizeof(strand[k2]->curICode),
+ pstr(" ") );
+ CIFGetString ( strand[k2]->prevAtom,Loop,
+ CIFTAG_RANGE_1_END_LABEL_ATOM_ID,
+ i,sizeof(strand[k2]->prevAtom),
+ pstr(" ") );
+ CIFGetString ( strand[k2]->prevResName,Loop,
+ CIFTAG_NDB_RANGE_1_END_LABEL_COMP_ID,
+ i,sizeof(strand[k2]->prevResName),
+ pstr(" ") );
+ CIFGetString ( strand[k2]->prevChainID,Loop,
+ CIFTAG_NDB_RANGE_1_END_LABEL_ASYM_ID,
+ i,sizeof(strand[k2]->prevChainID),
+ pstr(" ") );
+ if (CIFGetInteger(strand[k2]->prevResSeq,Loop,
+ CIFTAG_RANGE_1_END_LABEL_SEQ_ID,i)) {
+ FreeVectorMemory ( pair,0 );
+ return i;
+ }
+ CIFGetString ( strand[k2]->prevICode,Loop,
+ CIFTAG_NDB_RANGE_1_END_LABEL_INS_CODE,
+ i,sizeof(strand[k2]->prevICode),
+ pstr(" ") );
+ Loop->DeleteRow ( i );
+ } else
+ Ok = false;
+ } else
+ Ok = false;
+ } else
+ Ok = false;
+ } else
+ Ok = false;
+ }
+ }
+ }
+ if (!Ok) {
+ FreeVectorMemory ( pair,0 );
+ return Error_HBondInconsistency;
+ }
+ }
+ }
+
+ FreeVectorMemory ( pair,0 );
+
+ return 0;
+
+ }
+
+
+ void Sheet::Copy ( PSheet Sheet ) {
+ int i;
+ FreeMemory();
+ nStrands = Sheet->nStrands;
+ if (nStrands>0) {
+ strand = new PStrand[nStrands];
+ for (i=0;i<nStrands;i++)
+ if (Sheet->strand[i]) {
+ strand[i] = new Strand();
+ strand[i]->Copy ( Sheet->strand[i] );
+ } else
+ strand[i] = NULL;
+ }
+ strcpy ( sheetID,Sheet->sheetID );
+ }
+
+ void Sheet::write ( io::RFile f ) {
+ int i;
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &nStrands );
+ for (i=0;i<nStrands;i++)
+ StreamWrite ( f,strand[i] );
+ f.WriteTerLine ( sheetID,false );
+ }
+
+ void Sheet::read ( io::RFile f ) {
+ int i;
+ byte Version;
+ FreeMemory();
+ f.ReadByte ( &Version );
+ f.ReadInt ( &nStrands );
+ if (nStrands>0) {
+ strand = new PStrand[nStrands];
+ for (i=0;i<nStrands;i++) {
+ strand[i] = NULL;
+ StreamRead ( f,strand[i] );
+ }
+ }
+ f.ReadTerLine ( sheetID,false );
+ }
+
+ MakeStreamFunctions(Sheet)
+
+
+
+ // ==================== Sheets ============================
+
+
+ Sheets::Sheets() : io::Stream() {
+ InitSheets();
+ }
+
+
+ Sheets::Sheets ( io::RPStream Object ) : io::Stream ( Object ) {
+ InitSheets();
+ }
+
+
+ Sheets::~Sheets() {
+ FreeMemory();
+ }
+
+
+ void Sheets::InitSheets() {
+ nSheets = 0;
+ sheet = NULL;
+ }
+
+
+ void Sheets::FreeMemory() {
+ int i;
+ if (sheet) {
+ for (i=0;i<nSheets;i++)
+ if (sheet[i]) delete sheet[i];
+ delete[] sheet;
+ sheet = NULL;
+ }
+ nSheets = 0;
+ }
+
+
+ void Sheets::PDBASCIIDump ( io::RFile f ) {
+ int i;
+ if (sheet)
+ for (i=0;i<nSheets;i++)
+ if (sheet[i]) sheet[i]->PDBASCIIDump ( f );
+ }
+
+
+ void Sheets::MakeCIF ( mmcif::PData CIF ) {
+ int i;
+ if (sheet)
+ for (i=0;i<nSheets;i++)
+ if (sheet[i]) sheet[i]->MakeCIF ( CIF );
+ }
+
+
+ ERROR_CODE Sheets::ConvertPDBASCII ( cpstr S ) {
+ PPSheet sheet1;
+ SheetID sheetID;
+ int i,k;
+ strcpy_ncss ( sheetID,&(S[11]),3 );
+ // if (!sheetID[0]) return Error_NoSheetID;
+ k = -1;
+ for (i=0;i<nSheets;i++)
+ if (sheet[i]) {
+ if (!strcmp(sheetID,sheet[i]->sheetID)) {
+ k = i;
+ break;
+ }
+ }
+ if (k<0) {
+ sheet1 = new PSheet[nSheets+1];
+ for (i=0;i<nSheets;i++)
+ sheet1[i] = sheet[i];
+ if (sheet) delete[] sheet;
+ sheet = sheet1;
+ sheet[nSheets] = new Sheet();
+ k = nSheets;
+ nSheets++;
+ }
+ return sheet[k]->ConvertPDBASCII ( S );
+ }
+
+
+ void Sheets::CIFFindSheets ( mmcif::PData CIF, cpstr Category ) {
+ mmcif::PLoop Loop;
+ int RC,i,j,k,l;
+ pstr F;
+ PPSheet sheet1;
+ Loop = CIF->GetLoop ( Category );
+ if (Loop) {
+ l = Loop->GetLoopLength();
+ for (i=0;i<l;i++) {
+ F = Loop->GetString ( CIFTAG_SHEET_ID,i,RC );
+ if (F && (!RC)) {
+ k = -1;
+ j = 0;
+ while ((j<nSheets) && (k<0)) {
+ if (sheet[j]) {
+ if (!strcmp(F,sheet[j]->sheetID)) k = j;
+ }
+ j++;
+ }
+ if (k<0) {
+ sheet1 = new PSheet[nSheets+1];
+ for (i=0;i<nSheets;i++)
+ sheet1[i] = sheet[i];
+ if (sheet) delete[] sheet;
+ sheet = sheet1;
+ sheet[nSheets] = new Sheet();
+ strcpy ( sheet[nSheets]->sheetID,F );
+ nSheets++;
+ }
+ }
+ }
+ }
+ }
+
+ int Sheets::GetCIF ( mmcif::PData CIF ) {
+ int i,RC;
+
+ FreeMemory();
+
+ // First find all sheet names and create
+ // the corresponding classes. The CIF fields
+ // are not removed at this stage.
+
+ CIFFindSheets ( CIF,CIFCAT_STRUCT_SHEET );
+ CIFFindSheets ( CIF,CIFCAT_STRUCT_SHEET_ORDER );
+ CIFFindSheets ( CIF,CIFCAT_STRUCT_SHEET_RANGE );
+ CIFFindSheets ( CIF,CIFCAT_STRUCT_SHEET_HBOND );
+
+ // Read each sheet
+ i = 0;
+ RC = 0;
+ while ((i<nSheets) && (!RC)) {
+ RC = sheet[i]->GetCIF ( CIF );
+ i++;
+ }
+
+ return RC;
+
+ }
+
+
+ void Sheets::Copy ( PSheets Sheets ) {
+ int i;
+ FreeMemory();
+ if (Sheets->nSheets>0) {
+ nSheets = Sheets->nSheets;
+ sheet = new PSheet[nSheets];
+ for (i=0;i<nSheets;i++)
+ if (Sheets->sheet[i]) {
+ sheet[i] = new Sheet();
+ sheet[i]->Copy ( Sheets->sheet[i] );
+ } else
+ sheet[i] = NULL;
+ }
+ }
+
+
+ void Sheets::write ( io::RFile f ) {
+ int i;
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &nSheets );
+ for (i=0;i<nSheets;i++)
+ StreamWrite ( f,sheet[i] );
+ }
+
+
+ void Sheets::read ( io::RFile f ) {
+ int i;
+ byte Version;
+ FreeMemory();
+ f.ReadByte ( &Version );
+ f.ReadInt ( &nSheets );
+ if (nSheets>0) {
+ sheet = new PSheet[nSheets];
+ for (i=0;i<nSheets;i++) {
+ sheet[i] = NULL;
+ StreamRead ( f,sheet[i] );
+ }
+ }
+ }
+
+
+ MakeStreamFunctions(Sheets)
+
+
+
+ // ================ Turn ===================
+
+ Turn::Turn() : ContainerClass() {
+ InitTurn();
+ }
+
+ Turn::Turn ( cpstr S ) : ContainerClass() {
+ InitTurn();
+ ConvertPDBASCII ( S );
+ }
+
+ Turn::Turn ( io::RPStream Object ) : ContainerClass(Object) {
+ InitTurn();
+ }
+
+ Turn::~Turn() {
+ if (comment) delete[] comment;
+ }
+
+ void Turn::InitTurn() {
+ serNum = 0; // serial number
+ strcpy ( turnID ,"---" ); // turn ID
+ strcpy ( initResName,"---" ); // name of the turn's initial residue
+ strcpy ( initChainID," " ); // chain ID for the chain
+ // containing the turn
+ initSeqNum = 0; // sequence number of the initial
+ // residue
+ strcpy ( initICode ," " ); // insertion code of the initial
+ // residue
+ strcpy ( endResName ,"---" ); // name of the turn's terminal residue
+ strcpy ( endChainID ," " ); // chain ID for the chain
+ // containing the turn
+ endSeqNum = 0; // sequence number of the terminal
+ // residue
+ strcpy ( endICode ," " ); // insertion code of the terminal
+ // residue
+ comment = NULL; // comment about the helix
+ }
+
+ void Turn::PDBASCIIDump ( pstr S, int N ) {
+ UNUSED_ARGUMENT(N);
+ // makes the ASCII PDB OBSLTE line number N
+ // from the class' data
+ strcpy ( S,"TURN" );
+ PadSpaces ( S,80 );
+ PutInteger ( &(S[7]) ,serNum ,3 );
+ strcpy_n1 ( &(S[11]),turnID ,3 );
+ strcpy_n1 ( &(S[15]),initResName,3 );
+ strcpy_n1 ( &(S[19]),initChainID,1 );
+ PutIntIns ( &(S[20]),initSeqNum ,4,initICode );
+ strcpy_n1 ( &(S[26]),endResName ,3 );
+ strcpy_n1 ( &(S[30]),endChainID ,1 );
+ PutIntIns ( &(S[31]),endSeqNum ,4,endICode );
+ if (comment)
+ strcpy_n ( &(S[40]),comment ,30 );
+ }
+
+
+ #define TurnTypeID "TURN_P"
+
+ void Turn::MakeCIF ( mmcif::PData CIF, int N ) {
+ UNUSED_ARGUMENT(N);
+ mmcif::PLoop Loop;
+ int RC;
+ RC = CIF->AddLoop ( CIFCAT_STRUCT_CONF,Loop );
+ if (RC!=mmcif::CIFRC_Ok)
+ // the category was (re)created, provide tags
+ AddStructConfTags ( Loop );
+ Loop->AddString ( pstr(TurnTypeID) );
+ Loop->AddInteger ( serNum );
+ Loop->AddString ( turnID );
+ Loop->AddString ( initResName );
+ Loop->AddString ( initChainID );
+ Loop->AddInteger ( initSeqNum );
+ Loop->AddString ( initICode,true );
+ Loop->AddString ( endResName );
+ Loop->AddString ( endChainID );
+ Loop->AddInteger ( endSeqNum );
+ Loop->AddString ( endICode ,true );
+ Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION );
+ Loop->AddString ( comment );
+ Loop->AddNoData ( mmcif::CIF_NODATA_QUESTION );
+ }
+
+ ERROR_CODE Turn::ConvertPDBASCII ( cpstr S ) {
+ char L[100];
+ GetInteger ( serNum ,&(S[7]) ,3 );
+ strcpy_ncss ( turnID ,&(S[11]),3 );
+ strcpy_ncss ( initResName,&(S[15]),3 );
+ strcpy_ncss ( initChainID,&(S[19]),1 );
+ GetIntIns ( initSeqNum,initICode,&(S[20]),4 );
+ strcpy_ncss ( endResName ,&(S[26]),3 );
+ strcpy_ncss ( endChainID ,&(S[30]),1 );
+ GetIntIns ( endSeqNum ,endICode ,&(S[31]),4 );
+ strcpy_ncss ( L ,&(S[40]),30 );
+ CreateCopy ( comment ,L );
+ return Error_NoError;
+ }
+
+ ERROR_CODE Turn::GetCIF ( mmcif::PData CIF, int & n ) {
+ mmcif::PLoop Loop;
+ int RC,l;
+ pstr F;
+ bool Done;
+ ERROR_CODE rc;
+
+ Loop = CIF->GetLoop ( CIFCAT_STRUCT_CONF );
+ if (!Loop) {
+ n = -1; // signal to finish processing of this structure
+ return Error_EmptyCIF;
+ }
+
+ l = Loop->GetLoopLength();
+ Done = n>=l;
+ while (!Done) {
+ F = Loop->GetString ( CIFTAG_CONF_TYPE_ID,n,RC );
+ if ((!RC) && F) Done = (strcmp(F,TurnTypeID)==0);
+ else Done = false;
+ if (!Done) {
+ n++;
+ Done = n>=l;
+ }
+ }
+
+ if (n>=l) {
+ n = -1; // finish processing of Turn
+ return Error_EmptyCIF;
+ }
+
+ Loop->DeleteField ( CIFTAG_CONF_TYPE_ID,n );
+
+ rc = CIFGetInteger ( serNum,Loop,CIFTAG_ID,n );
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+
+ CIFGetString ( turnID,Loop,CIFTAG_PDB_ID,n,
+ sizeof(turnID),pstr(" ") );
+
+ CIFGetString ( initResName,Loop,CIFTAG_BEG_LABEL_COMP_ID,
+ n,sizeof(initResName),pstr(" ") );
+ CIFGetString ( initChainID,Loop,CIFTAG_BEG_LABEL_ASYM_ID,
+ n,sizeof(initChainID),pstr(" ") );
+ CIFGetString ( initICode ,Loop,CIFTAG_NDB_BEG_LABEL_INS_CODE_PDB,
+ n,sizeof(initICode),pstr(" ") );
+ rc = CIFGetInteger ( initSeqNum,Loop,CIFTAG_BEG_LABEL_SEQ_ID,n );
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+
+ CIFGetString ( endResName,Loop,CIFTAG_END_LABEL_COMP_ID,
+ n,sizeof(endResName),pstr(" ") );
+ CIFGetString ( endChainID,Loop,CIFTAG_END_LABEL_ASYM_ID,
+ n,sizeof(endChainID),pstr(" ") );
+ CIFGetString ( endICode ,Loop,CIFTAG_NDB_END_LABEL_INS_CODE_PDB,
+ n,sizeof(endICode),pstr(" ") );
+ rc = CIFGetInteger ( endSeqNum,Loop,CIFTAG_END_LABEL_SEQ_ID,n );
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+
+ CreateCopy ( comment,Loop->GetString(CIFTAG_DETAILS,n,RC));
+ Loop->DeleteField ( CIFTAG_DETAILS,n );
+
+ n++;
+
+ return Error_NoError;
+
+ }
+
+ void Turn::Copy ( PContainerClass Turn ) {
+ serNum = PTurn(Turn)->serNum;
+ initSeqNum = PTurn(Turn)->initSeqNum;
+ endSeqNum = PTurn(Turn)->endSeqNum;
+ strcpy ( turnID ,PTurn(Turn)->turnID );
+ strcpy ( initResName,PTurn(Turn)->initResName );
+ strcpy ( initChainID,PTurn(Turn)->initChainID );
+ strcpy ( initICode ,PTurn(Turn)->initICode );
+ strcpy ( endResName ,PTurn(Turn)->endResName );
+ strcpy ( endChainID ,PTurn(Turn)->endChainID );
+ strcpy ( endICode ,PTurn(Turn)->endICode );
+ CreateCopy ( comment,PTurn(Turn)->comment );
+ }
+
+ void Turn::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &serNum );
+ f.WriteInt ( &initSeqNum );
+ f.WriteInt ( &endSeqNum );
+ f.WriteTerLine ( turnID ,false );
+ f.WriteTerLine ( initResName,false );
+ f.WriteTerLine ( initChainID,false );
+ f.WriteTerLine ( initICode ,false );
+ f.WriteTerLine ( endResName ,false );
+ f.WriteTerLine ( endChainID ,false );
+ f.WriteTerLine ( endICode ,false );
+ f.CreateWrite ( comment );
+ }
+
+ void Turn::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ f.ReadInt ( &serNum );
+ f.ReadInt ( &initSeqNum );
+ f.ReadInt ( &endSeqNum );
+ f.ReadTerLine ( turnID ,false );
+ f.ReadTerLine ( initResName,false );
+ f.ReadTerLine ( initChainID,false );
+ f.ReadTerLine ( initICode ,false );
+ f.ReadTerLine ( endResName ,false );
+ f.ReadTerLine ( endChainID ,false );
+ f.ReadTerLine ( endICode ,false );
+ f.CreateRead ( comment );
+ }
+
+ MakeStreamFunctions(Turn)
+
+
+ // =================== LinkContainer ========================
+
+ PContainerClass LinkContainer::MakeContainerClass ( int ClassID ) {
+ switch (ClassID) {
+ default :
+ case ClassID_Template : return
+ ClassContainer::MakeContainerClass(ClassID);
+ case ClassID_Link : return new Link();
+ }
+ }
+
+ MakeStreamFunctions(LinkContainer)
+
+
+
+ // ======================== Link ===========================
+
+ Link::Link() : ContainerClass() {
+ InitLink();
+ }
+
+ Link::Link ( cpstr S ) : ContainerClass() {
+ InitLink();
+ ConvertPDBASCII ( S );
+ }
+
+ Link::Link ( io::RPStream Object ) : ContainerClass(Object) {
+ InitLink();
+ }
+
+ Link::~Link() {}
+
+ void Link::InitLink() {
+ strcpy ( atName1 ,"----" ); // name of 1st linked atom
+ strcpy ( aloc1 ," " ); // alternative location of 1st atom
+ strcpy ( resName1,"---" ); // residue name of 1st linked atom
+ strcpy ( chainID1," " ); // chain ID of 1st linked atom
+ seqNum1 = 0; // sequence number of 1st linked atom
+ strcpy ( insCode1," " ); // insertion code of 1st linked atom
+ strcpy ( atName2 ,"----" ); // name of 2nd linked atom
+ strcpy ( aloc2 ," " ); // alternative location of 2nd atom
+ strcpy ( resName2,"---" ); // residue name of 2nd linked atom
+ strcpy ( chainID2," " ); // chain ID of 2nd linked atom
+ seqNum2 = 0; // sequence number of 2nd linked atom
+ strcpy ( insCode2," " ); // insertion code of 2nd linked atom
+ s1 = 1; // sym id of 1st atom
+ i1 = 5;
+ j1 = 5;
+ k1 = 5;
+ s2 = 1; // sym id of 2nd atom
+ i2 = 5;
+ j2 = 5;
+ k2 = 5;
+ }
+
+
+ void Link::PDBASCIIDump ( pstr S, int N ) {
+ UNUSED_ARGUMENT(N);
+ // makes the ASCII PDB OBSLTE line number N
+ // from the class' data
+
+ strcpy ( S,"LINK" );
+ PadSpaces ( S,80 );
+
+ strcpy_n1 ( &(S[12]),atName1 ,4 );
+ strcpy_n1 ( &(S[16]),aloc1 ,1 );
+ strcpy_n1 ( &(S[17]),resName1,3 );
+ strcpy_n1 ( &(S[21]),chainID1,1 );
+ PutIntIns ( &(S[22]),seqNum1 ,4,insCode1 );
+
+ strcpy_n1 ( &(S[42]),atName2 ,4 );
+ strcpy_n1 ( &(S[46]),aloc2 ,1 );
+ strcpy_n1 ( &(S[47]),resName2,3 );
+ strcpy_n1 ( &(S[51]),chainID2,1 );
+ PutIntIns ( &(S[52]),seqNum2 ,4,insCode2 );
+
+ PutInteger ( &(S[59]),s1,3 );
+ PutInteger ( &(S[62]),i1,1 );
+ PutInteger ( &(S[63]),j1,1 );
+ PutInteger ( &(S[64]),k1,1 );
+
+ PutInteger ( &(S[66]),s2,3 );
+ PutInteger ( &(S[69]),i2,1 );
+ PutInteger ( &(S[70]),j2,1 );
+ PutInteger ( &(S[71]),k2,1 );
+
+ }
+
+
+ #define LinkTypeID "LINK"
+
+ void AddStructConnTags ( mmcif::PLoop Loop ) {
+
+ Loop->AddLoopTag ( CIFTAG_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_TYPE_ID );
+
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_AUTH_ATOM_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PDBX_PTNR1_AUTH_ALT_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_AUTH_COMP_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_AUTH_ASYM_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_AUTH_SEQ_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PDBX_PTNR1_PDB_INS_CODE );
+
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_AUTH_ATOM_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PDBX_PTNR2_AUTH_ALT_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_AUTH_COMP_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_AUTH_ASYM_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_AUTH_SEQ_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PDBX_PTNR2_PDB_INS_CODE );
+
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_SYMMETRY );
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_SYMMETRY );
+
+ }
+
+
+ void Link::MakeCIF ( mmcif::PData CIF, int N ) {
+ UNUSED_ARGUMENT(N);
+ mmcif::PLoop Loop;
+ char S[100];
+ int RC;
+
+ RC = CIF->AddLoop ( CIFCAT_STRUCT_CONN,Loop );
+ if (RC!=mmcif::CIFRC_Ok) // the category was (re)created, provide tags
+ AddStructConnTags ( Loop );
+
+ Loop->AddString ( "1" ); // should be a counter
+ Loop->AddString ( pstr(LinkTypeID) );
+
+ Loop->AddString ( atName1 );
+ Loop->AddString ( aloc1 );
+ Loop->AddString ( resName1 );
+ Loop->AddString ( chainID1 );
+ Loop->AddInteger ( seqNum1 );
+ Loop->AddString ( insCode1 );
+
+ Loop->AddString ( atName2 );
+ Loop->AddString ( aloc2 );
+ Loop->AddString ( resName2 );
+ Loop->AddString ( chainID2 );
+ Loop->AddInteger ( seqNum2 );
+ Loop->AddString ( insCode2 );
+
+ sprintf ( S,"%i%i%i%i",s1,i1,j1,k1 );
+ Loop->AddString ( S );
+ sprintf ( S,"%i%i%i%i",s2,i2,j2,k2 );
+ Loop->AddString ( S );
+
+ }
+
+ ERROR_CODE Link::ConvertPDBASCII ( cpstr S ) {
+
+ GetString ( atName1 ,&(S[12]),4 );
+ strcpy_ncss ( aloc1 ,&(S[16]),1 );
+ strcpy_ncss ( resName1,&(S[17]),3 );
+ strcpy_ncss ( chainID1,&(S[21]),1 );
+ GetIntIns ( seqNum1,insCode1,&(S[22]),4 );
+
+ GetString ( atName2 ,&(S[42]),4 );
+ strcpy_ncss ( aloc2 ,&(S[46]),1 );
+ strcpy_ncss ( resName2,&(S[47]),3 );
+ strcpy_ncss ( chainID2,&(S[51]),1 );
+ GetIntIns ( seqNum2,insCode2,&(S[52]),4 );
+
+ GetInteger ( s1,&(S[59]),3 );
+ GetInteger ( i1,&(S[62]),1 );
+ GetInteger ( j1,&(S[63]),1 );
+ GetInteger ( k1,&(S[64]),1 );
+
+ GetInteger ( s2,&(S[66]),3 );
+ GetInteger ( i2,&(S[69]),1 );
+ GetInteger ( j2,&(S[70]),1 );
+ GetInteger ( k2,&(S[71]),1 );
+
+ return Error_NoError;
+
+ }
+
+ ERROR_CODE Link::GetCIF ( mmcif::PData CIF, int & n ) {
+ mmcif::PLoop Loop;
+ pstr F;
+ char S[100];
+ int RC,l;
+ bool Done;
+ ERROR_CODE rc;
+
+ Loop = CIF->GetLoop ( CIFCAT_STRUCT_CONN );
+ if (!Loop) {
+ n = -1; // signal to finish processing of this structure
+ return Error_EmptyCIF;
+ }
+
+ l = Loop->GetLoopLength();
+ Done = (n>=l);
+ while (!Done) {
+ F = Loop->GetString ( CIFTAG_CONN_TYPE_ID,n,RC );
+ if ((!RC) && F) Done = (strcmp(F,LinkTypeID)==0);
+ else Done = false;
+ if (!Done) {
+ n++;
+ Done = (n>=l);
+ }
+ }
+
+ if (n>=l) {
+ n = -1; // finish processing of Turn
+ return Error_EmptyCIF;
+ }
+
+ Loop->DeleteField ( CIFTAG_CONN_TYPE_ID,n );
+
+ // CIFGetInteger ( l,Loop,CIFTAG_ID,n );
+
+ CIFGetString ( atName1,Loop,CIFTAG_CONN_PTNR1_AUTH_ATOM_ID,n,
+ sizeof(atName1),pstr(" ") );
+ CIFGetString ( aloc1,Loop,CIFTAG_CONN_PDBX_PTNR1_AUTH_ALT_ID,n,
+ sizeof(aloc1),pstr(" ") );
+ CIFGetString ( resName1,Loop,CIFTAG_CONN_PTNR1_AUTH_COMP_ID,n,
+ sizeof(resName1),pstr(" ") );
+ CIFGetString ( chainID1,Loop,CIFTAG_CONN_PTNR1_AUTH_ASYM_ID,n,
+ sizeof(chainID1),pstr(" ") );
+ rc = CIFGetInteger ( seqNum1,Loop,CIFTAG_CONN_PTNR1_AUTH_SEQ_ID,n );
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+
+ CIFGetString ( insCode1,Loop,CIFTAG_CONN_PDBX_PTNR1_PDB_INS_CODE,
+ n,sizeof(insCode1),pstr(" ") );
+
+ CIFGetString ( atName2,Loop,CIFTAG_CONN_PTNR2_AUTH_ATOM_ID,n,
+ sizeof(atName2),pstr(" ") );
+ CIFGetString ( aloc2,Loop,CIFTAG_CONN_PDBX_PTNR2_AUTH_ALT_ID,n,
+ sizeof(aloc2),pstr(" ") );
+ CIFGetString ( resName2,Loop,CIFTAG_CONN_PTNR2_AUTH_COMP_ID,n,
+ sizeof(resName2),pstr(" ") );
+ CIFGetString ( chainID2,Loop,CIFTAG_CONN_PTNR2_AUTH_ASYM_ID,n,
+ sizeof(chainID2),pstr(" ") );
+ rc = CIFGetInteger ( seqNum2,Loop,CIFTAG_CONN_PTNR2_AUTH_SEQ_ID,n );
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+
+ CIFGetString ( insCode2,Loop,CIFTAG_CONN_PDBX_PTNR2_PDB_INS_CODE,
+ n,sizeof(insCode2),pstr(" ") );
+
+ CIFGetString ( S,Loop,CIFTAG_CONN_PTNR1_SYMMETRY,n,
+ sizeof(S),pstr("") );
+ if (S[0]) {
+ l = strlen(S)-1;
+ k1 = int(S[l--]) - int('0');
+ j1 = int(S[l--]) - int('0');
+ i1 = int(S[l--]) - int('0');
+ S[l] = char(0);
+ s1 = atoi(S);
+ }
+
+ CIFGetString ( S,Loop,CIFTAG_CONN_PTNR2_SYMMETRY,n,
+ sizeof(S),pstr("") );
+ if (S[0]) {
+ l = strlen(S)-1;
+ k2 = int(S[l--]) - int('0');
+ j2 = int(S[l--]) - int('0');
+ i2 = int(S[l--]) - int('0');
+ S[l] = char(0);
+ s2 = atoi(S);
+ }
+
+ n++;
+
+ return Error_NoError;
+
+ }
+
+ void Link::Copy ( PContainerClass Link ) {
+
+ strcpy ( atName1 ,PLink(Link)->atName1 );
+ strcpy ( aloc1 ,PLink(Link)->aloc1 );
+ strcpy ( resName1,PLink(Link)->resName1 );
+ strcpy ( chainID1,PLink(Link)->chainID1 );
+ seqNum1 = PLink(Link)->seqNum1;
+ strcpy ( insCode1,PLink(Link)->insCode1 );
+
+ strcpy ( atName2 ,PLink(Link)->atName2 );
+ strcpy ( aloc2 ,PLink(Link)->aloc2 );
+ strcpy ( resName2,PLink(Link)->resName2 );
+ strcpy ( chainID2,PLink(Link)->chainID2 );
+ seqNum2 = PLink(Link)->seqNum2;
+ strcpy ( insCode2,PLink(Link)->insCode2 );
+
+ s1 = PLink(Link)->s1;
+ i1 = PLink(Link)->i1;
+ j1 = PLink(Link)->j1;
+ k1 = PLink(Link)->k1;
+
+ s2 = PLink(Link)->s2;
+ i2 = PLink(Link)->i2;
+ j2 = PLink(Link)->j2;
+ k2 = PLink(Link)->k2;
+
+ }
+
+ void Link::write ( io::RFile f ) {
+ byte Version=1;
+
+ f.WriteByte ( &Version );
+
+ f.WriteTerLine ( atName1 ,false );
+ f.WriteTerLine ( aloc1 ,false );
+ f.WriteTerLine ( resName1,false );
+ f.WriteTerLine ( chainID1,false );
+ f.WriteInt ( &seqNum1 );
+ f.WriteTerLine ( insCode1,false );
+
+ f.WriteTerLine ( atName2 ,false );
+ f.WriteTerLine ( aloc2 ,false );
+ f.WriteTerLine ( resName2,false );
+ f.WriteTerLine ( chainID2,false );
+ f.WriteInt ( &seqNum2 );
+ f.WriteTerLine ( insCode2,false );
+
+ f.WriteInt ( &s1 );
+ f.WriteInt ( &i1 );
+ f.WriteInt ( &j1 );
+ f.WriteInt ( &k1 );
+
+ f.WriteInt ( &s2 );
+ f.WriteInt ( &i2 );
+ f.WriteInt ( &j2 );
+ f.WriteInt ( &k2 );
+
+ }
+
+ void Link::read ( io::RFile f ) {
+ byte Version;
+
+ f.ReadByte ( &Version );
+
+ f.ReadTerLine ( atName1 ,false );
+ f.ReadTerLine ( aloc1 ,false );
+ f.ReadTerLine ( resName1,false );
+ f.ReadTerLine ( chainID1,false );
+ f.ReadInt ( &seqNum1 );
+ f.ReadTerLine ( insCode1,false );
+
+ f.ReadTerLine ( atName2 ,false );
+ f.ReadTerLine ( aloc2 ,false );
+ f.ReadTerLine ( resName2,false );
+ f.ReadTerLine ( chainID2,false );
+ f.ReadInt ( &seqNum2 );
+ f.ReadTerLine ( insCode2,false );
+
+ f.ReadInt ( &s1 );
+ f.ReadInt ( &i1 );
+ f.ReadInt ( &j1 );
+ f.ReadInt ( &k1 );
+
+ f.ReadInt ( &s2 );
+ f.ReadInt ( &i2 );
+ f.ReadInt ( &j2 );
+ f.ReadInt ( &k2 );
+
+ }
+
+ MakeStreamFunctions(Link)
+
+
+ // =================== LinkRContainer =======================
+
+ PContainerClass LinkRContainer::MakeContainerClass ( int ClassID ) {
+ switch (ClassID) {
+ default :
+ case ClassID_Template : return
+ ClassContainer::MakeContainerClass(ClassID);
+ case ClassID_LinkR : return new LinkR();
+ }
+ }
+
+ MakeStreamFunctions(LinkRContainer)
+
+
+ // ======================== LinkR ===========================
+
+ LinkR::LinkR() : ContainerClass() {
+ InitLinkR();
+ }
+
+ LinkR::LinkR ( cpstr S ) : ContainerClass() {
+ InitLinkR();
+ ConvertPDBASCII ( S );
+ }
+
+ LinkR::LinkR ( io::RPStream Object ) : ContainerClass(Object) {
+ InitLinkR();
+ }
+
+ LinkR::~LinkR() {}
+
+ void LinkR::InitLinkR() {
+ strcpy ( linkRID ,"----" ); // link name
+ strcpy ( atName1 ,"----" ); // name of 1st linked atom
+ strcpy ( aloc1 ," " ); // alternative location of 1st atom
+ strcpy ( resName1,"---" ); // residue name of 1st linked atom
+ strcpy ( chainID1," " ); // chain ID of 1st linked atom
+ seqNum1 = 0; // sequence number of 1st linked atom
+ strcpy ( insCode1," " ); // insertion code of 1st linked atom
+ strcpy ( atName2 ,"----" ); // name of 2nd linked atom
+ strcpy ( aloc2 ," " ); // alternative location of 2nd atom
+ strcpy ( resName2,"---" ); // residue name of 2nd linked atom
+ strcpy ( chainID2," " ); // chain ID of 2nd linked atom
+ seqNum2 = 0; // sequence number of 2nd linked atom
+ strcpy ( insCode2," " ); // insertion code of 2nd linked atom
+ dist = 0.0; // link distance
+ }
+
+ /*
+ LINK LYS A 27 PLP A 255 PLPLYS
+ LINK MAN S 3 MAN S 4 BETA1-4
+ LINK C6 BBEN B 1 O1 BMAF S 2 BEN-MAF
+ LINK OE2 AGLU A 320 C1 AMAF S 2 GLU-MAF
+ LINK OE2 GLU A 67 1.895 ZN ZN R 5 GLU-ZN
+ LINK NE2 HIS A 71 2.055 ZN ZN R 5 HIS-ZN
+ LINK O ARG A 69 2.240 NA NA R 9 ARG-NA
+ 012345678901234567890123456789012345678901234567890123456789012345678901234567890
+ 1 2 3 4 5 6 7
+ */
+
+ void LinkR::PDBASCIIDump ( pstr S, int N ) {
+ UNUSED_ARGUMENT(N);
+ // makes the ASCII PDB OBSLTE line number N
+ // from the class' data
+
+ strcpy ( S,"LINKR" );
+ PadSpaces ( S,80 );
+
+ strcpy_n1 ( &(S[12]),atName1 ,4 );
+ strcpy_n1 ( &(S[16]),aloc1 ,1 );
+ strcpy_n1 ( &(S[17]),resName1,3 );
+ strcpy_n1 ( &(S[21]),chainID1,1 );
+ PutIntIns ( &(S[22]),seqNum1 ,4,insCode1 );
+
+ if (dist>0.0)
+ PutRealF ( &(S[32]),dist,7,3 );
+
+ strcpy_n1 ( &(S[42]),atName2 ,4 );
+ strcpy_n1 ( &(S[46]),aloc2 ,1 );
+ strcpy_n1 ( &(S[47]),resName2,3 );
+ strcpy_n1 ( &(S[51]),chainID2,1 );
+ PutIntIns ( &(S[52]),seqNum2 ,4,insCode2 );
+
+ strcpy_ns ( &(S[72]),linkRID,8 );
+
+ }
+
+
+ #define LinkRTypeID "LINKR"
+
+ void AddStructConnLinkRTags ( mmcif::PLoop Loop ) {
+
+ Loop->AddLoopTag ( CIFTAG_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_TYPE_ID );
+
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_AUTH_ATOM_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PDBX_PTNR1_AUTH_ALT_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_AUTH_COMP_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_AUTH_ASYM_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR1_AUTH_SEQ_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PDBX_PTNR1_PDB_INS_CODE );
+
+ Loop->AddLoopTag ( CIFTAG_CONN_DIST );
+
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_AUTH_ATOM_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PDBX_PTNR2_AUTH_ALT_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_AUTH_COMP_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_AUTH_ASYM_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PTNR2_AUTH_SEQ_ID );
+ Loop->AddLoopTag ( CIFTAG_CONN_PDBX_PTNR2_PDB_INS_CODE );
+
+ Loop->AddLoopTag ( CIFTAG_CONN_NAME );
+
+ }
+
+ void LinkR::MakeCIF ( mmcif::PData CIF, int N ) {
+ UNUSED_ARGUMENT(N);
+ mmcif::PLoop Loop;
+ int RC;
+
+ RC = CIF->AddLoop ( CIFCAT_STRUCT_LINKR,Loop );
+ if (RC!=mmcif::CIFRC_Ok) // the category was (re)created, provide tags
+ AddStructConnLinkRTags ( Loop );
+
+ Loop->AddString ( "1" ); // should be a counter
+ Loop->AddString ( pstr(LinkTypeID) );
+
+ Loop->AddString ( atName1 );
+ Loop->AddString ( aloc1 );
+ Loop->AddString ( resName1 );
+ Loop->AddString ( chainID1 );
+ Loop->AddInteger ( seqNum1 );
+ Loop->AddString ( insCode1 );
+
+ Loop->AddReal ( dist );
+
+ Loop->AddString ( atName2 );
+ Loop->AddString ( aloc2 );
+ Loop->AddString ( resName2 );
+ Loop->AddString ( chainID2 );
+ Loop->AddInteger ( seqNum2 );
+ Loop->AddString ( insCode2 );
+
+ Loop->AddString ( linkRID );
+
+ }
+
+ ERROR_CODE LinkR::ConvertPDBASCII ( cpstr S ) {
+
+ GetString ( atName1 ,&(S[12]),4 );
+ strcpy_ncss ( aloc1 ,&(S[16]),1 );
+ strcpy_ncss ( resName1,&(S[17]),3 );
+ strcpy_ncss ( chainID1,&(S[21]),1 );
+ GetIntIns ( seqNum1,insCode1,&(S[22]),4 );
+
+ if (!GetReal(dist,&(S[32]),7)) dist = 0.0;
+
+ GetString ( atName2 ,&(S[42]),4 );
+ strcpy_ncss ( aloc2 ,&(S[46]),1 );
+ strcpy_ncss ( resName2,&(S[47]),3 );
+ strcpy_ncss ( chainID2,&(S[51]),1 );
+ GetIntIns ( seqNum2,insCode2,&(S[52]),4 );
+
+ strcpy_ncss ( linkRID,&(S[72]),8 );
+
+ return Error_NoError ;
+
+ }
+
+ ERROR_CODE LinkR::GetCIF ( mmcif::PData CIF, int & n ) {
+ mmcif::PLoop Loop;
+ pstr F;
+ int RC,l;
+ bool Done;
+ ERROR_CODE rc;
+
+ Loop = CIF->GetLoop ( CIFCAT_STRUCT_CONN );
+ if (!Loop) {
+ n = -1; // signal to finish processing of this structure
+ return Error_EmptyCIF;
+ }
+
+ l = Loop->GetLoopLength();
+ Done = (n>=l);
+ while (!Done) {
+ F = Loop->GetString ( CIFTAG_CONN_TYPE_ID,n,RC );
+ if ((!RC) && F) Done = (strcmp(F,LinkTypeID)==0);
+ else Done = false;
+ if (!Done) {
+ n++;
+ Done = (n>=l);
+ }
+ }
+
+ if (n>=l) {
+ n = -1; // finish processing of Turn
+ return Error_EmptyCIF;
+ }
+
+ Loop->DeleteField ( CIFTAG_CONN_TYPE_ID,n );
+
+ // CIFGetInteger ( l,Loop,CIFTAG_ID,n );
+
+ CIFGetString ( atName1,Loop,CIFTAG_CONN_PTNR1_AUTH_ATOM_ID,n,
+ sizeof(atName1),pstr(" ") );
+ CIFGetString ( aloc1,Loop,CIFTAG_CONN_PDBX_PTNR1_AUTH_ALT_ID,n,
+ sizeof(aloc1),pstr(" ") );
+ CIFGetString ( resName1,Loop,CIFTAG_CONN_PTNR1_AUTH_COMP_ID,n,
+ sizeof(resName1),pstr(" ") );
+ CIFGetString ( chainID1,Loop,CIFTAG_CONN_PTNR1_AUTH_ASYM_ID,n,
+ sizeof(chainID1),pstr(" ") );
+ rc = CIFGetInteger ( seqNum1,Loop,CIFTAG_CONN_PTNR1_AUTH_SEQ_ID,n );
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+
+ CIFGetString ( insCode1,Loop,CIFTAG_CONN_PDBX_PTNR1_PDB_INS_CODE,
+ n,sizeof(insCode1),pstr(" ") );
+
+ rc = CIFGetReal ( dist,Loop,CIFTAG_CONN_DIST,n );
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+
+ CIFGetString ( atName2,Loop,CIFTAG_CONN_PTNR2_AUTH_ATOM_ID,n,
+ sizeof(atName2),pstr(" ") );
+ CIFGetString ( aloc2,Loop,CIFTAG_CONN_PDBX_PTNR2_AUTH_ALT_ID,n,
+ sizeof(aloc2),pstr(" ") );
+ CIFGetString ( resName2,Loop,CIFTAG_CONN_PTNR2_AUTH_COMP_ID,n,
+ sizeof(resName2),pstr(" ") );
+ CIFGetString ( chainID2,Loop,CIFTAG_CONN_PTNR2_AUTH_ASYM_ID,n,
+ sizeof(chainID2),pstr(" ") );
+ rc = CIFGetInteger ( seqNum2,Loop,CIFTAG_CONN_PTNR2_AUTH_SEQ_ID,n );
+ if (rc==Error_NoData) return Error_EmptyCIF;
+ if (rc!=Error_NoError) return rc;
+
+ CIFGetString ( insCode2,Loop,CIFTAG_CONN_PDBX_PTNR2_PDB_INS_CODE,
+ n,sizeof(insCode2),pstr(" ") );
+
+ CIFGetString ( linkRID,Loop,CIFTAG_CONN_NAME,n,
+ sizeof(linkRID),pstr(" ") );
+
+ n++;
+
+ return Error_NoError;
+
+ }
+
+ void LinkR::Copy ( PContainerClass LinkR ) {
+
+ strcpy ( atName1 ,PLinkR(LinkR)->atName1 );
+ strcpy ( aloc1 ,PLinkR(LinkR)->aloc1 );
+ strcpy ( resName1,PLinkR(LinkR)->resName1 );
+ strcpy ( chainID1,PLinkR(LinkR)->chainID1 );
+ seqNum1 = PLinkR(LinkR)->seqNum1;
+ strcpy ( insCode1,PLinkR(LinkR)->insCode1 );
+
+ dist = PLinkR(LinkR)->dist;
+
+ strcpy ( atName2 ,PLinkR(LinkR)->atName2 );
+ strcpy ( aloc2 ,PLinkR(LinkR)->aloc2 );
+ strcpy ( resName2,PLinkR(LinkR)->resName2 );
+ strcpy ( chainID2,PLinkR(LinkR)->chainID2 );
+ seqNum2 = PLinkR(LinkR)->seqNum2;
+ strcpy ( insCode2,PLinkR(LinkR)->insCode2 );
+
+ strcpy ( linkRID,PLinkR(LinkR)->linkRID );
+
+ }
+
+ void LinkR::write ( io::RFile f ) {
+ byte Version=1;
+
+ f.WriteByte ( &Version );
+
+ f.WriteTerLine ( atName1 ,false );
+ f.WriteTerLine ( aloc1 ,false );
+ f.WriteTerLine ( resName1,false );
+ f.WriteTerLine ( chainID1,false );
+ f.WriteInt ( &seqNum1 );
+ f.WriteTerLine ( insCode1,false );
+
+ f.WriteReal ( &dist );
+
+ f.WriteTerLine ( atName2 ,false );
+ f.WriteTerLine ( aloc2 ,false );
+ f.WriteTerLine ( resName2,false );
+ f.WriteTerLine ( chainID2,false );
+ f.WriteInt ( &seqNum2 );
+ f.WriteTerLine ( insCode2,false );
+
+ f.WriteTerLine ( linkRID,false );
+
+ }
+
+ void LinkR::read ( io::RFile f ) {
+ byte Version;
+
+ f.ReadByte ( &Version );
+
+ f.ReadTerLine ( atName1 ,false );
+ f.ReadTerLine ( aloc1 ,false );
+ f.ReadTerLine ( resName1,false );
+ f.ReadTerLine ( chainID1,false );
+ f.ReadInt ( &seqNum1 );
+ f.ReadTerLine ( insCode1,false );
+
+ f.ReadReal ( &dist );
+
+ f.ReadTerLine ( atName2 ,false );
+ f.ReadTerLine ( aloc2 ,false );
+ f.ReadTerLine ( resName2,false );
+ f.ReadTerLine ( chainID2,false );
+ f.ReadInt ( &seqNum2 );
+ f.ReadTerLine ( insCode2,false );
+
+ f.ReadTerLine ( linkRID,false );
+
+ }
+
+ MakeStreamFunctions(LinkR)
+
+
+ // =================== CisPepContainer ======================
+
+ PContainerClass CisPepContainer::MakeContainerClass ( int ClassID ) {
+ switch (ClassID) {
+ default :
+ case ClassID_Template : return
+ ClassContainer::MakeContainerClass(ClassID);
+ case ClassID_CisPep : return new CisPep();
+ }
+ }
+
+ MakeStreamFunctions(CisPepContainer)
+
+
+ // ======================== CisPep ==========================
+
+ CisPep::CisPep() : ContainerClass() {
+ InitCisPep();
+ }
+
+ CisPep::CisPep ( cpstr S ) : ContainerClass() {
+ InitCisPep();
+ ConvertPDBASCII ( S );
+ }
+
+ CisPep::CisPep ( io::RPStream Object ) : ContainerClass(Object) {
+ InitCisPep();
+ }
+
+ CisPep::~CisPep() {}
+
+ void CisPep::InitCisPep() {
+ serNum = 1; // record serial number
+ strcpy ( pep1 ,"---" ); // residue name
+ strcpy ( chainID1," " ); // chain identifier 1
+ seqNum1 = 0; // residue sequence number 1
+ strcpy ( icode1 ," " ); // insertion code 1
+ strcpy ( pep2 ,"---" ); // residue name 2
+ strcpy ( chainID2," " ); // chain identifier 2
+ seqNum2 = 0; // residue sequence number 2
+ strcpy ( icode2 ," " ); // insertion code 2
+ modNum = 0; // model number
+ measure = 0.0; // measure of the angle in degrees.
+ }
+
+ void CisPep::PDBASCIIDump ( pstr S, int N ) {
+ UNUSED_ARGUMENT(N);
+
+ strcpy ( S,"CISPEP" );
+ PadSpaces ( S,80 );
+
+ PutInteger ( &(S[7]),serNum,3 );
+
+ strcpy_n1 ( &(S[11]),pep1 ,3 );
+ strcpy_n1 ( &(S[15]),chainID1,1 );
+ PutIntIns ( &(S[17]),seqNum1 ,4,icode1 );
+
+ strcpy_n1 ( &(S[25]),pep2 ,3 );
+ strcpy_n1 ( &(S[29]),chainID2,1 );
+ PutIntIns ( &(S[31]),seqNum2 ,4,icode1 );
+
+ PutInteger ( &(S[43]),modNum,3 );
+ PutRealF ( &(S[53]),measure,6,2 );
+
+ }
+
+
+ ERROR_CODE CisPep::ConvertPDBASCII ( cpstr S ) {
+
+ GetInteger ( serNum ,&(S[7]) ,3 );
+
+ strcpy_ncss ( pep1 ,&(S[11]),3 );
+ strcpy_ncss ( chainID1,&(S[15]),1 );
+ GetIntIns ( seqNum1,icode1,&(S[17]),4 );
+
+ strcpy_ncss ( pep2 ,&(S[25]),3 );
+ strcpy_ncss ( chainID2,&(S[29]),1 );
+ GetIntIns ( seqNum2,icode2,&(S[31]),4 );
+
+ GetInteger ( modNum ,&(S[43]),3 );
+ GetReal ( measure ,&(S[53]),6 );
+
+ return Error_NoError;
+
+ }
+
+
+ void CisPep::Copy ( PContainerClass CisPep ) {
+
+ serNum = PCisPep(CisPep)->serNum;
+
+ strcpy ( pep1 ,PCisPep(CisPep)->pep1 );
+ strcpy ( chainID1,PCisPep(CisPep)->chainID1 );
+ seqNum1 = PCisPep(CisPep)->seqNum1;
+ strcpy ( icode1 ,PCisPep(CisPep)->icode1 );
+
+ strcpy ( pep2 ,PCisPep(CisPep)->pep2 );
+ strcpy ( chainID2,PCisPep(CisPep)->chainID2 );
+ seqNum2 = PCisPep(CisPep)->seqNum2;
+ strcpy ( icode2 ,PCisPep(CisPep)->icode2 );
+
+ modNum = PCisPep(CisPep)->modNum;
+ measure = PCisPep(CisPep)->measure;
+
+ }
+
+ void CisPep::write ( io::RFile f ) {
+ byte Version=1;
+
+ f.WriteByte ( &Version );
+
+ f.WriteInt ( &serNum );
+
+ f.WriteTerLine ( pep1 ,false );
+ f.WriteTerLine ( chainID1,false );
+ f.WriteInt ( &seqNum1 );
+ f.WriteTerLine ( icode1 ,false );
+
+ f.WriteTerLine ( pep2 ,false );
+ f.WriteTerLine ( chainID2,false );
+ f.WriteInt ( &seqNum2 );
+ f.WriteTerLine ( icode2 ,false );
+
+ f.WriteInt ( &modNum );
+ f.WriteReal ( &measure );
+
+ }
+
+ void CisPep::read ( io::RFile f ) {
+ byte Version;
+
+ f.ReadByte ( &Version );
+
+ f.ReadInt ( &serNum );
+
+ f.ReadTerLine ( pep1 ,false );
+ f.ReadTerLine ( chainID1,false );
+ f.ReadInt ( &seqNum1 );
+ f.ReadTerLine ( icode1 ,false );
+
+ f.ReadTerLine ( pep2 ,false );
+ f.ReadTerLine ( chainID2,false );
+ f.ReadInt ( &seqNum2 );
+ f.ReadTerLine ( icode2 ,false );
+
+ f.ReadInt ( &modNum );
+ f.ReadReal ( &measure );
+
+ }
+
+ MakeStreamFunctions(CisPep)
+
+
+
+ // ===================== Model =======================
+
+ Model::Model() : ProModel() {
+ InitModel();
+ }
+
+ Model::Model ( PManager MMDBM, int serialNum ) : ProModel() {
+ InitModel();
+ manager = MMDBM;
+ serNum = serialNum;
+ }
+
+ Model::Model ( io::RPStream Object ) : ProModel(Object) {
+ InitModel();
+ }
+
+ void Model::InitModel() {
+ serNum = 0;
+ nChains = 0;
+ nChainsAlloc = 0;
+ chain = NULL;
+ manager = NULL;
+ Exclude = true;
+ }
+
+ Model::~Model() {
+ FreeMemory();
+ if (manager) manager->_ExcludeModel ( serNum );
+ }
+
+ void Model::FreeMemory() {
+
+ DeleteAllChains();
+ if (chain) delete[] chain;
+ chain = NULL;
+ nChains = 0;
+ nChainsAlloc = 0;
+
+ RemoveSecStructure();
+ RemoveHetInfo ();
+ RemoveLinks ();
+ RemoveLinkRs ();
+ RemoveCisPeps ();
+
+ }
+
+
+ void Model::SetMMDBManager ( PManager MMDBM, int serialNum ) {
+ manager = MMDBM;
+ serNum = serialNum;
+ }
+
+ void Model::CheckInAtoms() {
+ int i;
+ if (manager)
+ for (i=0;i<nChains;i++)
+ if (chain[i])
+ chain[i]->CheckInAtoms();
+ }
+
+
+ int Model::GetNumberOfAtoms ( bool countTers ) {
+ // returns number of atoms in the model
+ int i,na;
+ na = 0;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) na += chain[i]->GetNumberOfAtoms ( countTers );
+ return na;
+ }
+
+ int Model::GetNumberOfResidues() {
+ // returns number of residues in the model
+ PChain chn;
+ int ic,ir,nr;
+ nr = 0;
+ for (ic=0;ic<nChains;ic++) {
+ chn = chain[ic];
+ if (chn)
+ for (ir=0;ir<chn->nResidues;ir++)
+ if (chn->residue[ir]) nr++;
+ }
+ return nr;
+ }
+
+
+ // ---------------- Extracting chains --------------------------
+
+ int Model::GetNumberOfChains() {
+ return nChains;
+ }
+
+ PChain Model::GetChain ( int chainNo ) {
+ if ((0<=chainNo) && (chainNo<nChains))
+ return chain[chainNo];
+ else return NULL;
+ }
+
+
+ void Model::ExpandChainArray ( int nOfChains ) {
+ PPChain chain1;
+ int i;
+ if (nOfChains>=nChainsAlloc) {
+ nChainsAlloc = nOfChains+10;
+ chain1 = new PChain[nChainsAlloc];
+ for (i=0;i<nChains;i++)
+ chain1[i] = chain[i];
+ for (i=nChains;i<nChainsAlloc;i++)
+ chain1[i] = NULL;
+ if (chain) delete[] chain;
+ chain = chain1;
+ }
+ }
+
+ PChain Model::GetChainCreate ( const ChainID chID,
+ bool enforceUniqueChainID ) {
+ // Returns pointer on chain, whose identifier is
+ // given in chID. If such a chain is absent in the
+ // model, it is created.
+ PChain chn;
+ ChainID chainID;
+ int i,k;
+
+ // check if such a chain is already in the model
+ chn = NULL;
+ if (enforceUniqueChainID) {
+ k = 0;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) {
+ // here we check only first letter as it is kept in all
+ // derived names
+ if (chID[0]==chain[i]->chainID[0]) {
+ chn = chain[i];
+ if (chn->GetNumberOfResidues()>0) k++;
+ }
+ }
+ if (k) sprintf ( chainID,"%s%i",chID,k-1 );
+ else if (!chn) strcpy ( chainID,chID ); // chain is absent
+ else return chn; // the only empty chain
+ } else {
+ if (chID[0]) {
+ for (i=0;(i<nChains) && (!chn);i++)
+ if (chain[i]) {
+ if (!strcmp(chID,chain[i]->chainID))
+ chn = chain[i]; // it is there; just return the pointer
+ }
+ } else {
+ for (i=0;(i<nChains) && (!chn);i++)
+ if (chain[i]) {
+ if (!chain[i]->chainID[0])
+ chn = chain[i]; // it is there; just return the pointer
+ }
+ }
+ if (chn) return chn;
+ strcpy ( chainID,chID );
+ }
+
+ ExpandChainArray ( nChains );
+
+ // create new chain
+ chain[nChains] = newChain();
+ chain[nChains]->SetChain ( chainID );
+ chain[nChains]->SetModel ( this );
+ nChains++;
+
+ return chain[nChains-1];
+
+ }
+
+ PChain Model::CreateChain ( const ChainID chID ) {
+ // CreateChain() creates a new chain with chain ID regardless
+ // the presence of same-ID chains in the model. This function
+ // was introduced only for compatibility with older CCP4
+ // applications and using it in any new developments should be
+ // strictly discouraged.
+
+ ExpandChainArray ( nChains );
+
+ // create new chain
+ chain[nChains] = newChain();
+ chain[nChains]->SetChain ( chID );
+ chain[nChains]->SetModel ( this );
+ nChains++;
+
+ return chain[nChains-1];
+
+ }
+
+
+ void Model::GetChainTable ( PPChain & chainTable,
+ int & NumberOfChains ) {
+ chainTable = chain;
+ NumberOfChains = nChains;
+ }
+
+ bool Model::GetNewChainID ( ChainID chID, int length ) {
+ int i,k;
+ bool found;
+
+ memset ( chID,0,sizeof(ChainID) );
+ chID[0] = 'A';
+
+ do {
+ found = false;
+ for (i=0;(i<nChains) && (!found);i++)
+ if (chain[i])
+ found = (!strcmp(chID,chain[i]->chainID));
+ if (found) {
+ k = 0;
+ while (k<length)
+ if (!chID[k]) {
+ chID[k] = 'A';
+ break;
+ } else if (chID[k]<'Z') {
+ chID[k]++;
+ break;
+ } else {
+ chID[k] = 'A';
+ k++;
+ }
+ } else
+ k = 0;
+ } while (found && (k<length));
+
+ if (found) {
+ k = strlen(chID);
+ while (k<length)
+ chID[k++] = 'A';
+ }
+
+ return (!found);
+
+ }
+
+
+ PChain Model::GetChain ( const ChainID chID ) {
+ // Returns pointer on chain, whose identifier is
+ // given in chID. If such a chain is absent in the
+ // model, returns NULL.
+ int i;
+ bool isChainID;
+ if (chID) isChainID = (chID[0]!=char(0));
+ else isChainID = false;
+ if (isChainID) {
+ for (i=0;i<nChains;i++)
+ if (chain[i]) {
+ if (!strcmp(chID,chain[i]->chainID))
+ return chain[i]; // it is there; just return the pointer
+ }
+ } else {
+ for (i=0;i<nChains;i++)
+ if (chain[i]) {
+ if (!chain[i]->chainID[0])
+ return chain[i]; // it is there; just return the pointer
+ }
+ }
+ return NULL;
+ }
+
+
+ // ------------------ Deleting chains --------------------------
+
+ int Model::DeleteChain ( int chainNo ) {
+ if ((0<=chainNo) && (chainNo<nChains)) {
+ if (chain[chainNo]) {
+ Exclude = false;
+ delete chain[chainNo];
+ chain[chainNo] = NULL;
+ Exclude = true;
+ return 1;
+ }
+ }
+ return 0;
+ }
+
+ int Model::DeleteChain ( const ChainID chID ) {
+ int i;
+ if (chID[0]) {
+ for (i=0;i<nChains;i++)
+ if (chain[i]) {
+ if (!strcmp(chID,chain[i]->chainID)) {
+ Exclude = false;
+ delete chain[i];
+ chain[i] = NULL;
+ Exclude = true;
+ return 1;
+ }
+ }
+ } else {
+ for (i=0;i<nChains;i++)
+ if (chain[i]) {
+ if (!chain[i]->chainID[0]) {
+ Exclude = false;
+ delete chain[i];
+ chain[i] = NULL;
+ Exclude = true;
+ return 1;
+ }
+ }
+ }
+ return 0;
+ }
+
+
+ int Model::DeleteAllChains() {
+ int i,k;
+ Exclude = false;
+ k = 0;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) {
+ delete chain[i];
+ chain[i] = NULL;
+ k++;
+ }
+ nChains = 0;
+ Exclude = true;
+ return k;
+ }
+
+ int Model::DeleteSolventChains() {
+ int i,k;
+ Exclude = false;
+ k = 0;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) {
+ if (chain[i]->isSolventChain()) {
+ delete chain[i];
+ chain[i] = NULL;
+ k++;
+ }
+ }
+ Exclude = true;
+ return k;
+ }
+
+ void Model::TrimChainTable() {
+ int i,j;
+ Exclude = false;
+ j = 0;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) {
+ if (chain[i]->nResidues>0) {
+ if (j<i) {
+ chain[j] = chain[i];
+ chain[i] = NULL;
+ }
+ j++;
+ } else {
+ delete chain[i];
+ chain[i] = NULL;
+ }
+ }
+ nChains = j;
+ Exclude = true;
+ }
+
+
+ int Model::GetNumberOfResidues ( const ChainID chainID ) {
+ PChain chn;
+ chn = GetChain ( chainID );
+ if (chn) return chn->nResidues;
+ return 0;
+ }
+
+ int Model::GetNumberOfResidues ( int chainNo ) {
+ if ((0<=chainNo) && (chainNo<nChains)) {
+ if (chain[chainNo])
+ return chain[chainNo]->nResidues;
+ }
+ return 0;
+ }
+
+ PResidue Model::GetResidue ( const ChainID chainID, int seqNo,
+ const InsCode insCode ) {
+ PChain chn;
+ chn = GetChain ( chainID );
+ if (chn)
+ return chn->GetResidue ( seqNo,insCode );
+ return NULL;
+ }
+
+ PResidue Model::GetResidue ( const ChainID chainID, int resNo ) {
+ PChain chn;
+ chn = GetChain ( chainID );
+ if (chn) {
+ if ((0<=resNo) && (resNo<chn->nResidues))
+ return chn->residue[resNo];
+ }
+ return NULL;
+ }
+
+ PResidue Model::GetResidue ( int chainNo, int seqNo,
+ const InsCode insCode ) {
+ if ((0<=chainNo) && (chainNo<nChains)) {
+ if (chain[chainNo])
+ return chain[chainNo]->GetResidue ( seqNo,insCode );
+ }
+ return NULL;
+ }
+
+ PResidue Model::GetResidue ( int chainNo, int resNo ) {
+ if ((0<=chainNo) && (chainNo<nChains)) {
+ if (chain[chainNo]) {
+ if ((0<=resNo) && (resNo<chain[chainNo]->nResidues))
+ return chain[chainNo]->residue[resNo];
+ }
+ }
+ return NULL;
+ }
+
+ int Model::GetResidueNo ( const ChainID chainID, int seqNo,
+ const InsCode insCode ) {
+ PChain chn;
+ chn = GetChain ( chainID );
+ if (chn)
+ return chn->GetResidueNo ( seqNo,insCode );
+ return -2;
+ }
+
+ int Model::GetResidueNo ( int chainNo, int seqNo,
+ const InsCode insCode ) {
+ if ((0<=chainNo) && (chainNo<nChains)) {
+ if (chain[chainNo])
+ return chain[chainNo]->GetResidueNo ( seqNo,insCode );
+ }
+ return -2;
+ }
+
+
+ void Model::GetResidueTable ( PPResidue & resTable,
+ int & NumberOfResidues ) {
+ // resTable has to be NULL or it will be reallocated. The application
+ // is responsible for deallocating the resTable (but not of its
+ // residues!). This does not apply to other GetResidueTable
+ // functions.
+ PPChain chn;
+ PPResidue res;
+ int i,j,k,nChns,nResidues;
+
+ if (resTable) {
+ delete[] resTable;
+ resTable = NULL;
+ }
+
+ NumberOfResidues = 0;
+ GetChainTable ( chn,nChns );
+ for (i=0;i<nChns;i++)
+ if (chn[i]) {
+ chn[i]->GetResidueTable ( res,nResidues );
+ NumberOfResidues += nResidues;
+ }
+
+ if (NumberOfResidues>0) {
+ resTable = new PResidue[NumberOfResidues];
+ k = 0;
+ GetChainTable ( chn,nChns );
+ for (i=0;i<nChns;i++)
+ if (chn[i]) {
+ chn[i]->GetResidueTable ( res,nResidues );
+ for (j=0;j<nResidues;j++)
+ if (res[j]) resTable[k++] = res[j];
+ }
+ NumberOfResidues = k;
+ }
+
+ }
+
+ void Model::GetResidueTable ( const ChainID chainID,
+ PPResidue & resTable,
+ int & NumberOfResidues ) {
+ PChain chn;
+ resTable = NULL;
+ NumberOfResidues = 0;
+ chn = GetChain ( chainID );
+ if (chn) {
+ resTable = chn->residue;
+ NumberOfResidues = chn->nResidues;
+ }
+ }
+
+ void Model::GetResidueTable ( int chainNo, PPResidue & resTable,
+ int & NumberOfResidues ) {
+ resTable = NULL;
+ NumberOfResidues = 0;
+ if ((0<=chainNo) && (chainNo<nChains)) {
+ if (chain[chainNo]) {
+ resTable = chain[chainNo]->residue;
+ NumberOfResidues = chain[chainNo]->nResidues;
+ }
+ }
+ }
+
+
+ int Model::DeleteResidue ( const ChainID chainID, int seqNo,
+ const InsCode insCode ) {
+ PChain chn;
+ chn = GetChain ( chainID );
+ if (chn) return chn->DeleteResidue ( seqNo,insCode );
+ return 0;
+ }
+
+ int Model::DeleteResidue ( const ChainID chainID, int resNo ) {
+ PChain chn;
+ chn = GetChain ( chainID );
+ if (chn) return chn->DeleteResidue ( resNo );
+ return 0;
+ }
+
+ int Model::DeleteResidue ( int chainNo, int seqNo,
+ const InsCode insCode ) {
+ if ((0<=chainNo) && (chainNo<nChains)) {
+ if (chain[chainNo])
+ return chain[chainNo]->DeleteResidue ( seqNo,insCode );
+ }
+ return 0;
+ }
+
+ int Model::DeleteResidue ( int chainNo, int resNo ) {
+ if ((0<=chainNo) && (chainNo<nChains)) {
+ if (chain[chainNo])
+ return chain[chainNo]->DeleteResidue ( resNo );
+ }
+ return 0;
+ }
+
+ int Model::DeleteAllResidues ( const ChainID chainID ) {
+ PChain chn;
+ chn = GetChain ( chainID );
+ if (chn) return chn->DeleteAllResidues();
+ return 0;
+ }
+
+ int Model::DeleteAllResidues ( int chainNo ) {
+ if ((0<=chainNo) && (chainNo<nChains)) {
+ if (chain[chainNo])
+ return chain[chainNo]->DeleteAllResidues();
+ }
+ return 0;
+ }
+
+ int Model::DeleteAllResidues() {
+ int i,k;
+ k = 0;
+ for (i=0;i<nChains;i++)
+ if (chain[i])
+ k += chain[i]->DeleteAllResidues();
+ return k;
+ }
+
+
+ int Model::DeleteSolvent() {
+ int i,k;
+ Exclude = false;
+ k = 0;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) {
+ k += chain[i]->DeleteSolvent();
+ chain[i]->TrimResidueTable();
+ if (chain[i]->nResidues<=0) {
+ delete chain[i];
+ chain[i] = NULL;
+ }
+ }
+ Exclude = true;
+ return k;
+ }
+
+
+ int Model::AddResidue ( const ChainID chainID, PResidue res ) {
+ PChain chn;
+ chn = GetChain ( chainID );
+ if (chn) return chn->AddResidue ( res );
+ return 0;
+ }
+
+ int Model::AddResidue ( int chainNo, PResidue res ) {
+ if ((0<=chainNo) && (chainNo<nChains)) {
+ if (chain[chainNo])
+ return chain[chainNo]->AddResidue ( res );
+ }
+ return 0;
+ }
+
+
+ int Model::_ExcludeChain ( const ChainID chainID ) {
+ // _ExcludeChain(..) excludes (but does not dispose!) a chain
+ // from the model. Returns 1 if the model gets empty and 0 otherwise.
+ int i,k;
+
+ if (!Exclude) return 0;
+
+ // find the chain
+ k = -1;
+ for (i=0;(i<nChains) && (k<0);i++)
+ if (!strcmp(chainID,chain[i]->chainID))
+ k = i;
+
+ if (k>=0) {
+ for (i=k+1;i<nChains;i++)
+ chain[i-1] = chain[i];
+ nChains--;
+ chain[nChains] = NULL;
+ }
+
+ if (nChains<=0) return 1;
+ else return 0;
+
+ }
+
+
+ // -------------------- Sort chains ----------------------------
+
+ DefineClass(QSortChains)
+
+ class QSortChains : public QuickSort {
+ public :
+ QSortChains() : QuickSort() { sKey = 0; }
+ int Compare ( int i, int j );
+ void Swap ( int i, int j );
+ void Sort ( PPChain chain, int nChains, int sortKey );
+ private :
+ int sKey;
+ };
+
+ int QSortChains::Compare ( int i, int j ) {
+ int diff;
+
+ diff = strcmp ( (PPChain(data))[i]->GetChainID(),
+ (PPChain(data))[j]->GetChainID() );
+ if (diff>0) diff = 1;
+ if (diff<0) diff = -1;
+
+ if (sKey==SORT_CHAIN_ChainID_Desc) return -diff;
+
+ return diff;
+
+ }
+
+ void QSortChains::Swap ( int i, int j ) {
+ PChain chn;
+ chn = ((PPChain)data)[i];
+ ((PPChain)data)[i] = ((PPChain)data)[j];
+ ((PPChain)data)[j] = chn;
+ }
+
+ void QSortChains::Sort ( PPChain chain, int nChains, int sortKey ) {
+ sKey = sortKey;
+ QuickSort::Sort ( &(chain[0]),nChains );
+ }
+
+ void Model::SortChains ( int sortKey ) {
+ QSortChains SC;
+ TrimChainTable();
+ SC.Sort ( chain,nChains,sortKey );
+ }
+
+
+ // -------------------- Extracting atoms -----------------------
+
+
+ int Model::GetNumberOfAtoms ( const ChainID chainID, int seqNo,
+ const InsCode insCode ) {
+ PChain chn;
+ PResidue res;
+ chn = GetChain ( chainID );
+ if (chn) {
+ res = chn->GetResidue ( seqNo,insCode );
+ if (res) return res->nAtoms;
+ }
+ return 0;
+ }
+
+ int Model::GetNumberOfAtoms ( int chainNo, int seqNo,
+ const InsCode insCode ) {
+ PChain chn;
+ PResidue res;
+ chn = GetChain ( chainNo );
+ if (chn) {
+ res = chn->GetResidue ( seqNo,insCode );
+ if (res) return res->nAtoms;
+ }
+ return 0;
+ }
+
+ int Model::GetNumberOfAtoms ( const ChainID chainID, int resNo ) {
+ PChain chn;
+ PResidue res;
+ chn = GetChain ( chainID );
+ if (chn) {
+ if ((0<=resNo) && (resNo<chn->nResidues)) {
+ res = chn->residue[resNo];
+ if (res) return res->nAtoms;
+ }
+ }
+ return 0;
+ }
+
+ int Model::GetNumberOfAtoms ( int chainNo, int resNo ) {
+ PChain chn;
+ PResidue res;
+ if ((0<=chainNo) && (chainNo<nChains)) {
+ chn = chain[chainNo];
+ if (chn) {
+ if ((0<=resNo) && (resNo<chn->nResidues)) {
+ res = chn->residue[resNo];
+ if (res) return res->nAtoms;
+ }
+ }
+ }
+ return 0;
+ }
+
+ PAtom Model::GetAtom ( const ChainID chID,
+ int seqNo,
+ const InsCode insCode,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc
+ ) {
+ PChain chn;
+ PResidue res;
+ chn = GetChain ( chID );
+ if (chn) {
+ res = chn->GetResidue ( seqNo,insCode );
+ if (res)
+ return res->GetAtom ( aname,elmnt,aloc );
+ }
+ return NULL;
+ }
+
+ PAtom Model::GetAtom ( const ChainID chID, int seqNo,
+ const InsCode insCode, int atomNo ) {
+ PChain chn;
+ PResidue res;
+ chn = GetChain ( chID );
+ if (chn) {
+ res = chn->GetResidue ( seqNo,insCode );
+ if (res) {
+ if ((0<=atomNo) && (atomNo<res->nAtoms))
+ return res->atom[atomNo];
+ }
+ }
+ return NULL;
+ }
+
+ PAtom Model::GetAtom ( const ChainID chID,
+ int resNo,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc ) {
+ PChain chn;
+ PResidue res;
+ chn = GetChain ( chID );
+ if (chn) {
+ if ((0<=resNo) && (resNo<chn->nResidues)) {
+ res = chn->residue[resNo];
+ if (res)
+ return res->GetAtom ( aname,elmnt,aloc );
+ }
+ }
+ return NULL;
+ }
+
+ PAtom Model::GetAtom ( const ChainID chID, int resNo, int atomNo ) {
+ PChain chn;
+ PResidue res;
+ chn = GetChain ( chID );
+ if (chn) {
+ if ((0<=resNo) && (resNo<chn->nResidues)) {
+ res = chn->residue[resNo];
+ if (res) {
+ if ((0<=atomNo) && (atomNo<res->nAtoms))
+ return res->atom[atomNo];
+ }
+ }
+ }
+ return NULL;
+ }
+
+ PAtom Model::GetAtom ( int chNo, int seqNo,
+ const InsCode insCode,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc ) {
+ PResidue res;
+ if ((0<=chNo) && (chNo<nChains)) {
+ if (chain[chNo]) {
+ res = chain[chNo]->GetResidue ( seqNo,insCode );
+ if (res)
+ return res->GetAtom ( aname,elmnt,aloc );
+ }
+ }
+ return NULL;
+ }
+
+ PAtom Model::GetAtom ( int chNo, int seqNo, const InsCode insCode,
+ int atomNo ) {
+ PResidue res;
+ if ((0<=chNo) && (chNo<nChains)) {
+ if (chain[chNo]) {
+ res = chain[chNo]->GetResidue ( seqNo,insCode );
+ if (res) {
+ if ((0<=atomNo) && (atomNo<res->nAtoms))
+ return res->atom[atomNo];
+ }
+ }
+ }
+ return NULL;
+ }
+
+ PAtom Model::GetAtom ( int chNo, int resNo,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc ) {
+ PResidue res;
+ if ((0<=chNo) && (chNo<nChains)) {
+ if (chain[chNo]) {
+ if ((0<=resNo) && (resNo<chain[chNo]->nResidues)) {
+ res = chain[chNo]->residue[resNo];
+ if (res)
+ return res->GetAtom ( aname,elmnt,aloc );
+ }
+ }
+ }
+ return NULL;
+ }
+
+ PAtom Model::GetAtom ( int chNo, int resNo, int atomNo ) {
+ PResidue res;
+ if ((0<=chNo) && (chNo<nChains)) {
+ if (chain[chNo]) {
+ if ((0<=resNo) && (resNo<chain[chNo]->nResidues)) {
+ res = chain[chNo]->residue[resNo];
+ if (res) {
+ if ((0<=atomNo) && (atomNo<res->nAtoms))
+ return res->atom[atomNo];
+ }
+ }
+ }
+ }
+ return NULL;
+ }
+
+
+ void Model::GetAtomTable ( const ChainID chainID, int seqNo,
+ const InsCode insCode,
+ PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ res = GetResidue ( chainID,seqNo,insCode );
+ if (res) {
+ atomTable = res->atom;
+ NumberOfAtoms = res->nAtoms;
+ }
+ }
+
+ void Model::GetAtomTable ( int chainNo, int seqNo,
+ const InsCode insCode,
+ PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ res = GetResidue ( chainNo,seqNo,insCode );
+ if (res) {
+ atomTable = res->atom;
+ NumberOfAtoms = res->nAtoms;
+ }
+ }
+
+ void Model::GetAtomTable ( const ChainID chainID, int resNo,
+ PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ res = GetResidue ( chainID,resNo );
+ if (res) {
+ atomTable = res->atom;
+ NumberOfAtoms = res->nAtoms;
+ }
+ }
+
+ void Model::GetAtomTable ( int chainNo, int resNo,
+ PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ res = GetResidue ( chainNo,resNo );
+ if (res) {
+ atomTable = res->atom;
+ NumberOfAtoms = res->nAtoms;
+ }
+ }
+
+
+ void Model::GetAtomTable1 ( const ChainID chainID, int seqNo,
+ const InsCode insCode,
+ PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ res = GetResidue ( chainID,seqNo,insCode );
+ if (res)
+ res->GetAtomTable1 ( atomTable,NumberOfAtoms );
+ else {
+ if (atomTable) delete[] atomTable;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ }
+ }
+
+ void Model::GetAtomTable1 ( int chainNo, int seqNo,
+ const InsCode insCode,
+ PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ res = GetResidue ( chainNo,seqNo,insCode );
+ if (res)
+ res->GetAtomTable1 ( atomTable,NumberOfAtoms );
+ else {
+ if (atomTable) delete[] atomTable;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ }
+ }
+
+ void Model::GetAtomTable1 ( const ChainID chainID, int resNo,
+ PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ res = GetResidue ( chainID,resNo );
+ if (res)
+ res->GetAtomTable1 ( atomTable,NumberOfAtoms );
+ else {
+ if (atomTable) delete[] atomTable;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ }
+ }
+
+ void Model::GetAtomTable1 ( int chainNo, int resNo,
+ PPAtom & atomTable,
+ int & NumberOfAtoms ) {
+ PResidue res;
+ res = GetResidue ( chainNo,resNo );
+ if (res)
+ res->GetAtomTable1 ( atomTable,NumberOfAtoms );
+ else {
+ if (atomTable) delete[] atomTable;
+ atomTable = NULL;
+ NumberOfAtoms = 0;
+ }
+ }
+
+
+
+ int Model::DeleteAtom ( const ChainID chID,
+ int seqNo,
+ const InsCode insCode,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc
+ ) {
+ PChain chn;
+ chn = GetChain ( chID );
+ if (chn)
+ return chn->DeleteAtom ( seqNo,insCode,aname,elmnt,aloc );
+ return 0;
+ }
+
+ int Model::DeleteAtom ( const ChainID chID, int seqNo,
+ const InsCode insCode, int atomNo ) {
+ PChain chn;
+ chn = GetChain ( chID );
+ if (chn) return chn->DeleteAtom ( seqNo,insCode,atomNo );
+ return 0;
+ }
+
+ int Model::DeleteAtom ( const ChainID chID,
+ int resNo,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc ) {
+ PChain chn;
+ chn = GetChain ( chID );
+ if (chn) return chn->DeleteAtom ( resNo,aname,elmnt,aloc );
+ return 0;
+ }
+
+ int Model::DeleteAtom ( const ChainID chID, int resNo, int atomNo ) {
+ PChain chn;
+ chn = GetChain ( chID );
+ if (chn) return chn->DeleteAtom ( resNo,atomNo );
+ return 0;
+ }
+
+ int Model::DeleteAtom ( int chNo, int seqNo,
+ const InsCode insCode,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc ) {
+ if ((0<=chNo) && (chNo<nChains)) {
+ if (chain[chNo])
+ return chain[chNo]->DeleteAtom ( seqNo,insCode,aname,
+ elmnt,aloc );
+ }
+ return 0;
+ }
+
+ int Model::DeleteAtom ( int chNo, int seqNo, const InsCode insCode,
+ int atomNo ) {
+ if ((0<=chNo) && (chNo<nChains)) {
+ if (chain[chNo])
+ return chain[chNo]->DeleteAtom ( seqNo,insCode,atomNo );
+ }
+ return 0;
+ }
+
+ int Model::DeleteAtom ( int chNo, int resNo,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc ) {
+ if ((0<=chNo) && (chNo<nChains)) {
+ if (chain[chNo])
+ return chain[chNo]->DeleteAtom ( resNo,aname,elmnt,aloc );
+ }
+ return 0;
+ }
+
+ int Model::DeleteAtom ( int chNo, int resNo, int atomNo ) {
+ if ((0<=chNo) && (chNo<nChains)) {
+ if (chain[chNo])
+ return chain[chNo]->DeleteAtom ( resNo,atomNo );
+ }
+ return 0;
+ }
+
+ int Model::DeleteAllAtoms ( const ChainID chID, int seqNo,
+ const InsCode insCode ) {
+ PChain chn;
+ chn = GetChain ( chID );
+ if (chn) return chn->DeleteAllAtoms ( seqNo,insCode );
+ return 0;
+ }
+
+ int Model::DeleteAllAtoms ( const ChainID chID, int resNo ) {
+ PChain chn;
+ chn = GetChain ( chID );
+ if (chn) return chn->DeleteAllAtoms ( resNo );
+ return 0;
+ }
+
+ int Model::DeleteAllAtoms ( const ChainID chID ) {
+ PChain chn;
+ chn = GetChain ( chID );
+ if (chn) return chn->DeleteAllAtoms();
+ return 0;
+ }
+
+ int Model::DeleteAllAtoms ( int chNo, int seqNo,
+ const InsCode insCode ) {
+ if ((0<=chNo) && (chNo<nChains)) {
+ if (chain[chNo])
+ return chain[chNo]->DeleteAllAtoms ( seqNo,insCode );
+ }
+ return 0;
+ }
+
+ int Model::DeleteAllAtoms ( int chNo, int resNo ) {
+ if ((0<=chNo) && (chNo<nChains)) {
+ if (chain[chNo])
+ return chain[chNo]->DeleteAllAtoms ( resNo );
+ }
+ return 0;
+ }
+
+ int Model::DeleteAllAtoms ( int chNo ) {
+ if ((0<=chNo) && (chNo<nChains)) {
+ if (chain[chNo])
+ return chain[chNo]->DeleteAllAtoms();
+ }
+ return 0;
+ }
+
+ int Model::DeleteAllAtoms() {
+ int i,k;
+ k = 0;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) k += chain[i]->DeleteAllAtoms();
+ return k;
+ }
+
+ int Model::DeleteAltLocs() {
+ // This function leaves only alternative location with maximal
+ // occupancy, if those are equal or unspecified, the one with
+ // "least" alternative location indicator.
+ // The function returns the number of deleted. All tables remain
+ // untrimmed, so that explicit trimming or calling FinishStructEdit()
+ // is required.
+ int i,n;
+
+ n = 0;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) n += chain[i]->DeleteAltLocs();
+
+ return n;
+
+ }
+
+
+ int Model::AddAtom ( const ChainID chID, int seqNo,
+ const InsCode insCode,
+ PAtom atom ) {
+ PChain chn;
+ chn = GetChain ( chID );
+ if (chn) return chn->AddAtom ( seqNo,insCode,atom );
+ return 0;
+ }
+
+ int Model::AddAtom ( const ChainID chID, int resNo, PAtom atom ) {
+ PChain chn;
+ chn = GetChain ( chID );
+ if (chn) return chn->AddAtom ( resNo,atom );
+ return 0;
+ }
+
+ int Model::AddAtom ( int chNo, int seqNo, const InsCode insCode,
+ PAtom atom ) {
+ if ((0<=chNo) && (chNo<nChains)) {
+ if (chain[chNo])
+ return chain[chNo]->AddAtom ( seqNo,insCode,atom );
+ }
+ return 0;
+ }
+
+ int Model::AddAtom ( int chNo, int resNo, PAtom atom ) {
+ if ((0<=chNo) && (chNo<nChains)) {
+ if (chain[chNo])
+ return chain[chNo]->AddAtom ( resNo,atom );
+ }
+ return 0;
+ }
+
+
+
+ void Model::GetAtomStatistics ( RAtomStat AS ) {
+ AS.Init();
+ CalAtomStatistics ( AS );
+ AS.Finish();
+ }
+
+ void Model::CalAtomStatistics ( RAtomStat AS ) {
+ int i;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) chain[i]->CalAtomStatistics ( AS );
+ }
+
+
+
+ ERROR_CODE Model::ConvertPDBString ( pstr PDBString ) {
+ // Interprets PDB records DBREF, SEQADV, SEQRES, MODRES.
+ // Returns zero if the line was converted, otherwise returns a
+ // non-negative value of Error_XXXX.
+ // PDBString must be not shorter than 81 characters.
+ ChainID chainID;
+ PChain chn;
+ PHelix helix;
+ PTurn turn;
+ PLink link;
+ PLinkR linkR;
+ PCisPep cispep;
+ ERROR_CODE RC;
+
+ // pad input line with spaces, if necessary
+ PadSpaces ( PDBString,80 );
+
+ chainID[0] = char(0);
+ chainID[1] = char(0);
+
+ if (!strncmp(PDBString,"DBREF ",6)) {
+
+ if (PDBString[12]!=' ') chainID[0] = PDBString[12];
+ chn = GetChainCreate ( chainID,false );
+ return chn->ConvertDBREF ( PDBString );
+
+ } else if (!strncmp(PDBString,"SEQADV",6)) {
+
+ if (PDBString[16]!=' ') chainID[0] = PDBString[16];
+ chn = GetChainCreate ( chainID,false );
+ return chn->ConvertSEQADV ( PDBString );
+
+ } else if (!strncmp(PDBString,"SEQRES",6)) {
+
+ if (PDBString[11]!=' ') chainID[0] = PDBString[11];
+ chn = GetChainCreate ( chainID,false );
+ return chn->ConvertSEQRES ( PDBString );
+
+ } else if (!strncmp(PDBString,"MODRES",6)) {
+
+ if (PDBString[16]!=' ') chainID[0] = PDBString[16];
+ chn = GetChainCreate ( chainID,false );
+ return chn->ConvertMODRES ( PDBString );
+
+ } else if (!strncmp(PDBString,"HET ",6)) {
+
+ if (PDBString[12]!=' ') chainID[0] = PDBString[12];
+ chn = GetChainCreate ( chainID,false );
+ return chn->ConvertHET ( PDBString );
+
+ } else if (!strncmp(PDBString,"HETNAM",6)) {
+
+ hetCompounds.ConvertHETNAM ( PDBString );
+ return Error_NoError;
+
+ } else if (!strncmp(PDBString,"HETSYN",6)) {
+
+ hetCompounds.ConvertHETSYN ( PDBString );
+ return Error_NoError;
+
+ } else if (!strncmp(PDBString,"FORMUL",6)) {
+
+ hetCompounds.ConvertFORMUL ( PDBString );
+ return Error_NoError;
+
+ } else if (!strncmp(PDBString,"HELIX ",6)) {
+
+ helix = new Helix();
+ RC = helix->ConvertPDBASCII(PDBString);
+ if (RC==0) helices.AddData ( helix );
+ else delete helix;
+ return RC;
+
+ } else if (!strncmp(PDBString,"SHEET ",6)) {
+
+ return sheets.ConvertPDBASCII ( PDBString );
+
+ } else if (!strncmp(PDBString,"TURN ",6)) {
+
+ turn = new Turn();
+ RC = turn->ConvertPDBASCII(PDBString);
+ if (RC==0) turns.AddData ( turn );
+ else delete turn;
+ return RC;
+
+ } else if (!strncmp(PDBString,"LINK ",6)) {
+
+ link = new Link();
+ RC = link->ConvertPDBASCII(PDBString);
+ if (RC==0) links.AddData ( link );
+ else delete link;
+ return RC;
+
+
+ } else if (!strncmp(PDBString,"LINKR ",6)) {
+
+ linkR = new LinkR();
+ RC = linkR->ConvertPDBASCII(PDBString);
+ if (RC==0) linkRs.AddData ( linkR );
+ else delete linkR;
+ return RC;
+
+ } else if (!strncmp(PDBString,"CISPEP",6)) {
+
+ cispep = new CisPep();
+ RC = cispep->ConvertPDBASCII(PDBString);
+ if (RC==0) cisPeps.AddData ( cispep );
+ else delete cispep;
+ return RC;
+
+ } else
+ return Error_WrongSection;
+
+ }
+
+
+ void Model::PDBASCIIDumpPS ( io::RFile f ) {
+ int i;
+
+ for (i=0;i<nChains;i++)
+ if (chain[i])
+ chain[i]->DBRef.PDBASCIIDump ( f );
+
+ for (i=0;i<nChains;i++)
+ if (chain[i])
+ chain[i]->seqAdv.PDBASCIIDump ( f );
+
+ for (i=0;i<nChains;i++)
+ if (chain[i])
+ chain[i]->seqRes.PDBASCIIDump ( f );
+
+ for (i=0;i<nChains;i++)
+ if (chain[i])
+ chain[i]->modRes.PDBASCIIDump ( f );
+
+ for (i=0;i<nChains;i++)
+ if (chain[i])
+ chain[i]->Het.PDBASCIIDump ( f );
+
+ hetCompounds.PDBASCIIDump ( f );
+ helices .PDBASCIIDump ( f );
+ sheets .PDBASCIIDump ( f );
+ turns .PDBASCIIDump ( f );
+ links .PDBASCIIDump ( f );
+ linkRs .PDBASCIIDump ( f );
+
+ }
+
+ void Model::PDBASCIIDumpCP ( io::RFile f ) {
+ cisPeps.PDBASCIIDump ( f );
+ }
+
+ void Model::PDBASCIIDump ( io::RFile f ) {
+ char S[100];
+ int i;
+ bool singleModel = true;
+
+ if (manager)
+ singleModel = (manager->nModels<=1);
+
+ if (!singleModel) {
+ strcpy ( S,"MODEL " );
+ PadSpaces ( S,80 );
+ PutInteger ( &(S[10]),serNum,4 );
+ f.WriteLine ( S );
+ }
+
+ for (i=0;i<nChains;i++)
+ if (chain[i])
+ chain[i]->PDBASCIIAtomDump ( f );
+
+ if (!singleModel) {
+ strcpy ( S,"ENDMDL" );
+ PadSpaces ( S,80 );
+ f.WriteLine ( S );
+ }
+
+ }
+
+
+ void Model::MakeAtomCIF ( mmcif::PData CIF ) {
+ int i;
+ for (i=0;i<nChains;i++)
+ if (chain[i])
+ chain[i]->MakeAtomCIF ( CIF );
+ }
+
+
+ void Model::MakePSCIF ( mmcif::PData CIF ) {
+ int i;
+
+ for (i=0;i<nChains;i++)
+ if (chain[i])
+ chain[i]->DBRef.MakeCIF ( CIF );
+
+ for (i=0;i<nChains;i++)
+ if (chain[i])
+ chain[i]->seqAdv.MakeCIF ( CIF );
+
+ for (i=0;i<nChains;i++)
+ if (chain[i])
+ chain[i]->seqRes.MakeCIF ( CIF );
+
+ for (i=0;i<nChains;i++)
+ if (chain[i])
+ chain[i]->modRes.MakeCIF ( CIF );
+
+ for (i=0;i<nChains;i++)
+ if (chain[i])
+ chain[i]->Het.MakeCIF ( CIF );
+
+ hetCompounds.MakeCIF ( CIF );
+ helices .MakeCIF ( CIF );
+ sheets .MakeCIF ( CIF );
+ turns .MakeCIF ( CIF );
+ links .MakeCIF ( CIF );
+ linkRs .MakeCIF ( CIF );
+
+ }
+
+ ERROR_CODE Model::GetCIFPSClass ( mmcif::PData CIF, int ClassID ) {
+ ChainContainer PSClass;
+ PChainContainer Dest;
+ ERROR_CODE RC;
+ cpstr chainID;
+ PChain chn;
+ PSClass.SetChain ( NULL );
+ RC = PSClass.GetCIF ( CIF,ClassID );
+ if (RC!=Error_NoError) return RC;
+ chainID = PSClass.Get1stChainID();
+ while (chainID) {
+ chn = GetChainCreate ( chainID,false );
+ switch (ClassID) {
+ case ClassID_DBReference : Dest = &(chn->DBRef); break;
+ case ClassID_SeqAdv : Dest = &(chn->seqAdv); break;
+ case ClassID_ModRes : Dest = &(chn->modRes); break;
+ case ClassID_Het : Dest = &(chn->Het); break;
+ default : Dest = NULL;
+ }
+ if (Dest) {
+ PSClass.MoveByChainID ( chainID,Dest );
+ Dest->SetChain ( chn );
+ } else
+ printf ( " **** PROGRAM ERROR: wrong call to"
+ " Model::GetCIFPSClass(..)\n" );
+ chainID = PSClass.Get1stChainID();
+ }
+ return Error_NoError;
+ }
+
+ ERROR_CODE Model::GetCIF ( mmcif::PData CIF ) {
+ SeqRes seqRes;
+ ERROR_CODE RC;
+ PChain chn;
+
+ RC = GetCIFPSClass ( CIF,ClassID_DBReference );
+ if (RC!=Error_NoError) return RC;
+
+ RC = GetCIFPSClass ( CIF,ClassID_SeqAdv );
+ if (RC!=Error_NoError) return RC;
+
+ RC = seqRes.GetCIF ( CIF );
+ while (RC==Error_NoError) {
+ chn = GetChainCreate ( seqRes.chainID,false );
+ chn->seqRes.Copy ( &seqRes );
+ RC = seqRes.GetCIF ( CIF );
+ }
+
+ RC = GetCIFPSClass ( CIF,ClassID_ModRes );
+ if (RC!=Error_NoError) return RC;
+
+ RC = GetCIFPSClass ( CIF,ClassID_Het );
+ if (RC!=Error_NoError) return RC;
+
+ hetCompounds.GetCIF ( CIF );
+ helices .GetCIF ( CIF,ClassID_Helix );
+ sheets .GetCIF ( CIF );
+ turns .GetCIF ( CIF,ClassID_Turn );
+ links .GetCIF ( CIF,ClassID_Link );
+ linkRs .GetCIF ( CIF,ClassID_LinkR );
+
+ return RC;
+
+ }
+
+ cpstr Model::GetEntryID() {
+ if (manager) return manager->title.idCode;
+ else return pstr("");
+ }
+
+ void Model::SetEntryID ( const IDCode idCode ) {
+ if (manager)
+ manager->SetEntryID ( idCode );
+ }
+
+ int Model::GetNumberOfAllAtoms() {
+ if (manager) return manager->nAtoms;
+ else return 0;
+ }
+
+ int Model::GetSerNum() {
+ return serNum;
+ }
+
+ PAtom * Model::GetAllAtoms() {
+ if (manager) return manager->atom;
+ else return NULL;
+ }
+
+
+ cpstr Model::GetModelID ( pstr modelID ) {
+ modelID[0] = char(0);
+ sprintf ( modelID,"/%i",serNum );
+ return modelID;
+ }
+
+ int Model::GetNumberOfModels() {
+ if (manager) return manager->nModels;
+ else return 0;
+ }
+
+
+ void Model::Copy ( PModel model ) {
+ // modify both Model::_copy and Model::Copy methods simultaneously!
+ int i;
+
+ FreeMemory();
+
+ if (model) {
+
+ serNum = model->serNum;
+ nChains = model->nChains;
+ nChainsAlloc = nChains;
+ if (nChains>0) {
+ chain = new PChain[nChainsAlloc];
+ for (i=0;i<nChains;i++) {
+ if (model->chain[i]) {
+ chain[i] = newChain();
+ chain[i]->SetModel ( this );
+ chain[i]->Copy ( model->chain[i] );
+ } else
+ chain[i] = NULL;
+ }
+ }
+
+ hetCompounds.Copy ( &(model->hetCompounds) );
+ helices .Copy ( &(model->helices) );
+ sheets .Copy ( &(model->sheets) );
+ turns .Copy ( &(model->turns) );
+ links .Copy ( &(model->links) );
+ linkRs .Copy ( &(model->linkRs) );
+ cisPeps .Copy ( &(model->cisPeps) );
+
+ }
+
+ }
+
+ void Model::CopyHets ( PModel model ) {
+ if (model) hetCompounds.Copy ( &(model->hetCompounds) );
+ }
+
+ void Model::CopySecStructure ( PModel model ) {
+ if (model) {
+ helices.Copy ( &(model->helices) );
+ sheets .Copy ( &(model->sheets) );
+ turns .Copy ( &(model->turns) );
+ }
+ }
+
+ void Model::CopyLinks ( PModel model ) {
+ if (model)links.Copy ( &(model->links) );
+ }
+
+ void Model::CopyLinkRs ( PModel model ) {
+ if (model) linkRs.Copy ( &(model->linkRs) );
+ }
+
+ void Model::CopyCisPeps ( PModel model ) {
+ if (model) cisPeps.Copy ( &(model->cisPeps) );
+ }
+
+ void Model::_copy ( PModel model ) {
+ // modify both Model::_copy and Model::Copy methods simultaneously!
+ int i;
+
+ FreeMemory();
+
+ if (model) {
+
+ serNum = model->serNum;
+ nChains = model->nChains;
+ nChainsAlloc = nChains;
+ if (nChains>0) {
+ chain = new PChain[nChainsAlloc];
+ for (i=0;i<nChains;i++) {
+ if (model->chain[i]) {
+ chain[i] = newChain();
+ chain[i]->SetModel ( this );
+ chain[i]->_copy ( model->chain[i] );
+ } else
+ chain[i] = NULL;
+ }
+ }
+
+ hetCompounds.Copy ( &(model->hetCompounds) );
+ helices .Copy ( &(model->helices) );
+ sheets .Copy ( &(model->sheets) );
+ turns .Copy ( &(model->turns) );
+ links .Copy ( &(model->links) );
+ linkRs .Copy ( &(model->linkRs) );
+ cisPeps .Copy ( &(model->cisPeps) );
+
+ }
+
+ }
+
+
+ void Model::_copy ( PModel model, PPAtom atom, int & atom_index ) {
+ // modify both Model::_copy and Model::Copy methods simultaneously!
+ //
+ // _copy(PModel,PPAtom,int&) does copy atoms into array 'atom'
+ // starting from position atom_index. 'atom' should be able to
+ // accept all new atoms - no checks on the length of 'atom'
+ // is being made. This function should not be used in applications.
+ int i;
+
+ FreeMemory();
+
+ if (model) {
+
+ serNum = model->serNum;
+ nChains = model->nChains;
+ nChainsAlloc = nChains;
+ if (nChains>0) {
+ chain = new PChain[nChainsAlloc];
+ for (i=0;i<nChains;i++) {
+ if (model->chain[i]) {
+ chain[i] = newChain();
+ chain[i]->SetModel ( this );
+ chain[i]->_copy ( model->chain[i],atom,atom_index );
+ } else
+ chain[i] = NULL;
+ }
+ }
+
+ hetCompounds.Copy ( &(model->hetCompounds) );
+ helices .Copy ( &(model->helices) );
+ sheets .Copy ( &(model->sheets) );
+ turns .Copy ( &(model->turns) );
+ links .Copy ( &(model->links) );
+ linkRs .Copy ( &(model->linkRs) );
+
+ }
+
+ }
+
+
+ int Model::AddChain ( PChain chn ) {
+ // modify both Model::Copy methods simultaneously!
+ //
+ // Copy(PModel,PPAtom,int&) copies atoms into array 'atom'
+ // starting from position atom_index. 'atom' should be able to
+ // accept all new atoms - no checks on the length of 'atom'
+ // is being made. This function should not be used in applications.
+ PModel model1;
+ int i;
+
+ for (i=0;i<nChains;i++)
+ if (chain[i]==chn) return -i; // this chain is already there
+
+ if (chn) {
+
+ // get space for new chain
+ ExpandChainArray ( nChains );
+
+ if (chn->GetCoordHierarchy()) {
+ // The chain is associated with a coordinate hierarchy. It should
+ // remain there, therefore we physically copy all its residues
+ // and atoms.
+ chain[nChains] = newChain();
+ chain[nChains]->SetModel ( this );
+ if (manager) {
+ // get space for new atoms
+ manager->AddAtomArray ( chn->GetNumberOfAtoms(true) );
+ chain[nChains]->_copy ( chn,manager->atom,manager->nAtoms );
+ } else {
+ for (i=0;i<chn->nResidues;i++)
+ chain[nChains]->AddResidue ( chn->residue[i] );
+ }
+ } else {
+ // The chain is not associated with a coordinate hierarchy. Such
+ // unregistered objects are simply taken over, i.e. moved into
+ // the new destination (model).
+ chain[nChains] = chn;
+ // remove chain from its model:
+ model1 = chn->GetModel();
+ if (model1)
+ for (i=0;i<model1->nChains;i++)
+ if (model1->chain[i]==chn) {
+ model1->chain[i] = NULL;
+ break;
+ }
+ chain[nChains]->SetModel ( this );
+ if (manager)
+ chain[nChains]->CheckInAtoms();
+ }
+
+ nChains++;
+
+ }
+
+ return nChains;
+
+ }
+
+
+ void Model::MoveChain ( PChain & m_chain, PPAtom m_atom,
+ PPAtom atom, int & atom_index,
+ int chain_ext ) {
+ // MoveChain(..) adds chain m_chain on the top Chain array.
+ // The pointer on chain is then set to NULL (m_chain=NULL).
+ // If chain_ext is greater than 0, the moved chain will be
+ // forcefully renamed; the new name is composed as the previous
+ // one + underscore + chain_ext (e.g. A_1). If thus generated
+ // name duplicates any of existing chain IDs, or if chain_ext
+ // was set to 0 and there is a duplication of chain IDs, the
+ // name is again modified as above, with the extension number
+ // generated automatically (this may result in IDs like
+ // A_1_10).
+ // m_atom must give pointer to the Atom array, from which
+ // the atoms belonging to m_chain, are moved to Atom array
+ // given by 'atom', starting from poisition 'atom_index'.
+ // 'atom_index' is then automatically updated to the next
+ // free position in 'atom'.
+ // Note1: the moved atoms will occupy a continuous range
+ // in 'atom' array; no checks on whether the corresponding
+ // cells are occupied or not, are performed.
+ // Note2: the 'atom_index' is numbered from 0 on, i.e.
+ // it is equal to atom[atom_index]->index-1; atom[]->index
+ // is assigned automatically.
+ ChainID chainID;
+ int i,j,k,Ok;
+ PPChain chain1;
+ PResidue crRes;
+
+ if (!m_chain) return;
+
+ // modify chain ID with the extension given
+ if (chain_ext>0)
+ sprintf ( chainID,"%s_%i",m_chain->chainID,chain_ext );
+ else strcpy ( chainID,m_chain->chainID );
+
+ // Choose the chain ID. If a chain with such ID is
+ // already present in the model, it will be assigned
+ // a new ID 'ID_n', where 'ID' stands for the original
+ // chain ID and 'n' is the minimum (integer) number
+ // chosen such that 'name_n' represents a new chain ID
+ // (in the model).
+ k = 0;
+ do {
+ Ok = true;
+ for (i=0;(i<nChains) && (Ok);i++)
+ if (chain[i])
+ if (!strcmp(chainID,chain[i]->chainID)) Ok = false;
+ if (!Ok) {
+ k++;
+ if (chain_ext>0)
+ sprintf ( chainID,"%s_%i_%i",m_chain->chainID,
+ chain_ext,k );
+ else sprintf ( chainID,"%s_%i",m_chain->chainID,k );
+ }
+ } while (!Ok);
+
+ // add chain on the top of Chain array.
+ strcpy ( m_chain->chainID,chainID );
+ if (nChains>=nChainsAlloc) {
+ nChainsAlloc = nChains+10;
+ chain1 = new PChain[nChainsAlloc];
+ k = 0;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) chain1[k++] = chain[i];
+ for (i=k;i<nChainsAlloc;i++)
+ chain1[i] = NULL;
+ if (chain) delete[] chain;
+ chain = chain1;
+ }
+ chain[nChains] = m_chain;
+ chain[nChains]->SetModel ( this );
+ nChains++;
+
+ // Move all atoms of the chain. While residues belong
+ // atoms belong to the chain's manager class. Therefore
+ // they should be moved from one manager to another.
+ for (i=0;i<m_chain->nResidues;i++) {
+ crRes = m_chain->residue[i];
+ if (crRes)
+ for (j=0;j<crRes->nAtoms;j++)
+ if (crRes->atom[j]) {
+ k = crRes->atom[j]->index-1;
+ atom[atom_index] = m_atom[k];
+ atom[atom_index]->index = atom_index+1;
+ atom_index++;
+ m_atom[k] = NULL; // moved!
+ }
+ }
+
+ m_chain = NULL; // moved!
+
+ }
+
+ void Model::GetAIndexRange ( int & i1, int & i2 ) {
+ PChain chn;
+ PResidue res;
+ int ic,ir,ia;
+ i1 = MaxInt4;
+ i2 = MinInt4;
+ for (ic=0;ic<nChains;ic++) {
+ chn = chain[ic];
+ if (chn) {
+ for (ir=0;ir<chn->nResidues;ir++) {
+ res = chn->residue[ir];
+ if (res) {
+ for (ia=0;ia<res->nAtoms;ia++)
+ if (res->atom[ia]) {
+ if (res->atom[ia]->index<i1) i1 = res->atom[ia]->index;
+ if (res->atom[ia]->index>i2) i2 = res->atom[ia]->index;
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+
+ void Model::MaskAtoms ( PMask Mask ) {
+ int i;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) chain[i]->MaskAtoms ( Mask );
+ }
+
+ void Model::MaskResidues ( PMask Mask ) {
+ int i;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) chain[i]->MaskResidues ( Mask );
+ }
+
+ void Model::MaskChains ( PMask Mask ) {
+ int i;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) chain[i]->SetMask ( Mask );
+ }
+
+ void Model::UnmaskAtoms ( PMask Mask ) {
+ int i;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) chain[i]->UnmaskAtoms ( Mask );
+ }
+
+ void Model::UnmaskResidues ( PMask Mask ) {
+ int i;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) chain[i]->UnmaskResidues ( Mask );
+ }
+
+ void Model::UnmaskChains ( PMask Mask ) {
+ int i;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) chain[i]->RemoveMask ( Mask );
+ }
+
+
+ // ------ Getting Secondary Structure Elements
+
+ int Model::GetNumberOfHelices() {
+ return helices.Length();
+ }
+
+ int Model::GetNumberOfSheets() {
+ return sheets.nSheets;
+ }
+
+ PHelix Model::GetHelix ( int serialNum ) {
+ return (PHelix)helices.GetContainerClass ( serialNum-1 );
+ }
+
+ void Model::GetSheetID ( int serialNum, SheetID sheetID ) {
+ if ((1<=serialNum) && (serialNum<=sheets.nSheets)) {
+ if (sheets.sheet[serialNum-1]) {
+ strcpy ( sheetID,sheets.sheet[serialNum-1]->sheetID );
+ return;
+ }
+ }
+ sheetID[0] = char(0);
+ }
+
+ PSheet Model::GetSheet ( int serialNum ) {
+ if ((1<=serialNum) && (serialNum<=sheets.nSheets))
+ return sheets.sheet[serialNum-1];
+ else return NULL;
+ }
+
+ PSheet Model::GetSheet ( const SheetID sheetID ) {
+ int i;
+ for (i=0;i<sheets.nSheets;i++)
+ if (sheets.sheet[i]) {
+ if (!strcmp(sheets.sheet[i]->sheetID,sheetID))
+ return sheets.sheet[i];
+ }
+ return NULL;
+ }
+
+ int Model::GetNumberOfStrands ( int sheetSerNum ) {
+ if ((1<=sheetSerNum) && (sheetSerNum<=sheets.nSheets)) {
+ if (sheets.sheet[sheetSerNum-1])
+ return sheets.sheet[sheetSerNum-1]->nStrands;
+ }
+ return 0;
+ }
+
+ int Model::GetNumberOfStrands ( const SheetID sheetID ) {
+ int i;
+ for (i=0;i<sheets.nSheets;i++)
+ if (sheets.sheet[i]) {
+ if (!strcmp(sheets.sheet[i]->sheetID,sheetID))
+ return sheets.sheet[i]->nStrands;
+ }
+ return 0;
+ }
+
+ PStrand Model::GetStrand ( int sheetSerNum, int strandSerNum ) {
+ PSheet sheet;
+ if ((1<=sheetSerNum) && (sheetSerNum<=sheets.nSheets)) {
+ sheet = sheets.sheet[sheetSerNum-1];
+ if (sheet) {
+ if ((1<=strandSerNum) && (strandSerNum<=sheet->nStrands))
+ return sheet->strand[strandSerNum-1];
+ }
+ }
+ return NULL;
+ }
+
+ PStrand Model::GetStrand ( const SheetID sheetID,
+ int strandSerNum ) {
+ int i;
+ PSheet sheet;
+ for (i=0;i<sheets.nSheets;i++)
+ if (sheets.sheet[i]) {
+ if (!strcmp(sheets.sheet[i]->sheetID,sheetID)) {
+ sheet = sheets.sheet[i];
+ if (sheet) {
+ if ((1<=strandSerNum) && (strandSerNum<=sheet->nStrands))
+ return sheet->strand[strandSerNum-1];
+ }
+ }
+ }
+ return NULL;
+ }
+
+ void Model::RemoveSecStructure() {
+ helices.FreeContainer();
+ sheets .FreeMemory ();
+ turns .FreeContainer();
+ }
+
+ void Model::RemoveHetInfo() {
+ hetCompounds.FreeMemory();
+ }
+
+
+ int Model::GetNumberOfLinks() {
+ return links.Length();
+ }
+
+ PLink Model::GetLink ( int serialNum ) {
+ return (PLink)links.GetContainerClass ( serialNum-1 );
+ }
+
+ void Model::RemoveLinks() {
+ links.FreeContainer();
+ }
+
+ void Model::AddLink ( PLink link ) {
+ links.AddData ( link );
+ }
+
+
+ int Model::GetNumberOfLinkRs() {
+ return linkRs.Length();
+ }
+
+ PLinkR Model::GetLinkR ( int serialNum ) {
+ return (PLinkR)linkRs.GetContainerClass ( serialNum-1 );
+ }
+
+ void Model::RemoveLinkRs() {
+ linkRs.FreeContainer();
+ }
+
+ void Model::AddLinkR ( PLinkR linkR ) {
+ linkRs.AddData ( linkR );
+ }
+
+
+
+ int Model::GetNumberOfCisPeps() {
+ return cisPeps.Length();
+ }
+
+ PCisPep Model::GetCisPep ( int CisPepNum ) {
+ return (PCisPep)cisPeps.GetContainerClass ( CisPepNum-1 );
+ }
+
+ void Model::RemoveCisPeps() {
+ cisPeps.FreeContainer();
+ }
+
+ void Model::AddCisPep ( PCisPep cisPep ) {
+ cisPeps.AddData ( cisPep );
+ }
+
+
+ void Model::ApplyTransform ( mat44 & TMatrix ) {
+ // transforms all coordinates by multiplying with matrix TMatrix
+ int i;
+ for (i=0;i<nChains;i++)
+ if (chain[i]) chain[i]->ApplyTransform ( TMatrix );
+ }
+
+ bool Model::isInSelection ( int selHnd ) {
+ PMask mask;
+ if (manager) {
+ mask = PRoot(manager)->GetSelMask ( selHnd );
+ if (mask) return CheckMask ( mask );
+ }
+ return false;
+ }
+
+
+
+ // ------- user-defined data handlers
+
+ int Model::PutUDData ( int UDDhandle, int iudd ) {
+ if (UDDhandle & UDRF_MODEL)
+ return UDData::putUDData ( UDDhandle,iudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Model::PutUDData ( int UDDhandle, realtype rudd ) {
+ if (UDDhandle & UDRF_MODEL)
+ return UDData::putUDData ( UDDhandle,rudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Model::PutUDData ( int UDDhandle, cpstr sudd ) {
+ if (UDDhandle & UDRF_MODEL)
+ return UDData::putUDData ( UDDhandle,sudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Model::GetUDData ( int UDDhandle, int & iudd ) {
+ if (UDDhandle & UDRF_MODEL)
+ return UDData::getUDData ( UDDhandle,iudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Model::GetUDData ( int UDDhandle, realtype & rudd ) {
+ if (UDDhandle & UDRF_MODEL)
+ return UDData::getUDData ( UDDhandle,rudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Model::GetUDData ( int UDDhandle, pstr sudd, int maxLen ) {
+ if (UDDhandle & UDRF_MODEL)
+ return UDData::getUDData ( UDDhandle,sudd,maxLen );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Model::GetUDData ( int UDDhandle, pstr & sudd ) {
+ if (UDDhandle & UDRF_MODEL)
+ return UDData::getUDData ( UDDhandle,sudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+
+ // ------- calculation of Secondary Structure
+
+
+ int Model::CalcSecStructure ( bool flagBulge, int aminoSelHnd ) {
+ // This function is contributed by Liz Potterton, University of York
+ //------------------------------------------------------------------
+ // Define a secondary structure type of each amino acid residue in the
+ // structure.
+ // Procedure:
+ // Find all amino acids
+ // Find all pairs of amino acids which have inter-Ca distance < 10.0A
+ // Test for hydrogen bonds between the main chain N and O of the close
+ // residues and store the information in the hbonds matrix
+ // Analyse the info in hbonds matrix to assign secondary structure to
+ // secstr vector
+ PPResidue Res;
+ PPAtom Ca;
+ PChain chn;
+ PContact contact;
+ imatrix hbonds;
+ PPAtom * hbond_atoms;
+ int nres, ncontacts;
+ int ir1,ir2, irdif;
+ int i,j,k,l;
+
+ // 1a. Get protein residues from selection handle
+
+ if (aminoSelHnd>=0) {
+
+ manager->GetSelIndex(aminoSelHnd,Res,nres);
+ // printf ( " nres %3i " ,nres );
+ if (nres<=0) return SSERC_noResidues;
+
+ } else {
+
+ // 1b. Get all protein residues
+
+ nres = 0;
+ for (i=0;i<nChains;i++)
+ if (chain[i])
+ nres += chain[i]->nResidues;
+
+ if (nres<=0) return SSERC_noResidues;
+
+ Res = new PResidue[nres];
+ nres = 0;
+ for (i=0;i<nChains;i++) {
+ chn = chain[i];
+ if (chn) {
+ k = chn->nResidues;
+ for (j=0;j<k;j++)
+ Res[nres++] = chn->residue[j];
+ }
+ }
+
+
+ if (nres<=0) {
+ delete[] Res;
+ return SSERC_noResidues;
+ }
+
+ }
+
+ // 2. Get C-alphas of all aminoacids
+
+ Ca = new PAtom[nres];
+ k = 0;
+ for (i=0;i<nres;i++)
+ if (Res[i]) {
+ if (aminoSelHnd>=0 || Res[i]->isAminoacid()) {
+ Ca[i] = Res[i]->GetAtom("CA", " C", "*");
+ k++;
+ } else
+ Ca[i] = NULL;
+ Res[i]->SSE = SSE_None;
+ } else
+ Ca[i] = NULL;
+
+ if (k<=0) {
+ delete[] Res;
+ delete[] Ca;
+ return SSERC_noAminoacids;
+ }
+
+
+ // 3. Find all close Calphas - i.e. find the contacts between
+ // the two equivalent sets of Ca atoms
+
+ contact = NULL;
+ ncontacts = 0;
+ manager->SeekContacts ( Ca,nres, Ca,nres, 2.0,10.0, 2,
+ contact,ncontacts,0 );
+ if (ncontacts<=0) {
+ delete[] Res;
+ delete[] Ca;
+ if (contact) delete[] contact;
+ return SSERC_noSSE;
+ }
+
+
+ // 4. Get and initialize memory for analysing the SSE
+
+ GetMatrixMemory ( hbonds,nres,3,0,0 );
+ hbond_atoms = new PPAtom[nres];
+ for (i=0;i<nres;i++) {
+ hbond_atoms[i] = new PAtom[6];
+ for (j=0;j<6;j++) hbond_atoms[i][j] = NULL;
+ for (j=0;j<3;j++) hbonds [i][j] = 0;
+ }
+
+
+ // 5. Loop over all close (in space) residues - excluding those
+ // that are close in sequence
+
+ for (i=0;i<ncontacts;i++) {
+ ir1 = contact[i].id2;
+ ir2 = contact[i].id1;
+ irdif = ir1 - ir2;
+ if (irdif>2) {
+ // test if there is donor Hbond from residue ir1
+ if (Res[ir1]->isMainchainHBond(Res[ir2])) {
+ k = 0;
+ while ((hbonds[ir1][k]!=0) && (k<2)) k++;
+ hbonds [ir1][k] = -irdif;
+ hbond_atoms[ir1][k] = Res[ir1]->GetAtom ( "N" );
+ hbond_atoms[ir1][k+3] = Res[ir2]->GetAtom ( "O" );
+ }
+ // test if there is donor Hbond from residue ir2
+ if (Res[ir2]->isMainchainHBond(Res[ir1])) {
+ k = 0;
+ while ((hbonds[ir2][k]!=0) && (k<2)) k++;
+ hbonds [ir2][k] = irdif;
+ hbond_atoms[ir2][k] = Res[ir2]->GetAtom ( "N" );
+ hbond_atoms[ir2][k+3] = Res[ir1]->GetAtom ( "O" );
+ }
+ }
+ }
+
+ // 6. Assign the turns - if there is bifurcated bond then the 4-turn
+ // takes precedence - read the paper to make sense of this
+
+ for (i=0;i<nres;i++) {
+ k = 0;
+ while ((k<=2) && (hbonds[i][k]!=0)) {
+ if (hbonds[i][k]==-5) {
+ Res[i-1]->SSE = SSE_5Turn;
+ Res[i-2]->SSE = SSE_5Turn;
+ Res[i-3]->SSE = SSE_5Turn;
+ Res[i-4]->SSE = SSE_5Turn;
+ }
+ if (hbonds[i][k]==-3) {
+ Res[i-1]->SSE = SSE_3Turn;
+ Res[i-2]->SSE = SSE_3Turn;
+ }
+ k++;
+ }
+ }
+ for (i=0;i<nres;i++) {
+ k = 0;
+ while ((k<=2) && (hbonds[i][k]!=0)) {
+ if (hbonds[i][k]==-4) {
+ Res[i-1]->SSE = SSE_4Turn;
+ Res[i-2]->SSE = SSE_4Turn;
+ Res[i-3]->SSE = SSE_4Turn;
+ }
+ k++;
+ }
+ }
+
+
+ // 7. Look for consecutive 4-turns which make alpha helix
+
+ for (i=1;i<nres-3;i++) {
+ if (((Res[i ]->SSE==SSE_Helix) || (Res[i ]->SSE==SSE_4Turn)) &&
+ ((Res[i+1]->SSE==SSE_Helix) || (Res[i+1]->SSE==SSE_4Turn)) &&
+ ((Res[i+2]->SSE==SSE_Helix) || (Res[i+2]->SSE==SSE_4Turn)) &&
+ ((Res[i+3]->SSE==SSE_Helix) || (Res[i+3]->SSE==SSE_4Turn)))
+ for (j=i;j<=i+3;j++) Res[j]->SSE = SSE_Helix;
+ }
+
+ for (i=0;i<nres;i++) {
+
+ k = 0;
+ while ((k<=2) && (hbonds[i][k]!=0)) {
+
+ irdif = hbonds[i][k];
+ // Test for 'close' hbond
+ j = i + irdif;
+ l = 0;
+ while ((l<=2) && (hbonds[j][l]!=0)) {
+ // Antiparallel strands
+ if (hbonds[j][l]==-irdif) {
+ Res[i]->SSE = SSE_Strand;
+ Res[j]->SSE = SSE_Strand;
+ }
+ // Parallel strand
+ if (hbonds[j][l]==-irdif-2) {
+ Res[i-1]->SSE = SSE_Strand;
+ Res[j ]->SSE = SSE_Strand;
+ }
+ // Parallel beta bulge
+ if (hbonds[j][l]==-irdif-3) {
+ if (flagBulge) {
+ if (Res[i-1]->SSE==SSE_None) Res[i-1]->SSE = SSE_Bulge;
+ if (Res[i-2]->SSE==SSE_None) Res[i-2]->SSE = SSE_Bulge;
+ if (Res[j ]->SSE==SSE_None) Res[j ]->SSE = SSE_Bulge;
+ } else {
+ if (Res[i-1]->SSE==SSE_None) Res[i-1]->SSE = SSE_Strand;
+ if (Res[i-2]->SSE==SSE_None) Res[i-2]->SSE = SSE_Strand;
+ if (Res[j ]->SSE==SSE_None) Res[j ]->SSE = SSE_Strand;
+ }
+ }
+ l++;
+ }
+ // Test for 'wide' hbond
+ j = i + hbonds[i][k] + 2;
+ if (j<nres) {
+ l = 0;
+ while ((l<=2) && (hbonds[j][l]!=0)) {
+ // Antiaprallel strands
+ if (hbonds[j][l]==-irdif-4) {
+ Res[i-1]->SSE = SSE_Strand;
+ Res[j-1]->SSE = SSE_Strand;
+ }
+ // Parallel strands
+ if (hbonds[j][l]==-irdif-2) {
+ Res[i ]->SSE = SSE_Strand;
+ Res[j-1]->SSE = SSE_Strand;
+ }
+ l++;
+ }
+ }
+
+ // test for anti-parallel B-bulge between 'close' hbonds
+ j = i + hbonds[i][k] - 1;
+ if (j>=0) {
+ l = 0;
+ while ((l<=2) && (hbonds[j][l]!=0)) {
+ if (hbonds[j][l]==-irdif+1) {
+ if (flagBulge) {
+ if (Res[i ]->SSE==SSE_None) Res[i ]->SSE = SSE_Bulge;
+ if (Res[j+1]->SSE==SSE_None) Res[j+1]->SSE = SSE_Bulge;
+ if (Res[j ]->SSE==SSE_None) Res[j ]->SSE = SSE_Bulge;
+ } else {
+ if (Res[i ]->SSE==SSE_None) Res[i ]->SSE = SSE_Strand;
+ if (Res[j+1]->SSE==SSE_None) Res[j+1]->SSE = SSE_Strand;
+ if (Res[j ]->SSE==SSE_None) Res[j ]->SSE = SSE_Strand;
+ }
+ }
+ l++;
+ }
+ }
+
+ // test for anti-parallel B-bulge between 'wide' hbonds
+ j = i + hbonds[i][k] + 3;
+ if (j<nres) {
+ l = 0;
+ while ((l<=2) && (hbonds[j][l]!=0)) {
+ if ((hbonds[j][l]==-irdif+5) && (i>0)) {
+ if (flagBulge) {
+ if (Res[i-1]->SSE==SSE_None) Res[i-1]->SSE = SSE_Bulge;
+ if (Res[j-1]->SSE==SSE_None) Res[j-1]->SSE = SSE_Bulge;
+ if (Res[j-2]->SSE==SSE_None) Res[j-2]->SSE = SSE_Bulge;
+ } else {
+ if (Res[i-1]->SSE==SSE_None) Res[i-1]->SSE = SSE_Strand;
+ if (Res[j-1]->SSE==SSE_None) Res[j-1]->SSE = SSE_Strand;
+ if (Res[j-2]->SSE==SSE_None) Res[j-2]->SSE = SSE_Strand;
+ }
+ } else if (hbonds[j][l]==-irdif-3) {
+ // and bulge in parallel strand
+ if (flagBulge) {
+ if (Res[i ]->SSE==SSE_None) Res[i ]->SSE = SSE_Bulge;
+ if (Res[j-1]->SSE==SSE_None) Res[j-1]->SSE = SSE_Bulge;
+ if (Res[j-2]->SSE==SSE_None) Res[j-2]->SSE = SSE_Bulge;
+ }
+ else {
+ if (Res[i ]->SSE==SSE_None) Res[i ]->SSE = SSE_Strand;
+ if (Res[j-1]->SSE==SSE_None) Res[j-1]->SSE = SSE_Strand;
+ if (Res[j-2]->SSE==SSE_None) Res[j-2]->SSE = SSE_Strand;
+ }
+ }
+ l++;
+ }
+ }
+ k++;
+
+ } // Finish looping over Hbonds for residue (k loop)
+
+ } // Finish looping over residues ( i loop)
+
+
+ // 8. Free memory
+
+ if (hbond_atoms) {
+ for (i=0;i<nres;i++)
+ if (hbond_atoms[i]) delete[] hbond_atoms[i];
+ delete[] hbond_atoms;
+ }
+ FreeMatrixMemory ( hbonds,nres,0,0 );
+ if (contact) delete[] contact;
+ if (Res && aminoSelHnd<0) delete[] Res;
+ if (Ca) delete[] Ca;
+
+ return SSERC_Ok;
+
+ }
+
+
+ // ------- streaming
+
+ void Model::write ( io::RFile f ) {
+ int i,k;
+ byte Version=3;
+
+ f.WriteByte ( &Version );
+
+ ProModel::write ( f );
+
+ f.WriteInt ( &serNum );
+ f.WriteInt ( &nChains );
+
+ for (i=0;i<nChains;i++) {
+ if (chain[i]) k = 1;
+ else k = 0;
+ f.WriteInt ( &k );
+ if (chain[i]) chain[i]->write ( f );
+ }
+
+ hetCompounds.write ( f );
+ helices .write ( f );
+ sheets .write ( f );
+ turns .write ( f );
+ links .write ( f );
+ linkRs .write ( f );
+
+ }
+
+ void Model::read ( io::RFile f ) {
+ int i,k;
+ byte Version;
+
+ FreeMemory();
+
+ f.ReadByte ( &Version );
+
+ ProModel::read ( f );
+
+ f.ReadInt ( &serNum );
+ f.ReadInt ( &nChains );
+ nChainsAlloc = nChains;
+ if (nChains>0) {
+ chain = new PChain[nChainsAlloc];
+ for (i=0;i<nChains;i++) {
+ f.ReadInt ( &k );
+ if (k) {
+ chain[i] = newChain();
+ chain[i]->SetModel ( this );
+ chain[i]->read ( f );
+ }
+ }
+ }
+
+ hetCompounds.read ( f );
+ helices .read ( f );
+ sheets .read ( f );
+ turns .read ( f );
+ if (Version>1) links .read ( f );
+ if (Version>2) linkRs.read ( f );
+
+ }
+
+ MakeFactoryFunctions(Model)
+
+} // namespace mmdb
diff --git a/mmdb2/mmdb_model.h b/mmdb2/mmdb_model.h
new file mode 100644
index 0000000..3e184a9
--- /dev/null
+++ b/mmdb2/mmdb_model.h
@@ -0,0 +1,1073 @@
+// $Id: mmdb_model.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_Model <interface>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::HetCompound ( description of het compounds )
+// ~~~~~~~~~ mmdb::HetCompounds (HETNAM, HETSYN, FORMULA records)
+// mmdb::SSContainer (container for helixes and turns)
+// mmdb::Helix ( helix info )
+// mmdb::Strand ( strand info )
+// mmdb::Sheet ( sheet info )
+// mmdb::Sheets ( container for sheets )
+// mmdb::Turn ( turn info )
+// mmdb::LinkContainer ( container for link data )
+// mmdb::Link ( link data )
+// mmdb::LinkRContainer ( container for refmac link )
+// mmdb::LinkR ( link data )
+// mmdb::CisPepContainer ( container for CisPep data )
+// mmdb::CisPep ( CisPep data )
+// mmdb::Model ( PDB model )
+//
+// Copyright (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_Model__
+#define __MMDB_Model__
+
+#include "mmdb_io_stream.h"
+#include "mmdb_utils.h"
+#include "mmdb_chain.h"
+#include "mmdb_defs.h"
+
+namespace mmdb {
+
+ // ==================== HetCompound =======================
+
+ DefineClass(HetCompound);
+ DefineStreamFunctions(HetCompound);
+
+ class HetCompound : public io::Stream {
+
+ public :
+
+ ResName hetID; // Het identifiers, right-justified
+ pstr comment;
+ int nSynonyms;
+ psvector hetSynonym; // synonyms
+ int compNum; // component number
+ char wc; // '*' for water, otherwise space
+ pstr Formula; // formulas
+
+ HetCompound ( cpstr HetName );
+ HetCompound ( io::RPStream Object );
+ ~HetCompound();
+
+ void AddKeyWord ( cpstr W, bool Closed );
+ void HETNAM_PDBDump ( io::RFile f );
+ void HETSYN_PDBDump ( io::RFile f );
+ void FORMUL_PDBDump ( io::RFile f );
+
+ void FormComString ( pstr & F );
+ void FormSynString ( pstr & F );
+ void FormForString ( pstr & F );
+
+ void Copy ( PHetCompound hetCompound );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitHetCompound ( cpstr HetName );
+ void FreeMemory ();
+
+ };
+
+
+ // ==================== SSContainer ======================
+
+ DefineClass(SSContainer);
+ DefineStreamFunctions(SSContainer);
+
+ class SSContainer : public ClassContainer {
+
+ public :
+
+ SSContainer () : ClassContainer() {}
+ SSContainer ( io::RPStream Object )
+ : ClassContainer ( Object ) {}
+ ~SSContainer () {}
+
+ PContainerClass MakeContainerClass ( int ClassID );
+
+ };
+
+
+ // ==================== Helix ============================
+
+ DefineClass(Helix);
+ DefineStreamFunctions(Helix);
+
+ class Helix : public ContainerClass {
+
+ public :
+ int serNum; // serial number
+ HelixID helixID; // helix ID
+ ResName initResName; // name of the helix's initial residue
+ ChainID initChainID; // chain ID for the chain containing the helix
+ int initSeqNum; // sequence number of the initial residue
+ InsCode initICode; // insertion code of the initial residue
+ ResName endResName; // name of the helix's terminal residue
+ ChainID endChainID; // chain ID for the chain containing the helix
+ int endSeqNum; // sequence number of the terminal residue
+ InsCode endICode; // insertion code of the terminal residue
+ int helixClass; // helix class
+ pstr comment; // comment about the helix
+ int length; // length of the helix
+
+ Helix ();
+ Helix ( cpstr S );
+ Helix ( io::RPStream Object );
+ ~Helix();
+
+ void PDBASCIIDump ( pstr S, int N );
+ void MakeCIF ( mmcif::PData CIF, int N );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ ERROR_CODE GetCIF ( mmcif::PData CIF, int & n );
+ CLASS_ID GetClassID () { return ClassID_Helix; }
+
+ void Copy ( PContainerClass Helix );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitHelix();
+
+ };
+
+
+
+ // ==================== Strand ============================
+
+ DefineClass(Strand);
+ DefineStreamFunctions(Strand);
+
+ class Strand : public io::Stream {
+
+ public :
+
+ StrandID sheetID; // sheet ID
+ int strandNo; // strand number
+ ResName initResName; // name of the strand's initial residue
+ ChainID initChainID; // chain ID of initial residue in the strand
+ int initSeqNum; // sequence number of the initial residue
+ InsCode initICode; // insertion code of the initial residue
+ ResName endResName; // name of the strand's terminal residue
+ ChainID endChainID; // chain ID of terminal residue in the strand
+ int endSeqNum; // sequence number of the terminal residue
+ InsCode endICode; // insertion code of the terminal residue
+ int sense; // sense of strand with respect to previous
+ // strand
+ AtomName curAtom; // registration; atom name in current strand
+ ResName curResName; // registration; residue name in current
+ // strand
+ ChainID curChainID; // registration; chain ID in current strand
+ int curResSeq; // registration; res-e seq numb in current
+ // strand
+ InsCode curICode; // registration; ins code in current strand
+ AtomName prevAtom; // registration; atom name in previous strand
+ ResName prevResName; // registration; residue name in previous
+ // strand
+ ChainID prevChainID; // registration; chain ID in previous strand
+ int prevResSeq; // registration; res-e seq numb in previous
+ // strand
+ InsCode prevICode; // registration; ins code in previous strand
+
+ Strand ();
+ Strand ( io::RPStream Object );
+ ~Strand();
+
+ void PDBASCIIDump ( pstr S );
+ void MakeCIF ( mmcif::PData CIF );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ int GetCIF ( mmcif::PData CIF, cpstr sheet_id );
+
+ void Copy ( PStrand Strand );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitStrand();
+
+ };
+
+
+ // ==================== Sheet ============================
+
+ DefineClass(Sheet);
+ DefineStreamFunctions(Sheet);
+
+ class Sheet : public io::Stream {
+
+ public :
+ SheetID sheetID; // sheet ID
+ int nStrands; // number of strands in the sheet
+ PPStrand strand; // array of strands
+
+ Sheet ();
+ Sheet ( io::RPStream Object );
+ ~Sheet();
+
+ void FreeMemory();
+ void OrderSheet();
+
+ void PDBASCIIDump ( io::RFile f );
+ void MakeCIF ( mmcif::PData CIF );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ int GetCIF ( mmcif::PData CIF );
+
+ void Copy ( PSheet sheet );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+ void InitSheet ();
+ void CIFFindStrands ( mmcif::PData CIF, cpstr Category );
+ void TryStrand ( int strand_no );
+ int GetStrand ( int strand_no );
+
+ };
+
+
+ // ==================== Sheets ============================
+
+ DefineClass(Sheets);
+ DefineStreamFunctions(Sheets);
+
+ class Sheets : public io::Stream {
+
+ public :
+ int nSheets;
+ PPSheet sheet;
+
+ Sheets ();
+ Sheets ( io::RPStream Object );
+ ~Sheets();
+
+ void FreeMemory();
+
+ void PDBASCIIDump ( io::RFile f );
+ void MakeCIF ( mmcif::PData CIF );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ int GetCIF ( mmcif::PData CIF );
+
+ void Copy ( PSheets Sheets );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+ void InitSheets ();
+ void CIFFindSheets ( mmcif::PData CIF, cpstr Category );
+
+ };
+
+
+ // ==================== Turn ============================
+
+ DefineClass(Turn);
+ DefineStreamFunctions(Turn);
+
+ class Turn : public ContainerClass {
+
+ public :
+ int serNum; // serial number
+ TurnID turnID; // turn ID
+ ResName initResName; // name of the turn's initial residue
+ ChainID initChainID; // chain ID for the chain containing the turn
+ int initSeqNum; // sequence number of the initial residue
+ InsCode initICode; // insertion code of the initial residue
+ ResName endResName; // name of the turn's terminal residue
+ ChainID endChainID; // chain ID for the chain containing the turn
+ int endSeqNum; // sequence number of the terminal residue
+ InsCode endICode; // insertion code of the terminal residue
+ pstr comment; // comment about the helix
+
+ Turn ();
+ Turn ( cpstr S );
+ Turn ( io::RPStream Object );
+ ~Turn();
+
+ void PDBASCIIDump ( pstr S, int N );
+ void MakeCIF ( mmcif::PData CIF, int N );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ ERROR_CODE GetCIF ( mmcif::PData CIF, int & n );
+ CLASS_ID GetClassID () { return ClassID_Turn; }
+
+ void Copy ( PContainerClass turn );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitTurn();
+
+ };
+
+
+
+ // ==================== HetCompounds =======================
+
+ DefineClass(HetCompounds);
+ DefineStreamFunctions(HetCompounds);
+
+ class HetCompounds : public io::Stream {
+
+ public :
+
+ int nHets;
+ PPHetCompound hetCompound;
+
+ HetCompounds ();
+ HetCompounds ( io::RPStream Object );
+ ~HetCompounds();
+
+ void FreeMemory ();
+
+ void PDBASCIIDump ( io::RFile f );
+ void ConvertHETNAM ( cpstr S );
+ void ConvertHETSYN ( cpstr S );
+ void ConvertFORMUL ( cpstr S );
+
+ void MakeCIF ( mmcif::PData CIF );
+ ERROR_CODE GetCIF ( mmcif::PData CIF );
+
+ void Copy ( PHetCompounds hetCompounds );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+ bool Closed;
+
+ void InitHetCompounds();
+ int AddHetName ( cpstr H );
+
+ };
+
+
+ // =================== LinkContainer =====================
+
+ DefineClass(LinkContainer);
+ DefineStreamFunctions(LinkContainer);
+
+ class LinkContainer : public ClassContainer {
+
+ public :
+
+ LinkContainer () : ClassContainer() {}
+ LinkContainer ( io::RPStream Object )
+ : ClassContainer ( Object ) {}
+ ~LinkContainer () {}
+
+ PContainerClass MakeContainerClass ( int ClassID );
+
+ };
+
+
+ // ==================== Link ============================
+
+ DefineClass(Link);
+ DefineStreamFunctions(Link);
+
+ class Link : public ContainerClass {
+
+ public :
+ AtomName atName1; // name of 1st linked atom
+ AltLoc aloc1; // alternative location of 1st linked atom
+ ResName resName1; // residue name of 1st linked atom
+ ChainID chainID1; // chain ID of 1st linked atom
+ int seqNum1; // sequence number of 1st linked atom
+ InsCode insCode1; // insertion code of 1st linked atom
+ AtomName atName2; // name of 2nd linked atom
+ AltLoc aloc2; // alternative location of 2nd linked atom
+ ResName resName2; // residue name of 2nd linked atom
+ ChainID chainID2; // chain ID of 2nd linked atom
+ int seqNum2; // sequence number of 2nd linked atom
+ InsCode insCode2; // insertion code of 2nd linked atom
+ int s1,i1,j1,k1; // sym id of 1st atom
+ int s2,i2,j2,k2; // sym id of 2nd atom
+
+ Link ();
+ Link ( cpstr S );
+ Link ( io::RPStream Object );
+ ~Link();
+
+ void PDBASCIIDump ( pstr S, int N );
+ void MakeCIF ( mmcif::PData CIF, int N );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ ERROR_CODE GetCIF ( mmcif::PData CIF, int & n );
+ CLASS_ID GetClassID () { return ClassID_Link; }
+
+ void Copy ( PContainerClass link );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitLink();
+
+ };
+
+ // =================== LinkRContainer ====================
+
+ DefineClass(LinkRContainer);
+ DefineStreamFunctions(LinkRContainer);
+
+ class LinkRContainer : public ClassContainer {
+
+ public :
+
+ LinkRContainer () : ClassContainer() {}
+ LinkRContainer ( io::RPStream Object )
+ : ClassContainer ( Object ) {}
+ ~LinkRContainer () {}
+
+ PContainerClass MakeContainerClass ( int ClassID );
+
+ };
+
+
+ // ==================== LinkR ============================
+
+ DefineClass(LinkR);
+ DefineStreamFunctions(LinkR);
+
+ /*
+
+ Garib's
+ LINK LYS A 27 PLP A 255 PLPLYS
+ LINK MAN S 3 MAN S 4 BETA1-4
+ LINK C6 BBEN B 1 O1 BMAF S 2 BEN-MAF
+ LINK OE2 AGLU A 320 C1 AMAF S 2 GLU-MAF
+ LINK OE2 GLU A 67 1.895 ZN ZN R 5 GLU-ZN
+ LINK NE2 HIS A 71 2.055 ZN ZN R 5 HIS-ZN
+ LINK O ARG A 69 2.240 NA NA R 9 ARG-NA
+
+ Coot's
+ LINKR O VAL C 103 NA NA C 401 VAL-NA
+ LINKR OD1 ASP D 58 NA NA D 401 ASP-NA
+ LINKR O ALA D 97 NA NA D 401 ALA-NA
+ LINKR OG1 THR D 99 NA NA D 401 THR-NA
+ LINKR O SER D 101 NA NA D 401 SER-NA
+ LINKR O VAL D 103 NA NA D 401 VAL-NA
+
+ PDB's
+ LINK O GLY A 49 NA NA A6001 1555 1555 2.98
+ LINK OG1 THR A 51 NA NA A6001 1555 1555 2.72
+ LINK OD2 ASP A 66 NA NA A6001 1555 1555 2.72
+ LINK NE ARG A 68 NA NA A6001 1555 1555 2.93
+
+ LINK NE ARG A 68 NA NA A6001 1555 1555 2.93
+ LINK C21 2EG A 7 C22 2EG B 19 1555 1555 1.56
+ */
+
+ class LinkR : public ContainerClass {
+
+ public :
+ LinkRID linkRID; // link name
+ AtomName atName1; // name of 1st linked atom
+ AltLoc aloc1; // alternative location of 1st linked atom
+ ResName resName1; // residue name of 1st linked atom
+ ChainID chainID1; // chain ID of 1st linked atom
+ int seqNum1; // sequence number of 1st linked atom
+ InsCode insCode1; // insertion code of 1st linked atom
+ AtomName atName2; // name of 2nd linked atom
+ AltLoc aloc2; // alternative location of 2nd linked atom
+ ResName resName2; // residue name of 2nd linked atom
+ ChainID chainID2; // chain ID of 2nd linked atom
+ int seqNum2; // sequence number of 2nd linked atom
+ InsCode insCode2; // insertion code of 2nd linked atom
+ realtype dist; // link distance
+
+ LinkR ();
+ LinkR ( cpstr S );
+ LinkR ( io::RPStream Object );
+ ~LinkR();
+
+ void PDBASCIIDump ( pstr S, int N );
+ void MakeCIF ( mmcif::PData CIF, int N );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ ERROR_CODE GetCIF ( mmcif::PData CIF, int & n );
+ CLASS_ID GetClassID () { return ClassID_LinkR; }
+
+ void Copy ( PContainerClass LinkR );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitLinkR();
+
+ };
+
+
+
+ // =================== CisPepContainer =====================
+
+ DefineClass(CisPepContainer);
+ DefineStreamFunctions(CisPepContainer);
+
+ class CisPepContainer : public ClassContainer {
+
+ public :
+
+ CisPepContainer () : ClassContainer() {}
+ CisPepContainer ( io::RPStream Object )
+ : ClassContainer ( Object ) {}
+ ~CisPepContainer () {}
+
+ PContainerClass MakeContainerClass ( int ClassID );
+
+ };
+
+
+ // ===================== CisPep ===========================
+
+ DefineClass(CisPep);
+ DefineStreamFunctions(CisPep);
+
+ class CisPep : public ContainerClass {
+
+ public :
+ int serNum; // record serial number
+ ResName pep1; // residue name
+ ChainID chainID1; // chain identifier 1
+ int seqNum1; // residue sequence number 1
+ InsCode icode1; // insertion code 1
+ ResName pep2; // residue name 2
+ ChainID chainID2; // chain identifier 2
+ int seqNum2; // residue sequence number 2
+ InsCode icode2; // insertion code 2
+ int modNum; // model number
+ realtype measure; // measure of the angle in degrees.
+
+ CisPep ();
+ CisPep ( cpstr S );
+ CisPep ( io::RPStream Object );
+ ~CisPep();
+
+ void PDBASCIIDump ( pstr S, int N );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ CLASS_ID GetClassID () { return ClassID_CisPep; }
+
+ void Copy ( PContainerClass cisPep );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitCisPep();
+
+ };
+
+
+
+ // ==================== Model ===============================
+
+ enum SSE_RC {
+ SSERC_Ok = 0,
+ SSERC_noResidues = 1,
+ SSERC_noAminoacids = 2,
+ SSERC_noSSE = 3
+ };
+
+ enum SORT_CHAIN_DIR {
+ SORT_CHAIN_ChainID_Asc = 0,
+ SORT_CHAIN_ChainID_Desc = 1
+ };
+
+ DefineFactoryFunctions(Model);
+
+ class Model : public ProModel {
+
+ friend class Manager;
+ friend class BondManager;
+ friend class SelManager;
+ friend class CoorManager;
+ friend class Root;
+ friend class Chain;
+ friend class Residue;
+ friend class Atom;
+
+ public :
+
+ Model (); // SetMMDBFile() MUST be used after this constructor!
+ Model ( PManager MMDBF, int serialNum );
+ Model ( io::RPStream Object );
+ ~Model();
+
+ void SetMMDBManager ( PManager MMDBM, int serialNum );
+ PManager GetCoordHierarchy() { return manager; }
+
+ // GetChainCreate() returns pointer on chain, whose identifier
+ // is given in chID. If such a chain is absent in the model,
+ // it is created. If enforceUniqueChainID is true and chain with
+ // the same first letter in chain ID already exists in the model,
+ // then the new chain ID will be appended with a serial number
+ // in order to keep it unique. The model will contain chains like
+ // A, A0, A1, A2, ... in such cases.
+ PChain GetChainCreate ( const ChainID chID,
+ bool enforceUniqueChainID );
+
+ // CreateChain() creates a new chain with chain ID regardless
+ // the presence of same-ID chains in the model. This function
+ // was introduced only for compatibility with older CCP4
+ // applications and using it in any new developments should be
+ // strictly discouraged.
+ PChain CreateChain ( const ChainID chID );
+
+ cpstr GetEntryID ();
+ void SetEntryID ( const IDCode idCode );
+
+ int GetSerNum (); // returns the model's serial number
+
+ cpstr GetModelID ( pstr modelID ); // returns "/mdl"
+
+ int GetNumberOfModels (); // returns TOTAL number of models
+ int GetNumberOfAtoms ( bool countTers ); // returns number
+ // of atoms in the model
+ int GetNumberOfResidues(); // returns number of residues in
+ // the model
+
+
+ // ---------------- Extracting chains --------------------------
+
+ int GetNumberOfChains(); // returns number of chains in the model
+ bool GetNewChainID ( ChainID chID, int length=1 );
+ // GetChain() returns pointer on chain, whose identifier
+ // is given in chID. If such a chain is absent in the model,
+ // returns NULL.
+ PChain GetChain ( const ChainID chID );
+ PChain GetChain ( int chainNo ); // returns chainNo-th chain
+ // in the model;
+ // 0<=chainNo<nChains
+ void GetChainTable ( PPChain & chainTable,
+ int & NumberOfChains );
+
+ // ------------------ Deleting chains --------------------------
+
+ int DeleteChain ( const ChainID chID );
+ int DeleteChain ( int chainNo );
+ int DeleteAllChains ();
+ int DeleteSolventChains();
+ void TrimChainTable ();
+
+ // ------------------- Adding chains ---------------------------
+
+ int AddChain ( PChain chn );
+
+ // -------------------- Sort chains ----------------------------
+
+ void SortChains ( int sortKey ); // SORT_CHAIN_XXXX
+
+ // ---------------- Extracting residues ------------------------
+
+ int GetNumberOfResidues ( const ChainID chainID );
+ int GetNumberOfResidues ( int chainNo );
+ PResidue GetResidue ( const ChainID chainID, int seqNo,
+ const InsCode insCode );
+ PResidue GetResidue ( const ChainID chainID, int resNo );
+ PResidue GetResidue ( int chainNo, int seqNo,
+ const InsCode insCode );
+ PResidue GetResidue ( int chainNo, int resNo );
+ int GetResidueNo ( const ChainID chainID, int seqNo,
+ const InsCode insCode );
+ int GetResidueNo ( int chainNo, int seqNo,
+ const InsCode insCode );
+ void GetResidueTable ( PPResidue & resTable,
+ int & NumberOfResidues );
+ void GetResidueTable ( const ChainID chainID,
+ PPResidue & resTable,
+ int & NumberOfResidues );
+ void GetResidueTable ( int chainNo, PPResidue & resTable,
+ int & NumberOfResidues );
+
+ // ----------------- Deleting residues -------------------------
+
+ int DeleteResidue ( const ChainID chainID, int seqNo,
+ const InsCode insCode );
+ int DeleteResidue ( const ChainID chainID, int resNo );
+ int DeleteResidue ( int chainNo, int seqNo,
+ const InsCode insCode );
+ int DeleteResidue ( int chainNo, int resNo );
+ int DeleteAllResidues ( const ChainID chainID );
+ int DeleteAllResidues ( int chainNo );
+ int DeleteSolvent (); // in difference of DeleteSolventChains,
+ // this will remove all solvent molecules
+ // from the file rather then
+ // solely-solvent chains
+ int DeleteAllResidues ();
+
+ // ------------------ Adding residues --------------------------
+
+ int AddResidue ( const ChainID chainID, PResidue res );
+ int AddResidue ( int chainNo, PResidue res );
+
+ // ------------------- Extracting atoms ------------------------
+
+ int GetNumberOfAllAtoms(); // returns TOTAL number of atoms in all
+ // models
+ PPAtom GetAllAtoms (); // returns pointer to Atom array
+
+ int GetNumberOfAtoms ( const ChainID chainID, int seqNo,
+ const InsCode insCode );
+ int GetNumberOfAtoms ( int chainNo, int seqNo,
+ const InsCode insCode );
+ int GetNumberOfAtoms ( const ChainID chainID, int resNo );
+ int GetNumberOfAtoms ( int chainNo, int resNo );
+
+ PAtom GetAtom ( const ChainID chID,
+ int seqNo,
+ const InsCode insCode,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc );
+ PAtom GetAtom ( const ChainID chID, int seqNo,
+ const InsCode insCode, int atomNo );
+ PAtom GetAtom ( const ChainID chID,
+ int resNo,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc );
+ PAtom GetAtom ( const ChainID chID, int resNo, int atomNo );
+ PAtom GetAtom ( int chNo, int seqNo,
+ const InsCode insCode,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc );
+ PAtom GetAtom ( int chNo, int seqNo, const InsCode insCode,
+ int atomNo );
+ PAtom GetAtom ( int chNo, int resNo,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc );
+ PAtom GetAtom ( int chNo, int resNo, int atomNo );
+
+ void GetAtomTable ( const ChainID chainID, int seqNo,
+ const InsCode insCode,
+ PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable ( int chainNo, int seqNo,
+ const InsCode insCode,
+ PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable ( const ChainID chainID, int resNo,
+ PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable ( int chainNo, int resNo,
+ PPAtom & atomTable, int & NumberOfAtoms );
+
+ // GetAtomTable1(..) returns atom table without TER atoms and
+ // without NULL atom pointers. NumberOfAtoms returns the actual
+ // number of atom pointers in atomTable.
+ // atomTable is allocated withing the function. If it was
+ // not set to NULL before calling the function, the latter will
+ // attempt to deallocate it first.
+ // The application is responsible for deleting atomTable,
+ // however it must not touch atom pointers, i.e. use simply
+ // "delete atomTable;". Never pass atomTable from GetAtomTable(..)
+ // into this function, unless you set it to NULL before doing that.
+ void GetAtomTable1 ( const ChainID chainID, int seqNo,
+ const InsCode insCode,
+ PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable1 ( int chainNo, int seqNo,
+ const InsCode insCode,
+ PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable1 ( const ChainID chainID, int resNo,
+ PPAtom & atomTable, int & NumberOfAtoms );
+ void GetAtomTable1 ( int chainNo, int resNo,
+ PPAtom & atomTable, int & NumberOfAtoms );
+
+ void GetAtomStatistics ( RAtomStat AS );
+ void CalAtomStatistics ( RAtomStat AS );
+
+
+ // -------------------- Deleting atoms -------------------------
+
+ int DeleteAtom ( const ChainID chID,
+ int seqNo,
+ const InsCode insCode,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc );
+ int DeleteAtom ( const ChainID chID, int seqNo,
+ const InsCode insCode, int atomNo );
+ int DeleteAtom ( const ChainID chID,
+ int resNo,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc );
+ int DeleteAtom ( const ChainID chID, int resNo, int atomNo );
+ int DeleteAtom ( int chNo, int seqNo,
+ const InsCode insCode,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc );
+ int DeleteAtom ( int chNo, int seqNo, const InsCode insCode,
+ int atomNo );
+ int DeleteAtom ( int chNo, int resNo,
+ const AtomName aname,
+ const Element elmnt,
+ const AltLoc aloc );
+ int DeleteAtom ( int chNo, int resNo, int atomNo );
+
+ int DeleteAllAtoms ( const ChainID chID, int seqNo,
+ const InsCode insCode );
+ int DeleteAllAtoms ( const ChainID chID, int resNo );
+ int DeleteAllAtoms ( const ChainID chID );
+ int DeleteAllAtoms ( int chNo, int seqNo, const InsCode insCode );
+ int DeleteAllAtoms ( int chNo, int resNo );
+ int DeleteAllAtoms ( int chNo );
+ int DeleteAllAtoms ();
+
+ // DeleteAltLocs() leaves only alternative location with maximal
+ // occupancy, if those are equal or unspecified, the one with
+ // "least" alternative location indicator.
+ // The function returns the number of deleted. All tables remain
+ // untrimmed, so that explicit trimming or calling
+ // FinishStructEdit() is required.
+ int DeleteAltLocs();
+
+
+ // --------------------- Adding atoms --------------------------
+
+ int AddAtom ( const ChainID chID, int seqNo,
+ const InsCode insCode, PAtom atom );
+ int AddAtom ( const ChainID chID, int resNo, PAtom atom );
+ int AddAtom ( int chNo, int seqNo, const InsCode insCode,
+ PAtom atom );
+ int AddAtom ( int chNo, int resNo, PAtom atom );
+
+
+ // ---------------------------------------------------------------
+
+ // ConvertPDBString(..) interprets PDB records DBREF, SEQADV,
+ // SEQRES, MODRES.
+ // Returns zero if the line was converted, otherwise returns a
+ // non-negative value of Error_XXXX.
+ // PDBString must be not shorter than 81 characters.
+ ERROR_CODE ConvertPDBString ( pstr PDBString );
+
+ // PDBASCIIDumpPS(..) makes output of PDB primary structure records
+ // excluding cispeps
+ void PDBASCIIDumpPS ( io::RFile f );
+
+ // PDBASCIIDumpCP(..) makes output of cispep records
+ void PDBASCIIDumpCP ( io::RFile f );
+
+ // PDBASCIIDump(..) makes output of PDB coordinate (ATOM etc.)
+ // records
+ void PDBASCIIDump ( io::RFile f );
+
+ void MakeAtomCIF ( mmcif::PData CIF );
+ void MakePSCIF ( mmcif::PData CIF );
+ ERROR_CODE GetCIF ( mmcif::PData CIF );
+
+ // MoveChain(..) adds chain m_chain on the top Chain array.
+ // The pointer on chain is then set to NULL (m_chain=NULL).
+ // If chain_ext is greater than 0, the moved chain will be
+ // forcefully renamed; the new name is composed as the previous
+ // one + underscore + chain_ext (e.g. A_1). If thus generated
+ // name duplicates any of existing chain IDs, or if chain_ext
+ // was set to 0 and there is a duplication of chain IDs, the
+ // name is again modified as above, with the extension number
+ // generated automatically (this may result in IDs like
+ // A_1_10).
+ // m_atom must give pointer to the Atom array, from which
+ // the atoms belonging to m_chain, are moved to Atom array
+ // given by 'atom', starting from poisition 'atom_index'.
+ // 'atom_index' is then automatically updated to the next
+ // free position in 'atom'.
+ // Note1: the moved atoms will occupy a continuous range
+ // in 'atom' array; no checks on whether the corresponding
+ // cells are occupied or not, are performed.
+ // Note2: the 'atom_index' is numbered from 0 on, i.e.
+ // it is equal to atom[atom_index]->index-1; atom[]->index
+ // is assigned automatically.
+ void MoveChain ( PChain & m_chain, PPAtom m_atom,
+ PPAtom atom, int & atom_index,
+ int chain_ext );
+
+ void GetAIndexRange ( int & i1, int & i2 );
+
+ void MaskAtoms ( PMask mask );
+ void MaskResidues ( PMask mask );
+ void MaskChains ( PMask mask );
+ void UnmaskAtoms ( PMask mask );
+ void UnmaskResidues ( PMask mask );
+ void UnmaskChains ( PMask mask );
+
+
+ // ---- Getting Secondary Structure Elements
+
+ int GetNumberOfHelices ();
+ int GetNumberOfSheets ();
+
+ PHelix GetHelix ( int serialNum ); // 1<=serNum<=NofHelices
+
+ void GetSheetID ( int serialNum, SheetID sheetID );
+ // '\0' for none
+
+ PSheet GetSheet ( int serialNum ); //1<=serNum<=NofSheets
+ PSheet GetSheet ( const SheetID sheetID ); // NULL for none
+ int GetNumberOfStrands ( int sheetSerNum );
+ int GetNumberOfStrands ( const SheetID sheetID );
+ PStrand GetStrand ( int sheetSerNum,
+ int strandSerNum );
+ PStrand GetStrand ( const SheetID sheetID,
+ int strandSerNum );
+
+ inline PSSContainer GetHelices() { return &helices; }
+ inline PSheets GetSheets () { return &sheets; }
+
+ void RemoveSecStructure();
+ int CalcSecStructure ( bool flagBulge=true,
+ int aminoSelHnd=-1 );
+ // int CalcSecStructure ( bool flagBulge=true );
+
+ PHetCompounds GetHetInfo() { return &hetCompounds; }
+ void RemoveHetInfo ();
+
+
+ // ---- Working Links
+
+ int GetNumberOfLinks ();
+ PLink GetLink ( int serialNum ); // 1<=serNum<=NofLinks
+ PLinkContainer GetLinks() { return &links; }
+
+ void RemoveLinks();
+ void AddLink ( PLink link );
+
+ // ---- Working Refmac Links
+
+ int GetNumberOfLinkRs ();
+ PLinkR GetLinkR ( int serialNum ); // 1<=serNum<=NofLinks
+ PLinkRContainer GetLinkRs() { return &linkRs; }
+
+ void RemoveLinkRs();
+ void AddLinkR ( PLinkR linkR );
+
+
+ // ---- Working CisPeps
+
+ int GetNumberOfCisPeps();
+ PCisPep GetCisPep ( int CisPepNum );
+ PCisPepContainer GetCisPeps() { return &cisPeps; }
+
+ void RemoveCisPeps();
+ void AddCisPep ( PCisPep cisPep );
+
+
+
+ void ApplyTransform ( mat44 & TMatrix ); // transforms all
+ // coordinates by multiplying
+ // with matrix TMatrix
+
+ bool isInSelection ( int selHnd );
+
+
+ // ------- user-defined data handlers
+ int PutUDData ( int UDDhandle, int iudd );
+ int PutUDData ( int UDDhandle, realtype rudd );
+ int PutUDData ( int UDDhandle, cpstr sudd );
+
+ int GetUDData ( int UDDhandle, int & iudd );
+ int GetUDData ( int UDDhandle, realtype & rudd );
+ int GetUDData ( int UDDhandle, pstr sudd, int maxLen );
+ int GetUDData ( int UDDhandle, pstr & sudd );
+
+
+ void Copy ( PModel model );
+ void CopyHets ( PModel model );
+ void CopySecStructure ( PModel model );
+ void CopyLinks ( PModel model );
+ void CopyLinkRs ( PModel model );
+ void CopyCisPeps ( PModel model );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ int serNum; // the model serial number
+ PManager manager; // pointer to mmdbmanager class
+
+ HetCompounds hetCompounds; // information on heterocompounds
+ SSContainer helices; // information on helices
+ Sheets sheets; // information on sheets
+ SSContainer turns; // information on turns
+ LinkContainer links; // information on links
+ LinkRContainer linkRs; // information on refmac links
+ CisPepContainer cisPeps; // information on cispeps
+
+ int nChains; // number of chains
+ int nChainsAlloc; // actual length of Chain[]
+ PPChain chain; // array of chains
+
+ bool Exclude; // used internally
+
+ void InitModel ();
+ void FreeMemory ();
+ void ExpandChainArray ( int nOfChains );
+ ERROR_CODE GetCIFPSClass ( mmcif::PData CIF, int ClassID );
+
+ // _ExcludeChain(..) excludes (but does not dispose!) a chain
+ // from the model. Returns 1 if the chain gets empty and 0
+ // otherwise.
+ int _ExcludeChain ( const ChainID chainID );
+
+ // _copy(PModel) does not copy atoms! -- not for use in
+ // applications
+ void _copy ( PModel Model );
+
+ // _copy(PModel,PPAtom,int&) does copy atoms into array 'atom'
+ // starting from position atom_index. 'atom' should be able to
+ // accept all new atoms - no checks on the length of 'atom'
+ // is being made. This function should not be used in applications.
+ void _copy ( PModel Model, PPAtom atom, int & atom_index );
+
+ void CheckInAtoms ();
+
+ };
+
+} // namespace mmdb
+
+#endif
+
diff --git a/mmdb2/mmdb_root.cpp b/mmdb2/mmdb_root.cpp
new file mode 100644
index 0000000..3a98edb
--- /dev/null
+++ b/mmdb2/mmdb_root.cpp
@@ -0,0 +1,3054 @@
+// $Id: mmdb_root.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 14.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_Root <implementation>
+// ~~~~~~~~~
+// Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::Root
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include "string.h"
+#include "stdlib.h"
+
+#include "mmdb_root.h"
+#include "mmdb_atom.h"
+#include "mmdb_mmcif_.h"
+#include "mmdb_cifdefs.h"
+#include "mmdb_tables.h"
+#include "mmdb_defs.h"
+
+
+namespace mmdb {
+
+ // ===================== Root =======================
+
+ Root::Root() : UDData() {
+ InitMMDBRoot();
+ }
+
+ Root::Root ( io::RPStream Object ) : UDData(Object) {
+ InitMMDBRoot();
+ }
+
+ Root::~Root() {
+ FreeFileMemory();
+ }
+
+ void Root::InitMMDBRoot() {
+ nModels = 0;
+ model = NULL;
+ nAtoms = 0;
+ atmLen = 0;
+ atom = NULL;
+ CIF = NULL;
+ crModel = NULL;
+ crChain = NULL;
+ crRes = NULL;
+ lcount = 0;
+ strcpy ( S,"" );
+ // Flags = 0x00000000; // no special effects
+ Flags = MMDBF_IgnoreElement; // done at request for default
+ FType = MMDB_FILE_Undefined; // undefined file operation
+ Exclude = true;
+ ignoreRemarks = false; // used temporarily
+ allowDuplChID = false; // used temporarily
+ enforceUniqueChID = false; // used temporarily
+ modelCnt = 0; // used only at reading files
+ }
+
+
+ void Root::FreeCoordMemory() {
+ //int i;
+
+ /*
+ // All atoms are kept in array Atom. Models, chains
+ // and residues have only references to Atom and
+ // they do not dispose Atoms when disposed themselves.
+ // It is important, however, to dispose Atom at
+ // still alive residues, because each atom wipes out
+ // reference to itself from the corresponding residue
+ // before it dies.
+ if (Atom) {
+ for (i=0;i<atmLen;i++)
+ if (atom[i]) delete atom[i];
+ delete Atom;
+ }
+ Atom = NULL;
+ atmLen = 0;
+ nAtoms = 0;
+ */
+ DeleteAllModels();
+ if (model) delete[] model;
+ model = NULL;
+ nModels = 0;
+
+ crModel = NULL;
+ crChain = NULL;
+ crRes = NULL;
+
+ if (atom) delete[] atom;
+
+ atom = NULL;
+ atmLen = 0;
+ nAtoms = 0;
+
+ modelCnt = 0;
+
+ }
+
+ void Root::FreeFileMemory() {
+
+ FreeCoordMemory ();
+ title.FreeMemory ( false );
+ cryst.FreeMemory ();
+
+ SA .FreeContainer();
+ Footnote.FreeContainer();
+ SB .FreeContainer();
+ SC .FreeContainer();
+
+ if (CIF) delete CIF;
+ CIF = NULL;
+
+ lcount = 0;
+ S[0] = char(0);
+
+ }
+
+ // virtual to be served by MMDB manager classes
+ void Root::ResetManager() {
+ cryst.Reset();
+ }
+
+ void Root::SetFlag ( word Flag ) {
+ Flags |= Flag;
+ ignoreSegID = (Flags & MMDBF_IgnoreSegID ) != 0;
+ ignoreElement = (Flags & MMDBF_IgnoreElement ) != 0;
+ ignoreCharge = (Flags & MMDBF_IgnoreCharge ) != 0;
+ ignoreNonCoorPDBErrors = (Flags & MMDBF_IgnoreNonCoorPDBErrors ) != 0;
+ ignoreUnmatch = (Flags & MMDBF_IgnoreUnmatch ) != 0;
+ allowDuplChID = (Flags & MMDBF_AllowDuplChainID ) != 0;
+ enforceUniqueChID = (Flags & MMDBF_EnforceUniqueChainID ) != 0;
+ cryst.processSG = (Flags & MMDBF_DoNotProcessSpaceGroup ) == 0;
+ cryst.fixSpaceGroup = (Flags & MMDBF_FixSpaceGroup ) != 0;
+ }
+
+ void Root::RemoveFlag ( word Flag ) {
+ Flags &= ~Flag;
+ ignoreSegID = (Flags & MMDBF_IgnoreSegID ) != 0;
+ ignoreElement = (Flags & MMDBF_IgnoreElement ) != 0;
+ ignoreCharge = (Flags & MMDBF_IgnoreCharge ) != 0;
+ ignoreNonCoorPDBErrors = (Flags & MMDBF_IgnoreNonCoorPDBErrors ) != 0;
+ ignoreUnmatch = (Flags & MMDBF_IgnoreUnmatch ) != 0;
+ allowDuplChID = (Flags & MMDBF_AllowDuplChainID ) != 0;
+ enforceUniqueChID = (Flags & MMDBF_EnforceUniqueChainID ) != 0;
+ cryst.processSG = (Flags & MMDBF_DoNotProcessSpaceGroup ) == 0;
+ cryst.fixSpaceGroup = (Flags & MMDBF_FixSpaceGroup ) != 0;
+ }
+
+
+ ERROR_CODE Root::ReadPDBASCII1 ( cpstr PDBLFName, io::GZ_MODE gzipMode ) {
+ pstr FName;
+ FName = getenv ( PDBLFName );
+ if (FName) return ReadPDBASCII ( FName,gzipMode );
+ else return Error_NoLogicalName;
+ }
+
+ void Root::ReadPDBLine ( io::RFile f, pstr L, int maxlen ) {
+ int i;
+ bool Done;
+ do {
+ f.ReadLine ( L,maxlen );
+ Done = true;
+ if (ignoreRemarks) {
+ if (!strncasecmp(L,"REMARK",6)) Done = false;
+ }
+ if (Flags & MMDBF_IgnoreBlankLines) {
+ i = 0;
+ while (L[i] && (L[i]==' ')) i++;
+ if (!L[i]) Done = false;
+ }
+ if ((Flags & MMDBF_IgnoreHash) && (L[0]=='#'))
+ Done = false;
+ } while ((!f.FileEnd()) && (!Done));
+ PadSpaces ( L,80 );
+ }
+
+ ERROR_CODE Root::ReadPDBASCII ( cpstr PDBFileName, io::GZ_MODE gzipMode ) {
+ io::File f;
+ ERROR_CODE RC;
+
+ // open the file as ASCII for reading
+ // opening it in pseudo-binary mode helps reading various
+ // line terminators for files coming from different platforms
+ f.assign ( PDBFileName,false,false,gzipMode );
+
+ if (f.reset(true)) {
+
+ RC = ReadPDBASCII ( f );
+ f.shut();
+
+ } else {
+
+ RC = Error_CantOpenFile;
+ ResetManager ();
+ FreeFileMemory();
+ FType = MMDB_FILE_PDB;
+
+ }
+
+ return RC;
+
+ }
+
+
+ ERROR_CODE Root::ReadPDBASCII ( io::RFile f ) {
+ PContString contString;
+ word cleanKey;
+ int modNum;
+ bool fend;
+ ERROR_CODE RC;
+
+ // remove previous data
+ ResetManager ();
+ FreeFileMemory();
+
+ FType = MMDB_FILE_PDB;
+ SetFlag ( 0 );
+
+ if (f.FileEnd()) return Error_EmptyFile;
+
+ lcount = 1; // line counter
+
+ // read title section
+ RC = Error_NoError;
+ ReadPDBLine ( f,S,sizeof(S) );
+ if (Flags & MMDBF_EnforceSpaces) EnforceSpaces ( S );
+ do {
+ if (!strncmp(S,"FTNOTE",6)) {
+ contString = new ContString(S);
+ Footnote.AddData ( contString );
+ } else {
+ RC = title.ConvertPDBString(S);
+ if ((RC!=Error_WrongSection) && ignoreNonCoorPDBErrors)
+ RC = Error_NoError;
+ if (RC) break;
+ }
+ fend = f.FileEnd();
+ if (!fend) {
+ ReadPDBLine ( f,S,sizeof(S) );
+ lcount++;
+ }
+ } while (!fend);
+
+ title.GetResolution(); // only to fetch resolution from remarks
+
+ if (RC!=Error_WrongSection) return RC;
+
+ ignoreRemarks = (Flags & MMDBF_IgnoreRemarks)!=0;
+
+ // read primary structure section
+ SwitchModel ( 1 );
+ if (!crModel) return Error_GeneralError1;
+ do {
+ if (!strncmp(S,"FTNOTE",6)) {
+ contString = new ContString(S);
+ Footnote.AddData ( contString );
+ } else {
+ RC = crModel->ConvertPDBString ( S );
+ if ((RC!=Error_WrongSection) && ignoreNonCoorPDBErrors)
+ RC = Error_NoError;
+ if (RC) break;
+ }
+ fend = f.FileEnd();
+ if (!fend) {
+ ReadPDBLine ( f,S,sizeof(S) );
+ title.TrimInput ( S );
+ lcount++;
+ }
+ } while (!fend);
+
+ if (RC!=Error_WrongSection) return RC;
+
+ // temporary solution: the rest of file is stored
+ // in the form of strings
+ while (!f.FileEnd() &&
+ strncmp(S,"CRYST" ,5) &&
+ strncmp(S,"ORIGX" ,5) &&
+ strncmp(S,"SCALE" ,5) &&
+ strncmp(S,"MTRIX" ,5) &&
+ strncmp(S,"TVECT" ,5) &&
+ strncmp(S,"MODEL ",6) &&
+ strncmp(S,"ATOM ",6) &&
+ strncmp(S,"SIGATM",6) &&
+ strncmp(S,"ANISOU",6) &&
+ strncmp(S,"SIGUIJ",6) &&
+ strncmp(S,"TER ",6) &&
+ strncmp(S,"HETATM",6) &&
+ strncmp(S,"ENDMDL",6)) {
+ if (!strncmp(S,"LINK ",6))
+ crModel->ConvertPDBString ( S );
+ else if (!strncmp(S,"LINKR ",6))
+ crModel->ConvertPDBString ( S );
+ else if (!strncmp(S,"CISPEP",6)) {
+ GetInteger ( modNum,&(S[43]),3 );
+ if (modNum<=0) modNum = 1;
+ if (modNum!=1) SwitchModel ( modNum );
+ crModel->ConvertPDBString ( S );
+ if (modNum!=1) SwitchModel ( 1 );
+ } else {
+ contString = new ContString(S);
+ SA.AddData ( contString );
+ }
+ ReadPDBLine ( f,S,sizeof(S) );
+ title.TrimInput ( S );
+ lcount++;
+ }
+
+ // read crystallographic information section
+ do {
+ RC = cryst.ConvertPDBString ( S );
+ if ((RC!=Error_WrongSection) && ignoreNonCoorPDBErrors)
+ RC = Error_NoError;
+ if (RC) break;
+ fend = f.FileEnd();
+ if (!fend) {
+ ReadPDBLine ( f,S,sizeof(S) );
+ title.TrimInput ( S );
+ lcount++;
+ }
+ } while (!fend);
+
+ if (!RC) {
+ RC = cryst.ConvertPDBString ( S );
+ if ((RC!=Error_WrongSection) && ignoreNonCoorPDBErrors)
+ RC = Error_WrongSection;
+ }
+
+ cryst.CalcCoordTransforms();
+ if (Flags & MMDBF_SimRWBROOK)
+ cryst.RWBROOKReadPrintout();
+
+ if (RC!=Error_WrongSection) return RC;
+
+ // temporary solution: the rest of file is stored
+ // in the form of strings
+ while (!f.FileEnd() &&
+ strncmp(S,"MODEL ",6) &&
+ strncmp(S,"ATOM ",6) &&
+ strncmp(S,"SIGATM",6) &&
+ strncmp(S,"ANISOU",6) &&
+ strncmp(S,"SIGUIJ",6) &&
+ strncmp(S,"TER ",6) &&
+ strncmp(S,"HETATM",6) &&
+ strncmp(S,"ENDMDL",6)) {
+ contString = new ContString(S);
+ SB.AddData ( contString );
+ ReadPDBLine ( f,S,sizeof(S) );
+ title.TrimInput ( S );
+ lcount++;
+ }
+
+ if (Flags & MMDBF_NoCoordRead) return Error_NoError;
+
+ // read coordinate section
+ RC = Error_NoError;
+ do {
+ RC = ReadPDBAtom ( S );
+ if (RC) break;
+ fend = f.FileEnd();
+ if (!fend) {
+ ReadPDBLine ( f,S,sizeof(S) );
+ title.TrimInput ( S );
+ lcount++;
+ }
+ } while (!fend);
+ // if (!RC)
+ // RC = ReadPDBAtom(S);
+ // commented on 28.05.2004, it appears that "CHAIN_ORDER" should not
+ // be enforced here
+ // cleanKey = PDBCLEAN_ATNAME | PDBCLEAN_CHAIN_ORDER;
+ cleanKey = 0x00000000;
+ if (Flags & MMDBF_EnforceAtomNames)
+ cleanKey = PDBCLEAN_ATNAME;
+ if (Flags & MMDBF_AutoSerials)
+ cleanKey |= PDBCLEAN_SERIAL;
+
+ if (cleanKey)
+ PDBCleanup ( cleanKey );
+
+ if ((!f.FileEnd()) && (RC!=Error_WrongSection)) return RC;
+
+ // temporary solution: the rest of file is stored
+ // in the form of strings
+ while (!f.FileEnd()) {
+ if (strncmp(S,"END ",6)) { // END is added automatically
+ contString = new ContString(S);
+ SC.AddData ( contString );
+ }
+ ReadPDBLine ( f,S,sizeof(S) );
+ title.TrimInput ( S );
+ lcount++;
+ }
+ lcount--; // last line was not read
+
+ return Error_NoError;
+
+ }
+
+
+ ERROR_CODE Root::ReadCIFASCII1 ( cpstr CIFLFName, io::GZ_MODE gzipMode ) {
+ pstr FName;
+ FName = getenv ( CIFLFName );
+ if (FName) return ReadCIFASCII ( FName,gzipMode );
+ else return Error_NoLogicalName;
+ }
+
+ ERROR_CODE Root::ReadCIFASCII ( cpstr CIFFileName, io::GZ_MODE gzipMode ) {
+ io::File f;
+ ERROR_CODE rc;
+
+ // open the file as ASCII for reading
+ // opening it in pseudo-binary mode helps reading various
+ // line terminators for files coming from different platforms
+ f.assign ( CIFFileName,false,false,gzipMode );
+
+ if (f.reset(true)) {
+ rc = ReadCIFASCII ( f );
+ f.shut();
+ } else
+ rc = Error_CantOpenFile;
+
+ return rc;
+
+ }
+
+ ERROR_CODE Root::ReadCIFASCII ( io::RFile f ) {
+ int W;
+ ERROR_CODE RC;
+
+ // remove previous data
+ ResetManager ();
+ FreeFileMemory();
+ FType = MMDB_FILE_CIF;
+
+ SetFlag ( 0 );
+
+ CIFErrorLocation[0] = char(0); // CIF reading phase
+
+ lcount = 0; // line counter
+ S[0] = char(0);
+
+ if (f.FileEnd())
+ return Error_EmptyFile;
+
+ if (!CIF) CIF = new mmcif::Data();
+ CIF->SetStopOnWarning ( true );
+ CIF->SetPrintWarnings ( (Flags & MMDBF_PrintCIFWarnings)!=0 );
+ W = CIF->ReadMMCIFData ( f,S,lcount );
+
+ if (W) {
+ if (W == mmcif::CIFRC_NoDataLine) return Error_NotACIFFile;
+ if (W & mmcif::CIFW_UnrecognizedItems) return Error_UnrecognCIFItems;
+ if (W & mmcif::CIFW_MissingField) return Error_MissingCIFField;
+ if (W & mmcif::CIFW_EmptyLoop) return Error_EmptyCIFLoop;
+ if (W & mmcif::CIFW_UnexpectedEOF) return Error_UnexpEndOfCIF;
+ if (W & mmcif::CIFW_LoopFieldMissing) return Error_MissgCIFLoopField;
+ if (W & mmcif::CIFW_NotAStructure) return Error_NotACIFStructure;
+ if (W & mmcif::CIFW_NotALoop) return Error_NotACIFLoop;
+ return Error_Unknown;
+ }
+
+ RC = ReadFromCIF ( CIF );
+ if (CIF) {
+ delete CIF;
+ CIF = NULL;
+ }
+
+ return RC;
+
+ }
+
+
+ ERROR_CODE Root::ReadFromCIF ( mmcif::PData CIFD ) {
+ mmcif::PLoop Loop1,Loop2;
+ pstr F,FC;
+ word cleanKey;
+ int i,l,j,n,retc;
+ ERROR_CODE RC;
+
+ RC = title.GetCIF ( CIFD );
+
+ if (RC!=Error_NoError) {
+ CIFD->Optimize();
+ return RC;
+ }
+
+ SwitchModel ( 1 );
+ if (!crModel) return Error_GeneralError1;
+ RC = crModel->GetCIF ( CIFD );
+ if (RC!=Error_NoError) {
+ CIFD->Optimize();
+ return RC;
+ }
+
+ RC = cryst.GetCIF ( CIFD );
+ if (RC!=Error_NoError) {
+ CIFD->Optimize();
+ return RC;
+ }
+ cryst.CalcCoordTransforms();
+ if (Flags & MMDBF_SimRWBROOK)
+ cryst.RWBROOKReadPrintout();
+
+ RC = ReadCIFAtom ( CIFD );
+
+ Loop1 = CIFD->GetLoop ( CIFCAT_ENTITY );
+ Loop2 = CIFD->GetLoop ( CIFCAT_STRUCT_ASYM );
+ if (Loop1 && Loop2) {
+ // make 'Het' atoms
+ l = Loop1->GetLoopLength();
+ n = Loop2->GetLoopLength();
+ for (i=0;i<l;i++) {
+ F = Loop1->GetString ( CIFTAG_TYPE,i,retc );
+ if (F && (!retc)) {
+ if (!strcasecmp(F,"non-polymer")) {
+ F = Loop1->GetString ( CIFTAG_ID,i,retc );
+ if (F && (!retc))
+ for (j=0;j<n;j++) {
+ FC = Loop2->GetString ( CIFTAG_ENTITY_ID,j,retc );
+ if (FC && (!retc)) {
+ if (!strcasecmp(FC,F)) {
+ FC = Loop2->GetString ( CIFTAG_ID,j,retc );
+ if (FC && (!retc))
+ MakeHetAtoms ( FC,true );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (RC==Error_NoError) {
+ // deleting these CIF loops here is a temporary solution
+ // taken in order to avoid mess at rewriting the CIF file.
+ CIFD->DeleteLoop ( CIFCAT_ATOM_SITE );
+ CIFD->DeleteLoop ( CIFCAT_ATOM_SITE_ANISOTROP );
+ CIFD->Optimize ();
+ }
+
+ cleanKey = 0x00000000;
+ if (Flags & MMDBF_EnforceAtomNames)
+ cleanKey = PDBCLEAN_ATNAME;
+ if (Flags & MMDBF_AutoSerials)
+ cleanKey |= PDBCLEAN_SERIAL;
+ if (cleanKey)
+ PDBCleanup ( cleanKey );
+
+ return RC;
+
+ }
+
+ ERROR_CODE Root::ReadCoorFile1 ( cpstr LFName, io::GZ_MODE gzipMode ) {
+ pstr FName;
+ FName = getenv ( LFName );
+ if (FName) return ReadCoorFile ( FName,gzipMode );
+ else return Error_NoLogicalName;
+ }
+
+ ERROR_CODE Root::ReadCoorFile ( cpstr CFName, io::GZ_MODE gzipMode ) {
+ // auto format recognition
+ int kin;
+ bool IBL;
+
+ kin = isMMDBBIN ( CFName,gzipMode );
+ if (kin==Error_EmptyFile)
+ return Error_EmptyFile;
+ if (kin<0) return Error_CantOpenFile;
+
+ if (kin==0) return ReadMMDBF ( CFName,gzipMode );
+
+ IBL = ((Flags & MMDBF_IgnoreBlankLines)!=0);
+ if (isPDB(CFName,gzipMode,IBL)==0)
+ return ReadPDBASCII ( CFName,gzipMode );
+ if (mmcif::isCIF(CFName,gzipMode)==0)
+ return ReadCIFASCII ( CFName,gzipMode );
+
+ return Error_ForeignFile;
+
+ }
+
+
+ ERROR_CODE Root::ReadCoorFile ( io::RFile f ) {
+ // auto format recognition
+ int kin;
+ bool IBL;
+
+ kin = isMMDBBIN ( f );
+ f.reset ( true );
+ if (kin==Error_EmptyFile)
+ return Error_EmptyFile;
+ if (kin<0) return Error_CantOpenFile;
+
+ if (kin==0) return ReadMMDBF ( f );
+
+ IBL = ((Flags & MMDBF_IgnoreBlankLines)!=0);
+ kin = isPDB ( f,IBL );
+ f.reset ( true );
+ if (kin==0)
+ return ReadPDBASCII ( f );
+
+ kin = mmcif::isCIF ( f );
+ f.reset ( true );
+ if (kin==0)
+ return ReadCIFASCII ( f );
+
+ return Error_ForeignFile;
+
+ }
+
+
+ word Root::PDBCleanup ( word CleanKey ) {
+ // cleans coordinate part to comply with PDB standards:
+ //
+ // CleanKey Action
+ // PDBCLEAN_ATNAME pads atom names with spaces to form 4-symbol names
+ // PDBCLEAN_TER inserts TER cards in the end of each chain
+ // PDBCLEAN_CHAIN generates 1-character chain ids instead of
+ // those many-character
+ // PDBCLEAN_CHAIN_STRONG generates 1-character chain ids starting
+ // from 'A' on for all ids, including single-char
+ // PDBCLEAN_ALTCODE generates 1-character alternative codes instead
+ // of those many-character
+ // PDBCLEAN_ALTCODE_STRONG generates 1-character alternative codes
+ // from 'A' on for all codes, including
+ // single-character ones
+ // PDBCLEAN_SERIAL puts serial numbers in due order
+ // PDBCLEAN_INDEX reorders the internal index of atoms such that
+ // it follows the actual order of atoms in
+ // the object hierarchy
+ // PDBCLEAN_SEQNUM renumbers all residues so that they go
+ // incrementally-by-one without insertion codes
+ // PDBCLEAN_CHAIN_ORDER puts chains in order of atom's serial numbers
+ // PDBCLEAN_SOLVENT moves solvent chains at the end of each model
+ // PDBCLEAN_ELEMENT calculates PDB element names where they are not
+ // found in the chemical element table
+ // PDBCLEAN_ELEMENT_STRONG calculates all chemical element names
+ //
+ // Return codes (as bits):
+ // 0 Ok
+ // PDBCLEAN_CHAIN too many chains for assigning them 1-letter codes
+ // PDBCLEAN_ATNAME element names were not available
+ // PDBCLEAN_ALTCODE too many alternative codes encountered.
+ //
+ word RC;
+ int i,j,k,nal,nch,nr, nch1,nch2;
+ char c;
+ AltLoc * altLoc;
+ ChainID * chain_ID;
+ char aLoc [257];
+ char chnID[257];
+ int modN,modl;
+ PPAtom atom1;
+ PPChain Chain1,Chain2;
+ PModel crModel0;
+ PChain crChain0;
+ PResidue crRes0;
+ PAtom A;
+ pstr chID;
+ ChainID chainID;
+ bool NewChain,Done,Solvent;
+
+ RC = 0;
+ if (nAtoms<=0) return RC;
+
+ if (CleanKey & PDBCLEAN_ATNAME)
+ for (i=0;i<nAtoms;i++)
+ if (atom[i])
+ if (!atom[i]->MakePDBAtomName()) RC |= PDBCLEAN_ATNAME;
+
+ k = -1;
+
+ if (CleanKey & PDBCLEAN_TER) {
+ modN = -1;
+ crModel0 = crModel;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ modl = atom[i]->GetModelNum();
+ chID = atom[i]->GetChainID ();
+ if (modN<0) {
+ modN = modl;
+ SwitchModel ( modN );
+ if (chID) strcpy ( chainID,chID );
+ else chainID[0] = char(0);
+ } else {
+ if (modN!=modl) NewChain = true;
+ else if (chID) NewChain = strcmp(chID,chainID)!=0;
+ else NewChain = chainID[0]!=char(0);
+ if (NewChain) {
+ if (k>=0) {
+ if ((!atom[k]->Ter) && (!atom[k]->Het)) {
+ // insert 'Ter' before atom in position 'i'
+ PutAtom ( -(i+1),atom[k]->serNum+1,pstr("TER"),
+ atom[k]->GetResName(),atom[k]->GetChainID(),
+ atom[k]->GetSeqNum (),atom[k]->GetInsCode(),
+ pstr(" "),pstr(" "),pstr(" ") );
+ atom[i]->MakeTer();
+ }
+ }
+ modN = modl;
+ SwitchModel ( modN );
+ if (chID) strcpy ( chainID,chID );
+ else chainID[0] = char(0);
+ }
+ }
+ k = i;
+ }
+
+ if (k>=0) {
+ if ((!atom[k]->Ter) && (!atom[k]->Het)) { // add last TER
+ i = nAtoms;
+ SwitchModel ( atom[k]->GetModelNum() );
+ PutAtom ( 0,nAtoms+1,pstr("TER"),atom[k]->GetResName(),
+ atom[k]->GetChainID(),atom[k]->GetSeqNum(),
+ atom[k]->GetInsCode(),pstr(" "),pstr(" "),
+ pstr(" ") );
+ atom[i]->MakeTer();
+ }
+ }
+
+ crModel = crModel0;
+ }
+
+
+ if (CleanKey & (PDBCLEAN_CHAIN | PDBCLEAN_CHAIN_STRONG)) {
+ chain_ID = new ChainID[256];
+ for (i=0;i<nModels;i++)
+ if (model[i]) {
+ for (j=0;j<256;j++) {
+ strcpy ( chain_ID[j]," " );
+ chnID[j] = char(0);
+ }
+ chnID[256] = char(0);
+ nch = 0;
+ for (j=0;j<model[i]->nChains;j++) {
+ crChain0 = model[i]->chain[j];
+ if (crChain0) {
+ if (!crChain0->chainID[0])
+ strcpy ( crChain0->chainID," " );
+ k = 0;
+ while ((k<nch) && (strcmp(chain_ID[k],crChain0->chainID)))
+ k++;
+ if (k>=nch) {
+ if (nch>=255) RC |= PDBCLEAN_CHAIN;
+ else {
+ strcpy ( chain_ID[nch],crChain0->chainID );
+ if (!chain_ID[nch][1])
+ chnID[nch] = chain_ID[nch][0];
+ nch++;
+ }
+ }
+ }
+ }
+ c = 'A';
+ if (CleanKey & PDBCLEAN_CHAIN_STRONG) {
+ // rename all chains through from A to Z
+ for (k=0;k<nch;k++) {
+ chnID[k] = c;
+ c = char(int(c)+1);
+ }
+ } else {
+ // rename only multi-character chain IDs
+ for (j=0;(j<nch) && (k<256);j++) {
+ k = 0;
+ do {
+ while ((k<nch) && (chnID[k]!=c)) k++;
+ if (k<nch) c = char(int(c)+1);
+ } while (k<nch);
+ k = 0;
+ while ((k<256) && (chnID[k])) k++;
+ if (k<256) {
+ chnID[k] = c;
+ c = char(int(c)+1);
+ }
+ }
+ }
+ // assign new chain IDs
+ for (j=0;j<model[i]->nChains;j++) {
+ crChain0 = model[i]->chain[j];
+ if (crChain0) {
+ k = 0;
+ while ((k<nch) && (strcmp(chain_ID[k],crChain0->chainID)))
+ k++;
+ strcpy ( crChain0->prevChainID,crChain0->chainID );
+ crChain0->chainID[0] = chnID[k];
+ crChain0->chainID[1] = char(0);
+ }
+ }
+ }
+ delete[] chain_ID;
+ }
+
+
+ if (CleanKey & (PDBCLEAN_ALTCODE | PDBCLEAN_ALTCODE_STRONG)) {
+ altLoc = new AltLoc[256];
+ for (i=0;i<256;i++) {
+ strcpy ( altLoc[i]," " );
+ aLoc[i] = char(0);
+ }
+ aLoc[0] = ' ';
+ aLoc[256] = char(0);
+ nal = 1;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (!atom[i]->altLoc[0]) strcpy ( atom[i]->altLoc," " );
+ else {
+ k = 0;
+ while ((k<nal) && (strcmp(altLoc[k],atom[i]->altLoc))) k++;
+ if (k>=nal) {
+ if (nal>=255) RC |= PDBCLEAN_ALTCODE;
+ else {
+ strcpy ( altLoc[nal],atom[i]->altLoc );
+ if (!altLoc[nal][1]) aLoc[nal] = altLoc[nal][0];
+ nal++;
+ }
+ }
+ }
+ }
+ c = 'A';
+ if (CleanKey & PDBCLEAN_ALTCODE_STRONG)
+ for (i=1;i<nal;i++) {
+ aLoc[i] = c;
+ c = char(int(c)+1);
+ }
+ else
+ for (i=1;(i<nal) && (k<256);i++) {
+ k = 0;
+ do {
+ while ((k<nal) && (aLoc[k]!=c)) k++;
+ if (k<nal) c = char(int(c)+1);
+ } while (k<nal);
+ k = 0;
+ while ((k<256) && (aLoc[k])) k++;
+ if (k<256) {
+ aLoc[k] = c;
+ c = char(int(c)+1);
+ }
+ }
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ k = 0;
+ while ((k<nal) && (strcmp(altLoc[k],atom[i]->altLoc))) k++;
+ atom[i]->altLoc[0] = aLoc[k];
+ atom[i]->altLoc[1] = char(0);
+ }
+ delete[] altLoc;
+ }
+
+
+ if (CleanKey & PDBCLEAN_SEQNUM)
+ for (i=0;i<nModels;i++) {
+ crModel0 = model[i];
+ if (crModel0)
+ for (j=0;j<crModel0->nChains;j++) {
+ crChain0 = crModel0->chain[j];
+ if (crChain0) {
+ nr = 0;
+ for (k=0;k<crChain0->nResidues;k++) {
+ crRes0 = crChain0->residue[k];
+ if (crRes0) {
+ nr++;
+ crRes0->seqNum = nr;
+ crRes0->insCode[0] = char(0);
+ }
+ }
+ }
+ }
+ }
+
+ if (CleanKey & PDBCLEAN_SOLVENT) {
+ atom1 = new PAtom[nAtoms];
+ k = 1;
+ for (i=0;i<nModels;i++)
+ if (model[i]) {
+ if (model[i]->nChains>k) k = model[i]->nChains;
+ }
+ Chain1 = new PChain[k];
+ Chain2 = new PChain[k];
+ k = 0;
+ for (i=0;i<nModels;i++) {
+ crModel0 = model[i];
+ if (crModel0) {
+ nch1 = 0;
+ nch2 = 0;
+ for (nch=0;nch<crModel0->nChains;nch++) {
+ crChain0 = crModel0->chain[nch];
+ if (crChain0) {
+ Solvent = false;
+ for (nr=0;(nr<crChain0->nResidues) && (!Solvent);nr++) {
+ crRes0 = crChain0->residue[nr];
+ if (crRes0)
+ for (j=0;(j<nSolventNames) && (!Solvent);j++)
+ Solvent = !strcmp ( StdSolventName[j],crRes0->name );
+ }
+ if (Solvent) Chain2[nch2++] = crChain0;
+ else Chain1[nch1++] = crChain0;
+ }
+ }
+ for (nch=0;nch<nch1;nch++) {
+ crChain0 = Chain1[nch];
+ for (nr=0;nr<crChain0->nResidues;nr++) {
+ crRes0 = crChain0->residue[nr];
+ if (crRes0)
+ for (j=0;j<crRes0->nAtoms;j++)
+ if (crRes0->atom[j]) {
+ atom1[k] = crRes0->atom[j];
+ atom1[k]->index = k+1;
+ k++;
+ }
+ }
+ crModel0->chain[nch] = Chain1[nch];
+ }
+ for (nch=0;nch<nch2;nch++) {
+ crChain0 = Chain2[nch];
+ for (nr=0;nr<crChain0->nResidues;nr++) {
+ crRes0 = crChain0->residue[nr];
+ if (crRes0)
+ for (j=0;j<crRes0->nAtoms;j++)
+ if (crRes0->atom[j]) {
+ atom1[k] = crRes0->atom[j];
+ atom1[k]->index = k+1;
+ k++;
+ }
+ }
+ crModel0->chain[nch1++] = Chain2[nch];
+ }
+ crModel0->nChains = nch1;
+ }
+ }
+ delete[] Chain1;
+ delete[] Chain2;
+ if (atom) delete[] atom;
+ atom = atom1;
+ atmLen = nAtoms;
+ nAtoms = k;
+ }
+
+ if (CleanKey & (PDBCLEAN_CHAIN_ORDER | PDBCLEAN_CHAIN_ORDER_IX)) {
+ for (i=0;i<nModels;i++) {
+ crModel0 = model[i];
+ if (crModel0) {
+ k = 0;
+ for (j=0;j<crModel0->nChains;j++) {
+ crChain0 = crModel0->chain[j];
+ if (crChain0) {
+ crChain0->nWeights = 0;
+ crChain0->Weight = 0.0;
+ if (k<j) {
+ crModel0->chain[k] = crModel0->chain[j];
+ crModel0->chain[j] = NULL;
+ }
+ k++;
+ }
+ }
+ crModel0->nChains = k;
+ }
+ }
+ if (CleanKey & PDBCLEAN_CHAIN_ORDER)
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ crChain0 = atom[i]->GetChain();
+ crChain0->nWeights++;
+ crChain0->Weight += atom[i]->serNum;
+ }
+ else
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ crChain0 = atom[i]->GetChain();
+ crChain0->nWeights++;
+ crChain0->Weight += atom[i]->GetIndex();
+ }
+ for (i=0;i<nModels;i++) {
+ crModel0 = model[i];
+ if (crModel0) {
+ for (j=0;j<crModel0->nChains;j++) {
+ crChain0 = crModel0->chain[j];
+ if (crChain0->nWeights)
+ crChain0->Weight /= crChain0->nWeights;
+ }
+ // bubble sorting
+ do {
+ Done = true;
+ for (j=1;j<crModel0->nChains;j++)
+ if (crModel0->chain[j-1]->Weight >
+ crModel0->chain[j]->Weight) {
+ crChain0 = crModel0->chain[j-1];
+ crModel0->chain[j-1] = crModel0->chain[j];
+ crModel0->chain[j] = crChain0;
+ Done = false;
+ }
+ } while (!Done);
+ }
+ }
+ }
+
+ if (CleanKey & PDBCLEAN_INDEX) {
+ k = 0;
+ for (i=0;i<nModels;i++) {
+ crModel0 = model[i];
+ if (crModel0) {
+ for (nch=0;nch<crModel0->nChains;nch++) {
+ crChain0 = crModel0->chain[nch];
+ if (crChain0) {
+ for (nr=0;nr<crChain0->nResidues;nr++) {
+ crRes0 = crChain0->residue[nr];
+ if (crRes0) {
+ for (j=0;j<crRes0->nAtoms;j++) {
+ A = crRes0->atom[j];
+ if (A) {
+ atom[A->index-1] = atom[k];
+ if (atom[k])
+ atom[k]->index = A->index;
+ atom[k] = A;
+ k++;
+ A->index = k;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ nAtoms = k;
+ }
+
+ if (CleanKey & PDBCLEAN_SERIAL) {
+ k = 0;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (k<i) {
+ atom[k] = atom[i];
+ atom[i] = NULL;
+ }
+ atom[k]->index = k+1;
+ atom[k]->serNum = atom[k]->index;
+ k++;
+ }
+ nAtoms = k;
+ }
+
+ if (CleanKey & PDBCLEAN_ELEMENT) {
+ for (i=0;i<nAtoms;i++)
+ if (atom[i] && (!atom[i]->Ter)) {
+ if (getElementNo(atom[i]->element)==ELEMENT_UNKNOWN) {
+ strcpy ( atom[i]->element," " );
+ atom[i]->MakePDBAtomName();
+ }
+ }
+ }
+
+ if (CleanKey & PDBCLEAN_ELEMENT_STRONG) {
+ for (i=0;i<nAtoms;i++)
+ if (atom[i] && (!atom[i]->Ter)) {
+ strcpy ( atom[i]->element," " );
+ atom[i]->MakePDBAtomName();
+ }
+ }
+
+ return RC;
+
+ }
+
+ void Root::MakeHetAtoms ( cpstr chainID, bool Make ) {
+ // Makes all atoms in chain 'chainID', in all models, as 'Het' atoms
+ // if Make is set true, and makes them 'ordinary' atoms otherwise.
+ // 'Ter' is automatically removed when converting to 'Het' atoms,
+ // and is automatically added when converting to 'ordinary' atoms.
+ int i,j,k,l,n;
+ PModel crModel0;
+ PChain crChain0;
+ PResidue crRes0;
+ crModel0 = crModel;
+ for (i=0;i<nModels;i++)
+ if (model[i])
+ for (j=0;j<model[i]->nChains;j++) {
+ crChain0 = model[i]->chain[j];
+ if (crChain0) {
+ if (!strcmp(crChain0->chainID,chainID)) {
+ n = 0;
+ for (k=0;k<crChain0->nResidues;k++) {
+ crRes0 = crChain0->residue[k];
+ if (crRes0)
+ for (l=0;l<crRes0->nAtoms;l++)
+ if (crRes0->atom[l]) {
+ crRes0->atom[l]->Het = Make;
+ n = crRes0->atom[l]->index;
+ }
+ }
+ if (n>0) {
+ n--;
+ if (atom[n]->Het && atom[n]->Ter) RemoveAtom ( n+1 );
+ else if ((!atom[n]->Het) && (!atom[n]->Ter)) {
+ SwitchModel ( model[i]->GetSerNum() );
+ if (n<nAtoms-1)
+ PutAtom ( -(n+2),atom[n]->serNum+1,pstr("TER"),
+ atom[n]->GetResName(),atom[n]->GetChainID(),
+ atom[n]->GetSeqNum (),atom[n]->GetInsCode(),
+ pstr(" "),pstr(" "),pstr(" ") );
+ else
+ PutAtom ( 0,nAtoms+1,pstr("TER"),
+ atom[n]->GetResName(),atom[n]->GetChainID(),
+ atom[n]->GetSeqNum (),atom[n]->GetInsCode(),
+ pstr(" "),pstr(" "),pstr(" ") );
+ atom[n+1]->MakeTer();
+ }
+ }
+ }
+ }
+ }
+ crModel = crModel0;
+ }
+
+
+ void Root::RemoveAtom ( int index ) {
+ // Removes atom at the specified index in the Atom array.
+ // This index is always accessible as atom[index]->index.
+ // If this leaves a residue empty, the residue is removed.
+ // If this leaves an empty chain, the chain is removed as well;
+ // the same happens to the model.
+ PResidue crRes0;
+ PChain crChain0;
+ PModel crModel0;
+ int i,j;
+
+ if ((index>0) && (index<=nAtoms)) {
+ if (atom[index-1]) {
+ crRes0 = atom[index-1]->residue;
+ if (crRes0) {
+ if (crRes0->_ExcludeAtom(index)) {
+ // the residue appears empty after the exclusion
+ if (crRes) {
+ if ((crRes->seqNum==crRes0->seqNum) &&
+ (!strcmp(crRes->insCode,crRes0->insCode)))
+ crRes = NULL;
+ }
+ crChain0 = crRes0->chain;
+ if (crChain0) {
+ if (crChain0->_ExcludeResidue(crRes0->name,crRes0->seqNum,
+ crRes0->insCode)) {
+ // the chain appears empty after the exclusion
+ if (crChain) {
+ if (!strcmp(crChain->chainID,crChain0->chainID))
+ crChain = NULL;
+ }
+ crModel0 = PModel(crChain0->model);
+ if (crModel0) {
+ if (crModel0->_ExcludeChain(crChain0->chainID)) {
+ // the model appears ampty after the exclusion
+ if (crModel) {
+ if (crModel->serNum==crModel0->serNum)
+ crModel = NULL;
+ }
+ i = crModel0->serNum-1;
+ delete model[i];
+ model[i] = NULL;
+ }
+ }
+ delete crChain0; // it is already excluded from the hierarchy!
+ }
+ }
+ delete crRes0; // it is already excluded from the hierarchy!
+ }
+ }
+ delete atom[index-1]; // it is already excluded from the hierarchy!
+ atom[index-1] = NULL;
+ // now rearrange and re-index atoms.
+ j = 0;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (j<i) {
+ atom[j] = atom[i];
+ atom[i] = NULL;
+ }
+ atom[j]->index = j+1;
+ j++;
+ }
+ nAtoms = j;
+ }
+ }
+ }
+
+
+ int Root::_ExcludeModel ( int serNum ) {
+ // _ExcludeModel(..) excludes (but does not dispose!) a model
+ // from the file. Returns 1 if the file gets empty and 0 otherwise.
+ int i,k;
+
+ if (!Exclude) return 0;
+
+ if ((0<serNum) && (serNum<=nModels))
+ model[serNum-1] = NULL;
+
+ k = 0;
+ for (i=0;i<nModels;i++)
+ if (model[i]) {
+ if (k<i) {
+ model[k] = model[i];
+ model[i] = NULL;
+ }
+ model[k]->serNum = k+1;
+ k++;
+ }
+
+ nModels = k;
+
+ if (nModels<=0) return 1;
+ else return 0;
+
+ }
+
+
+ int Root::FinishStructEdit() {
+ // Makes a new atom index after insertion or deletion of atoms.
+ // This function may change atoms' positions in the index and
+ // correspondingly the Atom::index field.
+ PResidue res;
+ PChain chain;
+ PModel Model1;
+ PPAtom Atom1;
+ int i,j,k,l,n,index,nAtoms1;
+
+ // calculate new number of atoms
+ nAtoms1 = 0;
+ for (i=0;i<nModels;i++) {
+ Model1 = model[i];
+ if (Model1) {
+ for (j=0;j<Model1->nChains;j++) {
+ chain = Model1->chain[j];
+ if (chain) {
+ for (k=0;k<chain->nResidues;k++) {
+ res = chain->residue[k];
+ if (res) {
+ res->TrimAtomTable();
+ nAtoms1 += res->nAtoms;
+ }
+ }
+ chain->TrimResidueTable();
+ }
+ }
+ Model1->TrimChainTable();
+ }
+ }
+ TrimModelTable();
+
+ // compile a new index and null the old one
+
+ if (nAtoms1>0) Atom1 = new PAtom[nAtoms1];
+ else Atom1 = NULL;
+
+ n = 0;
+ for (i=0;i<nModels;i++) {
+ Model1 = model[i];
+ for (j=0;j<Model1->nChains;j++) {
+ chain = Model1->chain[j];
+ for (k=0;k<chain->nResidues;k++) {
+ res = chain->residue[k];
+ for (l=0;l<res->nAtoms;l++) {
+ Atom1[n] = res->atom[l];
+ index = Atom1[n]->index;
+ if ((index>0) && (index<=atmLen))
+ atom[index-1] = NULL;
+ Atom1[n]->index = n+1;
+ n++;
+ }
+ }
+ }
+ }
+
+ // if (n!=nAtoms1) {
+ // printf ( " **** PROGRAM ERROR IN Root::FinishStructEdit\n" );
+ // exit ( 1 );
+ // }
+
+
+ // check if there are dead atoms in the old index
+ for (i=0;i<atmLen;i++)
+ if (atom[i]) delete atom[i];
+
+ // dispose old index and replace it with the new one
+ if (atom) delete[] atom;
+
+ atom = Atom1;
+ atmLen = n;
+ nAtoms = n;
+
+ if (n==nAtoms1) return 0; // Ok
+ else return 1; // not Ok; should never happen
+
+ }
+
+ void Root::TrimModelTable() {
+ int i,j;
+ j = 0;
+ for (i=0;i<nModels;i++)
+ if (model[i]) {
+ if (j<i) {
+ model[j] = model[i];
+ model[i] = NULL;
+ }
+ model[j]->serNum = j+1;
+ j++;
+ }
+ nModels = j;
+ }
+
+
+ int Root::GenerateNCSMates() {
+ //
+ // Generates NCS mates according to NCS matrices given
+ // in cryst. This will result in generating many-character
+ // chain names, composed as 'x_n' where 'x' is the original
+ // name and 'n' is a unique number, which will coincide with
+ // the symmetry operation (order) number. Another side
+ // effect will be a disorder in atoms' serial numbers.
+ // The hierarchy should therefore be cleaned after
+ // generating the NCS mates. An appropriate way to do that
+ // is to issue the following call:
+ //
+ // PDBCleanup ( PDBCLEAN_TER | PDBCLEAN_ALTCODE_STRONG |
+ // PDBCLEAN_CHAIN_STRONG | PDBCLEAN_SERIAL );
+ //
+ PPChain chainTable,chain;
+ PChain chn;
+ mat44 ncs_m;
+ ChainID chainID;
+ int i,j,k,nNCSOps,nChains,iGiven;
+
+ nNCSOps = cryst.GetNumberOfNCSMatrices();
+ if (nNCSOps<=0) return 1;
+
+ for (i=0;i<nModels;i++)
+ if (model[i]) {
+ model[i]->GetChainTable ( chainTable,nChains );
+ if (nChains>0) {
+ chain = new PChain[nChains];
+ for (j=0;j<nChains;j++)
+ chain[j] = chainTable[j];
+ for (j=0;j<nChains;j++)
+ if (chain[j]) {
+ for (k=0;k<nNCSOps;k++)
+ if (cryst.GetNCSMatrix(k,ncs_m,iGiven)) {
+ if (!iGiven) {
+ chn = newChain();
+ chn->Copy ( chain[j] );
+ sprintf ( chainID,"%s_%i",
+ chain[j]->GetChainID(),k+1 );
+ chn->SetChainID ( chainID );
+ chn->ApplyTransform ( ncs_m );
+ model[i]->AddChain ( chn );
+ }
+ }
+ }
+ delete[] chain;
+ }
+ }
+
+ return 0;
+
+ }
+
+
+ void Root::ApplyNCSTransform ( int NCSMatrixNo ) {
+ mat33 t;
+ vect3 v;
+ int i;
+ if (!cryst.GetNCSMatrix(NCSMatrixNo,t,v)) return;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) atom[i]->Transform ( t,v );
+ }
+
+
+ ERROR_CODE Root::PutPDBString ( cpstr PDBString ) {
+ PContString contString;
+ ERROR_CODE RC;
+
+ strcpy ( S,PDBString ); // maintain the buffer!
+ PadSpaces ( S,80 );
+ lcount++;
+
+ // belongs to title?
+ RC = title.ConvertPDBString ( S );
+ if (RC!=Error_WrongSection) return RC;
+
+ // belongs to primary structure section?
+ SwitchModel ( 1 );
+ RC = crModel->ConvertPDBString ( S );
+ if (RC!=Error_WrongSection) return RC;
+
+ // belongs to the crystallographic information section?
+ RC = cryst.ConvertPDBString ( S );
+ if (RC!=Error_WrongSection) {
+ // if (RC==0) cryst.CalcCoordTransforms();
+ return RC;
+ }
+
+ // belongs to the coordinate section?
+ RC = ReadPDBAtom ( S );
+ if (RC!=Error_WrongSection) return RC;
+
+ // temporary solution: the rest of file is stored
+ // in the form of strings
+ if ((S[0]) && (S[0]!=' ') && (strncmp(S,"END ",6))) {
+ // END is added automatically
+ contString = new ContString(S);
+ SC.AddData ( contString );
+ }
+
+ return Error_NoError;
+
+ }
+
+
+ ERROR_CODE Root::AddPDBASCII1 ( cpstr PDBLFName, io::GZ_MODE gzipMode ) {
+ pstr FName;
+ FName = getenv ( PDBLFName );
+ if (FName) return AddPDBASCII ( FName,gzipMode );
+ else return Error_NoLogicalName;
+ }
+
+ ERROR_CODE Root::AddPDBASCII ( cpstr PDBFileName, io::GZ_MODE gzipMode ) {
+ io::File f;
+ ERROR_CODE RC;
+ // open the file as ASCII for reading
+ // opening it in pseudo-binary mode helps reading various
+ // line terminators for files coming from different platforms
+ f.assign ( PDBFileName,false,false,gzipMode );
+ if (f.reset(true)) {
+ lcount = 1; // line counter
+ RC = Error_NoError;
+ while ((!f.FileEnd()) && (!RC)) {
+ ReadPDBLine ( f,S,sizeof(S) );
+ RC = PutPDBString ( S );
+ }
+ f.shut();
+ } else
+ RC = Error_CantOpenFile;
+ return RC;
+ }
+
+
+ void Root::GetInputBuffer ( pstr Line, int & count ) {
+ if (FType==MMDB_FILE_PDB) { // PDB File
+ strcpy ( Line,S );
+ count = lcount;
+ } else if (FType==MMDB_FILE_CIF) {
+ if (!CIFErrorLocation[0]) { // CIF reading phase
+ strcpy ( Line,S );
+ count = lcount;
+ } else {
+ strcpy ( Line,CIFErrorLocation );
+ count = -1; // CIF interpretation phase
+ }
+ } else {
+ Line[0] = char(0);
+ count = -2;
+ }
+ }
+
+
+ int Root::CrystReady() {
+ // Returns flags:
+ // CRRDY_Complete if crystallographic information is complete
+ // CRRDY_NotPrecise if cryst. inf-n is not precise
+ // CRRDY_isTranslation if cryst. inf-n contains translation
+ // CRRDY_NoOrthCode no orthogonalization code
+ // Fatal:
+ // CRRDY_NoTransfMatrices if transform. matrices were not calculated
+ // CRRDY_Unchecked if cryst. inf-n was not checked
+ // CRRDY_Ambiguous if cryst. inf-n is ambiguous
+ // CRRDY_NoCell if cryst. inf-n is unusable
+ // CRRDY_NoSpaceGroup if space group is not set
+ int k;
+
+ if (!(cryst.WhatIsSet & CSET_Transforms))
+ return CRRDY_NoTransfMatrices;
+
+ if ((cryst.WhatIsSet & CSET_CellParams)!=CSET_CellParams)
+ return CRRDY_NoCell;
+
+ if (!(cryst.WhatIsSet & CSET_SpaceGroup))
+ return CRRDY_NoSpaceGroup;
+
+ if (cryst.CellCheck & CCHK_Unchecked)
+ return CRRDY_Unchecked;
+
+ if (cryst.CellCheck & CCHK_Disagreement)
+ return CRRDY_Ambiguous;
+
+ k = 0x0000;
+ if (cryst.CellCheck & CCHK_Error) k |= CRRDY_NotPrecise;
+ if (cryst.CellCheck & CCHK_Translations) k |= CRRDY_isTranslation;
+ if (cryst.CellCheck & CCHK_NoOrthCode) k |= CRRDY_NoOrthCode;
+
+ return k;
+
+ }
+
+
+ bool Root::isCrystInfo() {
+ return (((cryst.WhatIsSet & CSET_CellParams)==CSET_CellParams) &&
+ (cryst.WhatIsSet & CSET_SpaceGroup));
+ }
+
+ bool Root::isCellInfo() {
+ return ((cryst.WhatIsSet & CSET_CellParams)==CSET_CellParams);
+ }
+
+ bool Root::isSpaceGroup() {
+ return (cryst.WhatIsSet & CSET_SpaceGroup);
+ }
+
+ bool Root::isTransfMatrix() {
+ return cryst.areMatrices();
+ }
+
+ bool Root::isScaleMatrix() {
+ return ((cryst.WhatIsSet & CSET_ScaleMatrix)==CSET_ScaleMatrix);
+ }
+
+ bool Root::isNCSMatrix() {
+ return cryst.isNCSMatrix();
+ }
+
+ int Root::AddNCSMatrix ( mat33 & ncs_m, vect3 & ncs_v,
+ int iGiven ) {
+ return cryst.AddNCSMatrix ( ncs_m,ncs_v,iGiven );
+ }
+
+ int Root::GetNumberOfNCSMatrices() {
+ return cryst.GetNumberOfNCSMatrices();
+ }
+
+ int Root::GetNumberOfNCSMates() {
+ // Returns the number of NCS mates not given in the file (iGiven==0)
+ return cryst.GetNumberOfNCSMates();
+ }
+
+ bool Root::GetNCSMatrix ( int NCSMatrixNo, // 0..N-1
+ mat44 & ncs_m, int & iGiven ) {
+ return cryst.GetNCSMatrix ( NCSMatrixNo,ncs_m,iGiven );
+ }
+
+ ERROR_CODE Root::ReadPDBAtom ( cpstr L ) {
+ // If string L belongs to the coordinate section
+ // (records ATOM, SIGATM, ANISOU, SIGUIJ, TER, HETATM),
+ // the correspondent information is retrieved and
+ // stored in the dynamic Atom array. In parallel, the
+ // structures of Model/Chain/Residue are generated and
+ // referenced to the corresponding Atom.
+ // If processing of L was successful, the return is 0,
+ // otherwise it returns the corresponding Error_XXX
+ // code.
+ // If L does not belong to the coordinate section,
+ // Error_WrongSection is returned.
+ int index,i;
+ ERROR_CODE RC;
+
+ if (!strncmp(L,"ATOM ",6)) {
+
+ index = nAtoms+1; // index for the next atom in Atom array
+ RC = CheckAtomPlace ( index,L );
+ if (!RC) RC = atom[index-1]->ConvertPDBATOM ( index,L );
+
+ } else if (!strncmp(L,"SIGATM",6)) {
+
+ index = nAtoms; // keep index!
+ RC = CheckAtomPlace ( index,L );
+ if (!RC) RC = atom[index-1]->ConvertPDBSIGATM ( index,L );
+
+ } else if (!strncmp(L,"ANISOU",6)) {
+
+ index = nAtoms; // keep index
+ RC = CheckAtomPlace ( index,L );
+ if (!RC) RC = atom[index-1]->ConvertPDBANISOU ( index,L );
+
+ } else if (!strncmp(L,"SIGUIJ",6)) {
+
+ index = nAtoms; // keep index
+ RC = CheckAtomPlace ( index,L );
+ if (!RC) RC = atom[index-1]->ConvertPDBSIGUIJ ( index,L );
+
+ } else if (!strncmp(L,"TER ",6)) {
+
+ index = nAtoms+1; // new place in Atom array
+ RC = CheckAtomPlace ( index,L );
+ if (!RC) RC = atom[index-1]->ConvertPDBTER ( index,L );
+
+ } else if (!strncmp(L,"HETATM",6)) {
+
+ index = nAtoms+1; // new place in Atom array
+ RC = CheckAtomPlace ( index,L );
+ if (!RC) RC = atom[index-1]->ConvertPDBHETATM ( index,L );
+
+ } else if (!strncmp(L,"MODEL ",6)) {
+
+ modelCnt++;
+ RC = SwitchModel ( L );
+ for (i=0;(i<nModels) && (!RC);i++)
+ if (model[i] && (model[i]!=crModel)) {
+ if (crModel->serNum==model[i]->serNum)
+ RC = Error_DuplicatedModel;
+ }
+ // if (!RC) {
+ // if (crModel->serNum!=modelCnt)
+ // RC = Error_DuplicatedModel;
+ // }
+
+ } else if (!strncmp(L,"ENDMDL",6)) {
+
+ crModel = NULL;
+ crChain = NULL;
+ crRes = NULL;
+
+ RC = Error_NoError;
+
+ } else
+ return Error_WrongSection;
+
+ return RC;
+
+ }
+
+
+ ERROR_CODE Root::ReadCIFAtom ( mmcif::PData CIFD ) {
+ mmcif::PLoop Loop,LoopAnis;
+ int i,index,nATS;
+ ERROR_CODE RC;
+
+ Loop = CIFD->GetLoop ( CIFCAT_ATOM_SITE );
+ if (!Loop) return Error_NoError; // no atom coordinates in the file
+
+ LoopAnis = CIFD->GetLoop ( CIFCAT_ATOM_SITE_ANISOTROP );
+ nATS = Loop->GetLoopLength();
+
+ for (i=1;i<=nATS;i++) {
+ // nAtoms and i should always coincide at this point. This piece
+ // of code was however left in order to reach identity with
+ // ReadPDBAtom(..).
+ index = nAtoms+1; // index for the next atom in Atom array
+ RC = CheckAtomPlace ( index,Loop );
+ if (!RC) RC = atom[index-1]->GetCIF ( i,Loop,LoopAnis );
+ if (RC && (RC!=Error_CIF_EmptyRow)) return RC;
+ }
+ if (Flags & MMDBF_AutoSerials)
+ PDBCleanup ( PDBCLEAN_SERIAL );
+
+ return Error_NoError;
+
+ }
+
+ int Root::PutAtom ( int index,
+ int serNum,
+ const AtomName atomName,
+ const ResName resName,
+ const ChainID chainID,
+ int seqNum,
+ const InsCode insCode,
+ const AltLoc altLoc,
+ const SegID segID,
+ const Element element ) {
+
+ // An atom with the specified properties is put into the
+ // structure. The current model is used; if no model is
+ // set (crModel==NULL), one is created. Coordinates and
+ // other parameters of the atom need to be set separately.
+ //
+ // If index is positive and there is already an atom at
+ // this position in the system, the new atom will REPLACE
+ // it. The corresponding residues are automatically
+ // updated.
+ //
+ // If index is null (=0), the new atom will be put on
+ // the top of the structure, i.e. it will be put into
+ // (index=nAtoms+1)-th position.
+ //
+ // If index is negative, then the new atom is INSERTED
+ // BEFORE the atom in the (-index)th position. For
+ // saving the computational efforts, this WILL NOT cause
+ // the recalculation of all atoms' serial numbers
+ // according to their actual positions. It will be needed
+ // however to put the things in order by calling
+ // Root::OrderAtoms() at a certain point, especially
+ // before writing an output ASCII file. NOTE that this
+ // ordering is never done automatically.
+ //
+ // Limitation: if PutAtom implies creating new
+ // chains/residues, these are always created on the top
+ // of existing chains/residues.
+
+
+ int i,kndex,RC;
+
+ kndex = index;
+
+ if (kndex<0) { // the new atom is to be inserted
+
+ kndex = -kndex;
+ if (kndex>atmLen)
+ ExpandAtomArray ( kndex+1000-atmLen );
+
+ if (atom[kndex-1]!=NULL) { // the position is occupied
+
+ // expand the array if necessary
+ if (nAtoms>=atmLen)
+ ExpandAtomArray ( IMax(kndex,nAtoms)+1000-atmLen );
+
+ // now shift all atoms from (kndex-1)th to the end of array.
+ // note that this does not affect residues as they keep only
+ // pointers on atoms
+ for (i=nAtoms;i>=kndex;i--) {
+ atom[i] = atom[i-1];
+ atom[i]->index = i+1; // this is Ok because residues keep
+ // POINTERS rather than indices!
+ }
+ atom[kndex-1] = NULL;
+ nAtoms++;
+
+ }
+
+ }
+
+ if (kndex==0) kndex = nAtoms+1;
+
+ if (!crModel) SwitchModel ( 1 );
+
+
+ RC = AllocateAtom ( kndex,chainID,chainID,resName,resName,
+ seqNum,seqNum,1,insCode,true );
+ if (!RC)
+ atom[kndex-1]->SetAtomName ( kndex,serNum,atomName,altLoc,
+ segID,element );
+ return RC;
+
+ }
+
+
+ int Root::PutAtom ( int index, // same meaning as above
+ PAtom A, // pointer to completed atom
+ // class
+ int serNum // 0 means that the serial
+ // number will be set equal
+ // to "index". Otherwise,
+ // the serial number is set
+ // to the specified value
+ ) {
+ int i,kndex,RC,sn;
+
+ if (!A) return -1;
+
+ kndex = index;
+
+ if (kndex<0) { // the new atom is to be inserted
+
+ kndex = -kndex;
+
+ if (kndex>atmLen)
+ ExpandAtomArray ( kndex+1000-atmLen );
+
+ if (atom[kndex-1]!=NULL) { // the position is occupied
+
+ // expand the array if necessary
+ if (nAtoms>=atmLen)
+ ExpandAtomArray ( IMax(kndex,nAtoms)+1000-atmLen );
+ // now shift all atoms from (kndex-1)th to the end of array.
+ // note that this does not affect residues as they keep only
+ // pointers on atoms
+
+ for (i=nAtoms;i>=kndex;i--) {
+ atom[i] = atom[i-1];
+ atom[i]->index = i+1; // this is Ok because residues keep
+ // POINTERS rather than indices!
+ }
+
+ atom[kndex-1] = NULL;
+ nAtoms++;
+
+ }
+
+ }
+
+ if (kndex==0) kndex = nAtoms+1;
+
+
+ RC = AllocateAtom ( kndex,A->GetChainID(),A->GetLabelAsymID(),
+ A->GetResName(),A->GetLabelCompID(),
+ A->GetSeqNum (),A->GetLabelSeqID (),
+ A->GetLabelEntityID(),A->GetInsCode(),
+ true );
+
+ if (serNum<=0) sn = kndex;
+ else sn = serNum;
+ if (!RC) {
+ atom[kndex-1]->Copy ( A );
+ atom[kndex-1]->serNum = sn;
+ }
+
+ return RC;
+
+ }
+
+ int Root::CheckInAtom ( int index, // same meaning as above
+ PAtom A // pointer to completed
+ // atom class
+ ) {
+ int i,kndex;
+
+ if (!A) return -1;
+
+ kndex = index;
+
+ if (kndex<0) { // the new atom is to be inserted
+
+ kndex = -kndex;
+
+ if (kndex>atmLen)
+ ExpandAtomArray ( kndex+1000-atmLen );
+
+ if (atom[kndex-1]!=NULL) { // the position is occupied
+
+ // expand the array if necessary
+ if (nAtoms>=atmLen)
+ ExpandAtomArray ( IMax(kndex,nAtoms)+1000-atmLen );
+ // now shift all atoms from (kndex-1)th to the end of array.
+ // note that this does not affect residues as they keep only
+ // pointers on atoms
+
+ for (i=nAtoms;i>=kndex;i--) {
+ atom[i] = atom[i-1];
+ if (atom[i])
+ atom[i]->index = i+1; // this is Ok because residues keep
+ // POINTERS rather than indices!
+ }
+
+ }
+
+ nAtoms++;
+
+ } else {
+ if (kndex==0) kndex = nAtoms + 1; // add atom on the very top
+ if (kndex>atmLen) ExpandAtomArray ( kndex+1000-atmLen );
+ if (kndex>nAtoms) nAtoms = kndex;
+ if (atom[kndex-1]) delete atom[kndex-1];
+ }
+
+ atom[kndex-1] = A;
+ A->index = kndex;
+
+ return 0;
+
+ }
+
+ int Root::CheckInAtoms ( int index, // same meaning as above
+ PPAtom A, // array of atoms to check in
+ int natms // number of atoms to check in
+ ) {
+ PPAtom A1;
+ int i,j,k,k1,kndex;
+
+ if (!A) return -1;
+
+ A1 = NULL;
+ kndex = index;
+
+ if (kndex<0) { // the new atoms are to be inserted
+
+ kndex = -kndex;
+
+ if (nAtoms+natms>=atmLen)
+ ExpandAtomArray ( IMax(kndex,nAtoms)+1000+natms-atmLen );
+
+ if (kndex<nAtoms)
+ A1 = new PAtom[natms];
+ k = kndex-1;
+ j = 0;
+ for (i=0;i<natms;i++)
+ if (A[i]) {
+ if (atom[k]) A1[j++] = atom[k];
+ atom[k] = A[i];
+ atom[k]->index = k+1;
+ k++;
+ }
+
+ if (j>0) {
+ // insert removed atoms into the gap
+ nAtoms += j;
+ k1 = k+j;
+ for (i=nAtoms-1;i>=k1;i--) {
+ atom[i] = atom[i-j];
+ if (atom[i])
+ atom[i]->index = i+1; // this is Ok because residues keep
+ // POINTERS rather than indices!
+ }
+ for (i=0;i<j;i++) {
+ atom[k] = A1[i];
+ atom[k]->index = k+1;
+ k++;
+ }
+ }
+
+ delete[] A1;
+
+ } else {
+
+ if (kndex==0) kndex = nAtoms + 1; // add atom on the very top
+ k = kndex + natms;
+ if (k>atmLen) ExpandAtomArray ( k+1000-atmLen );
+ kndex--;
+ for (i=0;i<natms;i++)
+ if (A[i]) {
+ if (atom[kndex]) delete atom[kndex];
+ atom[kndex] = A[i];
+ atom[kndex]->index = kndex+1;
+ kndex++;
+ }
+ nAtoms = IMax(nAtoms,kndex);
+
+ }
+
+ return 0;
+
+ }
+
+
+ ERROR_CODE Root::SwitchModel ( cpstr L ) {
+ int nM;
+
+ if (!GetInteger(nM,&(L[10]),4))
+ return Error_UnrecognizedInteger;
+
+ return SwitchModel ( nM );
+
+ }
+
+ ERROR_CODE Root::SwitchModel ( int nM ) {
+ PPModel Mdl;
+ int i;
+ bool Transfer;
+
+ if (nM<=0)
+ return Error_WrongModelNo;
+
+ if (nM>nModels) {
+ if ((nModels==1) && model[0]) Transfer = (nAtoms<=0);
+ else Transfer = false;
+ Mdl = new PModel[nM];
+ for (i=0;i<nModels;i++)
+ Mdl[i] = model[i];
+ for (i=nModels;i<nM;i++)
+ Mdl[i] = NULL;
+ if (model) delete[] model;
+ model = Mdl;
+ nModels = nM;
+ if (Transfer) {
+ model[nM-1] = model[0];
+ model[0] = NULL;
+ }
+ }
+
+ if (!model[nM-1])
+ model[nM-1] = newModel();
+ model[nM-1]->SetMMDBManager ( PManager(this),nM );
+
+ crModel = model[nM-1];
+ crChain = NULL; // new model - new chain
+ crRes = NULL; // new chain - new residue
+
+ return Error_NoError;
+
+ }
+
+ ERROR_CODE Root::CheckAtomPlace ( int index, cpstr L ) {
+ // This function gets the residue/chain information stored
+ // in PDB string L (the records should start with the
+ // keywords ATOM, SIGATM, ANISOU, SIGUIJ, TER, HETATM) and
+ // sets the pointers crChain and crRes to the respective.
+ // chain and residue. If there is no chain/residue to place
+ // the atom in, these will be created.
+ // The function prepares place for the atom in the index-th
+ // cell of the Atom array, expanding it as necessary. If the
+ // corresponding element in the Atom array was not initialized,
+ // a Atom class is created with reference to the current
+ // residue.
+ // This function DOES NOT check the PDB string L for
+ // atom keywords.
+ ResName resName;
+ int seqNum;
+ ChainID chainID;
+ InsCode insCode;
+
+ // get the residue sequence number/ insert code
+ if (!GetIntIns(seqNum,insCode,&(L[22]),4)) {
+ if (strncmp(L,"TER ",6))
+ return Error_UnrecognizedInteger;
+ else { // we allow for empty TER card here
+ seqNum = 0;
+ insCode[0] = char(1); // unprintable symbol! used as
+ // flag that TER card does not
+ // have serial number
+ insCode[1] = char(0);
+ }
+ }
+
+ // get chain ID
+ if (L[20]!=' ') {
+ chainID[0] = L[20];
+ chainID[1] = L[21];
+ chainID[2] = char(0);
+ } else if (L[21]!=' ') {
+ chainID[0] = L[21];
+ chainID[1] = char(0);
+ } else
+ chainID[0] = char(0);
+
+ // get residue name
+ strcpy_ncss ( resName,&(L[17]),3 );
+ if ((!resName[0]) && (!strncmp(L,"TER ",6))) {
+ insCode[0] = char(1);
+ insCode[1] = char(0);
+ }
+
+ return AllocateAtom ( index ,chainID,chainID,resName,resName,
+ seqNum,seqNum,1,insCode,false );
+
+ }
+
+ ERROR_CODE Root::CheckAtomPlace ( int index, mmcif::PLoop Loop ) {
+ // Version of CheckAtomPlace(..) for reading from CIF file.
+ ResName resName,label_comp_id;
+ int seqNum ,label_seq_id,label_entity_id,RC,k,nM;
+ ChainID chainID,label_asym_id;
+ InsCode insCode;
+ pstr F;
+
+ // Get the residue sequence number/insert code. They are
+ // removed from the file after reading.
+ k = index-1;
+ // if (!CIFGetInteger1(seqNum,Loop,CIFTAG_LABEL_SEQ_ID,k))
+ if (!CIFGetInteger1(seqNum,Loop,CIFTAG_AUTH_SEQ_ID,k))
+ CIFGetString ( insCode,Loop,CIFTAG_NDB_HELIX_CLASS_PDB,k,
+ sizeof(InsCode),pstr("") );
+ else {
+ F = Loop->GetString ( CIFTAG_GROUP_PDB,k,RC );
+ if ((!F) || (RC)) return Error_CIF_EmptyRow;
+ if (strcmp(F,"TER")) {
+ seqNum = MinInt4; // only at reading CIF we allow this
+ CIFGetString ( insCode,Loop,CIFTAG_NDB_HELIX_CLASS_PDB,k,
+ sizeof(InsCode),pstr("") );
+ } else { // we allow for empty TER card here
+ seqNum = 0;
+ insCode[0] = char(1); // unprintable symbol! used as
+ // flag that TER card does not
+ // have serial number
+ insCode[1] = char(0);
+ }
+ }
+
+ CIFGetInteger1 ( label_seq_id ,Loop,CIFTAG_LABEL_SEQ_ID ,k );
+ CIFGetInteger1 ( label_entity_id,Loop,CIFTAG_LABEL_ENTITY_ID,k );
+
+ // get chain/residue ID
+ CIFGetString ( chainID,Loop,CIFTAG_AUTH_ASYM_ID,k,
+ sizeof(ChainID),pstr("") );
+ CIFGetString ( resName,Loop,CIFTAG_AUTH_COMP_ID,k,
+ sizeof(ResName),pstr("") );
+
+ CIFGetString ( label_asym_id,Loop,CIFTAG_LABEL_ASYM_ID,k,
+ sizeof(ChainID),pstr("") );
+ CIFGetString ( label_comp_id,Loop,CIFTAG_LABEL_COMP_ID,k,
+ sizeof(ResName),pstr("") );
+
+ if (!resName[0]) strcpy ( resName,label_comp_id );
+
+ if (!CIFGetInteger1(nM,Loop,CIFTAG_PDBX_PDB_MODEL_NUM,k)) {
+ if (crModel) {
+ if (nM!=crModel->serNum) SwitchModel ( nM );
+ } else
+ SwitchModel ( nM );
+ }
+
+ return AllocateAtom ( index ,chainID,label_asym_id,resName,
+ label_comp_id,seqNum,label_seq_id,
+ label_entity_id,insCode,false );
+
+ }
+
+
+ ERROR_CODE Root::AllocateAtom ( int index,
+ const ChainID chainID,
+ const ChainID label_asym_id,
+ const ResName resName,
+ const ResName label_comp_id,
+ int seqNum,
+ int label_seq_id,
+ int label_entity_id,
+ const InsCode insCode,
+ bool Replace ) {
+
+ if ((!resName[0]) && (insCode[0]!=char(1)))
+ return Error_EmptyResidueName;
+
+ // check if there is a pointer to model
+ if (!crModel) {
+ // the model pointer was not set. Check if there are
+ // models already defined
+ if (!model)
+ SwitchModel ( 1 ); // creates a model
+ else return Error_NoModel;
+ }
+
+ if (crChain && (insCode[0]!=char(1))) {
+ // If crChain is not NULL, the model pointer was not
+ // changed and we may try to keep using crChain as
+ // pointer to the being-read chain. However, we must
+ // check that the record still belongs to the same chain.
+ // All this does not work if insCode[0] is set to 1
+ // which indicates a special case of 'TER' card without
+ // parameters.
+ if (enforceUniqueChID) {
+ // enforcing unique chain IDs should be used only in case
+ // of multi-chain complexes where 1-letter chain IDs are
+ // not enough to accomodate all chains. Then chains are
+ // dynamically renamed like A0,A1,A2,.. etc. Therefore, we
+ // check only first symbol here.
+ if (chainID[0]!=crChain->chainID[0])
+ crChain = NULL; // the chain has to be changed
+ } else if (strcmp(chainID,crChain->chainID))
+ crChain = NULL; // the chain has to be changed
+ }
+ if (!crChain) {
+ // either the model or chain was changed -- get a new chain
+ if (allowDuplChID)
+ crChain = crModel->CreateChain ( chainID );
+ else crChain = crModel->GetChainCreate ( chainID,
+ enforceUniqueChID );
+ crRes = NULL; // new chain - new residue
+ }
+
+ if (crRes && (insCode[0]!=char(1))) {
+ // If crRes is not NULL, neither the model nor chain were
+ // changed. Check if this record still belongs to the
+ // same residue.
+ // All this does not work if insCode[0] is set to 1
+ // which indicates a special case of 'TER' card without
+ // parameters.
+ if ((seqNum!=crRes->seqNum) ||
+ strcmp(insCode,crRes->insCode) ||
+ strcmp(resName,crRes->name))
+ crRes = NULL; // the residue has to be changed
+ }
+ if (!crRes) {
+ // either the chain or residue was changed -- get a new residue
+ crRes = crChain->GetResidueCreate ( resName,seqNum,insCode,
+ Flags & MMDBF_IgnoreDuplSeqNum );
+ if (!crRes) return Error_DuplicateSeqNum;
+ }
+
+ strcpy ( crRes->label_asym_id,label_asym_id );
+ strcpy ( crRes->label_comp_id,label_comp_id );
+ crRes->label_seq_id = label_seq_id;
+ crRes->label_entity_id = label_entity_id;
+
+ // now check if there is place in the Atom array
+ if (index>atmLen)
+ // there is no place, expand Atom by 1000 atom places at once
+ ExpandAtomArray ( index+1000-atmLen );
+ nAtoms = IMax(nAtoms,index);
+
+ // delete the to-be-replaced atom if there is any
+ if (Replace && atom[index-1]) {
+ delete atom[index-1];
+ atom[index-1] = NULL;
+ }
+ if (!atom[index-1]) {
+ atom[index-1] = newAtom();
+ crRes->_AddAtom ( atom[index-1] );
+ atom[index-1]->index = index;
+ }
+
+ return Error_NoError;
+
+ }
+
+ void Root::ExpandAtomArray ( int inc ) {
+ // Expands the Atom array by adding more inc positions.
+ // The length of Atom array is increased unconditionally.
+ PPAtom Atom1;
+ int i;
+ atmLen += inc;
+ Atom1 = new PAtom[atmLen];
+ for (i=0;i<nAtoms;i++)
+ Atom1[i] = atom[i];
+ for (i=nAtoms;i<atmLen;i++)
+ Atom1[i] = NULL;
+ if (atom) delete[] atom;
+ atom = Atom1;
+ }
+
+ void Root::AddAtomArray ( int inc ) {
+ // Checks if 'inc' atoms may be added into Atom array,
+ // and if not, expands the Atom array such that to
+ // allocate exactly 'inc' atoms more than is currently
+ // contained.
+ PPAtom Atom1;
+ int i;
+ if (nAtoms+inc>atmLen) {
+ atmLen = nAtoms+inc;
+ Atom1 = new PAtom[atmLen];
+ for (i=0;i<nAtoms;i++)
+ Atom1[i] = atom[i];
+ for (i=nAtoms;i<atmLen;i++)
+ Atom1[i] = NULL;
+ if (atom) delete[] atom;
+ atom = Atom1;
+ }
+ }
+
+
+ ERROR_CODE Root::WritePDBASCII1 ( cpstr PDBLFName,
+ io::GZ_MODE gzipMode ) {
+ pstr FName;
+ FName = getenv ( PDBLFName );
+ if (FName) return WritePDBASCII ( FName,gzipMode );
+ else return Error_NoLogicalName;
+ }
+
+ ERROR_CODE Root::WritePDBASCII ( cpstr PDBFileName,
+ io::GZ_MODE gzipMode ) {
+ io::File f;
+
+ // opening it in pseudo-text mode ensures that the line
+ // endings will correspond to the system MMDB is running on
+ f.assign ( PDBFileName,true,false,gzipMode );
+ FType = MMDB_FILE_PDB;
+
+ if (f.rewrite()) {
+ WritePDBASCII ( f );
+ f.shut();
+ } else
+ return Error_CantOpenFile;
+
+ return Error_NoError;
+
+ }
+
+
+ void Root::WritePDBASCII ( io::RFile f ) {
+ int i;
+
+ FType = MMDB_FILE_PDB;
+
+ title.PDBASCIIDump ( f );
+
+ i = 0;
+ while (i<nModels)
+ if (model[i]) break;
+ else i++;
+ if (i<nModels)
+ model[i]->PDBASCIIDumpPS ( f );
+
+ // output cispep records
+ for (i=0;i<nModels;i++)
+ if (model[i])
+ model[i]->PDBASCIIDumpCP ( f );
+
+ SA .PDBASCIIDump ( f );
+ Footnote.PDBASCIIDump ( f );
+ cryst .PDBASCIIDump ( f );
+ SB .PDBASCIIDump ( f );
+
+ for (i=0;i<nModels;i++)
+ if (model[i])
+ model[i]->PDBASCIIDump ( f );
+
+ SC.PDBASCIIDump ( f );
+
+ f.WriteLine ( pstr("END") );
+
+ }
+
+
+ ERROR_CODE Root::WriteCIFASCII1 ( cpstr CIFLFName,
+ io::GZ_MODE gzipMode ) {
+ pstr FName;
+ FName = getenv ( CIFLFName );
+ if (FName) return WriteCIFASCII ( FName,gzipMode );
+ else return Error_NoLogicalName;
+ }
+
+ ERROR_CODE Root::WriteCIFASCII ( cpstr CIFFileName,
+ io::GZ_MODE gzipMode ) {
+ int i;
+
+ if (!CIF) CIF = new mmcif::Data();
+ CIF->SetStopOnWarning ( true );
+ CIF->SetPrintWarnings ( (Flags & MMDBF_PrintCIFWarnings)!=0 );
+ FType = MMDB_FILE_CIF;
+
+ title.MakeCIF ( CIF );
+
+ i = 0;
+ while (i<nModels)
+ if (model[i]) break;
+ else i++;
+ if (i<nModels)
+ model[i]->MakePSCIF ( CIF );
+
+ cryst.MakeCIF ( CIF );
+
+ for (i=0;i<nModels;i++)
+ if (model[i])
+ model[i]->MakeAtomCIF ( CIF );
+
+ CIF->Optimize();
+ CIF->WriteMMCIFData ( CIFFileName,gzipMode );
+
+ return Error_NoError;
+
+ }
+
+
+ PAtom Root::GetAtomI ( int index ) {
+ if (index>nAtoms) return NULL;
+ if (index<1) return NULL;
+ if (!atom) return NULL;
+ return atom[index-1];
+ }
+
+
+ #define MMDBFLabel "**** This is MMDB binary file ****"
+ #define Edition 1
+
+ ERROR_CODE Root::ReadMMDBF1 ( cpstr MMDBLFName,
+ io::GZ_MODE gzipMode ) {
+ pstr FName;
+ FName = getenv ( MMDBLFName );
+ if (FName) return ReadCoorFile ( FName,gzipMode );
+ else return Error_NoLogicalName;
+ }
+
+ ERROR_CODE Root::ReadMMDBF ( cpstr MMDBRootName,
+ io::GZ_MODE gzipMode ) {
+ io::File f;
+ ERROR_CODE rc;
+
+ f.assign ( MMDBRootName,false,true,gzipMode );
+ FType = MMDB_FILE_Binary;
+ if (f.reset(true)) {
+ rc = ReadMMDBF ( f );
+ f.shut();
+ } else
+ rc = Error_CantOpenFile;
+
+ return rc;
+
+ }
+
+ ERROR_CODE Root::ReadMMDBF ( io::RFile f ) {
+ char Label[100];
+ byte Version;
+
+ FType = MMDB_FILE_Binary;
+ f.ReadFile ( Label,sizeof(MMDBFLabel) );
+ if (strncmp(Label,MMDBFLabel,sizeof(MMDBFLabel)))
+ return Error_ForeignFile;
+
+ f.ReadByte ( &Version );
+ if (Version>Edition)
+ return Error_WrongEdition;
+
+ read ( f );
+
+ return Error_NoError;
+
+ }
+
+
+ ERROR_CODE Root::WriteMMDBF1 ( cpstr MMDBLFName, io::GZ_MODE gzipMode ) {
+ pstr FName;
+ FName = getenv ( MMDBLFName );
+ if (FName) return WriteMMDBF ( FName,gzipMode );
+ else return Error_NoLogicalName;
+ }
+
+ ERROR_CODE Root::WriteMMDBF ( cpstr MMDBRootName, io::GZ_MODE gzipMode ) {
+ io::File f;
+ char Label[100];
+ byte Version=Edition;
+
+ f.assign ( MMDBRootName,false,true,gzipMode );
+ FType = MMDB_FILE_Binary;
+ if (f.rewrite()) {
+ strcpy ( Label,MMDBFLabel );
+ f.WriteFile ( Label,sizeof(MMDBFLabel) );
+ f.WriteByte ( &Version );
+ write ( f );
+ f.shut();
+ } else
+ return Error_CantOpenFile;
+
+ return Error_NoError;
+
+ }
+
+
+ pstr Root::GetEntryID() {
+ return title.idCode;
+ }
+
+ void Root::SetEntryID ( const IDCode idCode ) {
+ strcpy ( title.idCode,idCode );
+ }
+
+ void Root::SetSyminfoLib ( cpstr syminfo_lib ) {
+ cryst.SetSyminfoLib ( syminfo_lib );
+ }
+
+ pstr Root::GetSyminfoLib() {
+ return cryst.GetSyminfoLib();
+ }
+
+ int Root::SetSpaceGroup ( cpstr spGroup ) {
+ return cryst.SetSpaceGroup ( spGroup );
+ }
+
+ pstr Root::GetSpaceGroup() {
+ return cryst.GetSpaceGroup();
+ }
+
+ pstr Root::GetSpaceGroupFix() {
+ return cryst.GetSpaceGroupFix();
+ }
+
+ void Root::GetAtomStatistics ( RAtomStat AS ) {
+ int i;
+ AS.Init();
+ for (i=0;i<nModels;i++)
+ if (model[i]) model[i]->CalAtomStatistics ( AS );
+ AS.Finish();
+ }
+
+ void Root::SetIgnoreSCALEi ( bool ignoreScalei ) {
+ cryst.ignoreScalei = ignoreScalei;
+ }
+
+ void Root::SetCell ( realtype cell_a,
+ realtype cell_b,
+ realtype cell_c,
+ realtype cell_alpha,
+ realtype cell_beta,
+ realtype cell_gamma,
+ int OrthCode ) {
+ cryst.SetCell ( cell_a,cell_b,cell_c,cell_alpha,cell_beta,
+ cell_gamma,OrthCode );
+ }
+
+ void Root::PutCell ( realtype cell_a,
+ realtype cell_b,
+ realtype cell_c,
+ realtype cell_alpha,
+ realtype cell_beta,
+ realtype cell_gamma,
+ int OrthCode ) {
+ cryst.PutCell ( cell_a,cell_b,cell_c,cell_alpha,cell_beta,
+ cell_gamma,OrthCode );
+ }
+
+ int Root::GetCell ( realtype & cell_a,
+ realtype & cell_b,
+ realtype & cell_c,
+ realtype & cell_alpha,
+ realtype & cell_beta,
+ realtype & cell_gamma,
+ realtype & vol,
+ int & OrthCode ) {
+ if (cryst.WhatIsSet & CSET_CellParams) {
+ cryst.GetCell ( cell_a,cell_b,cell_c,cell_alpha,cell_beta,
+ cell_gamma,vol );
+ OrthCode = cryst.NCode + 1;
+ return 1;
+ } else {
+ cell_a = 0.0; cell_b = 0.0; cell_c = 0.0;
+ cell_alpha = 0.0; cell_beta = 0.0; cell_gamma = 0.0;
+ vol = 0.0; OrthCode = 0;
+ return 0;
+ }
+ }
+
+ int Root::GetRCell ( realtype & cell_as,
+ realtype & cell_bs,
+ realtype & cell_cs,
+ realtype & cell_alphas,
+ realtype & cell_betas,
+ realtype & cell_gammas,
+ realtype & vols,
+ int & OrthCode ) {
+ if (cryst.WhatIsSet & CSET_CellParams) {
+ cryst.GetRCell ( cell_as,cell_bs,cell_cs,cell_alphas,cell_betas,
+ cell_gammas,vols );
+ OrthCode = cryst.NCode + 1;
+ return 1;
+ } else {
+ cell_as = 0.0; cell_bs = 0.0; cell_cs = 0.0;
+ cell_alphas = 0.0; cell_betas = 0.0; cell_gammas = 0.0;
+ vols = 0.0; OrthCode = 0;
+ return 0;
+ }
+ }
+
+ int Root::GetNumberOfSymOps() {
+ if (cryst.WhatIsSet & CSET_SpaceGroup)
+ return cryst.GetNumberOfSymOps();
+ else return 0;
+ }
+
+ pstr Root::GetSymOp ( int Nop ) {
+ return cryst.GetSymOp ( Nop );
+ }
+
+
+ void Root::GetROMatrix ( mat44 & RO ) {
+ Mat4Copy ( cryst.RO,RO );
+ }
+
+ int Root::GetTMatrix ( mat44 & TMatrix, int Nop,
+ int cellshift_a, int cellshift_b,
+ int cellshift_c ) {
+ // GetTMatrix(..) calculates and returns the coordinate transformation
+ // matrix, which converts orthogonal coordinates according to
+ // the symmetry operation number Nop and places them into unit cell
+ // shifted by cellshift_a a's, cellshift_b b's and cellshift_c c's.
+ //
+ // Return 0 means everything's fine,
+ // 1 there's no symmetry operation Nop defined
+ // 2 fractionalizing/orthogonalizing matrices were not
+ // calculated
+ // 3 cell parameters were not set up.
+ return cryst.GetTMatrix ( TMatrix,Nop,cellshift_a,cellshift_b,
+ cellshift_c,NULL );
+ }
+
+
+ int Root::GetUCTMatrix ( mat44 & TMatrix, int Nop,
+ realtype x, realtype y, realtype z,
+ int cellshift_a, int cellshift_b,
+ int cellshift_c ) {
+ // GetUCTMatrix(..) calculates and returns the coordinate
+ // transformation matrix, which converts orthogonal coordinates
+ // according to the symmetry operation number Nop. Translation
+ // part of the resulting matrix is being chosen such that point
+ // (x,y,z) has least distance to the center of primary (333)
+ // unit cell, and then it is shifted by cellshift_a a's,
+ // cellshift_b b's and cellshift_c c's.
+ //
+ // Return 0 means everything's fine,
+ // 1 there's no symmetry operation Nop defined
+ // 2 fractionalizing/orthogonalizing matrices were not
+ // calculated
+ // 3 cell parameters were not set up.
+ return cryst.GetUCTMatrix ( TMatrix,Nop,x,y,z,
+ cellshift_a,cellshift_b,cellshift_c,
+ NULL );
+ }
+
+
+ int Root::GetFractMatrix ( mat44 & TMatrix, int Nop,
+ int cellshift_a, int cellshift_b,
+ int cellshift_c ) {
+ // GetFractMatrix(..) calculates and returns the coordinate
+ // transformation matrix, which converts fractional coordinates
+ // according to the symmetry operation number Nop and places them
+ // into unit cell shifted by cellshift_a a's, cellshift_b b's and
+ // cellshift_c c's.
+ //
+ // Return 0 means everything's fine,
+ // 1 there's no symmetry operation Nop defined
+ // 2 fractionalizing/orthogonalizing matrices were not
+ // calculated
+ // 3 cell parameters were not set up.
+ return cryst.GetFractMatrix ( TMatrix,Nop,cellshift_a,cellshift_b,
+ cellshift_c,NULL );
+ }
+
+ int Root::GetSymOpMatrix ( mat44 & TMatrix, int Nop ) {
+ //
+ // GetSymOpMatrix(..) returns the transformation matrix for
+ // Nop-th symmetry operator in the space group
+ //
+ // Return 0 means everything's fine,
+ // 1 there's no symmetry operation Nop defined
+ // 2 fractionalizing/orthogonalizing matrices were not
+ // calculated
+ // 3 cell parameters were not set up.
+ //
+ return cryst.GetSymOpMatrix ( TMatrix,Nop );
+ }
+
+ // ------------- User-Defined Data ------------------------
+
+ int Root::RegisterUDInteger ( UDR_TYPE udr_type, cpstr UDDataID ) {
+ return udRegister.RegisterUDInteger ( udr_type,UDDataID );
+ }
+
+ int Root::RegisterUDReal ( UDR_TYPE udr_type, cpstr UDDataID ) {
+ return udRegister.RegisterUDReal ( udr_type,UDDataID );
+ }
+
+ int Root::RegisterUDString ( UDR_TYPE udr_type, cpstr UDDataID ) {
+ return udRegister.RegisterUDString ( udr_type,UDDataID );
+ }
+
+ int Root::GetUDDHandle ( UDR_TYPE udr_type, cpstr UDDataID ) {
+ return udRegister.GetUDDHandle ( udr_type,UDDataID );
+ }
+
+
+
+ // ----------------------------------------------------------
+
+ int Root::DeleteAllModels() {
+ int i,k;
+ Exclude = false;
+ k = 0;
+ for (i=0;i<nModels;i++) {
+ if (model[i]) {
+ delete model[i];
+ model[i] = NULL;
+ k++;
+ }
+ }
+ Exclude = true;
+ FinishStructEdit();
+ return k;
+ }
+
+ bool Root::GetNewChainID ( int modelNo, ChainID chID,
+ int length ) {
+ if ((modelNo>=1) && (modelNo<=nModels)) {
+ if (model[modelNo-1])
+ return model[modelNo-1]->GetNewChainID ( chID,length );
+ }
+ return false;
+ }
+
+ // -------------------------------------------------------------
+
+ PMask Root::GetSelMask ( int selHnd ) {
+ UNUSED_ARGUMENT(selHnd);
+ return NULL;
+ }
+
+ // -------------------------------------------------------------
+
+ int Root::GetNofExpDataRecs() {
+ return title.expData.Length();
+ }
+
+ pstr Root::GetExpDataRec ( int recNo ) {
+ PExpData expData;
+ expData = PExpData(title.expData.GetContainerClass(recNo));
+ if (expData) return expData->Line;
+ return NULL;
+ }
+
+
+ // -------------------------------------------------------------
+
+ int Root::GetNofMdlTypeRecs() {
+ return title.mdlType.Length();
+ }
+
+ pstr Root::GetMdlTypeRec ( int recNo ) {
+ PMdlType mdlType;
+ mdlType = PMdlType(title.mdlType.GetContainerClass(recNo));
+ if (mdlType) return mdlType->Line;
+ return NULL;
+ }
+
+
+ // ------------------- Stream functions ----------------------
+
+ void Root::Copy ( PRoot MMDBRoot ) {
+ int i;
+
+ title.Copy ( &MMDBRoot->title );
+ cryst.Copy ( &MMDBRoot->cryst );
+
+ // It is important to copy atoms _before_ models,
+ // residues and chains!
+ Flags = MMDBRoot->Flags;
+ nAtoms = MMDBRoot->nAtoms;
+ atmLen = nAtoms;
+ if (nAtoms>0) {
+ atom = new PAtom[atmLen];
+ for (i=0;i<nAtoms;i++)
+ if (MMDBRoot->atom[i]) {
+ atom[i] = newAtom();
+ atom[i]->Copy ( MMDBRoot->atom[i] );
+ atom[i]->index = i+1;
+ // the internal atom references are installed
+ // by residue classes when they are copied in
+ // model->chain below
+ } else
+ atom[i] = NULL;
+ }
+
+ nModels = MMDBRoot->nModels;
+ if (nModels>0) {
+ model = new PModel[nModels];
+ for (i=0;i<nModels;i++) {
+ if (MMDBRoot->model[i]) {
+ model[i] = newModel();
+ model[i]->SetMMDBManager ( PManager(this),i+1 );
+ model[i]->_copy ( MMDBRoot->model[i] );
+ } else
+ model[i] = NULL;
+ }
+ }
+
+ SA .Copy ( &MMDBRoot->SA );
+ Footnote.Copy ( &MMDBRoot->Footnote );
+ SB .Copy ( &MMDBRoot->SB );
+ SC .Copy ( &MMDBRoot->SC );
+
+ if (MMDBRoot->CIF) {
+ CIF = new mmcif::Data;
+ CIF->Copy ( MMDBRoot->CIF );
+ }
+
+ }
+
+
+
+ // ------- user-defined data handlers
+
+ int Root::PutUDData ( int UDDhandle, int iudd ) {
+ if (UDDhandle & UDRF_HIERARCHY)
+ return UDData::putUDData ( UDDhandle,iudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Root::PutUDData ( int UDDhandle, realtype rudd ) {
+ if (UDDhandle & UDRF_HIERARCHY)
+ return UDData::putUDData ( UDDhandle,rudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Root::PutUDData ( int UDDhandle, cpstr sudd ) {
+ if (UDDhandle & UDRF_HIERARCHY)
+ return UDData::putUDData ( UDDhandle,sudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Root::GetUDData ( int UDDhandle, int & iudd ) {
+ if (UDDhandle & UDRF_HIERARCHY)
+ return UDData::getUDData ( UDDhandle,iudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Root::GetUDData ( int UDDhandle, realtype & rudd ) {
+ if (UDDhandle & UDRF_HIERARCHY)
+ return UDData::getUDData ( UDDhandle,rudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Root::GetUDData ( int UDDhandle, pstr sudd, int maxLen ) {
+ if (UDDhandle & UDRF_HIERARCHY)
+ return UDData::getUDData ( UDDhandle,sudd,maxLen );
+ else return UDDATA_WrongUDRType;
+ }
+
+ int Root::GetUDData ( int UDDhandle, pstr & sudd ) {
+ if (UDDhandle & UDRF_HIERARCHY)
+ return UDData::getUDData ( UDDhandle,sudd );
+ else return UDDATA_WrongUDRType;
+ }
+
+
+ pstr Root::GetStructureTitle ( pstr & L ) {
+ return title.GetStructureTitle ( L );
+ }
+
+ void Root::SetShortBinary() {
+ // leaves only coordinates in binary files
+ int i;
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) atom[i]->SetShortBinary();
+ }
+
+
+ void Root::write ( io::RFile f ) {
+ int i,k;
+ byte Version=1;
+
+ f.WriteByte ( &Version );
+
+ UDData::write ( f );
+
+ title .write ( f );
+ cryst .write ( f );
+ udRegister.write ( f );
+ DefPath .write ( f );
+
+ f.WriteWord ( &Flags );
+ f.WriteInt ( &nAtoms );
+ for (i=0;i<nAtoms;i++) {
+ if (atom[i]) k = 1;
+ else k = 0;
+ f.WriteInt ( &k );
+ if (atom[i]) atom[i]->write ( f );
+ }
+
+ f.WriteInt ( &nModels );
+ for (i=0;i<nModels;i++) {
+ if (model[i]) k = 1;
+ else k = 0;
+ f.WriteInt ( &k );
+ if (model[i]) model[i]->write ( f );
+ }
+
+ SA .write ( f );
+ Footnote.write ( f );
+ SB .write ( f );
+ SC .write ( f );
+
+ StreamWrite ( f,CIF );
+
+ }
+
+ void Root::read ( io::RFile f ) {
+ int i,k;
+ byte Version;
+
+ ResetManager ();
+ FreeFileMemory();
+
+ f.ReadByte ( &Version );
+
+ UDData::read ( f );
+
+ title .read ( f );
+ cryst .read ( f );
+ udRegister.read ( f );
+ DefPath .read ( f );
+
+ // It is important to read atoms before models,
+ // residues and chains!
+ f.ReadWord ( &Flags );
+ f.ReadInt ( &nAtoms );
+ atmLen = nAtoms;
+ if (nAtoms>0) {
+ atom = new PAtom[atmLen];
+ for (i=0;i<nAtoms;i++) {
+ f.ReadInt ( &k );
+ if (k) {
+ atom[i] = newAtom();
+ atom[i]->read ( f );
+ // the internal atom references are installed
+ // by residue classes when they are read in
+ // model->chain below
+ } else
+ atom[i] = NULL;
+ }
+ }
+
+ f.ReadInt ( &nModels );
+ if (nModels>0) {
+ model = new PModel[nModels];
+ for (i=0;i<nModels;i++) {
+ f.ReadInt ( &k );
+ if (k) {
+ model[i] = newModel();
+ model[i]->SetMMDBManager ( PManager(this),0 );
+ model[i]->read ( f );
+ } else
+ model[i] = NULL;
+ }
+ }
+
+ SA .read ( f );
+ Footnote.read ( f );
+ SB .read ( f );
+ SC .read ( f );
+
+ StreamRead ( f,CIF );
+
+ }
+
+
+ MakeStreamFunctions(Root)
+
+
+ int isMMDBBIN ( cpstr FName, io::GZ_MODE gzipMode ) {
+ io::File f;
+ int rc;
+
+ f.assign ( FName,false,true,gzipMode );
+ if (f.reset(true)) {
+ rc = isMMDBBIN ( f );
+ f.shut();
+ } else
+ rc = -1;
+
+ return rc;
+
+ }
+
+ int isMMDBBIN ( io::RFile f ) {
+ char Label[100];
+ byte Version;
+
+ if (f.FileEnd())
+ return Error_EmptyFile;
+
+ f.ReadFile ( Label,sizeof(MMDBFLabel) );
+ if (strncmp(Label,MMDBFLabel,sizeof(MMDBFLabel)))
+ return 1;
+
+ f.ReadByte ( &Version );
+
+ if (Version>Edition) return 2;
+ else return 0;
+
+ }
+
+
+ int isPDB ( cpstr FName, io::GZ_MODE gzipMode,
+ bool IgnoreBlankLines ) {
+ io::File f;
+ int rc;
+
+ f.assign ( FName,false,false,gzipMode );
+ if (f.reset(true)) {
+ // opening it in pseudo-binary mode helps reading various
+ // line terminators for files coming from different platforms
+ rc = isPDB ( f,IgnoreBlankLines );
+ f.shut();
+ } else
+ rc = -1;
+
+ return rc;
+
+ }
+
+ int isPDB ( io::RFile f, bool IgnoreBlankLines ) {
+ char S[256];
+ int i;
+ bool Done;
+
+ if (f.FileEnd())
+ return Error_EmptyFile;
+
+ do {
+ Done = true;
+ f.ReadLine ( S,sizeof(S)-1 );
+ if (IgnoreBlankLines) {
+ i = 0;
+ while (S[i] && (S[i]==' ')) i++;
+ if (!S[i]) Done = false;
+ }
+ } while ((!f.FileEnd()) && (!Done));
+
+ PadSpaces ( S,80 );
+ if (!strncasecmp(S,"HEADER",6)) return 0;
+ if (!strncasecmp(S,"OBSLTE",6)) return 0;
+ if (!strncasecmp(S,"TITLE ",6)) return 0;
+ if (!strncasecmp(S,"CAVEAT",6)) return 0;
+ if (!strncasecmp(S,"COMPND",6)) return 0;
+ if (!strncasecmp(S,"SOURCE",6)) return 0;
+ if (!strncasecmp(S,"KEYWDS",6)) return 0;
+ if (!strncasecmp(S,"EXPDTA",6)) return 0;
+ if (!strncasecmp(S,"AUTHOR",6)) return 0;
+ if (!strncasecmp(S,"REVDAT",6)) return 0;
+ if (!strncasecmp(S,"SPRSDE",6)) return 0;
+ if (!strncasecmp(S,"JRNL ",6)) return 0;
+ if (!strncasecmp(S,"REMARK",6)) return 0;
+ if (!strncasecmp(S,"DBREF ",6)) return 0;
+ if (!strncasecmp(S,"SEQADV",6)) return 0;
+ if (!strncasecmp(S,"SEQRES",6)) return 0;
+ if (!strncasecmp(S,"MODRES",6)) return 0;
+ if (!strncasecmp(S,"HET ",6)) return 0;
+ if (!strncasecmp(S,"HETNAM",6)) return 0;
+ if (!strncasecmp(S,"HETSYN",6)) return 0;
+ if (!strncasecmp(S,"FORMUL",6)) return 0;
+ if (!strncasecmp(S,"HELIX ",6)) return 0;
+ if (!strncasecmp(S,"SHEET ",6)) return 0;
+ if (!strncasecmp(S,"TURN ",6)) return 0;
+ if (!strncasecmp(S,"SSBOND",6)) return 0;
+ if (!strncasecmp(S,"LINK ",6)) return 0;
+ if (!strncasecmp(S,"HYDBND",6)) return 0;
+ if (!strncasecmp(S,"SLTBRG",6)) return 0;
+ if (!strncasecmp(S,"CISPEP",6)) return 0;
+ if (!strncasecmp(S,"SITE ",6)) return 0;
+ if (!strncasecmp(S,"CRYST1",6)) return 0;
+ if (!strncasecmp(S,"CRYST ",6)) return 0;
+ if (!strncasecmp(S,"ORIGX1",6)) return 0;
+ if (!strncasecmp(S,"ORIGX2",6)) return 0;
+ if (!strncasecmp(S,"ORIGX3",6)) return 0;
+ if (!strncasecmp(S,"SCALE1",6)) return 0;
+ if (!strncasecmp(S,"SCALE2",6)) return 0;
+ if (!strncasecmp(S,"SCALE3",6)) return 0;
+ if (!strncasecmp(S,"MTRIX1",6)) return 0;
+ if (!strncasecmp(S,"MTRIX2",6)) return 0;
+ if (!strncasecmp(S,"MTRIX3",6)) return 0;
+ if (!strncasecmp(S,"TVECT ",6)) return 0;
+ if (!strncasecmp(S,"MODEL ",6)) return 0;
+ if (!strncasecmp(S,"ATOM ",6)) return 0;
+ if (!strncasecmp(S,"SIGATM",6)) return 0;
+ if (!strncasecmp(S,"ANISOU",6)) return 0;
+ if (!strncasecmp(S,"SIGUIJ",6)) return 0;
+ if (!strncasecmp(S,"TER ",6)) return 0;
+ if (!strncasecmp(S,"HETATM",6)) return 0;
+ if (!strncasecmp(S,"ENDMDL",6)) return 0;
+ if (!strncasecmp(S,"CONECT",6)) return 0;
+ if (!strncasecmp(S,"MASTER",6)) return 0;
+ if (!strncasecmp(S,"END ",6)) return 0;
+ if (!strncasecmp(S,"USER ",6)) return 0;
+
+ return 1;
+
+ }
+
+} // namespace mmdb
diff --git a/mmdb2/mmdb_root.h b/mmdb2/mmdb_root.h
new file mode 100644
index 0000000..df5c0e1
--- /dev/null
+++ b/mmdb2/mmdb_root.h
@@ -0,0 +1,639 @@
+// $Id: mmdb_root.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 14.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_Root <interface>
+// ~~~~~~~~~
+// Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::Root
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_Root__
+#define __MMDB_Root__
+
+#include "mmdb_io_file.h"
+#include "mmdb_uddata.h"
+#include "mmdb_title.h"
+#include "mmdb_cryst.h"
+#include "mmdb_chain.h"
+#include "mmdb_model.h"
+#include "mmdb_defs.h"
+
+namespace mmdb {
+
+ // ======================= Root ===========================
+
+ // special effect flags
+ enum MMDB_READ_FLAG {
+ MMDBF_AutoSerials = 0x00000001,
+ MMDBF_NoCoordRead = 0x00000002,
+ MMDBF_SimRWBROOK = 0x00000004,
+ MMDBF_PrintCIFWarnings = 0x00000008,
+ MMDBF_EnforceSpaces = 0x00000010,
+ MMDBF_IgnoreDuplSeqNum = 0x00000020,
+ MMDBF_IgnoreSegID = 0x00000040,
+ MMDBF_IgnoreElement = 0x00000080,
+ MMDBF_IgnoreCharge = 0x00000100,
+ MMDBF_IgnoreNonCoorPDBErrors = 0x00000200,
+ MMDBF_IgnoreUnmatch = 0x00000400,
+ MMDBF_IgnoreBlankLines = 0x00000800,
+ MMDBF_IgnoreHash = 0x00001000,
+ MMDBF_IgnoreRemarks = 0x00002000,
+ MMDBF_AllowDuplChainID = 0x00004000,
+ MMDBF_FixSpaceGroup = 0x00008000,
+ MMDBF_EnforceAtomNames = 0x00010000,
+ MMDBF_EnforceUniqueChainID = 0x00020000,
+ MMDBF_DoNotProcessSpaceGroup = 0x00040000
+ };
+
+ // MMDBF_EnforceUniqueChainID will make MMDB to rename chains on
+ // reading a file such as to maintain chains uniquesness. This
+ // is supposed to work only with 1-letter chain IDs and only
+ // if chain names are interchanged in the file. For example,
+ // if file contains a sequence of chains named
+ //
+ // A,B, A,B, A,B, A,B, A,B
+ //
+ // and this flag is set on, the resulting chain names in
+ // MMDB will be:
+ //
+ // A,B, A0,B0, A1,B1, A2,B2, A3,B3
+ //
+
+ // file types:
+ enum MMDB_FILE_TYPE {
+ MMDB_FILE_Undefined = -1,
+ MMDB_FILE_PDB = 0,
+ MMDB_FILE_CIF = 1,
+ MMDB_FILE_Binary = 2
+ };
+
+ // cleanup flags:
+ enum PDB_CLEAN_FLAG {
+ PDBCLEAN_ATNAME = 0x00000001,
+ PDBCLEAN_TER = 0x00000002,
+ PDBCLEAN_CHAIN = 0x00000004,
+ PDBCLEAN_CHAIN_STRONG = 0x00000008,
+ PDBCLEAN_ALTCODE = 0x00000010,
+ PDBCLEAN_ALTCODE_STRONG = 0x00000020,
+ PDBCLEAN_SERIAL = 0x00000040,
+ PDBCLEAN_SEQNUM = 0x00000080,
+ PDBCLEAN_CHAIN_ORDER = 0x00000100,
+ PDBCLEAN_CHAIN_ORDER_IX = 0x00000200,
+ PDBCLEAN_SOLVENT = 0x00000400,
+ PDBCLEAN_INDEX = 0x00000800,
+ PDBCLEAN_ELEMENT = 0x00001000,
+ PDBCLEAN_ELEMENT_STRONG = 0x00002000
+ };
+
+ // crystallographic info inquery
+ enum MMDB_CRYST_FLAG {
+ CRRDY_NotPrecise = 0x00000001,
+ CRRDY_isTranslation = 0x00000002,
+ CRRDY_NoOrthCode = 0x00000004,
+ CRRDY_Complete = 0,
+ CRRDY_NoTransfMatrices = -1,
+ CRRDY_Unchecked = -2,
+ CRRDY_Ambiguous = -3,
+ CRRDY_NoCell = -4,
+ CRRDY_NoSpaceGroup = -5
+ };
+
+ DefineClass(Root);
+ DefineStreamFunctions(Root);
+
+ class Root : public UDData {
+
+ friend class Model;
+ friend class Chain;
+ friend class Residue;
+ friend class Atom;
+
+ public :
+
+ Root ();
+ Root ( io::RPStream Object );
+ ~Root();
+
+ void FreeFileMemory();
+
+
+ // --------------- Reading/Writing external files ---------
+
+ void SetFlag ( word Flag );
+ void RemoveFlag ( word Flag );
+
+ ERROR_CODE ReadPDBASCII ( cpstr PDBFileName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+ ERROR_CODE ReadPDBASCII1 ( cpstr PDBLFName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+ ERROR_CODE ReadPDBASCII ( io::RFile f );
+
+ ERROR_CODE ReadCIFASCII ( cpstr CIFFileName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+ ERROR_CODE ReadCIFASCII1 ( cpstr CIFLFName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+ ERROR_CODE ReadCIFASCII ( io::RFile f );
+ ERROR_CODE ReadFromCIF ( mmcif::PData CIFD );
+
+ // adds info from PDB file
+ ERROR_CODE AddPDBASCII1 ( cpstr PDBLFName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+ ERROR_CODE AddPDBASCII ( cpstr PDBFileName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+
+ // auto format recognition
+ ERROR_CODE ReadCoorFile ( cpstr LFName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+ ERROR_CODE ReadCoorFile1 ( cpstr CFName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+ ERROR_CODE ReadCoorFile ( io::RFile f );
+
+ ERROR_CODE WritePDBASCII ( cpstr PDBFileName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+ ERROR_CODE WritePDBASCII1 ( cpstr PDBLFName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+ void WritePDBASCII ( io::RFile f );
+
+ ERROR_CODE WriteCIFASCII ( cpstr CIFFileName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+ ERROR_CODE WriteCIFASCII1 ( cpstr CIFLFName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+
+ ERROR_CODE ReadMMDBF ( cpstr MMDBRootName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+ ERROR_CODE ReadMMDBF1 ( cpstr MMDBLFName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+ ERROR_CODE ReadMMDBF ( io::RFile f );
+ ERROR_CODE WriteMMDBF ( cpstr MMDBRootName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+ ERROR_CODE WriteMMDBF1 ( cpstr MMDBLFName,
+ io::GZ_MODE gzipMode=io::GZM_CHECK );
+
+ void GetInputBuffer ( pstr Line, int & count );
+
+ // PutPDBString adds a PDB-keyworded string
+ // to the existing structure. Note that the string
+ // is namely added meaning that it will be the
+ // last REMARK, last JRNL, last ATOM etc. string
+ // -- always the last one in its group.
+ ERROR_CODE PutPDBString ( cpstr PDBString );
+
+
+ // PDBCleanup(..) cleans coordinate part to comply with PDB
+ // standards and MMDB "expectations":
+ //
+ // PDBCLEAN_ATNAME pads atom names with spaces to form
+ // 4-symbol names
+ // PDBCLEAN_TER inserts TER cards in the end of each chain
+ // PDBCLEAN_CHAIN generates 1-character chain ids instead of
+ // those many-character
+ // PDBCLEAN_CHAIN_STRONG generates 1-character chain ids starting
+ // from 'A' on for all ids, including the
+ // single-character ones
+ // PDBCLEAN_ALTCODE generates 1-character alternative codes
+ // instead of many-character ones
+ // PDBCLEAN_ALTCODE_STRONG generates 1-character alternative codes
+ // from 'A' on for all codes, including the
+ // single-character ones
+ // PDBCLEAN_SERIAL puts serial numbers in due order
+ // PDBCLEAN_SEQNUM renumbers all residues so that they go
+ // incrementally-by-one without insertion codes
+ // PDBCLEAN_CHAIN_ORDER puts chains in order of atom's serial
+ // numbers
+ // PDBCLEAN_CHAIN_ORDER_IX puts chains in order of atom's
+ // indices internal to MMDB
+ // PDBCLEAN_SOLVENT moves solvent chains at the end of each model
+ //
+ // Return codes (as bits):
+ // 0 Ok
+ // PDBCLEAN_CHAIN too many chains for assigning them
+ // 1-letter codes
+ // PDBCLEAN_ATNAME element names were not available
+ // PDBCLEAN_ALTCODE too many alternative codes encountered.
+ //
+ word PDBCleanup ( word CleanKey );
+
+ // Makes all atoms in chain 'chainID', in all models, as
+ // 'Het' atoms if Make is set True, and makes them 'ordinary'
+ // atoms otherwise. 'Ter' is automatically removed when
+ // converting to 'Het' atoms, and is automatically added
+ // when converting to 'ordinary' atoms. This may cause
+ // disorder in serial numbers -- just call
+ // PDBClean(PDBCLEAN_SERIAL) when necessary to fix this.
+ void MakeHetAtoms ( cpstr chainID, bool Make );
+
+ // --------------- Working with atoms by serial numbers ---
+
+ inline PPAtom GetAtomArray () { return atom; }
+ inline int GetAtomArrayLength() { return atmLen; } // strictly not for
+ // use in applications!!
+ PAtom GetAtomI ( int index ); // returns Atom[index-1]
+
+ // PutAtom(..) puts atom with the specified properties
+ // into the structure. The current model is used; if no model
+ // is set (crModel==NULL), one is created. Coordinates and
+ // other parameters of the atom need to be set separately.
+ // The place, at which the atom is put, is determined by
+ // index. If index is positive, then it points onto (index-1)th
+ // element of the Atom array (the index counts 1,2,... and
+ // generally coincides with the atom's serial number). If
+ // there is already an atom at this position in the system,
+ // the new atom will REPLACE it. The corresponding residues
+ // are automatically updated.
+ // If index is null (=0), the new atom will be put on
+ // the top of the structure, i.e. it will be put into
+ // (index=nAtoms+1)-th position.
+ // If index is negative, then the new atom is INSERTED
+ // BEFORE the atom in the (-index)th position. For saving
+ // the computational efforts, this WILL NOT cause the
+ // recalculation of all atoms' serial numbers according
+ // to their actual positions. It will be needed, however,
+ // for putting the things in order at a certain point,
+ // especially before writing an output ASCII file. NOTE
+ // that this ordering is never done automatically.
+ // In a correct PDB file the serial number (serNum) is always
+ // equal to its position (index). However here we allow them
+ // to be different for easing the management of relations,
+ // particularly the connectivity.
+ //
+ // Limitation: if PutAtom implies creating new
+ // chains/residues, these are always created on the top
+ // of existing chains/residues.
+ int PutAtom ( int index,
+ int serNum,
+ const AtomName atomName,
+ const ResName resName,
+ const ChainID chainID,
+ int seqNum,
+ const InsCode insCode,
+ const AltLoc altLoc,
+ const SegID segID,
+ const Element element );
+
+ int PutAtom (
+ int index, // same meaning as above
+ PAtom A, // pointer to completed atom class
+ int serNum=0 // 0 means that the serial number
+ // will be set equal to index.
+ // Otherwise the serial number
+ // is set to the specified
+ // value
+ );
+
+
+ // RemoveAtom(..) removes atom at the specified index
+ // in the Atom array. This index is always accessible
+ // as Atom[index]->index. If this leaves a residue empty,
+ // the residue is removed. If this leaves an empty chain,
+ // the chain is removed as well; the same happens to the
+ // model.
+ void RemoveAtom ( int index );
+
+ int FinishStructEdit();
+
+ void TrimModelTable();
+
+ // ---------------- Deleting models -----------------------
+
+ int DeleteAllModels ();
+ bool GetNewChainID ( int modelNo, ChainID chID, int length=1 );
+
+ // --------------- Enquiring -------------------------------
+
+ int CrystReady();
+ // Returns flags:
+ // CRRDY_Complete if crystallographic information is complete
+ // CRRDY_NotPrecise if cryst. inf-n is not precise
+ // CRRDY_isTranslation if cryst. inf-n contains translation
+ // CRRDY_NoOrthCode no orthogonalization code
+ // Fatal:
+ // CRRDY_NoTransfMatrices if transform. matrices were not
+ // calculated
+ // CRRDY_Unchecked if cryst. inf-n was not checked
+ // CRRDY_Ambiguous if cryst. inf-n is ambiguous
+ // CRRDY_NoCell if cryst. inf-n is unusable
+ // CRRDY_NoSpaceGroup if space group is not set
+
+
+ bool isCrystInfo (); // cell parameters and space group
+ bool isCellInfo (); // cell param-s a,b,c, alpha,beta,gamma
+ bool isSpaceGroup (); // space group on CRYST1 card
+ bool isTransfMatrix(); // orthogonalizing/fractionalizing
+ // matrices
+ bool isScaleMatrix (); // SCALEx PDB records
+ bool isNCSMatrix (); // MTRIXx PDB records
+ int GetNumberOfNCSMatrices();
+ int GetNumberOfNCSMates (); // Returns the number of
+ // NCS mates not given in
+ // the file (iGiven==0)
+ bool GetNCSMatrix ( int NCSMatrixNo, // 0..N-1
+ mat44 & ncs_m, int & iGiven );
+
+ int GetNumberOfSymOps (); // number of symmetry operations
+ pstr GetSymOp ( int Nop ); // XYZ symmetry operation name
+
+
+ // ------------- User-Defined Data ------------------------
+
+ int RegisterUDInteger ( UDR_TYPE udr_type, cpstr UDDataID );
+ int RegisterUDReal ( UDR_TYPE udr_type, cpstr UDDataID );
+ int RegisterUDString ( UDR_TYPE udr_type, cpstr UDDataID );
+ int GetUDDHandle ( UDR_TYPE udr_type, cpstr UDDataID );
+
+ // ----------------------------------------------------------
+
+ void SetSyminfoLib ( cpstr syminfo_lib );
+ pstr GetSyminfoLib ();
+ int SetSpaceGroup ( cpstr spGroup );
+ pstr GetSpaceGroup ();
+ pstr GetSpaceGroupFix();
+
+ void GetAtomStatistics ( RAtomStat AS );
+
+ void SetIgnoreSCALEi ( bool ignoreScalei );
+
+ // SetCell(..) is for changing cell parameters
+ void SetCell ( realtype cell_a,
+ realtype cell_b,
+ realtype cell_c,
+ realtype cell_alpha,
+ realtype cell_beta,
+ realtype cell_gamma,
+ int OrthCode=0 );
+
+ // PutCell(..) is for setting cell parameters
+ void PutCell ( realtype cell_a,
+ realtype cell_b,
+ realtype cell_c,
+ realtype cell_alpha,
+ realtype cell_beta,
+ realtype cell_gamma,
+ int OrthCode=0 );
+
+ int GetCell ( realtype & cell_a,
+ realtype & cell_b,
+ realtype & cell_c,
+ realtype & cell_alpha,
+ realtype & cell_beta,
+ realtype & cell_gamma,
+ realtype & vol,
+ int & OrthCode );
+
+ int GetRCell ( realtype & cell_as,
+ realtype & cell_bs,
+ realtype & cell_cs,
+ realtype & cell_alphas,
+ realtype & cell_betas,
+ realtype & cell_gammas,
+ realtype & vols,
+ int & OrthCode );
+
+ void GetROMatrix ( mat44 & RO );
+
+ // GetTMatrix(..) calculates and returns the coordinate
+ // transformation matrix, which converts orthogonal coordinates
+ // according to the symmetry operation number Nop and places
+ // them into unit cell shifted by cellshift_a a's, cellshift_b
+ // b's and cellshift_c c's.
+ //
+ // Return 0 means everything's fine,
+ // 1 there's no symmetry operation Nop defined
+ // 2 fractionalizing/orthogonalizing matrices were not
+ // calculated
+ // 3 cell parameters were not set up.
+ int GetTMatrix ( mat44 & TMatrix, int Nop,
+ int cellshift_a, int cellshift_b,
+ int cellshift_c );
+
+ // GetUCTMatrix(..) calculates and returns the coordinate
+ // transformation matrix, which converts orthogonal coordinates
+ // according to the symmetry operation number Nop. Translation
+ // part of the matrix is being chosen such that point (x,y,z)
+ // has least distance to the center of primary (333) unit cell,
+ // and then it is shifted by cellshift_a a's, cellshift_b b's and
+ // cellshift_c c's.
+ //
+ // Return 0 means everything's fine,
+ // 1 there's no symmetry operation Nop defined
+ // 2 fractionalizing/orthogonalizing matrices were not
+ // calculated
+ // 3 cell parameters were not set up.
+ int GetUCTMatrix ( mat44 & TMatrix, int Nop,
+ realtype x, realtype y, realtype z,
+ int cellshift_a, int cellshift_b,
+ int cellshift_c );
+
+ // GetFractMatrix(..) calculates and returns the coordinate
+ // transformation matrix, which converts fractional coordinates
+ // according to the symmetry operation number Nop and places them
+ // into unit cell shifted by cellshift_a a's, cellshift_b b's
+ // and cellshift_c c's.
+ //
+ // Return 0 means everything's fine,
+ // 1 there's no symmetry operation Nop defined
+ // 2 fractionalizing/orthogonalizing matrices were not
+ // calculated
+ // 3 cell parameters were not set up.
+ int GetFractMatrix ( mat44 & TMatrix, int Nop,
+ int cellshift_a, int cellshift_b,
+ int cellshift_c );
+
+
+ // GetSymOpMatrix(..) returns the transformation matrix for
+ // Nop-th symmetry operator in the space group
+ //
+ // Return 0 means everything's fine,
+ // 1 there's no symmetry operation Nop defined
+ // 2 fractionalizing/orthogonalizing matrices were not
+ // calculated
+ // 3 cell parameters were not set up.
+ //
+ int GetSymOpMatrix ( mat44 & TMatrix, int Nop );
+
+
+ int AddNCSMatrix ( mat33 & ncs_m, vect3 & ncs_v, int iGiven );
+ int GenerateNCSMates(); // 1: no NCS matrices, 0: Ok
+
+ pstr GetEntryID ();
+ void SetEntryID ( const IDCode idCode );
+
+ int GetNofExpDataRecs();
+ pstr GetExpDataRec ( int recNo ); // 0.. on
+
+ int GetNofMdlTypeRecs();
+ pstr GetMdlTypeRec ( int recNo ); // 0.. on
+
+ int GetFileType() { return FType; }
+
+ void Copy ( PRoot MMDBRoot );
+
+ void SetShortBinary(); // leaves only coordinates in binary files
+
+ // ------- user-defined data handlers
+ int PutUDData ( int UDDhandle, int iudd );
+ int PutUDData ( int UDDhandle, realtype rudd );
+ int PutUDData ( int UDDhandle, cpstr sudd );
+
+ int GetUDData ( int UDDhandle, int & iudd );
+ int GetUDData ( int UDDhandle, realtype & rudd );
+ int GetUDData ( int UDDhandle, pstr sudd, int maxLen );
+ int GetUDData ( int UDDhandle, pstr & sudd );
+
+ // GetStructureTitle() returns the contents of TITLE record
+ // unfolded into single line. If Title is missing, returns
+ // contents of COMPND(:MOLECULE). If COMPND is missing, returns
+ // HEADER. If Header is missing, returns PDB code. If no PDB
+ // code is there, returns "Not available".
+ pstr GetStructureTitle ( pstr & L );
+
+ PCryst GetCrystData() { return &cryst; }
+
+ PClassContainer GetUnparsedA() { return &SA; }
+ PClassContainer GetUnparsedB() { return &SB; }
+ PClassContainer GetUnparsedC() { return &SC; }
+
+ protected :
+
+ word Flags; // special effect flags
+ int FType; // type of last file operation:
+ // -1 : none
+ // 0 : PDB
+ // 1 : CIF
+ // 2 : BIN
+ // encoded as MMDB_FILE_XXXXX above
+
+ Title title; // title section
+ Cryst cryst; // crystallographic information section
+ UDRegister udRegister; // register of user-defined data
+
+ int nModels; // number of models
+ PPModel model; // array of models [0..nModels-1]
+
+ int nAtoms; // number of atoms
+ int atmLen; // length of Atom array
+ PPAtom atom; // array of atoms ordered by serial numbers
+
+ AtomPath DefPath; // default coordinate path
+
+ ClassContainer SA; // string container for unrecognized strings
+ // which are between the title and the
+ // crystallographic sections
+ ClassContainer Footnote; // string container for footnotes
+ ClassContainer SB; // string container for unrecognized strings
+ // which are between the crystallographic and
+ // the coordinate sections
+ ClassContainer SC; // string container for unrecognized strings
+ // following the coordinate section
+
+ // input buffer
+ int lcount; // input line counter
+ char S[500]; // read buffer
+ mmcif::PData CIF; // CIF file manager
+
+ PModel crModel; // current model, used at reading a PDB file
+ PChain crChain; // current chain, used at reading a PDB file
+ PResidue crRes; // current residue, used at reading a PDB file
+
+ bool Exclude; // used internally
+ bool ignoreRemarks; // used temporarily
+ bool allowDuplChID; // used temporarily
+ bool enforceUniqueChID; // used temporarily
+
+ void InitMMDBRoot ();
+ void FreeCoordMemory ();
+ void ReadPDBLine ( io::RFile f, pstr L, int maxlen );
+ ERROR_CODE ReadPDBAtom ( cpstr L );
+ ERROR_CODE ReadCIFAtom ( mmcif::PData CIFD );
+ ERROR_CODE CheckAtomPlace ( int index, cpstr L );
+ ERROR_CODE CheckAtomPlace ( int index, mmcif::PLoop Loop );
+ ERROR_CODE SwitchModel ( cpstr L );
+ ERROR_CODE SwitchModel ( int nM );
+ ERROR_CODE AllocateAtom ( int index,
+ const ChainID chainID,
+ const ChainID label_asym_id,
+ const ResName resName,
+ const ResName label_comp_id,
+ int seqNum,
+ int label_seq_id,
+ int label_entity_id,
+ const InsCode insCode,
+ bool Replace );
+ void ExpandAtomArray ( int inc );
+ void AddAtomArray ( int inc );
+
+ void ApplyNCSTransform ( int NCSMatrixNo );
+
+ virtual void ResetManager();
+
+ // --------------- Stream I/O -----------------------------
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ // don't use _ExcludeModel in your applications!
+ int _ExcludeModel ( int serNum );
+
+ int CheckInAtom ( int index, PAtom A );
+ int CheckInAtoms ( int index, PPAtom A, int natms );
+
+ virtual PMask GetSelMask ( int selHnd );
+
+ private :
+ int modelCnt; // used only at reading files
+
+ };
+
+
+
+ // isMMDBBIN will return
+ // -1 if file FName does not exist
+ // 0 if file FName is likely a MMDB BIN (binary) file
+ // 1 if file FName is not a MMDB BIN (binary) file
+ // 2 if file FName is likely a MMDB BIN (binary) file,
+ // but of a wrong edition (i.e. produced by a lower
+ // version of MMDB).
+ extern int isMMDBBIN ( cpstr FName, io::GZ_MODE gzipMode=io::GZM_CHECK );
+ extern int isMMDBBIN ( io::RFile f );
+
+ // isPDB will return
+ // -1 if file FName does not exist
+ // 0 if file FName is likely a PDB file
+ // 1 if file FName is not a PDB file
+ extern int isPDB ( cpstr FName, io::GZ_MODE gzipMode=io::GZM_CHECK,
+ bool IgnoreBlankLines=false );
+ extern int isPDB ( io::RFile f, bool IgnoreBlankLines=false );
+
+} // namespace mmdb
+
+#endif
+
diff --git a/mmdb/mmdb_rwbrook.cpp b/mmdb2/mmdb_rwbrook.cpp
old mode 100755
new mode 100644
similarity index 56%
rename from mmdb/mmdb_rwbrook.cpp
rename to mmdb2/mmdb_rwbrook.cpp
index 52bb4f5..5bc056c
--- a/mmdb/mmdb_rwbrook.cpp
+++ b/mmdb2/mmdb_rwbrook.cpp
@@ -1,4 +1,4 @@
-// $Id: mmdb_rwbrook.cpp,v 1.46 2012/01/26 17:52:20 ekr Exp $
+// $Id: mmdb_rwbrook.cpp $
// =================================================================
//
// CCP4 Coordinate Library: support of coordinate-related
@@ -6,13 +6,13 @@
//
// Copyright (C) Eugene Krissinel 2000-2008.
//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
// of the license to address the requirements of UK law.
//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
//
// This program is distributed in the hope that it will be useful,
@@ -22,164 +22,143 @@
//
// =================================================================
//
-// 29.01.10 <-- Date of Last Modification.
+// 16.09.13 <-- Date of Last Modification.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// -----------------------------------------------------------------
//
-// **** Module : MMDB_RWBrook <implementation>
+// **** Module : MMDB_RWBrook <implementation>
// ~~~~~~~~~
-// **** Project : MacroMolecular Data Base (MMDB)
+// **** Project : MacroMolecular Data Base (MMDB), "new rwbrook"
// ~~~~~~~~~
-// **** Classes : CChannel ( I/O unit class )
-// ~~~~~~~~~
-// **** Functions : mmdb_f_init_ ( initializer )
-// ~~~~~~~~~~~ mmdb_f_quit_ ( disposer )
-// autoserials_ ( switch to the autoserials regime )
-// setreadcoords_ ( switch for reading coordinates )
-// simrwbrook_ ( simulates old RWBROOK printout )
-// mmdb_f_openl_ ( associates a unit with a file )
-// mmdb_f_open_ ( associates a unit with a file )
-// mmdb_f_copy_ ( copies contents of units )
-// mmdb_f_delete_ ( deletes part of a unit )
-// mmdb_f_settype_ ( changes type of file and r/w mode )
-// mmdb_f_setname_ ( changes file name )
-// mmdb_f_write_ ( writes a data structure into file )
-// mmdb_f_close_ ( closes and disposes a data str-re )
-// mmdb_f_advance_ ( advances the internal pointer )
-// mmdb_f_rewd_ ( sets internal pointer on the top )
-// mmdb_f_bksp_ ( shifts int-l pointer 1 atom back )
-// mmdb_f_atom_ ( reads/writes atom properties )
-// mmdb_f_coord_ ( reads/writes atom coordinates )
-// mmdb_f_setcell_ ( sets the crystal cell parameters )
-// mmdb_f_wbspgrp_ ( sets the space group )
-// mmdb_f_rbspgrp_ ( gets the space group )
-// mmdb_f_wbcell_ ( sets the crystal cell parameters )
-// mmdb_f_rbcell_ ( gets the crystal cell parameters )
-// mmdb_f_rbcelln_ ( gets the crystal cell parameters )
-// mmdb_f_rbrcel_ ( gets the recipricol cell )
-// mmdb_f_rborf_ ( returns or fill transf. matrices )
-// mmdb_f_orthmat_ ( calc. standard othogonalisations )
-// mmdb_f_cvanisou_ ( converts between cryst-c units )
-// mmdb_f_wremark_ ( writes a remark statement )
-// mmdb_f_setter
-// mmdb_f_sethet
-// rberrstop_ ( error messenger )
-// rbcheckerr_ ( a simple error messenger )
+// **** Functions : mmdb_f_init_ ( initializer )
+// ~~~~~~~~~~~ mmdb_f_quit_ ( disposer )
+// autoserials_ ( switch to the autoserials regime )
+// setreadcoords_ ( switch for reading coordinates )
+// simrwbrook_ ( simulates old RWBROOK printout )
+// mmdb_f_openl_ ( associates a unit with a file )
+// mmdb_f_open_ ( associates a unit with a file )
+// mmdb_f_copy_ ( copies contents of units )
+// mmdb_f_delete_ ( deletes part of a unit )
+// mmdb_f_settype_ ( changes type of file and r/w mode )
+// mmdb_f_setname_ ( changes file name )
+// mmdb_f_write_ ( writes a data structure into file )
+// mmdb_f_close_ ( closes and disposes a data str-re )
+// mmdb_f_advance_ ( advances the internal pointer )
+// mmdb_f_rewd_ ( sets internal pointer on the top )
+// mmdb_f_bksp_ ( shifts int-l pointer 1 atom back )
+// mmdb_f_atom_ ( reads/writes atom properties )
+// mmdb_f_coord_ ( reads/writes atom coordinates )
+// mmdb_f_setcell_ ( sets the crystal cell parameters )
+// mmdb_f_wbspgrp_ ( sets the space group )
+// mmdb_f_rbspgrp_ ( gets the space group )
+// mmdb_f_wbcell_ ( sets the crystal cell parameters )
+// mmdb_f_rbcell_ ( gets the crystal cell parameters )
+// mmdb_f_rbcelln_ ( gets the crystal cell parameters )
+// mmdb_f_rbrcel_ ( gets the recipricol cell )
+// mmdb_f_rborf_ ( returns or fill transf. matrices )
+// mmdb_f_orthmat_ ( calc. standard othogonalisations )
+// mmdb_f_cvanisou_ ( converts between cryst-c units )
+// mmdb_f_wremark_ ( writes a remark statement )
+// mmdb_f_setter
+// mmdb_f_sethet
+// rberrstop_ ( error messenger )
+// rbcheckerr_ ( a simple error messenger )
//
-// (C) E. Krissinel 2000-2010
+// (C) E. Krissinel 2000-2013
//
// =================================================================
//
-// Note: what if the orthogonalization code is not defined?
-//
-#ifndef __STRING_H
#include "string.h"
-#endif
-
-#ifndef __STDLIB_H
#include "stdlib.h"
-#endif
-
-#ifndef __MATH_H
#include "math.h"
-#endif
-#ifndef __MMDB_RWBrook__
#include "mmdb_rwbrook.h"
-#endif
-
-#ifndef __MMDB_Manager__
#include "mmdb_manager.h"
-#endif
-
-#ifndef __MMDB_Tables__
#include "mmdb_tables.h"
-#endif
-
#include "hybrid_36.h"
-// ========================== CChannel ===========================
+// ========================== Channel ===========================
-DefineClass(CChannel)
+DefineClass(Channel)
-class CChannel {
+class Channel {
public :
- int nUnit; // unit number
- int nType; // unit type: 0- PDB; 1- CIF; 2- binary
- int nRead; // 0: input, 1: output
- PCMMDBManager MMDBManager; // MMDB manager
- pstr FName; // file name
- int fPos; // "position" in the file
- int ErrCode; // error code of last operation
- Boolean FAutoSer; // autoserials flag for reading PDB
- Boolean FReadCoords; // flag to read coordinate section
- Boolean FSimRWBROOK; // flag to simulate old RWBROOK's printout
-
- CChannel ();
- ~CChannel();
-
- void Dispose();
- void Init ();
-
- void SetFileType ( pstr FType );
- void SetFileName ( pstr FileName, int FNameLen );
- void IdentifyFile( pstr ExistingFName );
-
- Boolean EndOfFile ();
- PCAtom * GetAtomArray();
- PCAtom GetAtomI ( int index );
-
- PCMMDBCryst GetCryst ();
-
- Boolean areCrystMatrices();
- void Frac2Orth (
- realtype x, realtype y, realtype z,
- realtype & xx, realtype & yy, realtype & zz );
- void Orth2Frac (
- realtype x, realtype y, realtype z,
- realtype & xx, realtype & yy, realtype & zz );
- void Cryst2Orth ( rvector U );
- void Orth2Cryst ( rvector U );
- int SetCell ( realtype cell_a,
- realtype cell_b,
- realtype cell_c,
- realtype cell_alpha,
- realtype cell_beta,
- realtype cell_gamma,
- int OrthCode );
- int PutCell ( realtype cell_a,
- realtype cell_b,
- realtype cell_c,
- realtype cell_alpha,
- realtype cell_beta,
- realtype cell_gamma,
- int OrthCode );
- int SetSpGroup ( pstr spGroup );
- int GetSpGroup ( pstr spGroup );
- int GetCell ( realtype & cell_a,
- realtype & cell_b,
- realtype & cell_c,
- realtype & cell_alpha,
- realtype & cell_beta,
- realtype & cell_gamma,
- realtype & cell_v,
- int & OrthCode );
- int GetRCell ( realtype & cell_as,
- realtype & cell_bs,
- realtype & cell_cs,
- realtype & cell_alphas,
- realtype & cell_betas,
- realtype & cell_gammas,
- realtype & cell_vs );
+ int nUnit; // unit number
+ int nType; // unit type: 0- PDB; 1- CIF; 2- binary
+ int nRead; // 0: input, 1: output
+ mmdb::PManager MMDBManager; // MMDB manager
+ mmdb::pstr FName; // file name
+ int fPos; // "position" in the file
+ int ErrCode; // error code of last operation
+ bool FAutoSer; // autoserials flag for reading PDB
+ bool FReadCoords; // flag to read coordinate section
+ bool FSimRWBROOK; // flag to simulate old RWBROOK's printout
+
+ Channel ();
+ ~Channel();
+
+ void Dispose();
+ void Init ();
+
+ void SetFileType ( mmdb::pstr FType );
+ void SetFileName ( mmdb::pstr FileName, int FNameLen );
+ void IdentifyFile( mmdb::pstr ExistingFName );
+
+ bool EndOfFile ();
+ mmdb::PAtom * GetAtomArray();
+ mmdb::PAtom GetAtomI ( int index );
+
+ mmdb::PCryst GetCryst ();
+
+ bool areCrystMatrices();
+ void Frac2Orth (
+ mmdb::realtype x, mmdb::realtype y, mmdb::realtype z,
+ mmdb::realtype & xx, mmdb::realtype & yy, mmdb::realtype & zz );
+ void Orth2Frac (
+ mmdb::realtype x, mmdb::realtype y, mmdb::realtype z,
+ mmdb::realtype & xx, mmdb::realtype & yy, mmdb::realtype & zz );
+ void Cryst2Orth ( mmdb::rvector U );
+ void Orth2Cryst ( mmdb::rvector U );
+ int SetCell ( mmdb::realtype cell_a,
+ mmdb::realtype cell_b,
+ mmdb::realtype cell_c,
+ mmdb::realtype cell_alpha,
+ mmdb::realtype cell_beta,
+ mmdb::realtype cell_gamma,
+ int OrthCode );
+ int PutCell ( mmdb::realtype cell_a,
+ mmdb::realtype cell_b,
+ mmdb::realtype cell_c,
+ mmdb::realtype cell_alpha,
+ mmdb::realtype cell_beta,
+ mmdb::realtype cell_gamma,
+ int OrthCode );
+ int SetSpGroup ( mmdb::pstr spGroup );
+ int GetSpGroup ( mmdb::pstr spGroup );
+ int GetCell ( mmdb::realtype & cell_a,
+ mmdb::realtype & cell_b,
+ mmdb::realtype & cell_c,
+ mmdb::realtype & cell_alpha,
+ mmdb::realtype & cell_beta,
+ mmdb::realtype & cell_gamma,
+ mmdb::realtype & cell_v,
+ int & OrthCode );
+ int GetRCell ( mmdb::realtype & cell_as,
+ mmdb::realtype & cell_bs,
+ mmdb::realtype & cell_cs,
+ mmdb::realtype & cell_alphas,
+ mmdb::realtype & cell_betas,
+ mmdb::realtype & cell_gammas,
+ mmdb::realtype & cell_vs );
void MakeCoordStructure();
void Read ();
void Write();
- void GetInputBuffer ( pstr Line, int & count );
+ void GetInputBuffer ( mmdb::pstr Line, int & count );
protected :
@@ -187,15 +166,15 @@ class CChannel {
};
-CChannel::CChannel() {
+Channel::Channel() {
Init();
}
-CChannel::~CChannel() {
+Channel::~Channel() {
Dispose();
}
-void CChannel::Init() {
+void Channel::Init() {
nUnit = -1;
nType = -1;
nRead = 0;
@@ -203,12 +182,12 @@ void CChannel::Init() {
FName = NULL;
ErrCode = 0;
fPos = 0;
- FAutoSer = False;
- FReadCoords = True;
- FSimRWBROOK = False;
+ FAutoSer = false;
+ FReadCoords = true;
+ FSimRWBROOK = false;
}
-void CChannel::Dispose() {
+void Channel::Dispose() {
if (MMDBManager) delete MMDBManager;
if (FName) delete[] FName;
MMDBManager = NULL;
@@ -221,13 +200,13 @@ void CChannel::Dispose() {
}
-void CChannel::SetFileType ( pstr FType ) {
+void Channel::SetFileType ( mmdb::pstr FType ) {
switch (FType[0]) {
default :
case ' ' : if (nRead==0)
nType = -1; // auto at reading
else if (MMDBManager)
- nType = MMDBManager->FType; // auto at writing
+ nType = MMDBManager->GetFileType(); // auto at writing
else nType = -1;
break;
case 'P' : nType = 0; break; // PDB
@@ -236,41 +215,41 @@ void CChannel::SetFileType ( pstr FType ) {
}
}
-void CChannel::IdentifyFile ( pstr ExistingFName ) {
+void Channel::IdentifyFile ( mmdb::pstr ExistingFName ) {
if (nType==-1) {
if (ExistingFName) {
- if (isMMDBBIN(ExistingFName)==0) nType = 2;
- else if (isPDB(ExistingFName,GZM_CHECK,True)==0)
+ if (mmdb::isMMDBBIN(ExistingFName)==0) nType = 2;
+ else if (mmdb::isPDB(ExistingFName,mmdb::io::GZM_CHECK,true)==0)
nType = 0;
- else if (isCIF(ExistingFName)==0) nType = 1;
+ else if (mmdb::mmcif::isCIF(ExistingFName)==0) nType = 1;
else nType = -2; // unidentified
} else {
if (MMDBManager) {
- if (MMDBManager->FType<0)
+ if (MMDBManager->GetFileType()<0)
nType = 0; // PDB
- else nType = MMDBManager->FType; // same as it was on last input
+ else nType = MMDBManager->GetFileType(); // same as it was on last input
} else nType = 0;
}
}
}
-void CChannel::SetFileName ( pstr FileName, int FNameLen ) {
+void Channel::SetFileName ( mmdb::pstr FileName, int FNameLen ) {
if (FName) delete[] FName;
FName = new char[FNameLen+1];
strncpy ( FName,FileName,FNameLen );
FName[FNameLen] = char(0);
}
-void CChannel::MakeCoordStructure() {
+void Channel::MakeCoordStructure() {
if (MMDBManager)
- MMDBManager->Delete ( MMDBFCM_All );
+ MMDBManager->Delete ( mmdb::MMDBFCM_All );
else {
- MMDBManager = new CMMDBManager();
- MMDBManager->SetFlag ( MMDBF_AllowDuplChainID );
+ MMDBManager = new mmdb::Manager();
+ MMDBManager->SetFlag ( mmdb::MMDBF_AllowDuplChainID );
}
}
-void CChannel::Read() {
+void Channel::Read() {
int RC;
ErrCode = -2;
@@ -280,18 +259,18 @@ int RC;
IdentifyFile ( FName );
- if (FAutoSer) MMDBManager->SetFlag ( MMDBF_AutoSerials );
- else MMDBManager->RemoveFlag ( MMDBF_AutoSerials );
- if (FReadCoords) MMDBManager->RemoveFlag ( MMDBF_NoCoordRead );
- else MMDBManager->SetFlag ( MMDBF_NoCoordRead );
- if (FSimRWBROOK) MMDBManager->SetFlag ( MMDBF_SimRWBROOK );
- else MMDBManager->RemoveFlag ( MMDBF_SimRWBROOK );
+ if (FAutoSer) MMDBManager->SetFlag ( mmdb::MMDBF_AutoSerials );
+ else MMDBManager->RemoveFlag ( mmdb::MMDBF_AutoSerials );
+ if (FReadCoords) MMDBManager->RemoveFlag ( mmdb::MMDBF_NoCoordRead );
+ else MMDBManager->SetFlag ( mmdb::MMDBF_NoCoordRead );
+ if (FSimRWBROOK) MMDBManager->SetFlag ( mmdb::MMDBF_SimRWBROOK );
+ else MMDBManager->RemoveFlag ( mmdb::MMDBF_SimRWBROOK );
- MMDBManager->SetFlag ( MMDBF_IgnoreDuplSeqNum |
- MMDBF_IgnoreBlankLines |
- MMDBF_IgnoreRemarks |
- MMDBF_IgnoreNonCoorPDBErrors |
- MMDBF_AllowDuplChainID );
+ MMDBManager->SetFlag ( mmdb::MMDBF_IgnoreDuplSeqNum |
+ mmdb::MMDBF_IgnoreBlankLines |
+ mmdb::MMDBF_IgnoreRemarks |
+ mmdb::MMDBF_IgnoreNonCoorPDBErrors |
+ mmdb::MMDBF_AllowDuplChainID );
switch (nType) {
default : nType = 0; // nType=-2: unidentified: try PDB
@@ -302,10 +281,10 @@ int RC;
if (ErrCode==0) {
RC = MMDBManager->CrystReady();
switch (RC) {
- case CRRDY_NoTransfMatrices : ErrCode = RWBERR_NoMatrices; break;
- case CRRDY_Unchecked : ErrCode = RWBERR_NoCheck; break;
- case CRRDY_Ambiguous : ErrCode = RWBERR_Disagreement; break;
- case CRRDY_NoCell : ErrCode = RWBERR_NoCellParams; break;
+ case mmdb::CRRDY_NoTransfMatrices : ErrCode = RWBERR_NoMatrices; break;
+ case mmdb::CRRDY_Unchecked : ErrCode = RWBERR_NoCheck; break;
+ case mmdb::CRRDY_Ambiguous : ErrCode = RWBERR_Disagreement; break;
+ case mmdb::CRRDY_NoCell : ErrCode = RWBERR_NoCellParams; break;
default : ;
}
}
@@ -313,7 +292,7 @@ int RC;
TranslateError();
}
-void CChannel::Write() {
+void Channel::Write() {
ErrCode = -3;
if ((!MMDBManager) || (!FName)) return;
IdentifyFile ( FName );
@@ -327,52 +306,52 @@ void CChannel::Write() {
TranslateError();
}
-void CChannel::TranslateError() {
+void Channel::TranslateError() {
switch (ErrCode) {
- case Error_CantOpenFile : ErrCode = RWBERR_CantOpenFile; break;
- case Error_UnrecognizedInteger : ErrCode = RWBERR_WrongInteger; break;
- case Error_NoData : ErrCode = RWBERR_NotACIFFile; break;
- case Error_WrongModelNo : ErrCode = RWBERR_WrongModelNo; break;
- case Error_DuplicatedModel : ErrCode = RWBERR_DuplicatedModel; break;
- case Error_ForeignFile : ErrCode = RWBERR_ForeignFile; break;
- case Error_WrongEdition : ErrCode = RWBERR_WrongEdition; break;
- case Error_ATOM_Unrecognized : ErrCode = RWBERR_ATOM_Unrecognd; break;
- case Error_ATOM_AlreadySet : ErrCode = RWBERR_ATOM_AlreadySet; break;
- case Error_ATOM_NoResidue : ErrCode = RWBERR_ATOM_NoResidue; break;
- case Error_ATOM_Unmatch : ErrCode = RWBERR_ATOM_Unmatch; break;
- case Error_NotACIFFile : ErrCode = RWBERR_NotACIFFile; break;
- case Error_UnrecognCIFItems : ErrCode = RWBERR_UnrecognCIFItems; break;
- case Error_MissingCIFField : ErrCode = RWBERR_MissingCIFField; break;
- case Error_EmptyCIFLoop : ErrCode = RWBERR_EmptyCIFLoop; break;
- case Error_UnexpEndOfCIF : ErrCode = RWBERR_UnexpEndOfCIF; break;
- case Error_MissgCIFLoopField : ErrCode = RWBERR_MissgCIFLoopField; break;
- case Error_NotACIFStructure : ErrCode = RWBERR_NotACIFStructure; break;
- case Error_NotACIFLoop : ErrCode = RWBERR_NotACIFLoop; break;
- case Error_UnrecognizedReal : ErrCode = RWBERR_WrongReal; break;
-
- case Error_Ok : ErrCode = RWBERR_Ok; break;
- case Error_WrongChainID : ErrCode = RWBERR_WrongChainID; break;
- case Error_WrongEntryID : ErrCode = RWBERR_WrongEntryID; break;
- case Error_SEQRES_serNum : ErrCode = RWBERR_SEQRES_serNum; break;
- case Error_SEQRES_numRes : ErrCode = RWBERR_SEQRES_numRes; break;
- case Error_SEQRES_extraRes : ErrCode = RWBERR_SEQRES_exraRes; break;
- case Error_NCSM_Unrecognized : ErrCode = RWBERR_NCSM_Unrecogn; break;
- case Error_NCSM_AlreadySet : ErrCode = RWBERR_NCSM_AlreadySet; break;
- case Error_NCSM_WrongSerial : ErrCode = RWBERR_NCSM_WrongSerial; break;
- case Error_NCSM_UnmatchIG : ErrCode = RWBERR_NCSM_UnmatchIG; break;
- case Error_NoModel : ErrCode = RWBERR_NoModel; break;
- case Error_NoSheetID : ErrCode = RWBERR_NoSheetID; break;
- case Error_WrongSheetID : ErrCode = RWBERR_WrongSheetID; break;
- case Error_WrongStrandNo : ErrCode = RWBERR_WrongStrandNo; break;
- case Error_WrongNumberOfStrands : ErrCode = RWBERR_WrongNofStrands; break;
- case Error_WrongSheetOrder : ErrCode = RWBERR_WrongSheetOrder; break;
- case Error_HBondInconsistency : ErrCode = RWBERR_HBondInconsis; break;
- case Error_EmptyResidueName : ErrCode = RWBERR_EmptyResidueName; break;
- case Error_DuplicateSeqNum : ErrCode = RWBERR_DuplicateSeqNum; break;
- case Error_NoLogicalName : ErrCode = RWBERR_NoLogicalName; break;
- case Error_GeneralError1 : ErrCode = RWBERR_GeneralError1; break;
+ case mmdb::Error_CantOpenFile : ErrCode = RWBERR_CantOpenFile; break;
+ case mmdb::Error_UnrecognizedInteger : ErrCode = RWBERR_WrongInteger; break;
+ case mmdb::Error_NoData : ErrCode = RWBERR_NotACIFFile; break;
+ case mmdb::Error_WrongModelNo : ErrCode = RWBERR_WrongModelNo; break;
+ case mmdb::Error_DuplicatedModel : ErrCode = RWBERR_DuplicatedModel; break;
+ case mmdb::Error_ForeignFile : ErrCode = RWBERR_ForeignFile; break;
+ case mmdb::Error_WrongEdition : ErrCode = RWBERR_WrongEdition; break;
+ case mmdb::Error_ATOM_Unrecognized : ErrCode = RWBERR_ATOM_Unrecognd; break;
+ case mmdb::Error_ATOM_AlreadySet : ErrCode = RWBERR_ATOM_AlreadySet; break;
+ case mmdb::Error_ATOM_NoResidue : ErrCode = RWBERR_ATOM_NoResidue; break;
+ case mmdb::Error_ATOM_Unmatch : ErrCode = RWBERR_ATOM_Unmatch; break;
+ case mmdb::Error_NotACIFFile : ErrCode = RWBERR_NotACIFFile; break;
+ case mmdb::Error_UnrecognCIFItems : ErrCode = RWBERR_UnrecognCIFItems; break;
+ case mmdb::Error_MissingCIFField : ErrCode = RWBERR_MissingCIFField; break;
+ case mmdb::Error_EmptyCIFLoop : ErrCode = RWBERR_EmptyCIFLoop; break;
+ case mmdb::Error_UnexpEndOfCIF : ErrCode = RWBERR_UnexpEndOfCIF; break;
+ case mmdb::Error_MissgCIFLoopField : ErrCode = RWBERR_MissgCIFLoopField; break;
+ case mmdb::Error_NotACIFStructure : ErrCode = RWBERR_NotACIFStructure; break;
+ case mmdb::Error_NotACIFLoop : ErrCode = RWBERR_NotACIFLoop; break;
+ case mmdb::Error_UnrecognizedReal : ErrCode = RWBERR_WrongReal; break;
+
+ case mmdb::Error_Ok : ErrCode = RWBERR_Ok; break;
+ case mmdb::Error_WrongChainID : ErrCode = RWBERR_WrongChainID; break;
+ case mmdb::Error_WrongEntryID : ErrCode = RWBERR_WrongEntryID; break;
+ case mmdb::Error_SEQRES_serNum : ErrCode = RWBERR_SEQRES_serNum; break;
+ case mmdb::Error_SEQRES_numRes : ErrCode = RWBERR_SEQRES_numRes; break;
+ case mmdb::Error_SEQRES_extraRes : ErrCode = RWBERR_SEQRES_exraRes; break;
+ case mmdb::Error_NCSM_Unrecognized : ErrCode = RWBERR_NCSM_Unrecogn; break;
+ case mmdb::Error_NCSM_AlreadySet : ErrCode = RWBERR_NCSM_AlreadySet; break;
+ case mmdb::Error_NCSM_WrongSerial : ErrCode = RWBERR_NCSM_WrongSerial; break;
+ case mmdb::Error_NCSM_UnmatchIG : ErrCode = RWBERR_NCSM_UnmatchIG; break;
+ case mmdb::Error_NoModel : ErrCode = RWBERR_NoModel; break;
+ case mmdb::Error_NoSheetID : ErrCode = RWBERR_NoSheetID; break;
+ case mmdb::Error_WrongSheetID : ErrCode = RWBERR_WrongSheetID; break;
+ case mmdb::Error_WrongStrandNo : ErrCode = RWBERR_WrongStrandNo; break;
+ case mmdb::Error_WrongNumberOfStrands : ErrCode = RWBERR_WrongNofStrands; break;
+ case mmdb::Error_WrongSheetOrder : ErrCode = RWBERR_WrongSheetOrder; break;
+ case mmdb::Error_HBondInconsistency : ErrCode = RWBERR_HBondInconsis; break;
+ case mmdb::Error_EmptyResidueName : ErrCode = RWBERR_EmptyResidueName; break;
+ case mmdb::Error_DuplicateSeqNum : ErrCode = RWBERR_DuplicateSeqNum; break;
+ case mmdb::Error_NoLogicalName : ErrCode = RWBERR_NoLogicalName; break;
+ case mmdb::Error_GeneralError1 : ErrCode = RWBERR_GeneralError1; break;
default : ;
}
@@ -380,46 +359,46 @@ void CChannel::TranslateError() {
}
-Boolean CChannel::EndOfFile() {
+bool Channel::EndOfFile() {
int nA;
if (MMDBManager) {
nA = MMDBManager->GetNumberOfAtoms();
if (fPos>nA) {
fPos = nA+1;
- return True;
+ return true;
}
} else
- return True;
- return False;
+ return true;
+ return false;
}
-PCAtom * CChannel::GetAtomArray() {
+mmdb::PAtom * Channel::GetAtomArray() {
if (MMDBManager) return MMDBManager->GetAtomArray();
else return NULL;
}
-PCAtom CChannel::GetAtomI ( int index ) {
+mmdb::PAtom Channel::GetAtomI ( int index ) {
// returns index-th atom, as counted from the
// top of file
if (MMDBManager) return MMDBManager->GetAtomI ( index );
else return NULL;
}
-PCMMDBCryst CChannel::GetCryst() {
- if (MMDBManager) return &(MMDBManager->Cryst);
+mmdb::PCryst Channel::GetCryst() {
+ if (MMDBManager) return MMDBManager->GetCrystData();
else return NULL;
}
-Boolean CChannel::areCrystMatrices() {
- if (MMDBManager) return MMDBManager->Cryst.areMatrices();
- else return False;
+bool Channel::areCrystMatrices() {
+ if (MMDBManager) return MMDBManager->isTransfMatrix();
+ else return false;
}
-void CChannel::Frac2Orth (
- realtype x, realtype y, realtype z,
- realtype & xx, realtype & yy, realtype & zz ) {
+void Channel::Frac2Orth (
+ mmdb::realtype x, mmdb::realtype y, mmdb::realtype z,
+ mmdb::realtype & xx, mmdb::realtype & yy, mmdb::realtype & zz ) {
if (MMDBManager)
- MMDBManager->Cryst.Frac2Orth ( x,y,z,xx,yy,zz );
+ MMDBManager->Frac2Orth ( x,y,z,xx,yy,zz );
else {
xx = x;
yy = y;
@@ -427,11 +406,11 @@ void CChannel::Frac2Orth (
}
}
-void CChannel::Orth2Frac (
- realtype x, realtype y, realtype z,
- realtype & xx, realtype & yy, realtype & zz ) {
+void Channel::Orth2Frac (
+ mmdb::realtype x, mmdb::realtype y, mmdb::realtype z,
+ mmdb::realtype & xx, mmdb::realtype & yy, mmdb::realtype & zz ) {
if (MMDBManager)
- MMDBManager->Cryst.Orth2Frac ( x,y,z,xx,yy,zz );
+ MMDBManager->Orth2Frac ( x,y,z,xx,yy,zz );
else {
xx = x;
yy = y;
@@ -439,37 +418,38 @@ void CChannel::Orth2Frac (
}
}
-void CChannel::Cryst2Orth ( rvector U ) {
+void Channel::Cryst2Orth ( mmdb::rvector U ) {
if (MMDBManager)
- MMDBManager->Cryst.Cryst2Orth ( U );
+ MMDBManager->GetCrystData()->Cryst2Orth ( U );
}
-void CChannel::Orth2Cryst ( rvector U ) {
+void Channel::Orth2Cryst ( mmdb::rvector U ) {
if (MMDBManager)
- MMDBManager->Cryst.Orth2Cryst ( U );
+ MMDBManager->GetCrystData()->Orth2Cryst ( U );
}
-int CChannel::PutCell ( realtype cell_a,
- realtype cell_b,
- realtype cell_c,
- realtype cell_alpha,
- realtype cell_beta,
- realtype cell_gamma,
+int Channel::PutCell ( mmdb::realtype cell_a,
+ mmdb::realtype cell_b,
+ mmdb::realtype cell_c,
+ mmdb::realtype cell_alpha,
+ mmdb::realtype cell_beta,
+ mmdb::realtype cell_gamma,
int OrthCode ) {
if (MMDBManager) {
-
- MMDBManager->Cryst.PutCell ( cell_a,cell_b,cell_c,
- cell_alpha,cell_beta,cell_gamma,
- OrthCode );
+ mmdb::PCryst cryst = MMDBManager->GetCrystData();
+
+ cryst->PutCell ( cell_a,cell_b,cell_c,
+ cell_alpha,cell_beta,cell_gamma,
+ OrthCode );
if ((cell_a!=0.0) || (OrthCode>0)) {
- if (MMDBManager->Cryst.CellCheck & CCHK_Disagreement)
+ if (cryst->CellCheck & mmdb::CCHK_Disagreement)
return RWBERR_Disagreement;
- if (MMDBManager->Cryst.CellCheck & CCHK_NoOrthCode)
+ if (cryst->CellCheck & mmdb::CCHK_NoOrthCode)
return RWBERR_NoOrthCode;
- if (MMDBManager->Cryst.CellCheck & CCHK_Unchecked)
+ if (cryst->CellCheck & mmdb::CCHK_Unchecked)
return RWBERR_NoCheck;
}
@@ -482,25 +462,26 @@ int CChannel::PutCell ( realtype cell_a,
}
-int CChannel::SetCell ( realtype cell_a,
- realtype cell_b,
- realtype cell_c,
- realtype cell_alpha,
- realtype cell_beta,
- realtype cell_gamma,
+int Channel::SetCell ( mmdb::realtype cell_a,
+ mmdb::realtype cell_b,
+ mmdb::realtype cell_c,
+ mmdb::realtype cell_alpha,
+ mmdb::realtype cell_beta,
+ mmdb::realtype cell_gamma,
int OrthCode ) {
if (MMDBManager) {
-
- MMDBManager->Cryst.SetCell ( cell_a,cell_b,cell_c,
- cell_alpha,cell_beta,cell_gamma,
- OrthCode );
+ mmdb::PCryst cryst = MMDBManager->GetCrystData();
- if (MMDBManager->Cryst.CellCheck & CCHK_Disagreement)
+ cryst->SetCell ( cell_a,cell_b,cell_c,
+ cell_alpha,cell_beta,cell_gamma,
+ OrthCode );
+
+ if (cryst->CellCheck & mmdb::CCHK_Disagreement)
return RWBERR_Disagreement;
- if (MMDBManager->Cryst.CellCheck & CCHK_NoOrthCode)
+ if (cryst->CellCheck & mmdb::CCHK_NoOrthCode)
return RWBERR_NoOrthCode;
- if (MMDBManager->Cryst.CellCheck & CCHK_Unchecked)
+ if (cryst->CellCheck & mmdb::CCHK_Unchecked)
return RWBERR_NoCheck;
return RWBERR_Ok;
@@ -512,7 +493,7 @@ int CChannel::SetCell ( realtype cell_a,
}
-int CChannel::SetSpGroup ( pstr spGroup ) {
+int Channel::SetSpGroup ( mmdb::pstr spGroup ) {
if (MMDBManager) {
MMDBManager->SetSpaceGroup(spGroup);
return RWBERR_Ok;
@@ -521,10 +502,11 @@ int CChannel::SetSpGroup ( pstr spGroup ) {
}
-int CChannel::GetSpGroup ( pstr spGroup ) {
+int Channel::GetSpGroup ( mmdb::pstr spGroup ) {
if (MMDBManager) {
- if (MMDBManager->Cryst.WhatIsSet & CSET_SpaceGroup)
- strcpy ( spGroup,MMDBManager->Cryst.spaceGroup );
+ mmdb::PCryst cryst = MMDBManager->GetCrystData();
+ if (cryst->WhatIsSet & mmdb::CSET_SpaceGroup)
+ strcpy ( spGroup,cryst->spaceGroup );
else strcpy ( spGroup," " );
return RWBERR_Ok;
} else
@@ -532,29 +514,30 @@ int CChannel::GetSpGroup ( pstr spGroup ) {
}
-int CChannel::GetCell ( realtype & cell_a,
- realtype & cell_b,
- realtype & cell_c,
- realtype & cell_alpha,
- realtype & cell_beta,
- realtype & cell_gamma,
- realtype & cell_v,
+int Channel::GetCell ( mmdb::realtype & cell_a,
+ mmdb::realtype & cell_b,
+ mmdb::realtype & cell_c,
+ mmdb::realtype & cell_alpha,
+ mmdb::realtype & cell_beta,
+ mmdb::realtype & cell_gamma,
+ mmdb::realtype & cell_v,
int & OrthCode ) {
if (MMDBManager) {
- cell_a = MMDBManager->Cryst.a;
- cell_b = MMDBManager->Cryst.b;
- cell_c = MMDBManager->Cryst.c;
- cell_alpha = MMDBManager->Cryst.alpha;
- cell_beta = MMDBManager->Cryst.beta;
- cell_gamma = MMDBManager->Cryst.gamma;
- cell_v = MMDBManager->Cryst.Vol;
- OrthCode = MMDBManager->Cryst.NCode;
- if (!(MMDBManager->Cryst.WhatIsSet & CSET_CellParams))
+ mmdb::PCryst cryst = MMDBManager->GetCrystData();
+ cell_a = cryst->a;
+ cell_b = cryst->b;
+ cell_c = cryst->c;
+ cell_alpha = cryst->alpha;
+ cell_beta = cryst->beta;
+ cell_gamma = cryst->gamma;
+ cell_v = cryst->Vol;
+ OrthCode = cryst->NCode;
+ if (!(cryst->WhatIsSet & mmdb::CSET_CellParams))
return RWBERR_NoCellParams;
- if (!(MMDBManager->Cryst.WhatIsSet & CSET_Transforms))
+ if (!(cryst->WhatIsSet & mmdb::CSET_Transforms))
return RWBERR_NoCheck;
-// if (MMDBManager->Cryst.CellCheck & CCHK_NoOrthCode)
+// if (MMDBManager->Cryst.CellCheck & mmdb::CCHK_NoOrthCode)
// return RWBERR_NoOrthCode;
return RWBERR_Ok;
@@ -565,27 +548,28 @@ int CChannel::GetCell ( realtype & cell_a,
}
-int CChannel::GetRCell ( realtype & cell_as,
- realtype & cell_bs,
- realtype & cell_cs,
- realtype & cell_alphas,
- realtype & cell_betas,
- realtype & cell_gammas,
- realtype & cell_vs ) {
+int Channel::GetRCell ( mmdb::realtype & cell_as,
+ mmdb::realtype & cell_bs,
+ mmdb::realtype & cell_cs,
+ mmdb::realtype & cell_alphas,
+ mmdb::realtype & cell_betas,
+ mmdb::realtype & cell_gammas,
+ mmdb::realtype & cell_vs ) {
if (MMDBManager) {
- MMDBManager->Cryst.GetRCell ( cell_as,cell_bs,cell_cs,
- cell_alphas,cell_betas,cell_gammas,
- cell_vs );
- if (!(MMDBManager->Cryst.WhatIsSet & CSET_CellParams))
+ mmdb::PCryst cryst = MMDBManager->GetCrystData();
+ cryst->GetRCell ( cell_as,cell_bs,cell_cs,
+ cell_alphas,cell_betas,cell_gammas,
+ cell_vs );
+ if (!(cryst->WhatIsSet & mmdb::CSET_CellParams))
return RWBERR_NoCellParams;
- if (!(MMDBManager->Cryst.WhatIsSet & CSET_Transforms))
+ if (!(cryst->WhatIsSet & mmdb::CSET_Transforms))
return RWBERR_NoCheck;
return RWBERR_Ok;
} else
return RWBERR_NoFile;
}
-void CChannel::GetInputBuffer ( pstr Line, int & count ) {
+void Channel::GetInputBuffer ( mmdb::pstr Line, int & count ) {
if (MMDBManager)
MMDBManager->GetInputBuffer ( Line,count );
else {
@@ -598,53 +582,53 @@ void CChannel::GetInputBuffer ( pstr Line, int & count ) {
// ======================== static data ===========================
-static int nChannels; // number of channels in processing
-static PCChannel * Channel; // array of channels in processing
+static int nChannels; // number of channels in processing
+static PChannel * channel; // array of channels in processing
-static Boolean FAutoSer; // flag to automatically generate
- // serial numbers at reading PDB files
-static Boolean FReadCoords; // flag to read coordinates; if set to
- // False, only the header of PDB file
- // is read
-static Boolean FSimRWBROOK; // flag to simulate old RWBROOK printout
- // as closely as possible
+static bool FAutoSer; // flag to automatically generate
+ // serial numbers at reading PDB files
+static bool FReadCoords; // flag to read coordinates; if set to
+ // false, only the header of PDB file
+ // is read
+static bool FSimRWBROOK; // flag to simulate old RWBROOK printout
+ // as closely as possible
-static char LastFunc[80]; // name of the last called function
-static int LastUnit; // number of the last unit called
-static int LastRC; // last return code
-static int LastSer; // last serial number kept for
- // certain warnings
+static char LastFunc[80]; // name of the last called function
+static int LastUnit; // number of the last unit called
+static int LastRC; // last return code
+static int LastSer; // last serial number kept for
+ // certain warnings
// ======================== RWBrook API ===========================
FORTRAN_SUBR ( MMDB_F_INIT, mmdb_f_init,(),(),() ) {
- InitMatType();
+ mmdb::InitMatType();
nChannels = 0;
- Channel = NULL;
+ channel = NULL;
strcpy ( LastFunc,"MMDB_F_Init" );
LastUnit = -1;
LastRC = 0;
LastSer = 0;
- FAutoSer = False;
- FReadCoords = True;
- FSimRWBROOK = False;
+ FAutoSer = false;
+ FReadCoords = true;
+ FSimRWBROOK = false;
}
FORTRAN_SUBR ( MMDB_F_QUIT, mmdb_f_quit,(),(),() ) {
int i;
- for (i=0;i<nChannels;i++)
- if (Channel[i]) delete Channel[i];
- if (Channel) delete[] Channel;
- Channel = NULL;
+ for (i=0;i<nChannels;i++)
+ if (channel[i]) delete channel[i];
+ if (channel) delete[] channel;
+ channel = NULL;
nChannels = 0;
strcpy ( LastFunc,"MMDB_F_Quit" );
LastUnit = -1;
LastRC = 0;
LastSer = 0;
- FAutoSer = False;
+ FAutoSer = false;
}
@@ -678,8 +662,8 @@ int GetChannel ( int iUnit ) {
// If the channel is not found, returns -1
int i;
for (i=0;i<nChannels;i++)
- if (Channel[i]) {
- if (Channel[i]->nUnit==iUnit)
+ if (channel[i]) {
+ if (channel[i]->nUnit==iUnit)
return i;
}
return -1;
@@ -697,37 +681,37 @@ int MakeChannel ( int iUnit ) {
// Returns serial number of the channel
// associated with the newly reinitialized
// or created unit.
-int i,m;
-PCChannel * Channel1;
+int i,m;
+PChannel * channel1;
m = GetChannel ( iUnit );
if (m>=0) { // such channel already exists
- Channel[m]->Dispose(); // clear it first
- Channel[m]->Init(); // reinitialize it
- Channel[m]->nUnit = iUnit;
+ channel[m]->Dispose(); // clear it first
+ channel[m]->Init(); // reinitialize it
+ channel[m]->nUnit = iUnit;
return m;
- }
+ }
for (i=0;i<nChannels;i++) // look for free channel
- if (!Channel[i]) {
+ if (!channel[i]) {
m = i; // found!
break;
}
if (m<0) { // no free channel
// create new channel place
- Channel1 = new PCChannel[nChannels+1];
+ channel1 = new PChannel[nChannels+1];
for (i=0;i<nChannels;i++)
- Channel1[i] = Channel[i];
- if (Channel) delete[] Channel;
- Channel = Channel1;
+ channel1[i] = channel[i];
+ if (channel) delete[] channel;
+ channel = channel1;
m = nChannels;
nChannels++; // increase number of channels
}
- Channel[m] = new CChannel(); // create new channel
- Channel[m]->nUnit = iUnit;
+ channel[m] = new Channel(); // create new channel
+ channel[m]->nUnit = iUnit;
return m;
@@ -735,21 +719,21 @@ PCChannel * Channel1;
FORTRAN_SUBR ( MMDB_F_OPEN, mmdb_f_open,
( // lengths-at-end list
- fpstr FName, // file name
- fpstr RWStat, // "INPUT" or "OUTPUT"
- fpstr FType, // "PDB", "CIF", "BIN" or " "
+ mmdb::machine::fpstr FName, // file name
+ mmdb::machine::fpstr RWStat, // "INPUT" or "OUTPUT"
+ mmdb::machine::fpstr FType, // "PDB", "CIF", "BIN" or " "
int * iUnit, // channel number
int * iRet, // returns error code
int FName_len, // fortran-hidden length of FName
int RWStat_len, // fortran-hidden length of RWStat
int FType_len // fortran-hidden length of FType
), ( // lengths-in-structure list
- fpstr FName, fpstr RWStat, fpstr FType,
- int * iUnit, int * iRet
+ mmdb::machine::fpstr FName, mmdb::machine::fpstr RWStat, mmdb::machine::fpstr FType,
+ int * iUnit, int * iRet
), ( // lengths-follow list
- fpstr FName, int FName_len,
- fpstr RWStat, int RWStat_len,
- fpstr FType, int FType_len,
+ mmdb::machine::fpstr FName, int FName_len,
+ mmdb::machine::fpstr RWStat, int RWStat_len,
+ mmdb::machine::fpstr FType, int FType_len,
int * iUnit, int * iRet
) ) {
@@ -760,9 +744,9 @@ int k;
char L[500];
#ifdef WIN32
- GetStrTerWin32File ( L,FTN_STR(FName),0,sizeof(L),FTN_LEN(FName) );
+ mmdb::GetStrTerWin32File ( L,FTN_STR(FName),0,sizeof(L),FTN_LEN(FName) );
#else
- GetStrTer ( L,FTN_STR(FName),0,sizeof(L),FTN_LEN(FName) );
+ mmdb::GetStrTer ( L,FTN_STR(FName),0,sizeof(L),FTN_LEN(FName) );
#endif
strcpy ( LastFunc,"MMDB_F_Open" );
@@ -782,22 +766,22 @@ char L[500];
if (k>=0) {
if (FTN_STR(RWStat)[0]=='I') {
- Channel[k]->nRead = 0;
- Channel[k]->FAutoSer = FAutoSer;
- Channel[k]->FReadCoords = FReadCoords;
- Channel[k]->FSimRWBROOK = FSimRWBROOK;
+ channel[k]->nRead = 0;
+ channel[k]->FAutoSer = FAutoSer;
+ channel[k]->FReadCoords = FReadCoords;
+ channel[k]->FSimRWBROOK = FSimRWBROOK;
} else
- Channel[k]->nRead = 1;
+ channel[k]->nRead = 1;
// store file name
- Channel[k]->SetFileName ( L,sizeof(L) );
+ channel[k]->SetFileName ( L,sizeof(L) );
// store unit type
- Channel[k]->SetFileType ( FTN_STR(FType) );
- Channel[k]->IdentifyFile( L );
+ channel[k]->SetFileType ( FTN_STR(FType) );
+ channel[k]->IdentifyFile( L );
if (FSimRWBROOK) {
- switch (Channel[k]->nType) {
+ switch (channel[k]->nType) {
default : printf ( " unknown-format" ); break;
case 0 : printf ( " PDB" ); break;
case 1 : printf ( " mmCIF" ); break;
@@ -809,11 +793,11 @@ char L[500];
}
if (FTN_STR(RWStat)[0]=='I') {
- Channel[k]->Read();
- *iRet = Channel[k]->ErrCode;
+ channel[k]->Read();
+ *iRet = channel[k]->ErrCode;
} else {
- Channel[k]->MakeCoordStructure();
- Channel[k]->fPos = 1;
+ channel[k]->MakeCoordStructure();
+ channel[k]->fPos = 1;
*iRet = RWBERR_Ok;
}
@@ -826,37 +810,37 @@ char L[500];
FORTRAN_SUBR ( MMDB_F_OPENL, mmdb_f_openl,
( // lengths-at-end list
- fpstr LName, // logical name
- fpstr RWStat, // "INPUT" or "OUTPUT"
- fpstr FType, // "PDB", "CIF", "BIN" or " "
+ mmdb::machine::fpstr LName, // logical name
+ mmdb::machine::fpstr RWStat, // "INPUT" or "OUTPUT"
+ mmdb::machine::fpstr FType, // "PDB", "CIF", "BIN" or " "
int * iUnit, // channel number
int * iRet, // returns error code
int LName_len, // fortran-hidden length of LName
int RWStat_len, // fortran-hidden length of RWStat
int FType_len // fortran-hidden length of FType
), ( // lengths-in-structure list
- fpstr LName, fpstr RWStat, fpstr FType,
+ mmdb::machine::fpstr LName, mmdb::machine::fpstr RWStat, mmdb::machine::fpstr FType,
int * iUnit, int * iRet
), ( // lengths-follow list
- fpstr LName, int LName_len,
- fpstr RWStat, int RWStat_len,
- fpstr FType, int FType_len,
+ mmdb::machine::fpstr LName, int LName_len,
+ mmdb::machine::fpstr RWStat, int RWStat_len,
+ mmdb::machine::fpstr FType, int FType_len,
int * iUnit, int * iRet
) ) {
-char L[200];
-pstr S;
+char L[200];
+mmdb::pstr S;
char_struct(FName)
strcpy ( LastFunc,"MMDB_F_Openl" );
-
- GetStrTer ( L,FTN_STR(LName),0,sizeof(L),FTN_LEN(LName) );
-
+
+ mmdb::GetStrTer ( L,FTN_STR(LName),0,sizeof(L),FTN_LEN(LName) );
+
S = getenv ( L );
-
+
if (S) {
fill_char_struct(FName,S)
-
+
} else if (FTN_STR(RWStat)[0]=='O') {
// The user may not have assigned a logical
@@ -866,20 +850,20 @@ char_struct(FName)
fill_char_struct(FName,L)
} else {
- *iRet = RWBERR_NoLogicalName;
+ *iRet = RWBERR_NoLogicalName;
return;
}
printf ( "\n Logical name: %s File name: %s\n",L,FName );
- FORTRAN_CALL ( MMDB_F_OPEN, mmdb_f_open,
+ FORTRAN_CALL ( MMDB_F_OPEN, mmdb_f_open,
( FName,RWStat,FType,iUnit,iRet,
FName_len,RWStat_len,FType_len ),
( &FName,RWStat,FType,iUnit,iRet ),
( FName,FName_len,RWStat,RWStat_len,
FType,FType_len,iUnit,iRet ) );
-}
+}
FORTRAN_SUBR ( MMDB_F_COPY, mmdb_f_copy,
( // lengths-at-end list
@@ -904,8 +888,8 @@ FORTRAN_SUBR ( MMDB_F_COPY, mmdb_f_copy,
int * iUnit1, int * iUnit2,
int * copyKey, int * iRet
) ) {
-int k1,k2;
-word copyMask;
+int k1,k2;
+mmdb::COPY_MASK copyMask;
strcpy ( LastFunc,"MMDB_F_Copy" );
@@ -913,20 +897,20 @@ word copyMask;
k1 = GetChannel ( LastUnit );
if (k1>=0) {
- if (Channel[k1]->MMDBManager) {
+ if (channel[k1]->MMDBManager) {
LastUnit = *iUnit2;
k2 = GetChannel ( LastUnit );
if (k2>=0) {
- if (Channel[k2]->MMDBManager) {
+ if (channel[k2]->MMDBManager) {
switch (*copyKey) {
- case 1 : copyMask = MMDBFCM_All; break;
- case 2 : copyMask = MMDBFCM_Top; break;
- case 3 : copyMask = MMDBFCM_Title; break;
- case 4 : copyMask = MMDBFCM_Cryst; break;
- case 5 : copyMask = MMDBFCM_Coord; break;
- default : copyMask = 0x0000;
+ case 1 : copyMask = mmdb::MMDBFCM_All; break;
+ case 2 : copyMask = mmdb::MMDBFCM_Top; break;
+ case 3 : copyMask = mmdb::MMDBFCM_Title; break;
+ case 4 : copyMask = mmdb::MMDBFCM_Cryst; break;
+ case 5 : copyMask = mmdb::MMDBFCM_Coord; break;
+ default : copyMask = mmdb::MMDBFCM_None;
}
- Channel[k1]->MMDBManager->Copy ( Channel[k2]->MMDBManager,
+ channel[k1]->MMDBManager->Copy ( channel[k2]->MMDBManager,
copyMask );
*iRet = RWBERR_Ok;
} else
@@ -966,8 +950,8 @@ FORTRAN_SUBR ( MMDB_F_DELETE, mmdb_f_delete,
), ( // lengths-follow list
int * iUnit, int * delKey, int * iRet
) ) {
-int k;
-word delMask;
+int k;
+mmdb::word delMask;
strcpy ( LastFunc,"MMDB_F_Delete" );
@@ -976,16 +960,16 @@ word delMask;
k = GetChannel ( LastUnit );
if (k>=0) {
- if (Channel[k]->MMDBManager) {
+ if (channel[k]->MMDBManager) {
switch (*delKey) {
- case 1 : delMask = MMDBFCM_All; break;
- case 2 : delMask = MMDBFCM_Top; break;
- case 3 : delMask = MMDBFCM_Title; break;
- case 4 : delMask = MMDBFCM_Cryst; break;
- case 5 : delMask = MMDBFCM_Coord; break;
+ case 1 : delMask = mmdb::MMDBFCM_All; break;
+ case 2 : delMask = mmdb::MMDBFCM_Top; break;
+ case 3 : delMask = mmdb::MMDBFCM_Title; break;
+ case 4 : delMask = mmdb::MMDBFCM_Cryst; break;
+ case 5 : delMask = mmdb::MMDBFCM_Coord; break;
default : delMask = 0x0000;
}
- Channel[k]->MMDBManager->Delete ( delMask );
+ channel[k]->MMDBManager->Delete ( delMask );
*iRet = RWBERR_Ok;
} else
*iRet = RWBERR_NoFile;
@@ -1000,26 +984,26 @@ word delMask;
FORTRAN_SUBR ( MMDB_F_SETTYPE, mmdb_f_settype,
( // lengths-at-end list
int * iUnit, // unit number
- fpstr FType, // "PDB", "CIF", "BIN" or " "
- fpstr RWStat, // "INPUT" or "OUTPUT"
+ mmdb::machine::fpstr FType, // "PDB", "CIF", "BIN" or " "
+ mmdb::machine::fpstr RWStat, // "INPUT" or "OUTPUT"
int * iRet, // returns -1 if unit not found,
// otherwise 0
int FType_len, // fortran-hidden length of FType
int RWStat_len // fortran-hidden length of RWStat
), ( // lengths-in-structure list
- int * iUnit, fpstr FType,
- fpstr RWStat, int * iRet
+ int * iUnit, mmdb::machine::fpstr FType,
+ mmdb::machine::fpstr RWStat, int * iRet
), ( // length-follow list
- int * iUnit,
- fpstr FType, int FType_len,
- fpstr RWStat, int RWStat_len,
+ int * iUnit,
+ mmdb::machine::fpstr FType, int FType_len,
+ mmdb::machine::fpstr RWStat, int RWStat_len,
int * iRet
) ) {
UNUSED_ARGUMENT(FType_len);
UNUSED_ARGUMENT(RWStat_len);
int k;
-
+
strcpy ( LastFunc,"MMDB_F_SetType" );
if (*iUnit>0)
LastUnit = *iUnit;
@@ -1028,10 +1012,10 @@ int k;
if (k>=0) {
// store unit type
- Channel[k]->SetFileType ( FTN_STR(FType) );
+ channel[k]->SetFileType ( FTN_STR(FType) );
// store unit mode
- if (FTN_STR(RWStat)[0]=='I') Channel[k]->nRead = 0;
- else Channel[k]->nRead = 1;
+ if (FTN_STR(RWStat)[0]=='I') channel[k]->nRead = 0;
+ else channel[k]->nRead = 1;
*iRet = RWBERR_Ok;
} else
*iRet = RWBERR_NoChannel;
@@ -1045,15 +1029,15 @@ int k;
FORTRAN_SUBR ( MMDB_F_SETNAME, mmdb_f_setname,
( // lengths-at-end list
int * iUnit, // unit number
- fpstr FName, // file name
+ mmdb::machine::fpstr FName, // file name
int * iRet, // returns -1 if unit not found,
// otherwise 0
int FName_len // fortran-hidden length of FName
), ( // lengths-in-structure list
- int * iUnit, fpstr FName, int * iRet
+ int * iUnit, mmdb::machine::fpstr FName, int * iRet
), ( // lengths-follow list
int * iUnit,
- fpstr FName, int FName_len,
+ mmdb::machine::fpstr FName, int FName_len,
int * iRet
) ) {
@@ -1069,7 +1053,7 @@ int k;
*iRet = RWBERR_NoChannel;
else {
// store file name
- Channel[k]->SetFileName ( FTN_STR(FName),FTN_LEN(FName) );
+ channel[k]->SetFileName ( FTN_STR(FName),FTN_LEN(FName) );
*iRet = RWBERR_Ok;
}
@@ -1093,8 +1077,8 @@ int k;
if (k<0)
*iRet = RWBERR_NoChannel;
else {
- Channel[k]->Write();
- *iRet = Channel[k]->ErrCode;
+ channel[k]->Write();
+ *iRet = channel[k]->ErrCode;
}
LastRC = *iRet;
@@ -1116,23 +1100,23 @@ int k;
if (k<0)
*iRet = RWBERR_NoChannel;
- else if (Channel[k]->nRead==1) {
- Channel[k]->Write();
- *iRet = Channel[k]->ErrCode;
- if (!(*iRet)) {
- delete Channel[k];
- Channel[k] = NULL;
+ else if (channel[k]->nRead==1) {
+ channel[k]->Write();
+ *iRet = channel[k]->ErrCode;
+ if (!(*iRet)) {
+ delete channel[k];
+ channel[k] = NULL;
}
} else {
- delete Channel[k];
- Channel[k] = NULL;
+ delete channel[k];
+ channel[k] = NULL;
*iRet = RWBERR_Ok;
}
LastRC = *iRet;
}
-
+
FORTRAN_SUBR ( MMDB_F_ADVANCE, mmdb_f_advance,
@@ -1157,7 +1141,7 @@ FORTRAN_SUBR ( MMDB_F_ADVANCE, mmdb_f_advance,
UNUSED_ARGUMENT(iOut);
int k;
-PCAtom atom;
+mmdb::PAtom atom;
strcpy ( LastFunc,"mmdb_f_advance" );
LastUnit = *iUnit;
@@ -1168,17 +1152,17 @@ PCAtom atom;
*iRet = RWBERR_NoChannel;
- else if (Channel[k]->nRead==0) {
+ else if (channel[k]->nRead==0) {
// in the input file, try to get pointer on the next atom
do {
- Channel[k]->fPos++; // advance the pointer on Atom array
- if (Channel[k]->EndOfFile()) {
+ channel[k]->fPos++; // advance the pointer on Atom array
+ if (channel[k]->EndOfFile()) {
atom = NULL;
break;
}
- atom = Channel[k]->GetAtomI ( Channel[k]->fPos );
+ atom = channel[k]->GetAtomI ( channel[k]->fPos );
if (atom) {
if ((atom->Ter) && (*iTer==0)) {
// ignore 'ter' card if iTer is set to 0
@@ -1196,14 +1180,14 @@ PCAtom atom;
// in the output file, just advance the pointer
- if (Channel[k]->fPos==0) {
- Channel[k]->fPos++;
+ if (channel[k]->fPos==0) {
+ channel[k]->fPos++;
*iRet = 0;
} else {
- atom = Channel[k]->GetAtomI ( Channel[k]->fPos );
+ atom = channel[k]->GetAtomI ( channel[k]->fPos );
if (atom) {
// the previous atom was set -- advance the pointer
- Channel[k]->fPos++;
+ channel[k]->fPos++;
*iRet = 0;
} else
// no atom was set; make no advancement
@@ -1229,8 +1213,8 @@ int k;
k = GetChannel ( *iUnit );
if (k>=0) {
- Channel[k]->fPos = 0;
- if (Channel[k]->nRead!=0) *iRet = RWBWAR_RewOutput;
+ channel[k]->fPos = 0;
+ if (channel[k]->nRead!=0) *iRet = RWBWAR_RewOutput;
else *iRet = RWBERR_Ok;
} else
*iRet = RWBERR_NoChannel;
@@ -1253,9 +1237,9 @@ int k;
k = GetChannel ( *iUnit );
if (k>=0) {
*iRet = RWBERR_Ok;
- if (Channel[k]->fPos==0) *iRet |= RWBWAR_FileTop;
- else Channel[k]->fPos--;
- if (Channel[k]->nRead!=0) *iRet |= RWBWAR_RewOutput;
+ if (channel[k]->fPos==0) *iRet |= RWBWAR_FileTop;
+ else channel[k]->fPos--;
+ if (channel[k]->nRead!=0) *iRet |= RWBWAR_RewOutput;
} else
*iRet = RWBERR_NoChannel;
@@ -1286,7 +1270,7 @@ FORTRAN_SUBR ( MMDB_F_SEEK, mmdb_f_seek,
int * iUnit, int * fPos, int * iRet
) ) {
int k;
-PCAtom atom;
+mmdb::PAtom atom;
strcpy ( LastFunc,"MMDB_F_Seek" );
LastUnit = *iUnit;
@@ -1300,18 +1284,18 @@ PCAtom atom;
else {
// set the pointer
- Channel[k]->fPos = IMax(0,*fPos);
+ channel[k]->fPos = mmdb::IMax(0,*fPos);
if (*fPos==0) *iRet = RWBWAR_FileTop;
else *iRet = RWBERR_Ok;
- if (Channel[k]->nRead==0) {
+ if (channel[k]->nRead==0) {
// in the input file, check the end-of-file state
// and analyze the atom
- if (Channel[k]->EndOfFile()) *iRet = 2;
+ if (channel[k]->EndOfFile()) *iRet = 2;
- atom = Channel[k]->GetAtomI ( Channel[k]->fPos );
+ atom = channel[k]->GetAtomI ( channel[k]->fPos );
if (!atom) *iRet = RWBERR_EmptyPointer; // empty place
else if (atom->Ter) *iRet = 1; // 'ter' card encountered
@@ -1328,24 +1312,24 @@ PCAtom atom;
}
-void Make_AN_ID_IZ ( PCAtom atom, pstr AtNam, int AtNam_L,
- pstr ID, int ID_L, int * IZ, int * iRet ) {
+void Make_AN_ID_IZ ( mmdb::PAtom atom, mmdb::pstr AtNam, int AtNam_L,
+ mmdb::pstr ID, int ID_L, int * IZ, int * iRet ) {
char chrg[10];
int i,k;
if (atom->Ter) {
- strcpy_ns ( AtNam,pstr(" "),AtNam_L );
- strcpy_ns ( ID ,pstr(" "),ID_L );
+ mmdb::strcpy_ns ( AtNam,mmdb::pstr(" "),AtNam_L );
+ mmdb::strcpy_ns ( ID ,mmdb::pstr(" "),ID_L );
*IZ = 7;
} else {
- if (atom->name[0]==' ') strcpy_ns ( AtNam,&(atom->name[1]),4 );
- else strcpy_ns ( AtNam,atom->name,4 );
+ if (atom->name[0]==' ') mmdb::strcpy_ns ( AtNam,&(atom->name[1]),4 );
+ else mmdb::strcpy_ns ( AtNam,atom->name,4 );
// first try to identify the atom with the element name
- strcpy_ns ( ID,atom->element,ID_L ); // not more than ID_L symbols
+ mmdb::strcpy_ns ( ID,atom->element,ID_L ); // not more than ID_L symbols
// from element until but not including
// the terminated null are copied into
// ID, and the latter is padded with
@@ -1359,44 +1343,44 @@ int i,k;
}
k = 0;
- while ((k<nElementNames) &&
- ((atom->element[0]!=ElementName[k][0]) ||
- (atom->element[1]!=ElementName[k][1]))) k++;
+ while ((k<mmdb::nElementNames) &&
+ ((atom->element[0]!=mmdb::ElementName[k][0]) ||
+ (atom->element[1]!=mmdb::ElementName[k][1]))) k++;
+
+ if (k>=mmdb::nElementNames) {
- if (k>=nElementNames) {
-
// no match for atom ID -- make sure to set it blank
- strcpy_ns ( ID,pstr(" "),ID_L );
+ mmdb::strcpy_ns ( ID,mmdb::pstr(" "),ID_L );
// try to identify the atom using the atom name
k = 0;
- while ((k<nElementNames) &&
- ((atom->name[0]!=ElementName[k][0]) ||
- (atom->name[1]!=ElementName[k][1]))) k++;
+ while ((k<mmdb::nElementNames) &&
+ ((atom->name[0]!=mmdb::ElementName[k][0]) ||
+ (atom->name[1]!=mmdb::ElementName[k][1]))) k++;
// try to identify a heteroatom
i = 0;
- while ((i<nHydAtomNames) && (k>=nElementNames)) {
- if ((atom->name[0]==HydAtomName[i][0]) &&
- (atom->name[1]==HydAtomName[i][1]))
+ while ((i<mmdb::nHydAtomNames) && (k>=mmdb::nElementNames)) {
+ if ((atom->name[0]==mmdb::HydAtomName[i][0]) &&
+ (atom->name[1]==mmdb::HydAtomName[i][1]))
k = 0;
i++;
}
- if (k>=nElementNames) {
+ if (k>=mmdb::nElementNames) {
// unknown or ambiguous formfactor
k = -1;
- if ((atom->name[0]==' ') &&
+ if ((atom->name[0]==' ') &&
(atom->name[1]=='A')) k = 6;
if (k==-1) *iRet |= RWBWAR_UnkFormFactor;
- else *iRet |= RWBWAR_AmbFormFactor;
+ else *iRet |= RWBWAR_AmbFormFactor;
}
}
*IZ = k+1;
if (*IZ==0)
- strcpy_ns ( ID,pstr(" "),ID_L );
+ mmdb::strcpy_ns ( ID,mmdb::pstr(" "),ID_L );
else {
if (ID_L>3) {
if (ID[0]==' ') {
@@ -1410,7 +1394,7 @@ int i,k;
ID[3] = ' ';
}
}
- strcpy_ns ( ID,ElementName[k],IMin(2,ID_L) );
+ mmdb::strcpy_ns ( ID,mmdb::ElementName[k],mmdb::IMin(2,ID_L) );
}
}
@@ -1423,17 +1407,17 @@ FORTRAN_SUBR ( MMDB_F_ATOM, mmdb_f_atom,
( // lengths-at-end list
int * iUnit, // unit number
int * iSer, // atom serial number
- fpstr AtNam, // atom name (left justified)
- fpstr ResNam, // residue name
- fpstr ChnNam, // chain name
+ mmdb::machine::fpstr AtNam, // atom name (left justified)
+ mmdb::machine::fpstr ResNam, // residue name
+ mmdb::machine::fpstr ChnNam, // chain name
int * iResN, // residue number as an integer
- fpstr ResNo, // residue number as character (input only)
- fpstr InsCod, // the insertion code
- fpstr AltCod, // the alternate conformation code
- fpstr segID, // segment ID
+ mmdb::machine::fpstr ResNo, // residue number as character (input only)
+ mmdb::machine::fpstr InsCod, // the insertion code
+ mmdb::machine::fpstr AltCod, // the alternate conformation code
+ mmdb::machine::fpstr segID, // segment ID
int * IZ, // atomic number (input only, returned as
// 7 from ambiguous atoms)
- fpstr ID, // atomic ID related to atomic number
+ mmdb::machine::fpstr ID, // atomic ID related to atomic number
// (element symbol right justified), plus
// the ionic state +2, +3 etc..
//
@@ -1450,7 +1434,7 @@ FORTRAN_SUBR ( MMDB_F_ATOM, mmdb_f_atom,
// RWBWAR_WrongSerial if serial number
// differs from the position
// number in the file
- // RWBWAR_UnkFormFactor unknown formfactor
+ // RWBWAR_UnkFormFactor unknown formfactor
// RWBWAR_AmbFormFactor ambiguous formfactor
//
int AtNam_len, // fortran-hidden length of AtNam
@@ -1462,34 +1446,34 @@ FORTRAN_SUBR ( MMDB_F_ATOM, mmdb_f_atom,
int segID_len, // fortran-hidden length of SegID
int ID_len // fortran-hidden length of ID
), ( // lengths-in-structure list
- int * iUnit, int * iSer, fpstr AtNam, fpstr ResNam,
- fpstr ChnNam, int * iResN, fpstr ResNo, fpstr InsCod,
- fpstr AltCod, fpstr segID, int * IZ, fpstr ID,
+ int * iUnit, int * iSer, mmdb::machine::fpstr AtNam, mmdb::machine::fpstr ResNam,
+ mmdb::machine::fpstr ChnNam, int * iResN, mmdb::machine::fpstr ResNo, mmdb::machine::fpstr InsCod,
+ mmdb::machine::fpstr AltCod, mmdb::machine::fpstr segID, int * IZ, mmdb::machine::fpstr ID,
int * iRet
), ( // lengths-follow list
int * iUnit, int * iSer,
- fpstr AtNam, int AtNam_len,
- fpstr ResNam, int ResNam_len,
- fpstr ChnNam, int ChnNam_len,
+ mmdb::machine::fpstr AtNam, int AtNam_len,
+ mmdb::machine::fpstr ResNam, int ResNam_len,
+ mmdb::machine::fpstr ChnNam, int ChnNam_len,
int * iResN,
- fpstr ResNo, int ResNo_len,
- fpstr InsCod, int InsCod_len,
- fpstr AltCod, int AltCod_len,
- fpstr segID, int segID_len,
+ mmdb::machine::fpstr ResNo, int ResNo_len,
+ mmdb::machine::fpstr InsCod, int InsCod_len,
+ mmdb::machine::fpstr AltCod, int AltCod_len,
+ mmdb::machine::fpstr segID, int segID_len,
int * IZ,
- fpstr ID, int ID_len,
+ mmdb::machine::fpstr ID, int ID_len,
int * iRet
) ) {
-int k,RC;
-ChainID chainID;
-ResName resName;
-InsCode insCode;
-AtomName atomName;
-AltLoc altLoc;
-SegID sgID;
-Element element;
-PCAtom atom;
-char charge[10];
+int k,RC;
+mmdb::ChainID chainID;
+mmdb::ResName resName;
+mmdb::InsCode insCode;
+mmdb::AtomName atomName;
+mmdb::AltLoc altLoc;
+mmdb::SegID sgID;
+mmdb::Element element;
+mmdb::PAtom atom;
+char charge[10];
strcpy ( LastFunc,"MMDB_F_Atom" );
LastUnit = *iUnit;
@@ -1503,11 +1487,11 @@ char charge[10];
*iRet = RWBERR_Ok;
- if (Channel[k]->nRead==0) {
+ if (channel[k]->nRead==0) {
// reading the atom characteristics
- atom = Channel[k]->GetAtomI ( Channel[k]->fPos );
+ atom = channel[k]->GetAtomI ( channel[k]->fPos );
if (!atom) {
// atom position was not advanced properly
*iRet = RWBERR_EmptyPointer;
@@ -1516,42 +1500,42 @@ char charge[10];
}
*iSer = atom->serNum;
- if (*iSer!=Channel[k]->fPos) *iRet |= RWBWAR_WrongSerial;
+ if (*iSer!=channel[k]->fPos) *iRet |= RWBWAR_WrongSerial;
LastSer = *iSer;
Make_AN_ID_IZ ( atom,FTN_STR(AtNam),FTN_LEN(AtNam),
FTN_STR(ID),FTN_LEN(ID),IZ,iRet );
if (atom->residue) {
- strcpy_ns ( FTN_STR(ResNam),atom->residue->name,FTN_LEN(ResNam) );
+ mmdb::strcpy_ns ( FTN_STR(ResNam),atom->residue->name,FTN_LEN(ResNam) );
*iResN = atom->residue->seqNum;
- PutInteger ( FTN_STR(ResNo),*iResN,IMin(4,FTN_LEN(ResNo)) );
- strcpy_ns ( FTN_STR(InsCod),atom->residue->insCode,FTN_LEN(InsCod) );
- strcpy_ns ( &(FTN_STR(ResNo)[4]),FTN_STR(InsCod),FTN_LEN(ResNo)-4 );
- strcpy_ns ( FTN_STR(ChnNam),atom->GetChainID(),FTN_LEN(ChnNam) );
+ mmdb::PutInteger ( FTN_STR(ResNo),*iResN,mmdb::IMin(4,FTN_LEN(ResNo)) );
+ mmdb::strcpy_ns ( FTN_STR(InsCod),atom->residue->insCode,FTN_LEN(InsCod) );
+ mmdb::strcpy_ns ( &(FTN_STR(ResNo)[4]),FTN_STR(InsCod),FTN_LEN(ResNo)-4 );
+ mmdb::strcpy_ns ( FTN_STR(ChnNam),atom->GetChainID(),FTN_LEN(ChnNam) );
} else {
- strcpy_ns ( FTN_STR(ResNam),pstr(" "),FTN_LEN(ResNam) );
- strcpy_ns ( FTN_STR(ChnNam),pstr(" ") ,FTN_LEN(ChnNam) );
+ mmdb::strcpy_ns ( FTN_STR(ResNam),mmdb::pstr(" "),FTN_LEN(ResNam) );
+ mmdb::strcpy_ns ( FTN_STR(ChnNam),mmdb::pstr(" ") ,FTN_LEN(ChnNam) );
*iResN = 0;
- strcpy_ns ( FTN_STR(ResNo) ,pstr("0") ,FTN_LEN(ResNo) );
- strcpy_ns ( FTN_STR(InsCod),pstr(" ") ,FTN_LEN(InsCod) );
+ mmdb::strcpy_ns ( FTN_STR(ResNo) ,mmdb::pstr("0") ,FTN_LEN(ResNo) );
+ mmdb::strcpy_ns ( FTN_STR(InsCod),mmdb::pstr(" ") ,FTN_LEN(InsCod) );
}
- strcpy_ns ( FTN_STR(AltCod),atom->altLoc,FTN_LEN(AltCod) );
- strcpy_ns ( FTN_STR(segID) ,atom->segID ,FTN_LEN(segID) );
-
+ mmdb::strcpy_ns ( FTN_STR(AltCod),atom->altLoc,FTN_LEN(AltCod) );
+ mmdb::strcpy_ns ( FTN_STR(segID) ,atom->segID ,FTN_LEN(segID) );
+
} else {
// storing the atom characteristics
- if (!Channel[k]->MMDBManager) {
+ if (!channel[k]->MMDBManager) {
*iRet = RWBERR_Error1; // should never happen
LastRC = *iRet;
return;
}
- GetStrTer ( chainID,FTN_STR(ChnNam),1,sizeof(chainID),FTN_LEN(ChnNam) );
- GetStrTer ( resName,FTN_STR(ResNam),3,sizeof(resName),FTN_LEN(ResNam) );
- GetStrTer ( insCode,FTN_STR(InsCod),1,sizeof(insCode),FTN_LEN(InsCod) );
- GetStrTer ( altLoc ,FTN_STR(AltCod),1,sizeof(altLoc) ,FTN_LEN(AltCod) );
- GetStrTer ( sgID ,FTN_STR(segID) ,4,sizeof(sgID) ,FTN_LEN(segID) );
+ mmdb::GetStrTer ( chainID,FTN_STR(ChnNam),1,sizeof(chainID),FTN_LEN(ChnNam) );
+ mmdb::GetStrTer ( resName,FTN_STR(ResNam),3,sizeof(resName),FTN_LEN(ResNam) );
+ mmdb::GetStrTer ( insCode,FTN_STR(InsCod),1,sizeof(insCode),FTN_LEN(InsCod) );
+ mmdb::GetStrTer ( altLoc ,FTN_STR(AltCod),1,sizeof(altLoc) ,FTN_LEN(AltCod) );
+ mmdb::GetStrTer ( sgID ,FTN_STR(segID) ,4,sizeof(sgID) ,FTN_LEN(segID) );
element[0] = FTN_STR(ID)[0];
element[1] = FTN_STR(ID)[1];
element[2] = char(0);
@@ -1567,21 +1551,21 @@ char charge[10];
// if ((FTN_STR(AtNam)[1]=='H') ||
// ((FTN_STR(AtNam)[1]=='D') && (FTN_STR(ID)[2]=='D'))) {
// int i = 0;
-// while ((i<nHydAtomNames) &&
+// while ((i<nHydAtomNames) &&
// (FTN_STR(AtNam)[0]!=HydAtomName[i][0])) i++;
// if (i<nHydAtomNames)
// GetStrTer ( atomName,FTN_STR(AtNam),4,5,FTN_LEN(AtNam) );
// }
if ((FTN_STR(AtNam)[0]=='H') && (FTN_STR(AtNam)[3]!=' '))
- GetStrTer ( atomName,FTN_STR(AtNam),4,5,FTN_LEN(AtNam) );
+ mmdb::GetStrTer ( atomName,FTN_STR(AtNam),4,5,FTN_LEN(AtNam) );
if (!atomName[0]) {
atomName[0] = ' ';
- GetStrTer ( &(atomName[1]),FTN_STR(AtNam),3,4,FTN_LEN(AtNam) );
+ mmdb::GetStrTer ( &(atomName[1]),FTN_STR(AtNam),3,4,FTN_LEN(AtNam) );
}
} else
- GetStrTer ( atomName,FTN_STR(AtNam),4,5,4 );
+ mmdb::GetStrTer ( atomName,FTN_STR(AtNam),4,5,4 );
- RC = Channel[k]->MMDBManager->PutAtom ( Channel[k]->fPos,*iSer,
+ RC = channel[k]->MMDBManager->PutAtom ( channel[k]->fPos,*iSer,
atomName,resName,chainID,*iResN,
insCode,altLoc,sgID,element );
@@ -1591,9 +1575,9 @@ char charge[10];
return;
}
- DelSpaces ( charge );
+ mmdb::DelSpaces ( charge );
if (charge[0]) {
- atom = Channel[k]->GetAtomI ( Channel[k]->fPos );
+ atom = channel[k]->GetAtomI ( channel[k]->fPos );
if (!atom) {
*iRet = RWBERR_EmptyPointer; // should never be so
LastRC = *iRet;
@@ -1602,9 +1586,9 @@ char charge[10];
atom->SetCharge ( charge );
}
- if (*iSer!=Channel[k]->fPos) {
+ if (*iSer!=channel[k]->fPos) {
*iRet |= RWBWAR_WrongSerial; // this is not the right thing at all
- atom = Channel[k]->GetAtomI ( Channel[k]->fPos );
+ atom = channel[k]->GetAtomI ( channel[k]->fPos );
if (!atom) {
*iRet = RWBERR_EmptyPointer; // should never be so
LastRC = *iRet;
@@ -1628,7 +1612,7 @@ FORTRAN_SUBR ( MMDB_F_SETTER, mmdb_f_setter,
( int * iUnit, int * iRet ),
( int * iUnit, int * iRet ) ) {
int k;
-PCAtom atom;
+mmdb::PAtom atom;
strcpy ( LastFunc,"MMDB_F_SetTer" );
LastUnit = *iUnit;
@@ -1640,7 +1624,7 @@ PCAtom atom;
return;
}
- atom = Channel[k]->GetAtomI ( Channel[k]->fPos );
+ atom = channel[k]->GetAtomI ( channel[k]->fPos );
*iRet = RWBERR_Ok;
if (!atom) {
@@ -1649,8 +1633,8 @@ PCAtom atom;
return;
}
- atom->Ter = True;
- atom->WhatIsSet |= ASET_Coordinates;
+ atom->Ter = true;
+ atom->WhatIsSet |= mmdb::ASET_Coordinates;
}
@@ -1661,7 +1645,7 @@ FORTRAN_SUBR ( MMDB_F_SETHET, mmdb_f_sethet,
( int * iUnit, int * iRet ),
( int * iUnit, int * iRet ) ) {
int k;
-PCAtom atom;
+mmdb::PAtom atom;
strcpy ( LastFunc,"MMDB_F_SetHet" );
LastUnit = *iUnit;
@@ -1673,7 +1657,7 @@ PCAtom atom;
return;
}
- atom = Channel[k]->GetAtomI ( Channel[k]->fPos );
+ atom = channel[k]->GetAtomI ( channel[k]->fPos );
*iRet = RWBERR_Ok;
if (!atom) {
@@ -1682,8 +1666,8 @@ PCAtom atom;
return;
}
- atom->Het = True;
- atom->WhatIsSet |= ASET_Coordinates;
+ atom->Het = true;
+ atom->WhatIsSet |= mmdb::ASET_Coordinates;
}
@@ -1692,13 +1676,13 @@ FORTRAN_SUBR ( MMDB_F_GETHET, mmdb_f_gethet,
( int * iUnit, int * isHet, int * iRet ),
( int * iUnit, int * isHet, int * iRet ) ) {
int k;
-PCAtom atom;
+mmdb::PAtom atom;
strcpy ( LastFunc,"MMDB_F_GetHet" );
LastUnit = *iUnit;
*isHet = 0; // no HETATM record
-
+
k = GetChannel ( *iUnit );
if (k<0) {
*iRet = RWBERR_NoChannel;
@@ -1706,7 +1690,7 @@ PCAtom atom;
return;
}
- atom = Channel[k]->GetAtomI ( Channel[k]->fPos );
+ atom = channel[k]->GetAtomI ( channel[k]->fPos );
*iRet = RWBERR_Ok;
if (!atom) {
@@ -1716,7 +1700,7 @@ PCAtom atom;
}
if (atom->Het) *isHet = 1; // HETATM
-
+
}
@@ -1725,7 +1709,7 @@ FORTRAN_SUBR ( MMDB_F_COPYATOM, mmdb_f_copyatom,
( int * iUnit1, int * iUnit2, int * iRet ),
( int * iUnit1, int * iUnit2, int * iRet ) ) {
int k1,k2,RC;
-PCAtom atom;
+mmdb::PAtom atom;
strcpy ( LastFunc,"mmdb_f_copyatom" );
LastUnit = *iUnit1;
@@ -1744,7 +1728,7 @@ PCAtom atom;
return;
}
- atom = Channel[k1]->GetAtomI ( Channel[k1]->fPos );
+ atom = channel[k1]->GetAtomI ( channel[k1]->fPos );
*iRet = RWBERR_Ok;
if (!atom) {
@@ -1754,8 +1738,8 @@ PCAtom atom;
return;
}
- RC = Channel[k2]->MMDBManager->PutAtom ( Channel[k2]->fPos,atom,
- atom->serNum );
+ RC = channel[k2]->MMDBManager->PutAtom ( channel[k2]->fPos,atom,
+ atom->serNum );
if (RC) {
*iRet = RWBERR_Error2; // should never happen
LastRC = *iRet;
@@ -1770,22 +1754,22 @@ PCAtom atom;
FORTRAN_SUBR ( MMDB_F_COORD, mmdb_f_coord,
( // lengths-at-end list
int * iUnit, // unit number
- fpstr XFlag, // "F" or "O" flag for the fractional
+ mmdb::machine::fpstr XFlag, // "F" or "O" flag for the fractional
// or orthogonal coordinates x,y,z
// for output files XFlag may also be
// set to "HF" or "HO", where "F" and
// "O" have the same meaning as before
// and "H" indicates that the atom
// should be marked as heteroatom
- fpstr BFlag , // "F" or "O" flag for temperature
+ mmdb::machine::fpstr BFlag , // "F" or "O" flag for temperature
// factor in fractional or orthogonal
// Us
- apireal * x, // x-coordinate
- apireal * y, // y-coordinate
- apireal * z, // z-coordinate
- apireal * occ, // occupancy
- apireal * BIso, // isotropic temperature factor
- apireal * U, // array(6) of the anisotr. t-factor
+ mmdb::machine::apireal * x, // x-coordinate
+ mmdb::machine::apireal * y, // y-coordinate
+ mmdb::machine::apireal * z, // z-coordinate
+ mmdb::machine::apireal * occ, // occupancy
+ mmdb::machine::apireal * BIso, // isotropic temperature factor
+ mmdb::machine::apireal * U, // array(6) of the anisotr. t-factor
int * iRet, // returns
// RWBERR_NoChannel if iUnit was not
// initialized
@@ -1798,7 +1782,7 @@ FORTRAN_SUBR ( MMDB_F_COORD, mmdb_f_coord,
// not set in the atom
//
// >=0 : success, warning flags:
- // RWBERR_NoOccupancy if occupancy was
+ // RWBERR_NoOccupancy if occupancy was
// not set in the atom
// RWBERR_NoTempFactor if temp. factor was
// not set in the atom
@@ -1806,26 +1790,26 @@ FORTRAN_SUBR ( MMDB_F_COORD, mmdb_f_coord,
int XFlag_len, // fortran-hidden length of XFlag
int BFlag_len // fortran-hidden length of BFlag
), ( // lengths-in-structure list
- int * iUnit, fpstr XFlag, fpstr BFlag,
- apireal * x, apireal * y, apireal * z,
- apireal * occ, apireal * BIso, apireal * U,
+ int * iUnit, mmdb::machine::fpstr XFlag, mmdb::machine::fpstr BFlag,
+ mmdb::machine::apireal * x, mmdb::machine::apireal * y, mmdb::machine::apireal * z,
+ mmdb::machine::apireal * occ, mmdb::machine::apireal * BIso, mmdb::machine::apireal * U,
int * iRet
), ( // lengths-follow list
int * iUnit,
- fpstr XFlag, int XFlag_len,
- fpstr BFlag, int BFlag_len,
- apireal * x, apireal * y, apireal * z,
- apireal * occ, apireal * BIso, apireal * U,
+ mmdb::machine::fpstr XFlag, int XFlag_len,
+ mmdb::machine::fpstr BFlag, int BFlag_len,
+ mmdb::machine::apireal * x, mmdb::machine::apireal * y, mmdb::machine::apireal * z,
+ mmdb::machine::apireal * occ, mmdb::machine::apireal * BIso, mmdb::machine::apireal * U,
int * iRet
) ) {
UNUSED_ARGUMENT(XFlag_len);
UNUSED_ARGUMENT(BFlag_len);
-realtype AU[6];
-realtype xx,yy,zz;
-int k,i,m;
-PCAtom atom;
+mmdb::realtype AU[6];
+mmdb::realtype xx,yy,zz;
+int k,i,m;
+mmdb::PAtom atom;
strcpy ( LastFunc,"MMDB_F_Coord" );
LastUnit = *iUnit;
@@ -1837,7 +1821,7 @@ PCAtom atom;
return;
}
- atom = Channel[k]->GetAtomI ( Channel[k]->fPos );
+ atom = channel[k]->GetAtomI ( channel[k]->fPos );
*iRet = RWBERR_Ok;
if (!atom) {
@@ -1850,7 +1834,7 @@ PCAtom atom;
(FTN_STR(XFlag)[0]=='h')) m = 1;
else m = 0;
- if (Channel[k]->nRead==0) {
+ if (channel[k]->nRead==0) {
// reading the atomic coordinates
@@ -1868,26 +1852,26 @@ PCAtom atom;
U[5] = 0.0;
} else {
- if (atom->WhatIsSet & ASET_Coordinates) {
+ if (atom->WhatIsSet & mmdb::ASET_Coordinates) {
if ((FTN_STR(XFlag)[m]=='F') ||
(FTN_STR(XFlag)[m]=='f')) {
// receive fractional coordinates
- if (Channel[k]->areCrystMatrices()) {
- Channel[k]->Orth2Frac ( atom->x,atom->y,atom->z,xx,yy,zz );
- *x = (apireal)xx;
- *y = (apireal)yy;
- *z = (apireal)zz;
+ if (channel[k]->areCrystMatrices()) {
+ channel[k]->Orth2Frac ( atom->x,atom->y,atom->z,xx,yy,zz );
+ *x = (mmdb::machine::apireal)xx;
+ *y = (mmdb::machine::apireal)yy;
+ *z = (mmdb::machine::apireal)zz;
} else {
- *x = (apireal)atom->x;
- *y = (apireal)atom->y;
- *z = (apireal)atom->z;
+ *x = (mmdb::machine::apireal)atom->x;
+ *y = (mmdb::machine::apireal)atom->y;
+ *z = (mmdb::machine::apireal)atom->z;
*iRet = RWBERR_NoMatrices;
}
} else {
// receive orthogonal coordinates
- *x = (apireal)atom->x;
- *y = (apireal)atom->y;
- *z = (apireal)atom->z;
+ *x = (mmdb::machine::apireal)atom->x;
+ *y = (mmdb::machine::apireal)atom->y;
+ *z = (mmdb::machine::apireal)atom->z;
}
} else {
*x = 0.0;
@@ -1895,39 +1879,39 @@ PCAtom atom;
*z = 0.0;
*iRet = RWBERR_NoCoordinates;
}
-
+
// calculate isotropic Uf from Uo, and convert it
// if necessary
- if (atom->WhatIsSet & ASET_Anis_tFac) {
+ if (atom->WhatIsSet & mmdb::ASET_Anis_tFac) {
AU[0] = atom->u11; // this intermediate array is
AU[1] = atom->u22; // required because of possible
AU[2] = atom->u33; // type difference between
- AU[3] = atom->u12; // 'apireal' and 'realtype'
+ AU[3] = atom->u12; // 'mmdb::machine::apireal' and 'realtype'
AU[4] = atom->u13;
AU[5] = atom->u23;
- *BIso = (apireal)(8.0*Pi*Pi*(AU[0]+AU[1]+AU[2])/3.0);
+ *BIso = (mmdb::machine::apireal)(8.0*mmdb::Pi*mmdb::Pi*(AU[0]+AU[1]+AU[2])/3.0);
if ((FTN_STR(BFlag)[0]=='F') ||
(FTN_STR(BFlag)[0]=='f')) {
- if (Channel[k]->areCrystMatrices())
- Channel[k]->Orth2Cryst ( AU );
+ if (channel[k]->areCrystMatrices())
+ channel[k]->Orth2Cryst ( AU );
else if (*iRet==RWBERR_Ok)
*iRet = RWBERR_NoMatrices;
}
for (i=0;i<6;i++)
- U[i] = (apireal)AU[i];
+ U[i] = (mmdb::machine::apireal)AU[i];
} else {
for (i=0;i<6;i++)
U[i] = 0.0;
- if (atom->WhatIsSet & ASET_tempFactor)
- U[0] = (apireal)atom->tempFactor;
+ if (atom->WhatIsSet & mmdb::ASET_tempFactor)
+ U[0] = (mmdb::machine::apireal)atom->tempFactor;
else if (*iRet>=RWBERR_Ok)
*iRet |= RWBWAR_NoTempFactor;
*BIso = U[0];
}
// get occupancy now
- if (atom->WhatIsSet & ASET_Occupancy)
- *occ = (apireal)atom->occupancy;
+ if (atom->WhatIsSet & mmdb::ASET_Occupancy)
+ *occ = (mmdb::machine::apireal)atom->occupancy;
else {
*occ = 0.0;
if (*iRet>=RWBERR_Ok) *iRet |= RWBWAR_NoOccupancy;
@@ -1943,7 +1927,7 @@ PCAtom atom;
atom->x = 0.0;
atom->y = 0.0;
atom->z = 0.0;
- atom->WhatIsSet |= ASET_Coordinates;
+ atom->WhatIsSet |= mmdb::ASET_Coordinates;
atom->occupancy = 1.0;
atom->tempFactor = 1.0;
atom->u11 = 0.0;
@@ -1957,29 +1941,29 @@ PCAtom atom;
if ((FTN_STR(XFlag)[m]=='F') ||
(FTN_STR(XFlag)[m]=='f')) {
// convert fractional coordinates
- if (Channel[k]->areCrystMatrices()) {
+ if (channel[k]->areCrystMatrices()) {
xx = *x;
yy = *y;
zz = *z;
- Channel[k]->Frac2Orth ( xx,yy,zz,atom->x,atom->y,atom->z );
- atom->WhatIsSet |= ASET_Coordinates;
+ channel[k]->Frac2Orth ( xx,yy,zz,atom->x,atom->y,atom->z );
+ atom->WhatIsSet |= mmdb::ASET_Coordinates;
} else {
atom->x = *x;
atom->y = *y;
atom->z = *z;
*iRet = RWBERR_NoMatrices;
- atom->WhatIsSet &= ~ASET_Coordinates;
+ atom->WhatIsSet &= ~mmdb::ASET_Coordinates;
}
} else {
// store orthogonal coordinates
atom->x = *x;
atom->y = *y;
atom->z = *z;
- atom->WhatIsSet |= ASET_Coordinates;
+ atom->WhatIsSet |= mmdb::ASET_Coordinates;
}
atom->Het = (m>0);
-
+
// calculate isotropic Uf from Uo, and convert it
// if necessary
if ((U[1]!=0.0) || (U[2]!=0.0)) {
@@ -1987,19 +1971,19 @@ PCAtom atom;
AU[i] = U[i];
if ((FTN_STR(BFlag)[0]=='F') ||
(FTN_STR(BFlag)[0]=='f')) {
- if (Channel[k]->areCrystMatrices())
- Channel[k]->Cryst2Orth ( AU );
+ if (channel[k]->areCrystMatrices())
+ channel[k]->Cryst2Orth ( AU );
else *iRet = RWBERR_NoMatrices;
}
- *BIso = (apireal)(8.0*Pi*Pi*(AU[0]+AU[1]+AU[2])/3.0);
+ *BIso = (mmdb::machine::apireal)(8.0*mmdb::Pi*mmdb::Pi*(AU[0]+AU[1]+AU[2])/3.0);
atom->tempFactor = *BIso;
- atom->u11 = AU[0];
- atom->u22 = AU[1];
- atom->u33 = AU[2];
- atom->u12 = AU[3];
+ atom->u11 = AU[0];
+ atom->u22 = AU[1];
+ atom->u33 = AU[2];
+ atom->u12 = AU[3];
atom->u13 = AU[4];
atom->u23 = AU[5];
- atom->WhatIsSet |= ASET_tempFactor | ASET_Anis_tFac;
+ atom->WhatIsSet |= mmdb::ASET_tempFactor | mmdb::ASET_Anis_tFac;
} else {
*BIso = U[0];
atom->tempFactor = *BIso;
@@ -2009,12 +1993,12 @@ PCAtom atom;
atom->u12 = 0.0;
atom->u13 = 0.0;
atom->u23 = 0.0;
- atom->WhatIsSet |= ASET_tempFactor;
+ atom->WhatIsSet |= mmdb::ASET_tempFactor;
}
// store occupancy now
atom->occupancy = *occ;
- atom->WhatIsSet |= ASET_Occupancy;
+ atom->WhatIsSet |= mmdb::ASET_Occupancy;
}
@@ -2029,12 +2013,12 @@ PCAtom atom;
FORTRAN_SUBR ( MMDB_F_SETCELL, mmdb_f_setcell,
( // lengths-at-end list
int * iUnit, // unit number
- apireal * a, // cell parameter a, angstroms
- apireal * b, // cell parameter b, angstroms
- apireal * c, // cell parameter c, angstroms
- apireal * alpha, // cell parameter alpha, degrees
- apireal * beta, // cell parameter beta, degrees
- apireal * gamma, // cell parameter gamma, degrees
+ mmdb::machine::apireal * a, // cell parameter a, angstroms
+ mmdb::machine::apireal * b, // cell parameter b, angstroms
+ mmdb::machine::apireal * c, // cell parameter c, angstroms
+ mmdb::machine::apireal * alpha, // cell parameter alpha, degrees
+ mmdb::machine::apireal * beta, // cell parameter beta, degrees
+ mmdb::machine::apireal * gamma, // cell parameter gamma, degrees
int * ArgNCode, // orthogonalization code, 1-6
int * iRet // return code:
// RWBERR_Ok - success
@@ -2045,26 +2029,26 @@ FORTRAN_SUBR ( MMDB_F_SETCELL, mmdb_f_setcell,
// has been disposed
// RWBERR_Disagreement if a
// disagreement in
- // cell parameters
- // was found
- // RWBERR_NoOrthCode if no
+ // cell parameters
+ // was found
+ // RWBERR_NoOrthCode if no
// orthogonalization
- // code was found
- // RWBERR_NoCheck if check
- // of cell parameters
- // has failed.
+ // code was found
+ // RWBERR_NoCheck if check
+ // of cell parameters
+ // has failed.
// The last three returns would
- // rather indicate a programming
- // error in mmdb_rwbrook.cpp
+ // rather indicate a programming
+ // error in mmdb_rwbrook.cpp
), ( // lengths-in-structure list
int * iUnit,
- apireal * a, apireal * b, apireal * c,
- apireal * alpha, apireal * beta, apireal * gamma,
+ mmdb::machine::apireal * a, mmdb::machine::apireal * b, mmdb::machine::apireal * c,
+ mmdb::machine::apireal * alpha, mmdb::machine::apireal * beta, mmdb::machine::apireal * gamma,
int * ArgNCode, int * iRet
), ( // lengths-follow list
int * iUnit,
- apireal * a, apireal * b, apireal * c,
- apireal * alpha, apireal * beta, apireal * gamma,
+ mmdb::machine::apireal * a, mmdb::machine::apireal * b, mmdb::machine::apireal * c,
+ mmdb::machine::apireal * alpha, mmdb::machine::apireal * beta, mmdb::machine::apireal * gamma,
int * ArgNCode, int * iRet
) ) {
int k;
@@ -2074,10 +2058,10 @@ int k;
LastUnit = *iUnit;
k = GetChannel ( LastUnit );
- if (k<0)
+ if (k<0)
*iRet = RWBERR_NoChannel;
- else
- *iRet = Channel[k]->SetCell ( *a,*b,*c,*alpha,*beta,*gamma,
+ else
+ *iRet = channel[k]->SetCell ( *a,*b,*c,*alpha,*beta,*gamma,
*ArgNCode );
LastRC = *iRet;
@@ -2089,7 +2073,7 @@ FORTRAN_SUBR ( MMDB_F_WBSPGRP, mmdb_f_wbspgrp,
( // lengths-at-end list
int * iUnit, // unit number; *iUnit<=0 means
// "the last mentioned unit"
- fpstr spGroup, // space group
+ mmdb::machine::fpstr spGroup, // space group
int * iRet, // return code:
// RWBERR_Ok - success
// RWBERR_NoChannel if unit
@@ -2099,28 +2083,28 @@ FORTRAN_SUBR ( MMDB_F_WBSPGRP, mmdb_f_wbspgrp,
// has been disposed
int spGroup_len // fortran-hidden length of spGroup
), ( // lengths-in-structure list
- int * iUnit, fpstr spGroup, int * iRet
+ int * iUnit, mmdb::machine::fpstr spGroup, int * iRet
), ( // lengths-follow list
- int * iUnit, fpstr spGroup, int spGroup_len,
+ int * iUnit, mmdb::machine::fpstr spGroup, int spGroup_len,
int * iRet
)
- ) {
-int k;
-SymGroup spaceGroup;
+ ) {
+int k;
+mmdb::SymGroup spaceGroup;
strcpy ( LastFunc,"MMDB_F_WBSpGrp" );
if (*iUnit>0)
LastUnit = *iUnit;
k = GetChannel ( LastUnit );
- if (k<0)
+ if (k<0)
*iRet = RWBERR_NoChannel;
else {
// GetStrTer ( spaceGroup,FTN_STR(spGroup),0,
// sizeof(spaceGroup),FTN_LEN(spGroup) );
- strcpy_ncss(spaceGroup,FTN_STR(spGroup),IMin(FTN_LEN(spGroup),
+ mmdb::strcpy_ncss(spaceGroup,FTN_STR(spGroup),mmdb::IMin(FTN_LEN(spGroup),
sizeof(spaceGroup)-1) );
- *iRet = Channel[k]->SetSpGroup ( spaceGroup );
+ *iRet = channel[k]->SetSpGroup ( spaceGroup );
}
LastRC = *iRet;
@@ -2133,7 +2117,7 @@ FORTRAN_SUBR ( MMDB_F_RBSPGRP, mmdb_f_rbspgrp,
( // lengths-at-end list
int * iUnit, // unit number; *iUnit<=0 means
// "the last mentioned unit"
- fpstr spGroup, // space group
+ mmdb::machine::fpstr spGroup, // space group
int * iRet, // return code:
// RWBERR_Ok - success
// RWBERR_NoChannel if unit
@@ -2143,12 +2127,12 @@ FORTRAN_SUBR ( MMDB_F_RBSPGRP, mmdb_f_rbspgrp,
// has been disposed
int spGroup_len // fortran-hidden length of spGroup
), ( // lengths-in-structure list
- int * iUnit, fpstr spGroup, int * iRet
+ int * iUnit, mmdb::machine::fpstr spGroup, int * iRet
), ( // lengths-follow list
- int * iUnit, fpstr spGroup, int spGroup_len,
+ int * iUnit, mmdb::machine::fpstr spGroup, int spGroup_len,
int * iRet
)
- ) {
+ ) {
int k;
char SpaceGroup[100];
@@ -2159,11 +2143,11 @@ char SpaceGroup[100];
SpaceGroup[0] = char(0);
k = GetChannel ( LastUnit );
if (k<0) *iRet = RWBERR_NoChannel;
- else *iRet = Channel[k]->GetSpGroup ( SpaceGroup );
+ else *iRet = channel[k]->GetSpGroup ( SpaceGroup );
// all extra "superficial spaces" are killed in the following
- CutSpaces ( SpaceGroup,SCUTKEY_BEGEND );
- strcpy_ns ( FTN_STR(spGroup),SpaceGroup,FTN_LEN(spGroup) );
+ mmdb::CutSpaces ( SpaceGroup,mmdb::SCUTKEY_BEGEND );
+ mmdb::strcpy_ns ( FTN_STR(spGroup),SpaceGroup,FTN_LEN(spGroup) );
LastRC = *iRet;
@@ -2175,7 +2159,7 @@ FORTRAN_SUBR ( MMDB_F_WBCELL , mmdb_f_wbcell,
( // lengths-at-end list
int * iUnit, // unit number; *iUnit<=0 means
// "the last mentioned unit"
- apireal * ArgCell, // array to accept the cell parameters
+ mmdb::machine::apireal * ArgCell, // array to accept the cell parameters
// if ArgCell(1) is set to 0, then
// the cell does not change
int * ArgNCode, // orthogonalisation code
@@ -2190,10 +2174,10 @@ FORTRAN_SUBR ( MMDB_F_WBCELL , mmdb_f_wbcell,
// RWBERR_NoFile if unit
// has been disposed
), ( // lengths-in-structure list
- int * iUnit, apireal * ArgCell,
+ int * iUnit, mmdb::machine::apireal * ArgCell,
int * ArgNCode, int * iRet
), ( // lengths-follow list
- int * iUnit, apireal * ArgCell,
+ int * iUnit, mmdb::machine::apireal * ArgCell,
int * ArgNCode, int * iRet
)
) {
@@ -2204,10 +2188,10 @@ int k;
LastUnit = *iUnit;
k = GetChannel ( LastUnit );
- if (k<0)
+ if (k<0)
*iRet = RWBERR_NoChannel;
- else
- *iRet = Channel[k]->PutCell ( ArgCell[0],ArgCell[1],ArgCell[2],
+ else
+ *iRet = channel[k]->PutCell ( ArgCell[0],ArgCell[1],ArgCell[2],
ArgCell[3],ArgCell[4],ArgCell[5],
*ArgNCode );
@@ -2220,37 +2204,37 @@ int k;
FORTRAN_SUBR ( MMDB_F_RBCELL, mmdb_f_rbcell,
( // lengths-at-end list
int * iUnit, // unit number
- apireal * celld, // array to accept the cell parameters
- apireal * cvol, // returns the cell volume
+ mmdb::machine::apireal * celld, // array to accept the cell parameters
+ mmdb::machine::apireal * cvol, // returns the cell volume
int * iRet // return code
- // RWBERR_Ok - success
- // RWBERR_NoChannel if unit
- // iUnit was not
- // initialized
- // RWBERR_NoFile if unit
- // has been disposed
- // RWBERR_Parameters if the
- // cell parameters
- // were not set
- // RWBERR_NoOrthCode if no
+ // RWBERR_Ok - success
+ // RWBERR_NoChannel if unit
+ // iUnit was not
+ // initialized
+ // RWBERR_NoFile if unit
+ // has been disposed
+ // RWBERR_Parameters if the
+ // cell parameters
+ // were not set
+ // RWBERR_NoOrthCode if no
// orthogonalization
- // code was found
- // RWBERR_NoCheck if check
- // of cell parameters
- // has failed.
+ // code was found
+ // RWBERR_NoCheck if check
+ // of cell parameters
+ // has failed.
// The last three returns would
- // rather indicate a programming
- // error in mmdb_rwbrook.cpp
+ // rather indicate a programming
+ // error in mmdb_rwbrook.cpp
), ( // lengths-in-structure list
- int * iUnit, apireal * celld,
- apireal * cvol, int * iRet
+ int * iUnit, mmdb::machine::apireal * celld,
+ mmdb::machine::apireal * cvol, int * iRet
), ( // lengths-follow list
- int * iUnit, apireal * celld,
- apireal * cvol, int * iRet
+ int * iUnit, mmdb::machine::apireal * celld,
+ mmdb::machine::apireal * cvol, int * iRet
) ) {
-realtype p[6];
-realtype v;
-int k,i,nc;
+mmdb::realtype p[6];
+mmdb::realtype v;
+int k,i,nc;
strcpy ( LastFunc,"MMDB_F_RBCell" );
if (*iUnit>0)
@@ -2263,12 +2247,12 @@ int k,i,nc;
return;
}
- *iRet = Channel[k]->GetCell ( p[0],p[1],p[2],p[3],p[4],p[5],v,nc );
+ *iRet = channel[k]->GetCell ( p[0],p[1],p[2],p[3],p[4],p[5],v,nc );
if (*iRet==RWBERR_Ok) {
for (i=0;i<6;i++)
- celld[i] = (apireal)p[i];
- *cvol = (apireal)v;
+ celld[i] = (mmdb::machine::apireal)p[i];
+ *cvol = (mmdb::machine::apireal)v;
}
LastRC = *iRet;
@@ -2280,38 +2264,38 @@ int k,i,nc;
FORTRAN_SUBR ( MMDB_F_RBCELLN, mmdb_f_rbcelln,
( // lengths-at-end list
int * iUnit, // unit number
- apireal * celld, // array to accept the cell parameters
- apireal * cvol, // returns the cell volume
+ mmdb::machine::apireal * celld, // array to accept the cell parameters
+ mmdb::machine::apireal * cvol, // returns the cell volume
int * ArgNCode, // returns the orthogonalization code, 1-6
int * iRet // return code
- // RWBERR_Ok - success
- // RWBERR_NoChannel if unit
- // iUnit was not
- // initialized
- // RWBERR_NoFile if unit
- // has been disposed
- // RWBERR_Parameters if the
- // cell parameters
- // were not set
- // RWBERR_NoOrthCode if no
+ // RWBERR_Ok - success
+ // RWBERR_NoChannel if unit
+ // iUnit was not
+ // initialized
+ // RWBERR_NoFile if unit
+ // has been disposed
+ // RWBERR_Parameters if the
+ // cell parameters
+ // were not set
+ // RWBERR_NoOrthCode if no
// orthogonalization
- // code was found
- // RWBERR_NoCheck if check
- // of cell parameters
- // has failed.
+ // code was found
+ // RWBERR_NoCheck if check
+ // of cell parameters
+ // has failed.
// The last three returns would
- // rather indicate a programming
- // error in mmdb_rwbrook.cpp
+ // rather indicate a programming
+ // error in mmdb_rwbrook.cpp
), ( // lengths-in-structure list
- int * iUnit, apireal * celld, apireal * cvol,
+ int * iUnit, mmdb::machine::apireal * celld, mmdb::machine::apireal * cvol,
int * ArgNCode, int * iRet
), ( // lengths-follow list
- int * iUnit, apireal * celld, apireal * cvol,
+ int * iUnit, mmdb::machine::apireal * celld, mmdb::machine::apireal * cvol,
int * ArgNCode, int * iRet
) ) {
-realtype p[6];
-realtype v;
-int k,i,nc;
+mmdb::realtype p[6];
+mmdb::realtype v;
+int k,i,nc;
strcpy ( LastFunc,"MMDB_F_RBCellN" );
if (*iUnit>0)
@@ -2323,12 +2307,12 @@ int k,i,nc;
LastRC = *iRet;
return;
}
-
- *iRet = Channel[k]->GetCell ( p[0],p[1],p[2],p[3],p[4],p[5],v,nc );
+
+ *iRet = channel[k]->GetCell ( p[0],p[1],p[2],p[3],p[4],p[5],v,nc );
if (*iRet==RWBERR_Ok) {
for (i=0;i<6;i++)
- celld[i] = (apireal)p[i];
- *cvol = (apireal)v;
+ celld[i] = (mmdb::machine::apireal)p[i];
+ *cvol = (mmdb::machine::apireal)v;
*ArgNCode = nc;
}
@@ -2341,38 +2325,38 @@ int k,i,nc;
FORTRAN_SUBR ( MMDB_F_RBRCEL, mmdb_f_rbrcel,
( // lengths-at-end list
int * iUnit, // unit number
- apireal * rcell, // array to accept the reciprocal
+ mmdb::machine::apireal * rcell, // array to accept the reciprocal
// cell parameters
- apireal * rvol, // returns the reciprocal cell volume
+ mmdb::machine::apireal * rvol, // returns the reciprocal cell volume
int * iRet // return code
- // RWBERR_Ok - success
- // RWBERR_NoChannel if unit
- // iUnit was not
- // initialized
- // RWBERR_NoFile if unit
- // has been disposed
- // RWBERR_Parameters if the
- // cell parameters
- // were not set
- // RWBERR_NoOrthCode if no
+ // RWBERR_Ok - success
+ // RWBERR_NoChannel if unit
+ // iUnit was not
+ // initialized
+ // RWBERR_NoFile if unit
+ // has been disposed
+ // RWBERR_Parameters if the
+ // cell parameters
+ // were not set
+ // RWBERR_NoOrthCode if no
// orthogonalization
- // code was found
- // RWBERR_NoCheck if check
- // of cell parameters
- // has failed.
+ // code was found
+ // RWBERR_NoCheck if check
+ // of cell parameters
+ // has failed.
// The last three returns would
- // rather indicate a programming
- // error in mmdb_rwbrook.cpp
+ // rather indicate a programming
+ // error in mmdb_rwbrook.cpp
), ( // lengths-in-structure list
- int * iUnit, apireal * rcell, apireal * rvol,
+ int * iUnit, mmdb::machine::apireal * rcell, mmdb::machine::apireal * rvol,
int * iRet
), ( // lengths-follow list
- int * iUnit, apireal * rcell, apireal * rvol,
+ int * iUnit, mmdb::machine::apireal * rcell, mmdb::machine::apireal * rvol,
int * iRet
) ) {
-realtype p[6];
-realtype v;
-int k,i;
+mmdb::realtype p[6];
+mmdb::realtype v;
+int k,i;
strcpy ( LastFunc,"MMDB_F_RBRCel" );
if (*iUnit>0)
@@ -2384,12 +2368,12 @@ int k,i;
LastRC = *iRet;
return;
}
-
- *iRet = Channel[k]->GetRCell ( p[0],p[1],p[2],p[3],p[4],p[5],v );
+
+ *iRet = channel[k]->GetRCell ( p[0],p[1],p[2],p[3],p[4],p[5],v );
if (*iRet==RWBERR_Ok) {
for (i=0;i<6;i++)
- rcell[i] = (apireal)p[i];
- *rvol = (apireal)v;
+ rcell[i] = (mmdb::machine::apireal)p[i];
+ *rvol = (mmdb::machine::apireal)v;
}
LastRC = *iRet;
@@ -2401,8 +2385,8 @@ int k,i;
FORTRAN_SUBR ( MMDB_F_RBORF, mmdb_f_rborf,
( // lengths-at-end list
int * iUnit, // unit number
- apireal * RO, // array for orthogonalising matrix
- apireal * RF, // array for fractionalising matrix
+ mmdb::machine::apireal * RO, // array for orthogonalising matrix
+ mmdb::machine::apireal * RF, // array for fractionalising matrix
int * LCode, // buffer for orthogonalisation code
int * iRet // return code:
// RWBERR_Ok - success
@@ -2414,16 +2398,16 @@ FORTRAN_SUBR ( MMDB_F_RBORF, mmdb_f_rborf,
// RWBERR_NoMatrices if the
// orthogonalisation
// matrices were not
- // calculated
+ // calculated
), ( // lengths-in-structure list
- int * iUnit, apireal * RO, apireal * RF,
+ int * iUnit, mmdb::machine::apireal * RO, mmdb::machine::apireal * RF,
int * LCode, int * iRet
), ( // lengths-follow list
- int * iUnit, apireal * RO, apireal * RF,
+ int * iUnit, mmdb::machine::apireal * RO, mmdb::machine::apireal * RF,
int * LCode, int * iRet )
) {
int i,j,k,l;
-PCMMDBCryst Cryst;
+mmdb::PCryst Cryst;
strcpy ( LastFunc,"MMDB_F_RBORF" );
if (*iUnit>0)
@@ -2436,7 +2420,7 @@ PCMMDBCryst Cryst;
return;
}
- Cryst = Channel[k]->GetCryst();
+ Cryst = channel[k]->GetCryst();
if (Cryst==NULL) {
*iRet = RWBERR_NoFile;
LastRC = *iRet;
@@ -2450,12 +2434,12 @@ PCMMDBCryst Cryst;
if (RO[0]<=0.0000000001) {
for (j=0;j<4;j++)
for (i=0;i<4;i++) {
- RF[l] = (apireal)Cryst->RF[i][j];
- RO[l] = (apireal)Cryst->RO[i][j];
+ RF[l] = (mmdb::machine::apireal)Cryst->RF[i][j];
+ RO[l] = (mmdb::machine::apireal)Cryst->RO[i][j];
l++;
}
*LCode = Cryst->NCode;
- if (!(Cryst->WhatIsSet & CSET_Transforms))
+ if (!(Cryst->WhatIsSet & mmdb::CSET_Transforms))
*iRet = RWBERR_NoMatrices;
} else {
for (j=0;j<4;j++)
@@ -2465,7 +2449,7 @@ PCMMDBCryst Cryst;
l++;
}
Cryst->NCode = *LCode;
- Cryst->WhatIsSet |= CSET_Transforms;
+ Cryst->WhatIsSet |= mmdb::CSET_Transforms;
}
LastRC = *iRet;
@@ -2477,12 +2461,12 @@ FORTRAN_SUBR ( MMDB_F_ORTHMAT, mmdb_f_orthmat,
( // lengths-at-end list
int * iUnit, // unit number; *iUnit<=0 means
// "the last mentioned unit"
- apireal * Cell, // array of cell parameters:
+ mmdb::machine::apireal * Cell, // array of cell parameters:
// Cell(1) - a Cell(4) - alpha
// Cell(2) - b Cell(5) - beta
// Cell(3) - c Cell(6) - gamma
- apireal * Vol, // returns cell volume
- apireal * RRR, // array (3,3,6), returns
+ mmdb::machine::apireal * Vol, // returns cell volume
+ mmdb::machine::apireal * RRR, // array (3,3,6), returns
// orthogonalisation matrices
int * iRet // return code:
// RWBERR_Ok - success
@@ -2496,16 +2480,16 @@ FORTRAN_SUBR ( MMDB_F_ORTHMAT, mmdb_f_orthmat,
// matrices were not
// calculated
), ( // lengths-in-structure list
- int * iUnit, apireal * Cell, apireal * Vol,
- apireal * RRR, int * iRet
+ int * iUnit, mmdb::machine::apireal * Cell, mmdb::machine::apireal * Vol,
+ mmdb::machine::apireal * RRR, int * iRet
), ( // lengths-follow list
- int * iUnit, apireal * Cell, apireal * Vol,
- apireal * RRR, int * iRet
+ int * iUnit, mmdb::machine::apireal * Cell, mmdb::machine::apireal * Vol,
+ mmdb::machine::apireal * RRR, int * iRet
)
) {
-int i,j,k,l,m;
-PCMMDBCryst Cryst;
-realtype CelDel;
+int i,j,k,l,m;
+mmdb::PCryst Cryst;
+mmdb::realtype CelDel;
strcpy ( LastFunc,"MMDB_F_OrthMat" );
if (*iUnit>0)
@@ -2518,7 +2502,7 @@ realtype CelDel;
return;
}
- Cryst = Channel[k]->GetCryst();
+ Cryst = channel[k]->GetCryst();
if (Cryst==NULL) {
*iRet = RWBERR_NoFile;
LastRC = *iRet;
@@ -2527,18 +2511,18 @@ realtype CelDel;
CelDel = 0.0;
if (Cell[0]>0.0) {
- if ((Cryst->WhatIsSet & CSET_CellParams)==CSET_CellParams) {
+ if ((Cryst->WhatIsSet & mmdb::CSET_CellParams)==mmdb::CSET_CellParams) {
CelDel = fabs((Cell[0]-Cryst->a)/Cell[0]);
if (Cell[1]!=0.0)
- CelDel = RMax(CelDel,fabs((Cell[1]-Cryst->b)/Cell[1]));
+ CelDel = mmdb::RMax(CelDel,fabs((Cell[1]-Cryst->b)/Cell[1]));
if (Cell[2]!=0.0)
- CelDel = RMax(CelDel,fabs((Cell[2]-Cryst->c)/Cell[2]));
+ CelDel = mmdb::RMax(CelDel,fabs((Cell[2]-Cryst->c)/Cell[2]));
if (Cell[3]!=0.0)
- CelDel = RMax(CelDel,fabs((Cell[3]-Cryst->alpha)/Cell[3]));
+ CelDel = mmdb::RMax(CelDel,fabs((Cell[3]-Cryst->alpha)/Cell[3]));
if (Cell[4]!=0.0)
- CelDel = RMax(CelDel,fabs((Cell[4]-Cryst->beta )/Cell[4]));
+ CelDel = mmdb::RMax(CelDel,fabs((Cell[4]-Cryst->beta )/Cell[4]));
if (Cell[5]!=0.0)
- CelDel = RMax(CelDel,fabs((Cell[5]-Cryst->gamma)/Cell[5]));
+ CelDel = mmdb::RMax(CelDel,fabs((Cell[5]-Cryst->gamma)/Cell[5]));
if (FSimRWBROOK && (CelDel>0.01))
printf ( "\n Inconsistency in Cell Dimensions"
" - replacing old:\n"
@@ -2556,17 +2540,17 @@ realtype CelDel;
Cryst->alpha = Cell[3];
Cryst->beta = Cell[4];
Cryst->gamma = Cell[5];
- Cryst->WhatIsSet |= CSET_CellParams;
+ Cryst->WhatIsSet |= mmdb::CSET_CellParams;
} else {
- Cell[0] = (apireal)Cryst->a;
- Cell[1] = (apireal)Cryst->b;
- Cell[2] = (apireal)Cryst->c;
- Cell[3] = (apireal)Cryst->alpha;
- Cell[4] = (apireal)Cryst->beta;
- Cell[5] = (apireal)Cryst->gamma;
+ Cell[0] = (mmdb::machine::apireal)Cryst->a;
+ Cell[1] = (mmdb::machine::apireal)Cryst->b;
+ Cell[2] = (mmdb::machine::apireal)Cryst->c;
+ Cell[3] = (mmdb::machine::apireal)Cryst->alpha;
+ Cell[4] = (mmdb::machine::apireal)Cryst->beta;
+ Cell[5] = (mmdb::machine::apireal)Cryst->gamma;
}
- if ((Cryst->WhatIsSet & CSET_CellParams)!=CSET_CellParams) {
+ if ((Cryst->WhatIsSet & mmdb::CSET_CellParams)!=mmdb::CSET_CellParams) {
*iRet = RWBERR_NoCellParams;
LastRC = *iRet;
return;
@@ -2576,16 +2560,16 @@ realtype CelDel;
// Cryst->CalcOrthMatrices(); <-- old version, changed 09.01.2004
Cryst->CalcCoordTransforms();
- Cryst->WhatIsSet |= CSET_Transforms;
+ Cryst->WhatIsSet |= mmdb::CSET_Transforms;
- if (CelDel>0.01) *Vol = -(apireal)Cryst->Vol;
- else *Vol = (apireal)Cryst->Vol;
+ if (CelDel>0.01) *Vol = -(mmdb::machine::apireal)Cryst->Vol;
+ else *Vol = (mmdb::machine::apireal)Cryst->Vol;
l = 0;
for (j=0;j<3;j++)
for (i=0;i<3;i++)
for (m=0;m<6;m++)
- RRR[l++] = (apireal)Cryst->RR[m][j][i];
+ RRR[l++] = (mmdb::machine::apireal)Cryst->RR[m][j][i];
LastRC = *iRet;
@@ -2596,7 +2580,7 @@ FORTRAN_SUBR ( MMDB_F_CVANISOU, mmdb_f_cvanisou,
( // lengths-at-end list
int * iUnit, // unit number; *iUnit<=0 means
// "the last mentioned unit"
- apireal * U, // array of coordinates to convert
+ mmdb::machine::apireal * U, // array of coordinates to convert
int * iFlag, // =0: convert from fract. to orthog.
// =1: convert from orthog. to fract.
int * iRet // return code:
@@ -2611,14 +2595,14 @@ FORTRAN_SUBR ( MMDB_F_CVANISOU, mmdb_f_cvanisou,
// matrices were not
// calculated
), ( // lengths-in-structure list
- int * iUnit, apireal * U, int * iFlag, int * iRet
+ int * iUnit, mmdb::machine::apireal * U, int * iFlag, int * iRet
), ( // lengths-follow list
- int * iUnit, apireal * U, int * iFlag, int * iRet
+ int * iUnit, mmdb::machine::apireal * U, int * iFlag, int * iRet
)
) {
-int k,i;
-PCMMDBCryst Cryst;
-realtype U1[6];
+int k,i;
+mmdb::PCryst Cryst;
+mmdb::realtype U1[6];
strcpy ( LastFunc,"MMDB_F_CVAnisou" );
if (*iUnit>0)
@@ -2631,7 +2615,7 @@ realtype U1[6];
return;
}
- Cryst = Channel[k]->GetCryst();
+ Cryst = channel[k]->GetCryst();
if (Cryst==NULL) {
*iRet = RWBERR_NoFile;
LastRC = *iRet;
@@ -2650,7 +2634,7 @@ realtype U1[6];
if (*iRet==RWBERR_Ok)
for (i=0;i<6;i++)
- U[i] = (apireal)U1[i];
+ U[i] = (mmdb::machine::apireal)U1[i];
LastRC = *iRet;
@@ -2662,7 +2646,7 @@ FORTRAN_SUBR ( MMDB_F_WREMARK, mmdb_f_wremark,
( // lengths-at-end list
int * iUnit, // unit number; *iUnit<=0 means
// "the last mentioned unit"
- fpstr Line, // line to be added
+ mmdb::machine::fpstr Line, // line to be added
int * iRet, // return code:
// RWBERR_Ok - success
// RWBERR_NoChannel if unit
@@ -2674,9 +2658,9 @@ FORTRAN_SUBR ( MMDB_F_WREMARK, mmdb_f_wremark,
// returned by xyzopen1_(..)
int Line_len // fortran-hidden length of Line
), ( // lengths-in-structure list
- int * iUnit, fpstr Line, int * iRet
+ int * iUnit, mmdb::machine::fpstr Line, int * iRet
), ( // lengths-follow list
- int * iUnit, fpstr Line, int Line_len, int *iRet
+ int * iUnit, mmdb::machine::fpstr Line, int Line_len, int *iRet
)
) {
int k;
@@ -2693,22 +2677,22 @@ char S[500];
return;
}
- if (Channel[k]->MMDBManager) {
- GetStrTer ( S,FTN_STR(Line),FTN_LEN(Line),sizeof(S),FTN_LEN(Line) );
- *iRet = Channel[k]->MMDBManager->PutPDBString ( S );
+ if (channel[k]->MMDBManager) {
+ mmdb::GetStrTer ( S,FTN_STR(Line),FTN_LEN(Line),sizeof(S),FTN_LEN(Line) );
+ *iRet = channel[k]->MMDBManager->PutPDBString ( S );
} else
*iRet = RWBERR_NoFile;
LastRC = *iRet;
-
+
}
/*
FORTRAN_SUBR ( RBRINV, rbrinv,
- ( apireal * A, apireal * AI ),
- ( apireal * A, apireal * AI ),
- ( apireal * A, apireal * AI ) ) {
+ ( mmdb::machine::apireal * A, mmdb::machine::apireal * AI ),
+ ( mmdb::machine::apireal * A, mmdb::machine::apireal * AI ),
+ ( mmdb::machine::apireal * A, mmdb::machine::apireal * AI ) ) {
mat44 A1,AI1;
int i,j,k;
@@ -2729,16 +2713,16 @@ int i,j,k;
/*
FORTRAN_SUBR ( RES3TO1, res3to1,
( // lengths-at-end list
- fpstr ResNm3, // 3-char name, 4th char
+ mmdb::machine::fpstr ResNm3, // 3-char name, 4th char
// will be set blank
- fpstr ResNm1, // 1-char name
+ mmdb::machine::fpstr ResNm1, // 1-char name
int ResNm3_len, // fortran-hidden length of ResNm3
int ResNm1_len // fortran-hidden length of ResNm3
), ( // lengths-in-structure list
- fpstr ResNm3, fpstr ResNm1
+ mmdb::machine::fpstr ResNm3, mmdb::machine::fpstr ResNm1
), ( // lengths-follow list
- fpstr ResNm3, int ResNm3_len,
- fpstr ResNm1, int ResNm1_len
+ mmdb::machine::fpstr ResNm3, int ResNm3_len,
+ mmdb::machine::fpstr ResNm1, int ResNm1_len
)
) {
int i;
@@ -2774,71 +2758,71 @@ int i;
}
*/
-static pstr MSG_NoChannel = pstr("unassigned unit");
-static pstr MSG_NoFile = pstr("unassigned unit or disposed file");
-static pstr MSG_NoLogicalName = pstr("logical name does not exist");
-
-static pstr MSG_CantOpenFile = pstr("cannot open a file");
-static pstr MSG_WrongInteger = pstr("unrecognized integer at reading a file");
-static pstr MSG_WrongModelNo = pstr("wrong model number read from a file");
-static pstr MSG_DuplicatedModel = pstr("duplicated model number");
-static pstr MSG_ForeignFile = pstr("unknown file format");
-static pstr MSG_WrongEdition = pstr("unknown file version");
-
-static pstr MSG_ATOM_Unrecognd = pstr("unrecognized data in coordinate section");
-static pstr MSG_ATOM_AlreadySet = pstr("duplicate atom serial number");
-static pstr MSG_ATOM_NoResidue = pstr("residue for atom cannot be found");
-static pstr MSG_ATOM_Unmatch = pstr("ambiguous data in coordinate section");
-
-static pstr MSG_NoAdvance = pstr("atom position was not advanced");
-static pstr MSG_EmptyPointer = pstr("atom was not allocated");
-static pstr MSG_NoMatrices = pstr("no coordinate transformation matrices");
-
-static pstr MSG_NoCoordinates = pstr("no atom coordinates set");
-
-static pstr MSG_Disagreement = pstr("ambiguous cell parameters");
-static pstr MSG_NoOrthCode = pstr("no orthogonalization code");
-static pstr MSG_NoCheck = pstr("missing check of cell parameters");
-
-static pstr MSG_NoCellParams = pstr("no cell parameters");
-
-static pstr MSG_NotACIFFile = pstr("not a CIF file: 'data_' tag missing");
-static pstr MSG_NoData = pstr("expected data is not met at reading a file");
-static pstr MSG_UnrecognCIFItems = pstr("unrecognized CIF items (syntax error?)");
-static pstr MSG_MissingCIFField = pstr("missing CIF data field");
-static pstr MSG_EmptyCIFLoop = pstr("CIF loop does not contain any data");
-static pstr MSG_UnexpEndOfCIF = pstr("unexpected end of CIF file");
-static pstr MSG_MissgCIFLoopField = pstr("CIF loop is incomplete");
-static pstr MSG_NotACIFStructure = pstr("wrong use of CIF structure (as a loop?)");
-static pstr MSG_NotACIFLoop = pstr("wrong use of CIF loop (as a structure?)");
-static pstr MSG_WrongReal = pstr("unrecognized real at reading a file");
-
-static pstr MSG_WrongChainID = pstr("Wrong or inconsistent chain ID");
-static pstr MSG_WrongEntryID = pstr("Wrong or insonsistent entry ID");
-static pstr MSG_SEQRES_serNum = pstr("Wrong serial number in SEQRES");
-static pstr MSG_SEQRES_numRes = pstr("Wrong number of residues in SEQRES");
-static pstr MSG_SEQRES_extraRes = pstr("Extra residues in SEQRES");
-static pstr MSG_NCSM_Unrecogn = pstr("Unrecognized item in NCSM cards");
-static pstr MSG_NCSM_AlreadySet = pstr("Attempt to reset NCSM");
-static pstr MSG_NCSM_WrongSerial = pstr("Wrong serial number in NCSM cards");
-static pstr MSG_NCSM_UnmatchIG = pstr("Unmatched IG parameter in NCSM cards");
-static pstr MSG_NoModel = pstr("MMDB's error in structuring models");
-static pstr MSG_NoSheetID = pstr("No sheet ID on SHEET card(s)");
-static pstr MSG_WrongSheetID = pstr("Wrong sheet ID on SHEET card(s)");
-static pstr MSG_WrongStrandNo = pstr("Wrong strand no. on SHEET card(s)");
-static pstr MSG_WrongNofStrands = pstr("Wrong number of strands in sheet");
-static pstr MSG_WrongSheetOrder = pstr("Wrong sheet ordering");
-static pstr MSG_HBondInconsistency = pstr("Inconsistency in H-bonds");
-static pstr MSG_EmptyResidueName = pstr("No (blank) residue name");
-static pstr MSG_DuplicateSeqNum = pstr("Duplicated sequence number and insertion code");
-static pstr MSG_GeneralError1 = pstr("MMDB's general error #1");
-
-
-static pstr MSG_Error1 = pstr("internal error #1 -- report to developer");
-static pstr MSG_Error2 = pstr("internal error #2 -- report to developer");
-static pstr MSG_Error3 = pstr("internal error #3 -- report to developer");
-
-static pstr MSG_Unknown = pstr("unknown return code");
+static mmdb::pstr MSG_NoChannel = mmdb::pstr("unassigned unit");
+static mmdb::pstr MSG_NoFile = mmdb::pstr("unassigned unit or disposed file");
+static mmdb::pstr MSG_NoLogicalName = mmdb::pstr("logical name does not exist");
+
+static mmdb::pstr MSG_CantOpenFile = mmdb::pstr("cannot open a file");
+static mmdb::pstr MSG_WrongInteger = mmdb::pstr("unrecognized integer at reading a file");
+static mmdb::pstr MSG_WrongModelNo = mmdb::pstr("wrong model number read from a file");
+static mmdb::pstr MSG_DuplicatedModel = mmdb::pstr("duplicated model number");
+static mmdb::pstr MSG_ForeignFile = mmdb::pstr("unknown file format");
+static mmdb::pstr MSG_WrongEdition = mmdb::pstr("unknown file version");
+
+static mmdb::pstr MSG_ATOM_Unrecognd = mmdb::pstr("unrecognized data in coordinate section");
+static mmdb::pstr MSG_ATOM_AlreadySet = mmdb::pstr("duplicate atom serial number");
+static mmdb::pstr MSG_ATOM_NoResidue = mmdb::pstr("residue for atom cannot be found");
+static mmdb::pstr MSG_ATOM_Unmatch = mmdb::pstr("ambiguous data in coordinate section");
+
+static mmdb::pstr MSG_NoAdvance = mmdb::pstr("atom position was not advanced");
+static mmdb::pstr MSG_EmptyPointer = mmdb::pstr("atom was not allocated");
+static mmdb::pstr MSG_NoMatrices = mmdb::pstr("no coordinate transformation matrices");
+
+static mmdb::pstr MSG_NoCoordinates = mmdb::pstr("no atom coordinates set");
+
+static mmdb::pstr MSG_Disagreement = mmdb::pstr("ambiguous cell parameters");
+static mmdb::pstr MSG_NoOrthCode = mmdb::pstr("no orthogonalization code");
+static mmdb::pstr MSG_NoCheck = mmdb::pstr("missing check of cell parameters");
+
+static mmdb::pstr MSG_NoCellParams = mmdb::pstr("no cell parameters");
+
+static mmdb::pstr MSG_NotACIFFile = mmdb::pstr("not a CIF file: 'data_' tag missing");
+static mmdb::pstr MSG_NoData = mmdb::pstr("expected data is not met at reading a file");
+static mmdb::pstr MSG_UnrecognCIFItems = mmdb::pstr("unrecognized CIF items (syntax error?)");
+static mmdb::pstr MSG_MissingCIFField = mmdb::pstr("missing CIF data field");
+static mmdb::pstr MSG_EmptyCIFLoop = mmdb::pstr("CIF loop does not contain any data");
+static mmdb::pstr MSG_UnexpEndOfCIF = mmdb::pstr("unexpected end of CIF file");
+static mmdb::pstr MSG_MissgCIFLoopField = mmdb::pstr("CIF loop is incomplete");
+static mmdb::pstr MSG_NotACIFStructure = mmdb::pstr("wrong use of CIF structure (as a loop?)");
+static mmdb::pstr MSG_NotACIFLoop = mmdb::pstr("wrong use of CIF loop (as a structure?)");
+static mmdb::pstr MSG_WrongReal = mmdb::pstr("unrecognized real at reading a file");
+
+static mmdb::pstr MSG_WrongChainID = mmdb::pstr("Wrong or inconsistent chain ID");
+static mmdb::pstr MSG_WrongEntryID = mmdb::pstr("Wrong or insonsistent entry ID");
+static mmdb::pstr MSG_SEQRES_serNum = mmdb::pstr("Wrong serial number in SEQRES");
+static mmdb::pstr MSG_SEQRES_numRes = mmdb::pstr("Wrong number of residues in SEQRES");
+static mmdb::pstr MSG_SEQRES_extraRes = mmdb::pstr("Extra residues in SEQRES");
+static mmdb::pstr MSG_NCSM_Unrecogn = mmdb::pstr("Unrecognized item in NCSM cards");
+static mmdb::pstr MSG_NCSM_AlreadySet = mmdb::pstr("Attempt to reset NCSM");
+static mmdb::pstr MSG_NCSM_WrongSerial = mmdb::pstr("Wrong serial number in NCSM cards");
+static mmdb::pstr MSG_NCSM_UnmatchIG = mmdb::pstr("Unmatched IG parameter in NCSM cards");
+static mmdb::pstr MSG_NoModel = mmdb::pstr("MMDB's error in structuring models");
+static mmdb::pstr MSG_NoSheetID = mmdb::pstr("No sheet ID on SHEET card(s)");
+static mmdb::pstr MSG_WrongSheetID = mmdb::pstr("Wrong sheet ID on SHEET card(s)");
+static mmdb::pstr MSG_WrongStrandNo = mmdb::pstr("Wrong strand no. on SHEET card(s)");
+static mmdb::pstr MSG_WrongNofStrands = mmdb::pstr("Wrong number of strands in sheet");
+static mmdb::pstr MSG_WrongSheetOrder = mmdb::pstr("Wrong sheet ordering");
+static mmdb::pstr MSG_HBondInconsistency = mmdb::pstr("Inconsistency in H-bonds");
+static mmdb::pstr MSG_EmptyResidueName = mmdb::pstr("No (blank) residue name");
+static mmdb::pstr MSG_DuplicateSeqNum = mmdb::pstr("Duplicated sequence number and insertion code");
+static mmdb::pstr MSG_GeneralError1 = mmdb::pstr("MMDB's general error #1");
+
+
+static mmdb::pstr MSG_Error1 = mmdb::pstr("internal error #1 -- report to developer");
+static mmdb::pstr MSG_Error2 = mmdb::pstr("internal error #2 -- report to developer");
+static mmdb::pstr MSG_Error3 = mmdb::pstr("internal error #3 -- report to developer");
+
+static mmdb::pstr MSG_Unknown = mmdb::pstr("unknown return code");
#define nWarnings 7
@@ -2853,14 +2837,14 @@ static int RWBWarCode[nWarnings] = {
RWBWAR_NoTempFactor
};
-static pstr RWBWarning[nWarnings] = {
- pstr("output file rewind"),
- pstr("rewind or backspace at top of file"),
- pstr("atom serial number does not match position"),
- pstr("unknown form factor encountered"),
- pstr("ambiguous form factor encountered"),
- pstr("occupancy was not set"),
- pstr("temperature factor was not set")
+static mmdb::pstr RWBWarning[nWarnings] = {
+ mmdb::pstr("output file rewind"),
+ mmdb::pstr("rewind or backspace at top of file"),
+ mmdb::pstr("atom serial number does not match position"),
+ mmdb::pstr("unknown form factor encountered"),
+ mmdb::pstr("ambiguous form factor encountered"),
+ mmdb::pstr("occupancy was not set"),
+ mmdb::pstr("temperature factor was not set")
};
@@ -2878,9 +2862,9 @@ FORTRAN_SUBR ( RBERRSTOP, rberrstop,
int * iPlace, int * iRet,
int * iUnit, int * iStop
) ) {
-int i,k,lcount;
-pstr Msg;
-char ErrLine[500];
+int i,k,lcount;
+mmdb::pstr Msg;
+char ErrLine[500];
strcpy ( ErrLine,"" );
lcount = -11;
@@ -2918,7 +2902,7 @@ char ErrLine[500];
case RWBERR_NoOrthCode : Msg = MSG_NoOrthCode; break;
case RWBERR_NoCheck : Msg = MSG_NoCheck; break;
- case RWBERR_NoCellParams : Msg = MSG_NoCellParams; break;
+ case RWBERR_NoCellParams : Msg = MSG_NoCellParams; break;
case RWBERR_NotACIFFile : Msg = MSG_NotACIFFile; break;
case RWBERR_NoData : Msg = MSG_NoData; break;
@@ -2954,15 +2938,15 @@ char ErrLine[500];
case RWBERR_Error1 : Msg = MSG_Error1; break;
case RWBERR_Error2 : Msg = MSG_Error2; break;
case RWBERR_Error3 : Msg = MSG_Error3; break;
-
+
default :
if ((*iRet & RWBWAR_Warning)==RWBWAR_Warning) {
Msg = NULL;
printf ( "\n\n *** Warning(s): point code unit function\n" );
printf ( " *** %5i %4i %4i %s\n",
*iPlace,*iRet,*iUnit,LastFunc );
- if (k>=0)
- printf ( " *** file : %s\n",Channel[k]->FName );
+ if (k>=0)
+ printf ( " *** file : %s\n",channel[k]->FName );
for (i=0;i<nWarnings;i++)
if ((*iRet & RWBWarCode[i])==RWBWarCode[i]) {
Msg = RWBWarning[i];
@@ -2970,7 +2954,7 @@ char ErrLine[500];
if ((*iRet & RWBWAR_WrongSerial)==RWBWAR_WrongSerial) {
if (k>0)
printf ( " *** position %i, serial number %i\n",
- Channel[k]->fPos,LastSer );
+ channel[k]->fPos,LastSer );
else
printf ( " *** position unavailable, serial number %i\n",
LastSer );
@@ -2988,20 +2972,20 @@ char ErrLine[500];
((*iRet<=RWBERR_ATOM_Unrecognd) && (*iRet>=RWBERR_ATOM_Unmatch)) ||
((*iRet<=RWBERR_NoData) && (*iRet>=RWBERR_DuplicateSeqNum))
))
- Channel[k]->GetInputBuffer ( ErrLine,lcount );
+ channel[k]->GetInputBuffer ( ErrLine,lcount );
printf ( " \n *** RWBROOK error: point code unit function\n" );
printf ( " *** %5i %4i %4i %s\n",*iPlace,*iRet,
*iUnit,LastFunc );
k = GetChannel(*iUnit);
- if (k>=0)
- printf ( " *** file : %s\n",Channel[k]->FName );
+ if (k>=0)
+ printf ( " *** file : %s\n",channel[k]->FName );
printf ( " *** reason : %s\n",Msg );
if (lcount>=0)
printf ( " *** at input line #%i:\n"
" %s\n",lcount,ErrLine );
- else if (lcount==-1)
+ else if (lcount==-1)
printf ( " *** at taking the following data from CIF:\n"
" %s\n",ErrLine );
@@ -3044,9 +3028,12 @@ FORTRAN_SUBR ( RBCHECKERR, rbcheckerr,
*/
FORTRAN_SUBR ( HY36ENCODE_F, hy36encode_f,
- (const int *iwidth, int *value, fpstr strval, int strval_len),
- (const int *iwidth, int *value, fpstr strval),
- (const int *iwidth, int *value, fpstr strval, int strval_len))
+ (const int *iwidth, int *value,
+ mmdb::machine::fpstr strval, int strval_len),
+ (const int *iwidth, int *value,
+ mmdb::machine::fpstr strval),
+ (const int *iwidth, int *value,
+ mmdb::machine::fpstr strval, int strval_len))
{
unsigned width;
char result[6];
@@ -3056,7 +3043,7 @@ FORTRAN_SUBR ( HY36ENCODE_F, hy36encode_f,
if (hy36encode(width, *value, result)) {
printf("problem in hy36encode_f! \n");
}
- strcpy_ns(FTN_STR(strval),result,FTN_LEN(strval));
+ mmdb::strcpy_ns(FTN_STR(strval),result,FTN_LEN(strval));
}
@@ -3072,9 +3059,12 @@ FORTRAN_SUBR ( HY36ENCODE_F, hy36encode_f,
FORTRAN_SUBR ( HY36DECODE_F, hy36decode_f,
- (const int *iwidth, fpstr strval, int *value, int strval_len),
- (const int *iwidth, fpstr strval, int *value),
- (const int *iwidth, fpstr strval, int strval_len, int *value))
+ (const int *iwidth,
+ mmdb::machine::fpstr strval, int *value, int strval_len),
+ (const int *iwidth,
+ mmdb::machine::fpstr strval, int *value),
+ (const int *iwidth,
+ mmdb::machine::fpstr strval, int strval_len, int *value))
{ UNUSED_ARGUMENT(strval);
unsigned width;
size_t length = FTN_LEN(strval);
diff --git a/mmdb/mmdb_rwbrook.h b/mmdb2/mmdb_rwbrook.h
old mode 100755
new mode 100644
similarity index 79%
rename from mmdb/mmdb_rwbrook.h
rename to mmdb2/mmdb_rwbrook.h
index 94d05fa..2f59f5f
--- a/mmdb/mmdb_rwbrook.h
+++ b/mmdb2/mmdb_rwbrook.h
@@ -1,4 +1,4 @@
-// $Id: mmdb_rwbrook.h,v 1.19 2012/01/26 17:52:20 ekr Exp $
+// $Id: mmdb_rwbrook.h $
// =================================================================
//
// CCP4 Coordinate Library: support of coordinate-related
@@ -6,13 +6,13 @@
//
// Copyright (C) Eugene Krissinel 2000-2008.
//
-// This library is free software: you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 3, modified in accordance with the provisions
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
// of the license to address the requirements of UK law.
//
-// You should have received a copy of the modified GNU Lesser
-// General Public License along with this library. If not, copies
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
//
// This program is distributed in the hope that it will be useful,
@@ -22,7 +22,7 @@
//
// =================================================================
//
-// 07.11.02 <-- Date of Last Modification.
+// 16.09.13 <-- Date of Last Modification.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// -----------------------------------------------------------------
//
@@ -64,7 +64,7 @@
// rberrstop_ ( error messenger )
// rbcheckerr_ ( a simple error messenger )
//
-// (C) E. Krissinel 2000-2008
+// (C) E. Krissinel 2000-2013
//
// =================================================================
//
@@ -73,96 +73,93 @@
#ifndef __MMDB_RWBrook__
#define __MMDB_RWBrook__
-#ifndef __MatType__
-#include "mattype_.h"
-#endif
-
-#ifndef __Machine__
-#include "machine_.h"
-#endif
+#include "mmdb_mattype.h"
+#include "mmdb_machine_.h"
// ****** mmdb_rwbrook error codes
-#define RWBERR_Ok 0
-#define RWBERR_NoChannel -1
-#define RWBERR_NoFile -2
-#define RWBERR_NoLogicalName -3
-
-#define RWBERR_CantOpenFile -4
-#define RWBERR_WrongInteger -5
-#define RWBERR_WrongModelNo -6
-#define RWBERR_DuplicatedModel -7
-#define RWBERR_ForeignFile -8
-#define RWBERR_WrongEdition -9
-
-#define RWBERR_ATOM_Unrecognd -10
-#define RWBERR_ATOM_AlreadySet -11
-#define RWBERR_ATOM_NoResidue -12
-#define RWBERR_ATOM_Unmatch -13
-
-#define RWBERR_NoAdvance -14
-#define RWBERR_EmptyPointer -15
-#define RWBERR_NoMatrices -16
-
-#define RWBERR_NoCoordinates -17
-
-#define RWBERR_Disagreement -18
-#define RWBERR_NoOrthCode -19
-#define RWBERR_NoCheck -20
-
-#define RWBERR_NoCellParams -21
-
-#define RWBERR_NotACIFFile -22
-#define RWBERR_NoData -23
-#define RWBERR_UnrecognCIFItems -24
-#define RWBERR_MissingCIFField -25
-#define RWBERR_EmptyCIFLoop -26
-#define RWBERR_UnexpEndOfCIF -27
-#define RWBERR_MissgCIFLoopField -28
-#define RWBERR_NotACIFStructure -29
-#define RWBERR_NotACIFLoop -30
-#define RWBERR_WrongReal -31
-
-#define RWBERR_WrongChainID -32
-#define RWBERR_WrongEntryID -33
-#define RWBERR_SEQRES_serNum -34
-#define RWBERR_SEQRES_numRes -35
-#define RWBERR_SEQRES_exraRes -36
-#define RWBERR_NCSM_Unrecogn -37
-#define RWBERR_NCSM_AlreadySet -38
-#define RWBERR_NCSM_WrongSerial -39
-#define RWBERR_NCSM_UnmatchIG -40
-#define RWBERR_NoModel -41
-#define RWBERR_NoSheetID -42
-#define RWBERR_WrongSheetID -43
-#define RWBERR_WrongStrandNo -44
-#define RWBERR_WrongNofStrands -45
-#define RWBERR_WrongSheetOrder -46
-#define RWBERR_HBondInconsis -47
-#define RWBERR_EmptyResidueName -48
-#define RWBERR_DuplicateSeqNum -49
-#define RWBERR_GeneralError1 -50
-
-
-#define RWBERR_Error1 -101
-#define RWBERR_Error2 -102
-#define RWBERR_Error3 -103
-
+enum RWB_ERROR {
+
+ RWBERR_Ok = 0,
+ RWBERR_NoChannel = -1,
+ RWBERR_NoFile = -2,
+ RWBERR_NoLogicalName = -3,
+
+ RWBERR_CantOpenFile = -4,
+ RWBERR_WrongInteger = -5,
+ RWBERR_WrongModelNo = -6,
+ RWBERR_DuplicatedModel = -7,
+ RWBERR_ForeignFile = -8,
+ RWBERR_WrongEdition = -9,
+
+ RWBERR_ATOM_Unrecognd = -10,
+ RWBERR_ATOM_AlreadySet = -11,
+ RWBERR_ATOM_NoResidue = -12,
+ RWBERR_ATOM_Unmatch = -13,
+
+ RWBERR_NoAdvance = -14,
+ RWBERR_EmptyPointer = -15,
+ RWBERR_NoMatrices = -16,
+
+ RWBERR_NoCoordinates = -17,
+
+ RWBERR_Disagreement = -18,
+ RWBERR_NoOrthCode = -19,
+ RWBERR_NoCheck = -20,
+
+ RWBERR_NoCellParams = -21,
+
+ RWBERR_NotACIFFile = -22,
+ RWBERR_NoData = -23,
+ RWBERR_UnrecognCIFItems = -24,
+ RWBERR_MissingCIFField = -25,
+ RWBERR_EmptyCIFLoop = -26,
+ RWBERR_UnexpEndOfCIF = -27,
+ RWBERR_MissgCIFLoopField = -28,
+ RWBERR_NotACIFStructure = -29,
+ RWBERR_NotACIFLoop = -30,
+ RWBERR_WrongReal = -31,
+
+ RWBERR_WrongChainID = -32,
+ RWBERR_WrongEntryID = -33,
+ RWBERR_SEQRES_serNum = -34,
+ RWBERR_SEQRES_numRes = -35,
+ RWBERR_SEQRES_exraRes = -36,
+ RWBERR_NCSM_Unrecogn = -37,
+ RWBERR_NCSM_AlreadySet = -38,
+ RWBERR_NCSM_WrongSerial = -39,
+ RWBERR_NCSM_UnmatchIG = -40,
+ RWBERR_NoModel = -41,
+ RWBERR_NoSheetID = -42,
+ RWBERR_WrongSheetID = -43,
+ RWBERR_WrongStrandNo = -44,
+ RWBERR_WrongNofStrands = -45,
+ RWBERR_WrongSheetOrder = -46,
+ RWBERR_HBondInconsis = -47,
+ RWBERR_EmptyResidueName = -48,
+ RWBERR_DuplicateSeqNum = -49,
+ RWBERR_GeneralError1 = -50,
+
+ RWBERR_Error1 = -101,
+ RWBERR_Error2 = -102,
+ RWBERR_Error3 = -103
+
+};
// ***** mmdb_rwbrook warning flags
// 0x00004000 means "it's a warning"
-#define RWBWAR_Warning 0x00004000
-#define RWBWAR_RewOutput 0x00004010
-#define RWBWAR_FileTop 0x00004020
-#define RWBWAR_WrongSerial 0x00004040
-#define RWBWAR_UnkFormFactor 0x00004080
-#define RWBWAR_AmbFormFactor 0x00004100
-#define RWBWAR_NoOccupancy 0x00004200
-#define RWBWAR_NoTempFactor 0x00004400
-
-
+enum RWB_WARNING {
+ RWBWAR_Warning = 0x00004000,
+ RWBWAR_RewOutput = 0x00004010,
+ RWBWAR_FileTop = 0x00004020,
+ RWBWAR_WrongSerial = 0x00004040,
+ RWBWAR_UnkFormFactor = 0x00004080,
+ RWBWAR_AmbFormFactor = 0x00004100,
+ RWBWAR_NoOccupancy = 0x00004200,
+ RWBWAR_NoTempFactor = 0x00004400
+};
// ------------------------------------------------------------------
@@ -174,7 +171,7 @@
FORTRAN_SUBR ( MMDB_F_INIT, mmdb_f_init, (),(),() );
-
+
// ------------------------------------------------------------------
// mmdb_f_quit_() disposes the file system. A correct use assumes that
@@ -184,7 +181,7 @@ FORTRAN_SUBR ( MMDB_F_INIT, mmdb_f_init, (),(),() );
// ~~~~~~~~~~~~~~~~~~~
FORTRAN_SUBR ( MMDB_F_QUIT, mmdb_f_quit, (),(),() );
-
+
// ------------------------------------------------------------------
@@ -217,7 +214,7 @@ FORTRAN_SUBR ( AUTOSERIALS,autoserials,
( int * iOnOff ),
( int * iOnOff ),
( int * iOnOff ) );
-
+
// ------------------------------------------------------------------
@@ -236,7 +233,7 @@ FORTRAN_SUBR ( SETREADCOORDS,setreadcoords,
( int * iOnOff ),
( int * iOnOff ),
( int * iOnOff ) );
-
+
// ------------------------------------------------------------------
@@ -299,25 +296,27 @@ FORTRAN_SUBR ( SIMRWBROOK,simrwbrook,
// FORTRAN equivalent: subroutine MMDB_F_Open ( LName,RWStat,FType,
// ~~~~~~~~~~~~~~~~~~~ iUnit,iRet )
// character*(*) LName,RWStat,FType
-// integer iUnit,iRet
+// integer iUnit,iRet
FORTRAN_SUBR ( MMDB_F_OPEN, mmdb_f_open,
( // lengths-at-end list
- fpstr LName, // logical name
- fpstr RWStat, // "INPUT" or "OUTPUT"
- fpstr FType, // "PDB", "CIF", "BIN" or " "
+ mmdb::machine::fpstr LName, // logical name
+ mmdb::machine::fpstr RWStat, // "INPUT" or "OUTPUT"
+ mmdb::machine::fpstr FType, // "PDB", "CIF", "BIN" or " "
int * iUnit, // channel number
int * iRet, // returns error code
int LName_len, // fortran-hidden length of LName
int RWStat_len, // fortran-hidden length of RWStat
int FType_len // fortran-hidden length of FType
), ( // lengths-in-structure list
- fpstr LName, fpstr RWStat, fpstr FType,
- int * iUnit, int * iRet
+ mmdb::machine::fpstr LName,
+ mmdb::machine::fpstr RWStat,
+ mmdb::machine::fpstr FType,
+ int * iUnit, int * iRet
), ( // lengths-follow list
- fpstr LName, int LName_len,
- fpstr RWStat, int RWStat_len,
- fpstr FType, int FType_len,
+ mmdb::machine::fpstr LName, int LName_len,
+ mmdb::machine::fpstr RWStat, int RWStat_len,
+ mmdb::machine::fpstr FType, int FType_len,
int * iUnit, int * iRet
) );
@@ -331,25 +330,27 @@ FORTRAN_SUBR ( MMDB_F_OPEN, mmdb_f_open,
// FORTRAN equivalent: subroutine MMDB_F_Open1 ( FName,RWStat,FType,
// ~~~~~~~~~~~~~~~~~~~ iUnit,iRet )
// character*(*) FName,RWStat,FType
-// integer iUnit,iRet
+// integer iUnit,iRet
FORTRAN_SUBR ( MMDB_F_OPEN1, mmdb_f_open1,
( // lengths-at-end list
- fpstr FName, // file name
- fpstr RWStat, // "INPUT" or "OUTPUT"
- fpstr FType, // "PDB", "CIF", "BIN" or " "
+ mmdb::machine::fpstr FName, // file name
+ mmdb::machine::fpstr RWStat, // "INPUT" or "OUTPUT"
+ mmdb::machine::fpstr FType, // "PDB", "CIF", "BIN" or " "
int * iUnit, // channel number
int * iRet, // returns error code
int FName_len, // fortran-hidden length of FName
int RWStat_len, // fortran-hidden length of RWStat
int FType_len // fortran-hidden length of FType
), ( // lengths-in-structure list
- fpstr FName, fpstr RWStat, fpstr FType,
- int * iUnit, int * iRet
+ mmdb::machine::fpstr FName,
+ mmdb::machine::fpstr RWStat,
+ mmdb::machine::fpstr FType,
+ int * iUnit, int * iRet
), ( // lengths-follow list
- fpstr FName, int FName_len,
- fpstr RWStat, int RWStat_len,
- fpstr FType, int FType_len,
+ mmdb::machine::fpstr FName, int FName_len,
+ mmdb::machine::fpstr RWStat, int RWStat_len,
+ mmdb::machine::fpstr FType, int FType_len,
int * iUnit, int * iRet
) );
@@ -447,21 +448,21 @@ FORTRAN_SUBR ( MMDB_F_DELETE, mmdb_f_delete,
FORTRAN_SUBR ( MMDB_F_SETTYPE, mmdb_f_settype,
( // lengths-at-end list
int * iUnit, // unit number
- fpstr FType, // "PDB", "CIF", "BIN" or " "
- fpstr RWStat, // "INPUT" or "OUTPUT"
+ mmdb::machine::fpstr FType, // "PDB", "CIF", "BIN" or " "
+ mmdb::machine::fpstr RWStat, // "INPUT" or "OUTPUT"
int * iRet, // returns -1 if unit not found,
// otherwise 0
int FType_len, // fortran-hidden length of FType
int RWStat_len // fortran-hidden length of RWStat
), ( // lengths-in-structure list
- int * iUnit, fpstr FType,
- fpstr RWStat, int * iRet
+ int * iUnit, mmdb::machine::fpstr FType,
+ mmdb::machine::fpstr RWStat, int * iRet
), ( // lengths-follow list
- int * iUnit,
- fpstr FType, int FType_len,
- fpstr RWStat, int RWStat_len,
+ int * iUnit,
+ mmdb::machine::fpstr FType, int FType_len,
+ mmdb::machine::fpstr RWStat, int RWStat_len,
int * iRet
- ) );
+ ) );
@@ -483,15 +484,15 @@ FORTRAN_SUBR ( MMDB_F_SETTYPE, mmdb_f_settype,
FORTRAN_SUBR ( MMDB_F_SETNAME, mmdb_f_setname,
( // lengths-at-end list
int * iUnit, // unit number
- fpstr FName, // file name
+ mmdb::machine::fpstr FName, // file name
int * iRet, // returns -1 if unit not found,
// otherwise 0
int FName_len // fortran-hidden length of FName
), ( // lengths-in-structure list
- int * iUnit, fpstr FName, int * iRet
+ int * iUnit, mmdb::machine::fpstr FName, int * iRet
), ( // lengths-follow list
int * iUnit,
- fpstr FName, int FName_len,
+ mmdb::machine::fpstr FName, int FName_len,
int * iRet
) );
@@ -540,7 +541,7 @@ FORTRAN_SUBR ( MMDB_F_CLOSE, mmdb_f_close,
// If unit iUnit is associated with input, mmdb_f_advance_(..) sets
// the internal pointer on the next atom in the file. The atom
-// properties may then be retrieved using mmdb_f_atom_(..) and
+// properties may then be retrieved using mmdb_f_atom_(..) and
// mmdb_f_coord_(..). If iTer is set to 0, then 'ter' cards are
// completely ignored. If iTer is set to 1, then 'ter' card will
// cause return with iRet=1 with internal pointer left on this 'ter'
@@ -697,17 +698,17 @@ FORTRAN_SUBR ( MMDB_F_ATOM, mmdb_f_atom,
( // lengths-at-end list
int * iUnit, // unit number
int * iSer, // atom serial number
- fpstr AtNam, // atom name (left justified)
- fpstr ResNam, // residue name
- fpstr ChnNam, // chain name
+ mmdb::machine::fpstr AtNam, // atom name (left justified)
+ mmdb::machine::fpstr ResNam, // residue name
+ mmdb::machine::fpstr ChnNam, // chain name
int * iResN, // residue number as an integer
- fpstr ResNo, // residue number as character (input only)
- fpstr InsCod, // the insertion code
- fpstr AltCod, // the alternate conformation code
- fpstr segID, // segment ID
+ mmdb::machine::fpstr ResNo, // residue number as character (input only)
+ mmdb::machine::fpstr InsCod, // the insertion code
+ mmdb::machine::fpstr AltCod, // the alternate conformation code
+ mmdb::machine::fpstr segID, // segment ID
int * IZ, // atomic number (input only, returned as
// 7 from ambiguous atoms)
- fpstr ID, // atomic ID related to atomic number
+ mmdb::machine::fpstr ID, // atomic ID related to atomic number
// (element symbol right justified), plus
// the ionic state +2, +3 etc..
//
@@ -724,7 +725,7 @@ FORTRAN_SUBR ( MMDB_F_ATOM, mmdb_f_atom,
// RWBWAR_WrongSerial if serial number
// differs from the position
// number in the file
- // RWBWAR_UnkFormFactor unknown formfactor
+ // RWBWAR_UnkFormFactor unknown formfactor
// RWBWAR_AmbFormFactor ambiguous formfactor
//
int AtNam_len, // fortran-hidden length of AtNam
@@ -736,22 +737,28 @@ FORTRAN_SUBR ( MMDB_F_ATOM, mmdb_f_atom,
int segID_len, // fortran-hidden length of SegID
int ID_len // fortran-hidden length of ID
), ( // lengths-in-structure list
- int * iUnit, int * iSer, fpstr AtNam, fpstr ResNam,
- fpstr ChnNam, int * iResN, fpstr ResNo, fpstr InsCod,
- fpstr AltCod, fpstr segID, int * IZ, fpstr ID,
+ int * iUnit, int * iSer,
+ mmdb::machine::fpstr AtNam,
+ mmdb::machine::fpstr ResNam,
+ mmdb::machine::fpstr ChnNam, int * iResN,
+ mmdb::machine::fpstr ResNo,
+ mmdb::machine::fpstr InsCod,
+ mmdb::machine::fpstr AltCod,
+ mmdb::machine::fpstr segID, int * IZ,
+ mmdb::machine::fpstr ID,
int * iRet
), ( // lengths-follow list
int * iUnit, int * iSer,
- fpstr AtNam, int AtNam_len,
- fpstr ResNam, int ResNam_len,
- fpstr ChnNam, int ChnNam_len,
+ mmdb::machine::fpstr AtNam, int AtNam_len,
+ mmdb::machine::fpstr ResNam, int ResNam_len,
+ mmdb::machine::fpstr ChnNam, int ChnNam_len,
int * iResN,
- fpstr ResNo, int ResNo_len,
- fpstr InsCod, int InsCod_len,
- fpstr AltCod, int AltCod_len,
- fpstr segID, int segID_len,
+ mmdb::machine::fpstr ResNo, int ResNo_len,
+ mmdb::machine::fpstr InsCod, int InsCod_len,
+ mmdb::machine::fpstr AltCod, int AltCod_len,
+ mmdb::machine::fpstr segID, int segID_len,
int * IZ,
- fpstr ID, int ID_len,
+ mmdb::machine::fpstr ID, int ID_len,
int * iRet
) );
@@ -767,7 +774,7 @@ FORTRAN_SUBR ( MMDB_F_ATOM, mmdb_f_atom,
FORTRAN_SUBR ( MMDB_F_COPYATOM, mmdb_f_copyatom,
( // length-at-end list
- int * iUnit1, // source channel number
+ int * iUnit1, // source channel number
int * iUnit2, // destination channel number
int * iRet // returns
// RWBERR_NoChannel if iUnit was not
@@ -775,7 +782,7 @@ FORTRAN_SUBR ( MMDB_F_COPYATOM, mmdb_f_copyatom,
// RWBERR_EmptyPointer if atom was not
// advanced
// >=0 : success
- ), ( // length-in-structure list
+ ), ( // length-in-structure list
int * iUnit1, int * iUnit2, int * iRet
), ( // length-follow list
int * iUnit1, int * iUnit2, int * iRet
@@ -806,22 +813,22 @@ FORTRAN_SUBR ( MMDB_F_COPYATOM, mmdb_f_copyatom,
FORTRAN_SUBR ( MMDB_F_COORD, mmdb_f_coord,
( // lengths-at-end list
int * iUnit, // unit number
- fpstr XFlag, // "F" or "O" flag for the fractional
+ mmdb::machine::fpstr XFlag, // "F" or "O" flag for the fractional
// or orthogonal coordinates x,y,z
// for output files XFlag may also be
// set to "HF" or "HO", where "F" and
// "O" have the same meaning as before
// and "H" indicates that the atom
// should be marked as heteroatom
- fpstr BFlag , // "F" or "O" flag for temperature
+ mmdb::machine::fpstr BFlag , // "F" or "O" flag for temperature
// factor in fractional or orthogonal
// Us
- apireal * x, // x-coordinate
- apireal * y, // y-coordinate
- apireal * z, // z-coordinate
- apireal * occ, // occupancy
- apireal * BIso, // isotropic temperature factor
- apireal * U, // array(6) of the anisotr. t-factor
+ mmdb::machine::apireal * x, // x-coordinate
+ mmdb::machine::apireal * y, // y-coordinate
+ mmdb::machine::apireal * z, // z-coordinate
+ mmdb::machine::apireal * occ, // occupancy
+ mmdb::machine::apireal * BIso, // isotropic temperature factor
+ mmdb::machine::apireal * U, // array(6) of the anisotr. t-factor
int * iRet, // returns
// RWBERR_NoChannel if iUnit was not
// initialized
@@ -834,7 +841,7 @@ FORTRAN_SUBR ( MMDB_F_COORD, mmdb_f_coord,
// not set in the atom
//
// >=0 : success, warning flags:
- // RWBERR_NoOccupancy if occupancy was
+ // RWBERR_NoOccupancy if occupancy was
// not set in the atom
// RWBERR_NoTempFactor if temp. factor was
// not set in the atom
@@ -842,16 +849,26 @@ FORTRAN_SUBR ( MMDB_F_COORD, mmdb_f_coord,
int XFlag_len, // fortran-hidden length of XFlag
int BFlag_len // fortran-hidden length of BFlag
), ( // lengths-in-structure list
- int * iUnit, fpstr XFlag, fpstr BFlag,
- apireal * x, apireal * y, apireal * z,
- apireal * occ, apireal * BIso, apireal * U,
+ int * iUnit,
+ mmdb::machine::fpstr XFlag,
+ mmdb::machine::fpstr BFlag,
+ mmdb::machine::apireal * x,
+ mmdb::machine::apireal * y,
+ mmdb::machine::apireal * z,
+ mmdb::machine::apireal * occ,
+ mmdb::machine::apireal * BIso,
+ mmdb::machine::apireal * U,
int * iRet
), ( // lengths-follow list
int * iUnit,
- fpstr XFlag, int XFlag_len,
- fpstr BFlag, int BFlag_len,
- apireal * x, apireal * y, apireal * z,
- apireal * occ, apireal * BIso, apireal * U,
+ mmdb::machine::fpstr XFlag, int XFlag_len,
+ mmdb::machine::fpstr BFlag, int BFlag_len,
+ mmdb::machine::apireal * x,
+ mmdb::machine::apireal * y,
+ mmdb::machine::apireal * z,
+ mmdb::machine::apireal * occ,
+ mmdb::machine::apireal * BIso,
+ mmdb::machine::apireal * U,
int * iRet
) );
@@ -903,10 +920,10 @@ FORTRAN_SUBR ( MMDB_F_SETHET, mmdb_f_sethet,
// real a,b,c,alpha,beta,gamma
-// Relation to the former RBFRAC2 FORTRAN subroutine:
+// Relation to the former RBFRAC2 FORTRAN subroutine:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// subroutine RBFRAC2 ( a,b,c,alpha,beta,gamma,ArgNCode )
-//
+//
// ** the unit number iUnit and buffer for the return code iRet
// have to be supplied.
@@ -914,12 +931,12 @@ FORTRAN_SUBR ( MMDB_F_SETCELL, mmdb_f_setcell,
( // lengths-at-end list
int * iUnit, // unit number; *iUnit<=0 means
// "the last mentioned unit"
- apireal * a, // cell parameter a, angstroms
- apireal * b, // cell parameter b, angstroms
- apireal * c, // cell parameter c, angstroms
- apireal * alpha, // cell parameter alpha, degrees
- apireal * beta, // cell parameter beta, degrees
- apireal * gamma, // cell parameter gamma, degrees
+ mmdb::machine::apireal * a, // cell parameter a, angstroms
+ mmdb::machine::apireal * b, // cell parameter b, angstroms
+ mmdb::machine::apireal * c, // cell parameter c, angstroms
+ mmdb::machine::apireal * alpha, // cell parameter alpha, degrees
+ mmdb::machine::apireal * beta, // cell parameter beta, degrees
+ mmdb::machine::apireal * gamma, // cell parameter gamma, degrees
int * ArgNCode, // orthogonalization code, 1-6
int * iRet // return code:
// RWBERR_Ok - success
@@ -943,13 +960,21 @@ FORTRAN_SUBR ( MMDB_F_SETCELL, mmdb_f_setcell,
// error in mmdb_rwbrook.cpp
), ( // lengths-in-structure list
int * iUnit,
- apireal * a, apireal * b, apireal * c,
- apireal * alpha, apireal * beta, apireal * gamma,
+ mmdb::machine::apireal * a,
+ mmdb::machine::apireal * b,
+ mmdb::machine::apireal * c,
+ mmdb::machine::apireal * alpha,
+ mmdb::machine::apireal * beta,
+ mmdb::machine::apireal * gamma,
int * ArgNCode, int * iRet
), ( // lengths-follow list
int * iUnit,
- apireal * a, apireal * b, apireal * c,
- apireal * alpha, apireal * beta, apireal * gamma,
+ mmdb::machine::apireal * a,
+ mmdb::machine::apireal * b,
+ mmdb::machine::apireal * c,
+ mmdb::machine::apireal * alpha,
+ mmdb::machine::apireal * beta,
+ mmdb::machine::apireal * gamma,
int * ArgNCode, int * iRet
)
);
@@ -968,7 +993,7 @@ FORTRAN_SUBR ( MMDB_F_SETCELL, mmdb_f_setcell,
// Relation to the former WBSpGrp FORTRAN subroutine:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// subroutine WBSpGrp ( spGroup )
-//
+//
// ** the unit number iUnit and buffer for the return code iRet
// have to be supplied.
@@ -976,7 +1001,7 @@ FORTRAN_SUBR ( MMDB_F_WBSPGRP, mmdb_f_wbspgrp,
( // lengths-at-end list
int * iUnit, // unit number; *iUnit<=0 means
// "the last mentioned unit"
- fpstr spGroup, // space group
+ mmdb::machine::fpstr spGroup, // space group
int * iRet, // return code:
// RWBERR_Ok - success
// RWBERR_NoChannel if unit
@@ -986,9 +1011,9 @@ FORTRAN_SUBR ( MMDB_F_WBSPGRP, mmdb_f_wbspgrp,
// has been disposed
int spGroup_len // fortran-hidden length of spGroup
), ( // lengths-in-structure list
- int * iUnit, fpstr spGroup, int * iRet
+ int * iUnit, mmdb::machine::fpstr spGroup, int * iRet
), ( // lengths-follow list
- int * iUnit, fpstr spGroup, int spGroup_len,
+ int * iUnit, mmdb::machine::fpstr spGroup, int spGroup_len,
int * iRet
)
);
@@ -1007,7 +1032,7 @@ FORTRAN_SUBR ( MMDB_F_WBSPGRP, mmdb_f_wbspgrp,
// Relation to the former RBSpGrp FORTRAN subroutine:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// subroutine RBSpGrp ( spGroup )
-//
+//
// ** the unit number iUnit and buffer for the return code iRet
// have to be supplied.
@@ -1015,7 +1040,7 @@ FORTRAN_SUBR ( MMDB_F_RBSPGRP, mmdb_f_rbspgrp,
( // lengths-at-end list
int * iUnit, // unit number; *iUnit<=0 means
// "the last mentioned unit"
- fpstr spGroup, // space group
+ mmdb::machine::fpstr spGroup, // space group
int * iRet, // return code:
// RWBERR_Ok - success
// RWBERR_NoChannel if unit
@@ -1025,9 +1050,9 @@ FORTRAN_SUBR ( MMDB_F_RBSPGRP, mmdb_f_rbspgrp,
// has been disposed
int spGroup_len // fortran-hidden length of spGroup
), ( // lengths-in-structure list
- int * iUnit, fpstr spGroup, int * iRet
+ int * iUnit, mmdb::machine::fpstr spGroup, int * iRet
), ( // lengths-follow list
- int * iUnit, fpstr spGroup, int spGroup_len,
+ int * iUnit, mmdb::machine::fpstr spGroup, int spGroup_len,
int * iRet
)
);
@@ -1043,19 +1068,19 @@ FORTRAN_SUBR ( MMDB_F_RBSPGRP, mmdb_f_rbspgrp,
// ~~~~~~~~~~~~~~~~~~~ ArgNCode,iRet )
// integer iUnit,ArgNCode,iRet
// real ArgCell(6)
-//
+//
-// Relation to the former WBCELL FORTRAN subroutine:
+// Relation to the former WBCELL FORTRAN subroutine:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// subroutine WBCELL ( iUnit,ArgCell,ArgNCode )
-//
+//
// ** the buffer for the return code iRet has to be supplied
FORTRAN_SUBR ( MMDB_F_WBCELL, mmdb_f_wbcell,
( // lengths-at-end list
int * iUnit, // unit number; *iUnit<=0 means
// "the last mentioned unit"
- apireal * ArgCell, // array to accept the cell parameters
+ mmdb::machine::apireal * ArgCell, // array to accept the cell parameters
// if ArgCell(1) is set to 0, then
// the cell does not change
int * ArgNCode, // orthogonalisation code
@@ -1070,10 +1095,10 @@ FORTRAN_SUBR ( MMDB_F_WBCELL, mmdb_f_wbcell,
// RWBERR_NoFile if unit
// has been disposed
), ( // lengths-in-structure list
- int * iUnit, apireal * ArgCell,
+ int * iUnit, mmdb::machine::apireal * ArgCell,
int * ArgNCode, int * iRet
), ( // lengths-follow list
- int * iUnit, apireal * ArgCell,
+ int * iUnit, mmdb::machine::apireal * ArgCell,
int * ArgNCode, int * iRet
)
);
@@ -1090,10 +1115,10 @@ FORTRAN_SUBR ( MMDB_F_WBCELL, mmdb_f_wbcell,
// real celld(6),cvol
// character*(*) spGroup
-// Relation to the former RBCELL FORTRAN subroutine:
+// Relation to the former RBCELL FORTRAN subroutine:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// subroutine RBCELL ( celld,cvol )
-//
+//
// ** the unit number iUnit and buffer for the return code iRet
// have to be supplied.
@@ -1101,33 +1126,33 @@ FORTRAN_SUBR ( MMDB_F_RBCELL, mmdb_f_rbcell,
( // lengths-at-end list
int * iUnit, // unit number; *iUnit<=0 means
// "the last mentioned unit"
- apireal * celld, // array to accept the cell parameters
- apireal * cvol, // returns the cell volume
+ mmdb::machine::apireal * celld, // array to accept the cell parameters
+ mmdb::machine::apireal * cvol, // returns the cell volume
int * iRet // return code
- // RWBERR_Ok - success
- // RWBERR_NoChannel if unit
- // iUnit was not
- // initialized
- // RWBERR_NoFile if unit
- // has been disposed
- // RWBERR_Parameters if the
- // cell parameters
- // were not set
- // RWBERR_NoOrthCode if no
+ // RWBERR_Ok - success
+ // RWBERR_NoChannel if unit
+ // iUnit was not
+ // initialized
+ // RWBERR_NoFile if unit
+ // has been disposed
+ // RWBERR_Parameters if the
+ // cell parameters
+ // were not set
+ // RWBERR_NoOrthCode if no
// orthogonalization
- // code was found
- // RWBERR_NoCheck if check
- // of cell parameters
- // has failed.
+ // code was found
+ // RWBERR_NoCheck if check
+ // of cell parameters
+ // has failed.
// The last three returns would
- // rather indicate a programming
- // error in mmdb_rwbrook.cpp
+ // rather indicate a programming
+ // error in mmdb_rwbrook.cpp
), ( // lengths-in-structure list
- int * iUnit, apireal * celld,
- apireal * cvol, int * iRet
+ int * iUnit, mmdb::machine::apireal * celld,
+ mmdb::machine::apireal * cvol, int * iRet
), ( // lengths-follow list
- int * iUnit, apireal * celld,
- apireal * cvol, int * iRet
+ int * iUnit, mmdb::machine::apireal * celld,
+ mmdb::machine::apireal * cvol, int * iRet
) );
@@ -1142,10 +1167,10 @@ FORTRAN_SUBR ( MMDB_F_RBCELL, mmdb_f_rbcell,
// integer iUnit,ArgNCode,iRet
// real celld(6),cvol
-// Relation to the former RBCELL FORTRAN subroutine:
+// Relation to the former RBCELL FORTRAN subroutine:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// subroutine RBCELL ( celld,cvol )
-//
+//
// ** the unit number iUnit, buffer for orthogonalization code
// ArgNCode and for the return code iRet have to be supplied.
@@ -1153,8 +1178,8 @@ FORTRAN_SUBR ( MMDB_F_RBCELLN, mmdb_f_rbcelln,
( // lengths-at-end list
int * iUnit, // unit number; *iUnit<=0 means
// "the last mentioned unit"
- apireal * celld, // array to accept the cell parameters
- apireal * cvol, // returns the cell volume
+ mmdb::machine::apireal * celld, // array to accept the cell parameters
+ mmdb::machine::apireal * cvol, // returns the cell volume
int * ArgNCode, // returns the orthogonalization code, 1-6
int * iRet // return code
// RWBERR_Ok - success
@@ -1176,10 +1201,14 @@ FORTRAN_SUBR ( MMDB_F_RBCELLN, mmdb_f_rbcelln,
// rather indicate a programming
// error in mmdb_rwbrook.cpp
), ( // lengths-in-structure list
- int * iUnit, apireal * celld, apireal * cvol,
+ int * iUnit,
+ mmdb::machine::apireal * celld,
+ mmdb::machine::apireal * cvol,
int * ArgNCode, int * iRet
), ( // lengths-follow list
- int * iUnit, apireal * celld, apireal * cvol,
+ int * iUnit,
+ mmdb::machine::apireal * celld,
+ mmdb::machine::apireal * cvol,
int * ArgNCode, int * iRet
)
);
@@ -1196,43 +1225,47 @@ FORTRAN_SUBR ( MMDB_F_RBCELLN, mmdb_f_rbcelln,
// integer iUnit,iRet
// real rcell(6),rvol
-// Relation to the former RBRCEL FORTRAN subroutine:
+// Relation to the former RBRCEL FORTRAN subroutine:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// subroutine RBRCEL ( rcell,rvol )
-//
+//
// ** the unit number iUnit and buffer for the return code iRet
// have to be supplied.
FORTRAN_SUBR ( MMDB_F_RBRCEL, mmdb_f_rbrcel,
( // lengths-at-end list
int * iUnit, // unit number
- apireal * rcell, // array to accept the reciprocal
+ mmdb::machine::apireal * rcell, // array to accept the reciprocal
// cell parameters
- apireal * rvol, // returns the reciprocal cell volume
+ mmdb::machine::apireal * rvol, // returns the reciprocal cell volume
int * iRet // return code
- // RWBERR_Ok - success
- // RWBERR_NoChannel if unit
- // iUnit was not
- // initialized
- // RWBERR_NoFile if unit
- // has been disposed
- // RWBERR_Parameters if the
- // cell parameters
- // were not set
- // RWBERR_NoOrthCode if no
+ // RWBERR_Ok - success
+ // RWBERR_NoChannel if unit
+ // iUnit was not
+ // initialized
+ // RWBERR_NoFile if unit
+ // has been disposed
+ // RWBERR_Parameters if the
+ // cell parameters
+ // were not set
+ // RWBERR_NoOrthCode if no
// orthogonalization
- // code was found
- // RWBERR_NoCheck if check
- // of cell parameters
- // has failed.
+ // code was found
+ // RWBERR_NoCheck if check
+ // of cell parameters
+ // has failed.
// The last three returns would
- // rather indicate a programming
- // error in mmdb_rwbrook.cpp
+ // rather indicate a programming
+ // error in mmdb_rwbrook.cpp
), ( // lengths-in-structure list
- int * iUnit, apireal * rcell, apireal * rvol,
+ int * iUnit,
+ mmdb::machine::apireal * rcell,
+ mmdb::machine::apireal * rvol,
int * iRet
), ( // lengths-follow list
- int * iUnit, apireal * rcell, apireal * rvol,
+ int * iUnit,
+ mmdb::machine::apireal * rcell,
+ mmdb::machine::apireal * rvol,
int * iRet
) );
@@ -1251,10 +1284,10 @@ FORTRAN_SUBR ( MMDB_F_RBRCEL, mmdb_f_rbrcel,
// integer iUnit,LCode,iRet
// real RO(4,4),RF(4,4)
-// Relation to the former RBRORF2 FORTRAN subroutine:
+// Relation to the former RBRORF2 FORTRAN subroutine:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// subroutine RBRORF2 ( RO,RF,LCode )
-//
+//
// ** the unit number iUnit and buffer for the return code iRet
// have to be supplied.
@@ -1262,8 +1295,8 @@ FORTRAN_SUBR ( MMDB_F_RBORF, mmdb_f_rborf,
( // lengths-at-end list
int * iUnit, // unit number; *iUnit<=0 means
// "the last mentioned unit"
- apireal * RO, // array for orthogonalising matrix
- apireal * RF, // array for fractionalising matrix
+ mmdb::machine::apireal * RO, // array for orthogonalising matrix
+ mmdb::machine::apireal * RF, // array for fractionalising matrix
int * LCode, // buffer for orthogonalisation code
int * iRet // return code:
// RWBERR_Ok - success
@@ -1277,10 +1310,14 @@ FORTRAN_SUBR ( MMDB_F_RBORF, mmdb_f_rborf,
// matrices were not
// calculated
), ( // lengths-in-structure list
- int * iUnit, apireal * RO, apireal * RF,
+ int * iUnit,
+ mmdb::machine::apireal * RO,
+ mmdb::machine::apireal * RF,
int * LCode, int * iRet
), ( // lengths-follow list
- int * iUnit, apireal * RO, apireal * RF,
+ int * iUnit,
+ mmdb::machine::apireal * RO,
+ mmdb::machine::apireal * RF,
int * LCode, int * iRet
)
);
@@ -1300,10 +1337,10 @@ FORTRAN_SUBR ( MMDB_F_RBORF, mmdb_f_rborf,
// integer iUnit,iRet
// real Cell(6),Vol,RRR(3,3,6)
-// Relation to the former RBFRO1 FORTRAN subroutine:
+// Relation to the former RBFRO1 FORTRAN subroutine:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// subroutine RBFRO1 ( Cell,Vol,RRR )
-//
+//
// ** the unit number iUnit and buffer for the return code iRet
// have to be supplied.
@@ -1311,12 +1348,12 @@ FORTRAN_SUBR ( MMDB_F_ORTHMAT, mmdb_f_orthmat,
( // lengths-at-end list
int * iUnit, // unit number; *iUnit<=0 means
// "the last mentioned unit"
- apireal * Cell, // array of cell parameters:
+ mmdb::machine::apireal * Cell, // array of cell parameters:
// Cell(1) - a Cell(4) - alpha
// Cell(2) - b Cell(5) - beta
// Cell(3) - c Cell(6) - gamma
- apireal * Vol, // returns cell volume
- apireal * RRR, // array (3,3,6), returns
+ mmdb::machine::apireal * Vol, // returns cell volume
+ mmdb::machine::apireal * RRR, // array (3,3,6), returns
// orthogonalisation matrices
int * iRet // return code:
// RWBERR_Ok - success
@@ -1330,11 +1367,15 @@ FORTRAN_SUBR ( MMDB_F_ORTHMAT, mmdb_f_orthmat,
// matrices were not
// calculated
), ( // lengths-in-structure list
- int * iUnit, apireal * Cell, apireal * Vol,
- apireal * RRR, int * iRet
+ int * iUnit,
+ mmdb::machine::apireal * Cell,
+ mmdb::machine::apireal * Vol,
+ mmdb::machine::apireal * RRR, int * iRet
), ( // lengths-follow list
- int * iUnit, apireal * Cell, apireal * Vol,
- apireal * RRR, int * iRet
+ int * iUnit,
+ mmdb::machine::apireal * Cell,
+ mmdb::machine::apireal * Vol,
+ mmdb::machine::apireal * RRR, int * iRet
)
);
@@ -1349,10 +1390,10 @@ FORTRAN_SUBR ( MMDB_F_ORTHMAT, mmdb_f_orthmat,
// ~~~~~~~~~~~~~~~~~~~ integer iUnit,iFlag,iRet
// real U(6)
-// Relation to the former CVANISOU FORTRAN subroutine:
+// Relation to the former CVANISOU FORTRAN subroutine:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// subroutine CVANISOU ( U,iFlag )
-//
+//
// ** the unit number iUnit and buffer for the return code iRet
// have to be supplied.
@@ -1360,7 +1401,7 @@ FORTRAN_SUBR ( MMDB_F_CVANISOU, mmdb_f_cvanisou,
( // lengths-at-end list
int * iUnit, // unit number; *iUnit<=0 means
// "the last mentioned unit"
- apireal * U, // array of coordinates to convert
+ mmdb::machine::apireal * U, // array of coordinates to convert
int * iFlag, // =0: convert from fract. to orthog.
// =1: convert from orthog. to fract.
int * iRet // return code:
@@ -1375,9 +1416,11 @@ FORTRAN_SUBR ( MMDB_F_CVANISOU, mmdb_f_cvanisou,
// matrices were not
// calculated
), ( // lengths-in-structure list
- int * iUnit, apireal * U, int * iFlag, int * iRet
+ int * iUnit,
+ mmdb::machine::apireal * U, int * iFlag, int * iRet
), ( // lengths-follow list
- int * iUnit, apireal * U, int * iFlag, int * iRet
+ int * iUnit,
+ mmdb::machine::apireal * U, int * iFlag, int * iRet
)
);
@@ -1398,17 +1441,17 @@ FORTRAN_SUBR ( MMDB_F_CVANISOU, mmdb_f_cvanisou,
// ~~~~~~~~~~~~~~~~~~~ integer iUnit,iRet
// character*(*) Line
-// Relation to the former WRemark FORTRAN subroutine:
+// Relation to the former WRemark FORTRAN subroutine:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// subroutine WRemark ( iUnit,Line )
-//
+//
// ** the buffer for return code iRet has to be supplied
FORTRAN_SUBR ( MMDB_F_WREMARK, mmdb_f_wremark,
( // lengths-at-end list
int * iUnit, // unit number; *iUnit<=0 means
// "the last mentioned unit"
- fpstr Line, // line to be added
+ mmdb::machine::fpstr Line, // line to be added
int * iRet, // return code:
// RWBERR_Ok - success
// RWBERR_NoChannel if unit
@@ -1420,9 +1463,11 @@ FORTRAN_SUBR ( MMDB_F_WREMARK, mmdb_f_wremark,
// returned by mmdb_f_open1_(..)
int Line_len // fortran-hidden length of Line
), ( // lengths-in-structure list
- int * iUnit, fpstr Line, int * iRet
+ int * iUnit,
+ mmdb::machine::fpstr Line, int * iRet
), ( // lengths-follow list
- int * iUnit, fpstr Line, int Line_len, int *iRet
+ int * iUnit,
+ mmdb::machine::fpstr Line, int Line_len, int *iRet
)
);
@@ -1437,9 +1482,9 @@ FORTRAN_SUBR ( MMDB_F_WREMARK, mmdb_f_wremark,
// ~~~~~~~~~~~~~~~~~~~ real A(4,4),AI(4,4)
FORTRAN_SUBR ( RBRINV, rbrinv,
- ( apireal * A, apireal * AI ),
- ( apireal * A, apireal * AI ),
- ( apireal * A, apireal * AI )
+ ( mmdb::machine::apireal * A, mmdb::machine::apireal * AI ),
+ ( mmdb::machine::apireal * A, mmdb::machine::apireal * AI ),
+ ( mmdb::machine::apireal * A, mmdb::machine::apireal * AI )
);
*/
@@ -1457,16 +1502,16 @@ FORTRAN_SUBR ( RBRINV, rbrinv,
FORTRAN_SUBR ( RES3TO1, res3to1,
( // lengths-at-end list
- fpstr ResNm3, // 3-char name, 4th char
+ mmdb::machine::fpstr ResNm3, // 3-char name, 4th char
// will be set blank
- fpstr ResNm1, // 1-char name
+ mmdb::machine::fpstr ResNm1, // 1-char name
int ResNm3_len, // fortran-hidden length of ResNm3
int ResNm1_len // fortran-hidden length of ResNm3
), ( // lengths-in-structure list
- fpstr ResNm3, fpstr ResNm1
+ mmdb::machine::fpstr ResNm3, mmdb::machine::fpstr ResNm1
), ( // lengths-follow list
- fpstr ResNm3, int ResNm3_len,
- fpstr ResNm1, int ResNm1_len
+ mmdb::machine::fpstr ResNm3, int ResNm3_len,
+ mmdb::machine::fpstr ResNm1, int ResNm1_len
)
);
diff --git a/mmdb2/mmdb_selmngr.cpp b/mmdb2/mmdb_selmngr.cpp
new file mode 100644
index 0000000..3aeec25
--- /dev/null
+++ b/mmdb2/mmdb_selmngr.cpp
@@ -0,0 +1,3421 @@
+// $Id: mmdb_selmngr.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 15.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : mmdb_selmngr <implementation>
+// ~~~~~~~~~
+// Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::Manager ( MMDB atom selection manager )
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "mmdb_selmngr.h"
+
+
+namespace mmdb {
+
+ const int ANY_RES = MinInt4;
+
+ // ==================== SelManager =====================
+
+ SelManager::SelManager() : CoorManager() {
+ InitSelManager();
+ }
+
+ SelManager::SelManager ( io::RPStream Object )
+ : CoorManager(Object) {
+ InitSelManager();
+ }
+
+ SelManager::~SelManager() {
+ DeleteAllSelections();
+ }
+
+ void SelManager::ResetManager() {
+ CoorManager::ResetManager();
+ DeleteAllSelections();
+ InitSelManager ();
+ }
+
+ void SelManager::InitSelManager() {
+ nSelections = 0; // number of selections
+ mask = NULL; // vector of selections
+ selType = NULL; // vector of selection types
+ nSelItems = NULL; // numbers of selected items
+ selection = NULL; // vector of selected items
+ }
+
+
+ // ------------------------ Selection -----------------------------
+
+ int SelManager::NewSelection() {
+ PMask M;
+ PPMask Mask1;
+ PPMask * Selection1;
+ ivector nSelItems1;
+ SELECTION_TYPE * SelType1;
+ int i,l;
+
+ M = new Mask();
+ M->NewMask ( mask,nSelections );
+
+ i = 0;
+ while (i<nSelections)
+ if (!mask[i]) break;
+ else i++;
+
+ if (i>=nSelections) {
+ l = nSelections+10;
+ Mask1 = new PMask [l];
+ Selection1 = new PPMask[l];
+ nSelItems1 = new int[l];
+ SelType1 = new SELECTION_TYPE[l];
+ for (i=0;i<nSelections;i++) {
+ Mask1 [i] = mask [i];
+ Selection1[i] = selection[i];
+ nSelItems1[i] = nSelItems[i];
+ SelType1 [i] = selType [i];
+ }
+ for (i=nSelections;i<l;i++) {
+ Mask1 [i] = NULL;
+ Selection1[i] = NULL;
+ nSelItems1[i] = 0;
+ SelType1 [i] = STYPE_UNDEFINED;
+ }
+ if (mask) delete[] mask;
+ if (selection) delete[] selection;
+ if (nSelItems) delete[] nSelItems;
+ if (selType) delete[] selType;
+ mask = Mask1;
+ selection = Selection1;
+ nSelItems = nSelItems1;
+ selType = SelType1;
+ i = nSelections;
+ nSelections = l;
+ }
+
+ mask[i] = M;
+ if (selection[i]) delete[] selection[i];
+ selection[i] = NULL;
+ nSelItems[i] = 0;
+ selType [i] = STYPE_UNDEFINED;
+
+ return i+1;
+
+ }
+
+ int SelManager::GetSelType ( int selHnd ) {
+ int k;
+ if ((selHnd>0) && (selHnd<=nSelections)) {
+ k = selHnd-1;
+ if (mask[k]) return selType[k];
+ }
+ return STYPE_INVALID;
+ }
+
+ void SelManager::DeleteSelection ( int selHnd ) {
+ int i,k;
+ if ((selHnd>0) && (selHnd<=nSelections)) {
+ k = selHnd-1;
+ if (mask[k]) {
+ for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->RemoveMask ( mask[k] );
+
+ // for (i=0;i<nAtoms;i++)
+ // if (atom[i])
+ // atom[i]->RemoveMask ( mask[k] );
+
+ delete mask[k];
+ }
+ mask[k] = NULL;
+ if (selection[k]) delete[] selection[k];
+ selection[k] = NULL;
+ nSelItems[k] = 0;
+ selType [k] = STYPE_UNDEFINED;
+ }
+ }
+
+
+ PMask SelManager::GetSelMask ( int selHnd ) {
+ if ((selHnd>0) && (selHnd<=nSelections))
+ return mask[selHnd-1];
+ else return NULL;
+ }
+
+ void SelManager::DeleteAllSelections() {
+ PResidue res ,res1;
+ PChain chain,chain1;
+ PModel model,model1;
+ int i;
+
+ if (mask) {
+ res = NULL;
+ chain = NULL;
+ model = NULL;
+ if (atom)
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ atom[i]->ClearMask();
+ res1 = atom[i]->GetResidue();
+ if (res1!=res) {
+ res = res1;
+ res->ClearMask();
+ chain1 = res->GetChain();
+ if (chain1!=chain) {
+ chain = chain1;
+ chain->ClearMask();
+ model1 = chain->GetModel();
+ if (model1!=model) {
+ model = model1;
+ model->ClearMask();
+ }
+ }
+ }
+ }
+ for (i=0;i<nSelections;i++) {
+ if (mask [i]) delete mask[i];
+ if (selection[i]) delete[] selection[i];
+ }
+ delete[] mask;
+ if (selection) delete[] selection;
+ if (nSelItems) delete[] nSelItems;
+ if (selType) delete[] selType;
+ }
+
+ nSelections = 0;
+ mask = NULL;
+ selection = NULL;
+ nSelItems = NULL;
+ selType = NULL;
+
+ }
+
+ void SelManager::SelectAtoms ( int selHnd, int iSer1, int iSer2,
+ SELECTION_KEY sKey ) {
+ // SelectAtoms(..) selects atoms in the serial number range
+ // of iSer1 to iSer2 by adding them to the set of atoms
+ // marked by the given mask. If iSer1=iSer2=0 then all atoms
+ // are selected. Each atom may be selected by a number of masks
+ // simultaneously
+ int i,s1,s2,k,nsel;
+ SELECTION_KEY sk;
+
+ if ((selHnd<=0) || (selHnd>nSelections) || (nAtoms<=0)) return;
+
+ k = selHnd-1;
+ sk = sKey;
+
+ if ((selType[k]==STYPE_UNDEFINED) || (sKey==SKEY_NEW))
+ selType[k] = STYPE_ATOM;
+ else if (selType[k]!=STYPE_ATOM) return;
+
+ switch (sKey) {
+ case SKEY_NEW : for (i=0;i<nAtoms;i++)
+ if (atom[i]) atom[i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k];
+ break;
+ case SKEY_AND : nsel = 0; break;
+ case SKEY_XOR : nsel = nSelItems[k]; break;
+ case SKEY_CLR : nsel = nSelItems[k];
+ if (nsel<=0) return;
+ break;
+ case SKEY_XAND: nsel = 0; break;
+ }
+
+ if ((iSer1==0) && (iSer2==0)) {
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (!atom[i]->Ter)
+ SelectAtom ( atom[i],k,sk,nsel );
+ }
+ } else {
+ if (iSer1<=iSer2) {
+ s1 = iSer1;
+ s2 = iSer2;
+ } else {
+ s1 = iSer2;
+ s2 = iSer1;
+ }
+ // for a very general use, we allow the serial number
+ // to differ from the atom's index, although this is
+ // against PDB format. Therefore we apply here the most
+ // primitive and less efficient way of selection
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (!atom[i]->Ter) {
+ if ((s1<=atom[i]->serNum) && (atom[i]->serNum<=s2))
+ SelectAtom ( atom[i],k,sk,nsel );
+ else if (sk==SKEY_AND)
+ atom[i]->RemoveMask ( mask[k] );
+ }
+ }
+ }
+
+ MakeSelIndex ( selHnd,STYPE_ATOM,nsel );
+
+ }
+
+
+ void SelManager::SelectAtoms ( int selHnd, ivector asn, int nsn,
+ SELECTION_KEY selKey ) {
+ // SelectAtoms(..) selects atoms with serial numbers given in
+ // vector asn[0..nsn-1].
+ QuickSort QS;
+ ivector asn1;
+ int i,k,nsn1,j,j1,j2, sn,nsel;
+ SELECTION_KEY sk;
+
+ if ((selHnd<=0) || (selHnd>nSelections) || (nAtoms<=0)) return;
+
+ k = selHnd-1;
+ sk = selKey;
+
+ if ((selType[k]==STYPE_UNDEFINED) ||
+ (selKey==SKEY_NEW)) selType[k] = STYPE_ATOM;
+ else if (selType[k]!=STYPE_ATOM) return;
+
+ switch (selKey) {
+ case SKEY_NEW : for (i=0;i<nAtoms;i++)
+ if (atom[i]) atom[i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k];
+ break;
+ case SKEY_AND : nsel = 0; break;
+ case SKEY_XOR : nsel = nSelItems[k]; break;
+ case SKEY_CLR : nsel = nSelItems[k];
+ if (nsel<=0) return;
+ break;
+ case SKEY_XAND: nsel = 0; break;
+ }
+
+ GetVectorMemory ( asn1,nsn,0 );
+ for (i=0;i<nsn;i++)
+ asn1[i] = asn[i];
+
+ QS.Sort ( asn1,nsn );
+ nsn1 = nsn-1;
+
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (!atom[i]->Ter) {
+ sn = atom[i]->serNum;
+ if ((asn1[0]<=sn) && (sn<=asn1[nsn1])) {
+ // binary search
+ j1 = 0;
+ j2 = nsn1;
+ do {
+ j = (j1+j2)/2;
+ if (sn<asn1[j]) j2 = j;
+ else if (sn>asn1[j]) j1 = j;
+ else j1 = j2;
+ } while (j1<j2-1);
+ if ((sn==asn1[j]) || (sn==asn1[j1]) || (sn==asn1[j2]))
+ SelectAtom ( atom[i],k,sk,nsel );
+ else if (sk==SKEY_AND)
+ atom[i]->RemoveMask ( mask[k] );
+ } else if (sk==SKEY_AND)
+ atom[i]->RemoveMask ( mask[k] );
+ }
+ }
+
+ FreeVectorMemory ( asn1,0 );
+
+ MakeSelIndex ( selHnd,STYPE_ATOM,nsel );
+
+ }
+
+
+ void SelManager::UnselectAtoms ( int selHnd, int iSer1, int iSer2 ) {
+ // UnselectAtoms(..) clears the specified mask for atoms in
+ // the serial number range of iSer1 to iSer2. If iSer1=iSer2=0
+ // then all atoms are cleared of the specified mask. If selHnd
+ // is set to 0, then the atoms are cleared of any mask.
+ int i,s1,s2,k;
+
+ if ((selHnd<=nSelections) && (nAtoms>0)) {
+
+ k = selHnd-1;
+
+ if (selType[k]==STYPE_UNDEFINED) selType[k] = STYPE_ATOM;
+ else if (selType[k]!=STYPE_ATOM) return;
+
+ if ((iSer1==0) && (iSer2==0)) {
+ if (k<0) {
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) atom[i]->ClearMask();
+ } else {
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) atom[i]->RemoveMask ( mask[k] );
+ }
+ } else {
+ if (iSer1<=iSer2) {
+ s1 = iSer1;
+ s2 = iSer2;
+ } else {
+ s1 = iSer2;
+ s2 = iSer1;
+ }
+ // for a very general use, we allow the serial number
+ // to differ from the atom's index, although this is
+ // against PDB format. Therefore we apply here the most
+ // primitive and less efficient way of selection
+ if (k<0) {
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if ((s1<=atom[i]->serNum) && (atom[i]->serNum<=s2))
+ atom[i]->ClearMask();
+ }
+ } else {
+ for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if ((s1<=atom[i]->serNum) && (atom[i]->serNum<=s2))
+ atom[i]->RemoveMask ( mask[k] );
+ }
+ }
+ }
+
+ MakeSelIndex ( selHnd,STYPE_ATOM,-1 );
+
+ }
+
+ }
+
+
+ pstr MakeList ( cpstr S ) {
+ // makes the list of selecting items:
+ // 1st character - special use,
+ // then each item from S embraced by commas
+ pstr L;
+ int i,j;
+ i = 0;
+ while (S[i]==' ') i++;
+ if (S[i]!='*') {
+ // compile a searchable list
+ L = new char[strlen(S)+5];
+ if (S[i]=='!') {
+ L[0] = '!';
+ i++;
+ } else
+ L[0] = ' ';
+ if (strchr(S,'[')) L[1] = '"';
+ else L[1] = ' ';
+ L[2] = ',';
+ j = 3;
+ while (S[i]) {
+ while (S[i]==' ') i++;
+ if (S[i]=='[') {
+ while (S[i] && (S[i]!=']'))
+ L[j++] = S[i++];
+ L[j++] = ']';
+ if (S[i]==']') i++;
+ } else
+ while (S[i] && (S[i]!=' ') && (S[i]!=','))
+ L[j++] = S[i++];
+ while (S[i]==' ') i++;
+ L[j++] = ',';
+ if (S[i]==',') {
+ i++;
+ if (!S[i]) L[j++] = ','; // blank chain ID at the end assumed
+ }
+ }
+ if (j==3) L[j++] = ',';
+ L[j] = char(0);
+ } else
+ L = NULL;
+ return L;
+ }
+
+ bool MatchName ( pstr L, pstr N ) {
+ char M[sizeof(maxMMDBName)+5];
+ int i,j;
+ if (L) {
+ i = 0;
+ M[0] = ',';
+ j = 1;
+ while (N[i])
+ if (N[i]==' ') i++;
+ else M[j++] = N[i++];
+ M[j++] = ',';
+ M[j] = char(0);
+ if (strstr(&(L[2]),M)) return (L[0]!='!');
+ else if (L[1]!='"') return (L[0]=='!');
+ else {
+ strcpy ( M,",[" );
+ strcat ( M,N );
+ strcat ( M,"]," );
+ if (strstr(&(L[2]),M)) return (L[0]!='!');
+ else return (L[0]=='!');
+ }
+ } else
+ return true;
+ }
+
+ bool MatchCharge ( pstr L, PAtom atom ) {
+ char N[100];
+ if (L) {
+ if (atom->WhatIsSet & ASET_Charge) {
+ sprintf ( N,"%+2i",mround(atom->charge) );
+ return MatchName ( L,N );
+ } else
+ return false;
+ } else
+ return true;
+ }
+
+
+ void SelManager::SelectAtom ( int selHnd, PAtom A,
+ SELECTION_KEY selKey,
+ bool makeIndex ) {
+ int i, k, nsel;
+ SELECTION_KEY sk;
+
+ if ((selHnd<=0) || (selHnd>nSelections)) return;
+
+ k = selHnd-1;
+ sk = selKey;
+
+ if ((selType[k]==STYPE_UNDEFINED) ||
+ (selKey==SKEY_NEW)) selType[k] = STYPE_ATOM;
+ else if (selType[k]!=STYPE_ATOM) return;
+
+ switch (selKey) {
+ case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k];
+ break;
+ case SKEY_AND : if (nSelItems[k]==0) return;
+ nsel = 0;
+ break;
+ case SKEY_XOR : nsel = nSelItems[k];
+ break;
+ case SKEY_CLR : nsel = nSelItems[k];
+ if (nsel<=0) return;
+ break;
+ case SKEY_XAND: nsel = 0; break;
+ }
+
+ SelectAtom ( A,k,sk,nsel);
+ if (makeIndex) MakeSelIndex ( selHnd,STYPE_ATOM,nsel );
+
+ }
+
+
+ void SelManager::SelectResidue ( int selHnd, PResidue Res,
+ SELECTION_TYPE sType,
+ SELECTION_KEY sKey,
+ bool makeIndex ) {
+ // Selects residue Res or all its atoms depending on selType
+ PPAtom A;
+ int i, k, nsel, nat;
+ SELECTION_KEY sk;
+
+ if ((selHnd<=0) || (selHnd>nSelections)) return;
+
+ k = selHnd-1;
+ sk = sKey;
+
+ if ((selType[k]==STYPE_UNDEFINED) || (sKey==SKEY_NEW))
+ selType[k] = sType;
+ else if (selType[k]!=sType) return;
+
+ switch (sKey) {
+ case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k];
+ break;
+ case SKEY_AND : if (nSelItems[k]==0) return;
+ nsel = 0;
+ break;
+ case SKEY_XOR : nsel = nSelItems[k];
+ break;
+ case SKEY_CLR : nsel = nSelItems[k];
+ if (nsel<=0) return;
+ break;
+ case SKEY_XAND: nsel = 0; break;
+ }
+
+ switch (sType) {
+ case STYPE_ATOM : Res->GetAtomTable ( A,nat );
+ for (i=0;i<nat;i++)
+ if (A[i]) {
+ if (!A[i]->Ter)
+ SelectAtom ( A[i],k,sk,nsel);
+ }
+ break ;
+ case STYPE_RESIDUE : SelectObject ( Res,k,sk,nsel );
+ break ;
+ default : ;
+ }
+
+ if (makeIndex) MakeSelIndex ( selHnd,sType,nsel );
+
+ }
+
+
+ void SelManager::SelectChain ( int selHnd, PChain Chain,
+ SELECTION_TYPE sType,
+ SELECTION_KEY sKey,
+ bool makeIndex ) {
+ // Selects chain Chain or all its residues or atoms depending on selType
+ PPAtom A;
+ PPResidue Res;
+ int i,j, k, nsel, nat,nres;
+ SELECTION_KEY sk;
+
+ if ((selHnd<=0) || (selHnd>nSelections)) return;
+
+ k = selHnd-1;
+ sk = sKey;
+
+ if ((selType[k]==STYPE_UNDEFINED) || (sKey==SKEY_NEW))
+ selType[k] = sType;
+ else if (selType[k]!=sType) return;
+
+ switch (sKey) {
+ case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k];
+ break;
+ case SKEY_AND : if (nSelItems[k]==0) return;
+ nsel = 0;
+ break;
+ case SKEY_XOR : nsel = nSelItems[k];
+ break;
+ case SKEY_CLR : nsel = nSelItems[k];
+ if (nsel<=0) return;
+ break;
+ case SKEY_XAND: nsel = 0; break;
+ }
+
+ switch (sType) {
+ case STYPE_ATOM : Chain->GetResidueTable ( Res,nres );
+ for (i=0;i<nres;i++)
+ if (Res[i]) {
+ Res[i]->GetAtomTable ( A,nat );
+ for (j=0;j<nat;j++)
+ if (A[j]) {
+ if (!A[j]->Ter)
+ SelectAtom ( A[j],k,sk,nsel);
+ }
+ }
+ break ;
+ case STYPE_RESIDUE : Chain->GetResidueTable ( Res,nres );
+ for (i=0;i<nres;i++)
+ if (Res[i])
+ SelectObject ( Res[i],k,sk,nsel );
+ break ;
+ case STYPE_CHAIN : SelectObject ( Chain,k,sk,nsel );
+ break ;
+ default : ;
+ }
+
+ if (makeIndex) MakeSelIndex ( selHnd,sType,nsel );
+
+ }
+
+
+ void SelManager::SelectModel ( int selHnd, PModel model,
+ SELECTION_TYPE sType,
+ SELECTION_KEY sKey,
+ bool makeIndex ) {
+ // Selects model or all its chains or residues or atoms depending
+ // on selType
+ PPAtom A;
+ PPResidue Res;
+ PPChain Chain;
+ int i,j,n, k, nsel, nat,nres,nch;
+ SELECTION_KEY sk;
+
+ if ((selHnd<=0) || (selHnd>nSelections)) return;
+
+ k = selHnd-1;
+ sk = sKey;
+
+ if ((selType[k]==STYPE_UNDEFINED) || (sKey==SKEY_NEW))
+ selType[k] = sType;
+ else if (selType[k]!=sType) return;
+
+ switch (sKey) {
+ case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k];
+ break;
+ case SKEY_AND : if (nSelItems[k]==0) return;
+ nsel = 0;
+ break;
+ case SKEY_XOR : nsel = nSelItems[k];
+ break;
+ case SKEY_CLR : nsel = nSelItems[k];
+ if (nsel<=0) return;
+ break;
+ case SKEY_XAND: nsel = 0; break;
+ }
+
+ switch (sType) {
+ case STYPE_ATOM : model->GetChainTable ( Chain,nch );
+ for (i=0;i<nch;i++)
+ if (Chain[i]) {
+ Chain[i]->GetResidueTable ( Res,nres );
+ for (j=0;j<nres;j++)
+ if (Res[j]) {
+ Res[j]->GetAtomTable ( A,nat );
+ for (n=0;n<nat;n++)
+ if (A[n]) {
+ if (!A[n]->Ter)
+ SelectAtom ( A[n],k,sk,nsel);
+ }
+ }
+ }
+ break ;
+ case STYPE_RESIDUE : model->GetChainTable ( Chain,nch );
+ for (i=0;i<nch;i++)
+ if (Chain[i]) {
+ Chain[i]->GetResidueTable ( Res,nres );
+ for (j=0;j<nres;j++)
+ if (Res[j])
+ SelectObject ( Res[j],k,sk,nsel );
+ }
+ break ;
+ case STYPE_CHAIN : model->GetChainTable ( Chain,nch );
+ for (i=0;i<nch;i++)
+ if (Chain[i])
+ SelectObject ( Chain[i],k,sk,nsel );
+ break ;
+ case STYPE_MODEL : SelectObject ( model,k,sk,nsel );
+ break ;
+ default : ;
+ }
+
+ if (makeIndex) MakeSelIndex ( selHnd,sType,nsel );
+
+ }
+
+
+ int SelManager::MakeSelIndex ( int selHnd ) {
+ int k;
+ if ((selHnd<=0) || (selHnd>nSelections)) return 0;
+ k = selHnd-1;
+ if (selType[k]==STYPE_UNDEFINED) return 0;
+ MakeSelIndex ( selHnd,selType[k],-1 );
+ return nSelItems[k];
+ }
+
+ void SelManager::MakeAllSelIndexes() {
+ int k;
+ for (k=0;k<nSelections;k++)
+ if (selType[k]!=STYPE_UNDEFINED)
+ MakeSelIndex ( k+1,selType[k],-1 );
+ }
+
+ void SelManager::SelectAtoms (
+ int selHnd, // must be obtained from NewSelection()
+ int iModel, // model number; iModel=0 means
+ // 'any models'
+ cpstr Chains, // may be several chains "A,B,W";
+ // "*" means 'any chain' (in model)
+ int ResNo1, // starting residue number
+ cpstr Ins1, // starting residue insertion code;
+ // "*" means 'any code'
+ int ResNo2, // ending residue number.
+ // ResNo1=ResNo2=ANY_RES
+ // means 'any residue number'
+ // (in chain)
+ cpstr Ins2, // ending residue insertion code
+ // "*" means 'any code'
+ cpstr RNames, // may be several residue names
+ // "ALA,GLU,CIS"; "*" means
+ // 'any residue name'
+ cpstr ANames, // may be several names "CA,CB";
+ // "*" means 'any atom' (in residue)
+ cpstr Elements, // may be several element types like
+ // "H,C,O,CU"; "*" means 'any element'
+ cpstr altLocs, // may be several alternative
+ // locations 'A,B'; "*" means 'any
+ // alternative location'
+ cpstr Segments, // may be several segment IDs like
+ // "S1,S2,A234"; "*" means 'any
+ // segment'
+ cpstr Charges, // may be several charges like
+ // "+1,-2, "; "*" means 'any charge'
+ realtype occ1, // lowest occupancy
+ realtype occ2, // highest occupancy;
+ // occ1=occ2<0.0 means
+ // "any occupancy"
+ realtype x0, // reference x-point
+ realtype y0, // reference y-point
+ realtype z0, // reference z-point
+ realtype d0, // selection distance from the reference
+ // reference point; d0<=0.0 means
+ // 'any distance" and values of
+ // x0, y0 and z0 are ignored
+ SELECTION_KEY selKey // selection key
+ ) {
+
+ Select ( selHnd,STYPE_ATOM,iModel,Chains,ResNo1,Ins1,ResNo2,Ins2,
+ RNames,ANames,Elements,altLocs,Segments,Charges,
+ occ1,occ2,x0,y0,z0,d0,selKey );
+
+ }
+
+
+ #define hetIndicator '@'
+
+ void SelManager::Select (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ int iModel, // model number; iModel=0 means
+ // 'any models'
+ cpstr Chains, // may be several chains "A,B,W";
+ // "*" means 'any chain' (in model)
+ int ResNo1, // starting residue number
+ cpstr Ins1, // starting residue insertion code;
+ // "*" means 'any code'
+ int ResNo2, // ending residue number.
+ // ResNo1=ResNo2=ANY_RES means 'any
+ // residue number' (in chain)
+ cpstr Ins2, // ending residue insertion code
+ // "*" means 'any code'
+ cpstr RNames, // may be several residue names
+ // "ALA,GLU,CIS"; "*" means 'any
+ // residue name'
+ cpstr ANames, // may be several names "CA,CB";"*"
+ // means 'any atom' (in residue)
+ cpstr Elements, // may be several element types like
+ // "H,C,O,CU"; "*" means 'any element'
+ cpstr altLocs, // may be several alternative
+ // locations 'A,B'; "*" means 'any
+ // alternative location'
+ cpstr Segments, // may be several segment IDs like
+ // "S1,S2,A234"; "*" means 'any
+ // segment'
+ cpstr Charges, // may be several charges like
+ // "+1,-2, "; "*" means 'any charge'
+ realtype occ1, // lowest occupancy
+ realtype occ2, // highest occupancy;
+ // occ1=occ2<0.0 means
+ // "any occupancy"
+ realtype x0, // reference x-point
+ realtype y0, // reference y-point
+ realtype z0, // reference z-point
+ realtype d0, // selection distance from the reference
+ // reference point; d0<=0.0 means
+ // 'any distance" and values of
+ // x0, y0 and z0 are ignored
+ SELECTION_KEY sKey // selection key
+ ) {
+ PModel mdl;
+ PChain chain;
+ PResidue res;
+ PAtom atom;
+ pstr chain_l;
+ pstr res_l;
+ pstr atom_l;
+ pstr elem_l;
+ pstr altLocs1;
+ pstr aloc_l;
+ pstr segm_l;
+ pstr charge_l;
+ realtype dx,dy,dz,d02;
+ int i,j,k,n,m1,m2,c, nsel;
+ bool noRes,Occ,Dist,Sel,selAND;
+ bool modelSel,chainSel,resSel;
+ SELECTION_KEY sk;
+
+ if ((selHnd<=0) || (selHnd>nSelections) || (nAtoms<=0)) return;
+
+ modelSel = false;
+
+ k = selHnd-1;
+ sk = sKey;
+
+ if ((selType[k]==STYPE_UNDEFINED) || (sKey==SKEY_NEW))
+ selType[k] = sType;
+ else if (selType[k]!=sType) return;
+
+ // if something goes wrong, sk should be assigned SKEY_OR if
+ // selKey is set to SKEY_NEW or SKEY_OR below
+ switch (sKey) {
+ case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k];
+ break;
+ case SKEY_AND : nsel = 0; break;
+ case SKEY_XOR : nsel = nSelItems[k]; break;
+ case SKEY_CLR : nsel = nSelItems[k];
+ if (nsel<=0) return;
+ break;
+ default : return;
+ }
+
+ selAND = (sKey==SKEY_AND);
+
+ altLocs1 = NULL;
+ if (altLocs) {
+ if (strchr(altLocs,hetIndicator)) {
+ CreateCopy ( altLocs1,altLocs );
+ DelSpaces ( altLocs1 );
+ aloc_l = strchr ( altLocs1,hetIndicator );
+ aloc_l[0] = ' ';
+ if (aloc_l[1]) aloc_l[1] = ' '; // instead of comma
+ else if (aloc_l!=altLocs1) {
+ aloc_l--;
+ aloc_l[0] = ' ';
+ }
+ DelSpaces ( altLocs1 );
+ aloc_l = MakeList ( altLocs1 );
+ } else
+ aloc_l = MakeList ( altLocs );
+ } else
+ aloc_l = MakeList ( altLocs );
+
+ chain_l = MakeList ( Chains );
+ res_l = MakeList ( RNames );
+ atom_l = MakeList ( ANames );
+ elem_l = MakeList ( Elements );
+ segm_l = MakeList ( Segments );
+ charge_l = MakeList ( Charges );
+
+ // noRes==true means no residue restrictions
+ noRes = (ResNo1==ResNo2) && (ResNo1==ANY_RES) &&
+ (Ins1[0]==Ins2[0]) && (Ins1[0]=='*');
+
+ Occ = (occ1>=0.0) || (occ2>=0.0);
+ Dist = (d0>0.0);
+ d02 = d0*d0;
+
+ m1 = iModel-1;
+
+ if (m1>=0)
+ m2 = m1+1; // will take only this model
+ else {
+ m1 = 0; // will take
+ m2 = nModels; // all models
+ }
+
+ if (m1>=nModels) return;
+
+ for (n=0;n<nModels;n++) {
+ mdl = model[n];
+ if (mdl) { // check for safety
+ if ((m1<=n) && (n<m2)) {
+ modelSel = false; // will be true on any selection in the model
+ for (c=0;c<mdl->nChains;c++) {
+ chain = mdl->chain[c];
+ if (chain) { // again check for safety
+ if (MatchName(chain_l,chain->chainID)) {
+ // the chain has to be taken
+ i = 0;
+ if (!noRes)
+ while (i<chain->nResidues) {
+ res = chain->residue[i];
+ if (res) {
+ if ((res->seqNum==ResNo1) &&
+ MatchName(res_l,res->name) &&
+ ((Ins1[0]=='*') ||
+ (!strcmp(res->insCode,Ins1))))
+ break;
+ else if (selAND) {
+ if (sType==STYPE_ATOM)
+ res->UnmaskAtoms ( mask[k] );
+ else if (sType==STYPE_RESIDUE)
+ res->RemoveMask ( mask[k] );
+ }
+ }
+ i++;
+ }
+ while (i<chain->nResidues) {
+ res = chain->residue[i];
+ if (res) {
+ resSel = false; // will be true on 1st sel-n in the res-e
+ if (MatchName(res_l,res->name)) {
+ for (j=0;j<res->nAtoms;j++) {
+ atom = res->atom[j];
+ if (atom) {
+ if ((!atom->Ter) &&
+ MatchName(atom_l ,atom->name ) &&
+ MatchName(elem_l ,atom->element) &&
+ MatchName(aloc_l ,atom->altLoc ) &&
+ MatchName(segm_l ,atom->segID ) &&
+ MatchCharge(charge_l,atom ) &&
+ ((!altLocs1) || atom->Het)) {
+ Sel = true;
+ if (Occ)
+ Sel = ((occ1<=atom->occupancy) &&
+ (atom->occupancy<=occ2));
+ if (Dist) {
+ dx = atom->x - x0;
+ dy = atom->y - y0;
+ dz = atom->z - z0;
+ Sel = Sel && ((dx*dx+dy*dy+dz*dz)<=d02);
+ }
+ } else
+ Sel = false;
+ if (Sel) {
+ SelectObject ( sType,atom,k,sk,nsel );
+ resSel = true;
+ chainSel = true;
+ modelSel = true;
+ } else if (selAND && (sType==STYPE_ATOM))
+ atom->RemoveMask ( mask[k] );
+ }
+ if (resSel && (sType!=STYPE_ATOM)) break;
+ }
+ } else if (selAND && (sType==STYPE_ATOM))
+ res->UnmaskAtoms ( mask[k] );
+ if ((!resSel) && selAND && (sType==STYPE_RESIDUE))
+ res->RemoveMask ( mask[k] );
+ if (chainSel && (sType>STYPE_RESIDUE)) break;
+ if (!noRes) {
+ if ((res->seqNum==ResNo2) &&
+ ((Ins2[0]=='*') || (!strcmp(res->insCode,Ins2)))
+ ) break;
+ }
+ }
+ i++;
+ }
+ if (selAND) {
+ if (sType==STYPE_ATOM)
+ while (i<chain->nResidues) {
+ res = chain->residue[i];
+ if (res) res->UnmaskAtoms ( mask[k] );
+ i++;
+ }
+ if (sType==STYPE_RESIDUE)
+ while (i<chain->nResidues) {
+ res = chain->residue[i];
+ if (res) res->RemoveMask ( mask[k] );
+ i++;
+ }
+ }
+ } else if (selAND)
+ switch (sType) {
+ case STYPE_ATOM : chain->UnmaskAtoms ( mask[k] ); break;
+ case STYPE_RESIDUE : chain->UnmaskResidues ( mask[k] ); break;
+ case STYPE_CHAIN : chain->RemoveMask ( mask[k] ); break;
+ default : ;
+ }
+ if ((!chainSel) && selAND && (sType==STYPE_CHAIN))
+ chain->RemoveMask ( mask[k] );
+ if (modelSel && (sType>STYPE_CHAIN)) break;
+ }
+ }
+ } else if (selAND)
+ switch (sType) {
+ case STYPE_ATOM : mdl->UnmaskAtoms ( mask[k] ); break;
+ case STYPE_RESIDUE : mdl->UnmaskResidues ( mask[k] ); break;
+ case STYPE_CHAIN : mdl->UnmaskChains ( mask[k] ); break;
+ default : ;
+ }
+ if ((!modelSel) && selAND && (sType==STYPE_MODEL))
+ mdl->RemoveMask ( mask[k] );
+ }
+ }
+
+ // release dynamic memory
+ if (chain_l) delete[] chain_l;
+ if (res_l) delete[] res_l;
+ if (atom_l) delete[] atom_l;
+ if (elem_l) delete[] elem_l;
+ if (altLocs1) delete[] altLocs1;
+ if (aloc_l) delete[] aloc_l;
+ if (segm_l) delete[] segm_l;
+ if (charge_l) delete[] charge_l;
+
+ MakeSelIndex ( selHnd,STYPE_ATOM,nsel );
+
+ }
+
+
+ void SelManager::SelectAtoms (
+ int selHnd, // must be obtained from NewSelection()
+ int iModel, // model number; iModel=0 means
+ // 'any models'
+ cpstr Chains, // may be several chains "A,B,W";
+ // "*" means 'any chain' (in model)
+ int ResNo1, // starting residue number
+ cpstr Ins1, // starting residue insertion code;
+ // "*" means 'any code'
+ int ResNo2, // ending residue number.
+ // ResNo1=ResNo2=ANY_RES means 'any
+ // residue number' (in chain)
+ cpstr Ins2, // ending residue insertion code
+ // "*" means 'any code'
+ cpstr RNames, // may be several residue names
+ // "ALA,GLU,CIS"; "*" means 'any
+ // residue name'
+ cpstr ANames, // may be several names "CA,CB"; "*"
+ // means 'any atom' (in residue)
+ cpstr Elements, // may be several element types like
+ // "H,C,O,CU"; "*" means 'any
+ // element'
+ cpstr altLocs, // may be several alternative
+ // locations 'A,B'; "*" means 'any
+ // alternative location'
+ SELECTION_KEY sKey // selection key
+ ) {
+ Select ( selHnd,STYPE_ATOM,iModel,Chains,ResNo1,Ins1,ResNo2,Ins2,
+ RNames,ANames,Elements,altLocs,sKey );
+ }
+
+
+ int SelManager::Select (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ cpstr CID, // coordinate ID
+ SELECTION_KEY sKey // selection key
+ ) {
+ InsCode insCode1,insCode2;
+ pstr RNames;
+ pstr ANames;
+ pstr Elements;
+ pstr altLocs;
+ pstr Chains;
+ int seqNum1 ,seqNum2;
+ int iModel,l,RC;
+
+ l = IMax(10,strlen(CID))+1;
+ Chains = new char[l];
+ RNames = new char[l];
+ ANames = new char[l];
+ Elements = new char[l];
+ altLocs = new char[l];
+
+ if (strcmp(CID,"-all")) {
+ RC = ParseSelectionPath ( CID,iModel,Chains,seqNum1,insCode1,
+ seqNum2,insCode2,RNames,ANames,
+ Elements,altLocs );
+ } else {
+ iModel = 0;
+ strcpy ( Chains,"*" );
+ seqNum1 = ANY_RES;
+ seqNum2 = ANY_RES;
+ strcpy ( insCode1,"*" );
+ strcpy ( insCode2,"*" );
+ strcpy ( RNames ,"*" );
+ strcpy ( ANames ,"*" );
+ strcpy ( Elements,"*" );
+ strcpy ( altLocs ,"" ); // only main conformation by default
+ RC = 0;
+ }
+
+ if (!RC) {
+ Select ( selHnd,sType,iModel,Chains,seqNum1,insCode1,
+ seqNum2,insCode2,RNames,ANames,Elements,altLocs,sKey );
+ RC = 0;
+ }
+
+ delete[] Chains;
+ delete[] RNames;
+ delete[] ANames;
+ delete[] Elements;
+ delete[] altLocs;
+
+ return RC;
+
+ }
+
+ void SelManager::Select (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ int iModel, // model number; iModel=0 means
+ // 'any model'
+ cpstr Chains, // may be several chains "A,B,W";
+ // "*" means 'any chain' (in model)
+ int ResNo1, // starting residue number
+ cpstr Ins1, // starting residue insertion code;
+ // "*" means 'any code'
+ int ResNo2, // ending residue number.
+ // ResNo1=ResNo2=ANY_RES means 'any
+ // residue number' (in chain)
+ cpstr Ins2, // ending residue insertion code
+ // "*" means 'any code'
+ cpstr RNames, // may be several residue names
+ // "ALA,GLU,CIS"; "*" means 'any
+ // residue name'
+ cpstr ANames, // may be several names "CA,CB"; "*"
+ // means 'any atom' (in residue)
+ cpstr Elements, // may be several element types like
+ // "H,C,O,CU"; "*" means 'any element'
+ cpstr altLocs, // may be several alternative
+ // locations 'A,B'; "*" means 'any
+ // alternative location'
+ SELECTION_KEY sKey // selection key
+ ) {
+ PModel mdl;
+ PChain chain;
+ PResidue res;
+ PAtom atom;
+ pstr chain_l;
+ pstr res_l;
+ pstr atom_l;
+ pstr elem_l;
+ pstr altLocs1;
+ pstr aloc_l;
+ int i,j,k,n,m1,m2,c, nsel;
+ bool noRes,modelSel,chainSel,resSel,selAND;
+ SELECTION_KEY sk;
+
+ if ((selHnd<=0) || (selHnd>nSelections) || (nAtoms<=0)) return;
+
+ modelSel = false;
+
+ k = selHnd-1;
+ sk = sKey;
+
+ if ((selType[k]==STYPE_UNDEFINED) || (sKey==SKEY_NEW))
+ selType[k] = sType;
+ else if (selType[k]!=sType) return;
+
+ // if something goes wrong, sk should be assigned SKEY_OR if
+ // selKey is set to SKEY_NEW or SKEY_OR below
+ switch (sKey) {
+ case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k];
+ break;
+ case SKEY_AND : nsel = 0; break;
+ case SKEY_XOR : nsel = nSelItems[k]; break;
+ case SKEY_CLR : nsel = nSelItems[k];
+ if (nsel<=0) return;
+ break;
+ default : return;
+ }
+
+ selAND = (sKey==SKEY_AND);
+
+ altLocs1 = NULL;
+ if (altLocs) {
+ if (strchr(altLocs,hetIndicator)) {
+ CreateCopy ( altLocs1,altLocs );
+ DelSpaces ( altLocs1 );
+ aloc_l = strchr ( altLocs1,hetIndicator );
+ aloc_l[0] = ' ';
+ if (aloc_l[1]) aloc_l[1] = ' '; // instead of comma
+ else if (aloc_l!=altLocs1) {
+ aloc_l--;
+ aloc_l[0] = ' ';
+ }
+ DelSpaces ( altLocs1 );
+ aloc_l = MakeList ( altLocs1 );
+ } else
+ aloc_l = MakeList ( altLocs );
+ } else
+ aloc_l = MakeList ( altLocs );
+
+ chain_l = MakeList ( Chains );
+ res_l = MakeList ( RNames );
+ atom_l = MakeList ( ANames );
+ elem_l = MakeList ( Elements );
+
+ // noRes==true means no residue restrictions
+ noRes = (ResNo1==ResNo2) && (ResNo1==ANY_RES) &&
+ (Ins1[0]=='*') && (Ins2[0]=='*');
+
+ m1 = iModel-1;
+ if (m1>=0)
+ m2 = m1+1; // will take only this model
+ else {
+ m1 = 0; // will take
+ m2 = nModels; // all models
+ }
+
+ if (m1>=nModels) return;
+
+ for (n=0;n<nModels;n++) {
+ mdl = model[n];
+ if (mdl) { // check for safety
+ if ((m1<=n) && (n<m2)) {
+ modelSel = false; // will be true on any selection in the model
+ for (c=0;c<mdl->nChains;c++) {
+ chain = mdl->chain[c];
+ if (chain) { // again check for safety
+ chainSel = false; // will be true on 1st sel-n in the chain
+ if (MatchName(chain_l,chain->chainID)) {
+ // the chain is to be taken
+ i = 0;
+ if (!noRes) // skip "leading" residues
+ while (i<chain->nResidues) {
+ res = chain->residue[i];
+ if (res) {
+ if ((res->seqNum==ResNo1) &&
+ MatchName(res_l,res->name) &&
+ ((Ins1[0]=='*') ||
+ (!strcmp(res->insCode,Ins1))))
+ break;
+ else if (selAND) {
+ if (sType==STYPE_ATOM)
+ res->UnmaskAtoms ( mask[k] );
+ else if (sType==STYPE_RESIDUE)
+ res->RemoveMask ( mask[k] );
+ }
+ }
+ i++;
+ }
+ while (i<chain->nResidues) {
+ res = chain->residue[i];
+ i++;
+ if (res) {
+ resSel = false; // will be true on 1st selection
+ // in the residue
+ if (MatchName(res_l,res->name)) {
+ for (j=0;j<res->nAtoms;j++) {
+ atom = res->atom[j];
+ if (atom) {
+ if ((!atom->Ter) &&
+ MatchName(atom_l,atom->name ) &&
+ MatchName(elem_l,atom->element) &&
+ MatchName(aloc_l,atom->altLoc ) &&
+ ((!altLocs1) || atom->Het)) {
+ SelectObject ( sType,atom,k,sk,nsel );
+ resSel = true;
+ chainSel = true;
+ modelSel = true;
+ } else if (selAND && (sType==STYPE_ATOM))
+ atom->RemoveMask ( mask[k] );
+ }
+ if (resSel && (sType!=STYPE_ATOM)) break;
+ }
+ } else if (selAND && (sType==STYPE_ATOM))
+ res->UnmaskAtoms ( mask[k] );
+ if ((!resSel) && selAND && (sType==STYPE_RESIDUE))
+ res->RemoveMask ( mask[k] );
+ if (chainSel && (sType>STYPE_RESIDUE)) break;
+ if (!noRes) {
+ if ((res->seqNum==ResNo2) &&
+ ((Ins2[0]=='*') || (!strcmp(res->insCode,Ins2)))
+ ) break;
+ }
+ }
+ }
+ if (selAND) {
+ if (sType==STYPE_ATOM)
+ while (i<chain->nResidues) {
+ res = chain->residue[i];
+ if (res) res->UnmaskAtoms ( mask[k] );
+ i++;
+ }
+ if (sType==STYPE_RESIDUE)
+ while (i<chain->nResidues) {
+ res = chain->residue[i];
+ if (res) res->RemoveMask ( mask[k] );
+ i++;
+ }
+ }
+ } else if (selAND)
+ switch (sType) {
+ case STYPE_ATOM : chain->UnmaskAtoms ( mask[k] ); break;
+ case STYPE_RESIDUE : chain->UnmaskResidues ( mask[k] ); break;
+ default : ;
+ }
+ if ((!chainSel) && selAND && (sType==STYPE_CHAIN))
+ chain->RemoveMask ( mask[k] );
+ if (modelSel && (sType>STYPE_CHAIN)) break;
+ }
+ }
+ } else if (selAND)
+ switch (sType) {
+ case STYPE_ATOM : mdl->UnmaskAtoms ( mask[k] ); break;
+ case STYPE_RESIDUE : mdl->UnmaskResidues ( mask[k] ); break;
+ case STYPE_CHAIN : mdl->UnmaskChains ( mask[k] ); break;
+ default : ;
+ }
+ if ((!modelSel) && selAND && (sType==STYPE_MODEL))
+ mdl->RemoveMask ( mask[k] );
+ }
+ }
+
+ // release dynamic memory
+ if (chain_l) delete[] chain_l;
+ if (res_l) delete[] res_l;
+ if (atom_l) delete[] atom_l;
+ if (elem_l) delete[] elem_l;
+ if (altLocs1) delete[] altLocs1;
+ if (aloc_l) delete[] aloc_l;
+
+ MakeSelIndex ( selHnd,sType,nsel );
+
+ }
+
+
+ void SelManager::Select (
+ int selHnd1, // destination, must be obtained
+ // from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ int selHnd2, // source, must be obtained from
+ // NewSelection() and have been
+ // used for selection
+ SELECTION_KEY sKey // selection key
+ ) {
+ // SKEY_XOR works only downward the hierarchy!
+ PAtom atom;
+ PResidue res;
+ PChain chain;
+ PModel model;
+ int k1,k2,i,j,l,n,nsel;
+ SELECTION_KEY sk;
+
+ if ((selHnd1<=0) || (selHnd1>nSelections) ||
+ (selHnd2<=0) || (selHnd2>nSelections) || (nAtoms<=0)) return;
+
+ k1 = selHnd1-1;
+ k2 = selHnd2-1;
+ sk = sKey;
+
+ if ((selType[k1]==STYPE_UNDEFINED) || (sKey==SKEY_NEW))
+ selType[k1] = sType;
+ else if (selType[k1]!=sType) return;
+
+ if (selType[k2]==STYPE_UNDEFINED) return;
+
+ switch (sKey) {
+ case SKEY_NEW : for (i=0;i<nSelItems[k1];i++)
+ if (selection[k1][i])
+ selection[k1][i]->RemoveMask ( mask[k1] );
+ nSelItems[k1] = 0;
+ sk = SKEY_OR;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k1]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k1];
+ break;
+ case SKEY_AND : if (nSelItems[k1]==0) return;
+ sk = SKEY_XAND;
+ nsel = 0;
+ break;
+ case SKEY_XOR : nsel = nSelItems[k1]; break;
+ case SKEY_CLR : nsel = nSelItems[k1];
+ if (nsel<=0) return;
+ break;
+ default : return;
+ }
+
+
+ switch (selType[k2]) {
+
+ case STYPE_ATOM :
+ for (i=0;i<nSelItems[k2];i++) {
+ atom = (PAtom)selection[k2][i];
+ if (atom) {
+ if (!atom->Ter)
+ SelectObject ( sType,atom,k1,sk,nsel );
+ }
+ }
+ break;
+
+ case STYPE_RESIDUE :
+ for (i=0;i<nSelItems[k2];i++) {
+ res = (PResidue)selection[k2][i];
+ if (res)
+ switch (sType) {
+ case STYPE_ATOM : for (j=0;j<res->nAtoms;j++) {
+ atom = res->atom[j];
+ if (atom) {
+ if (!atom->Ter)
+ SelectObject (atom,k1,sk,nsel);
+ }
+ }
+ break;
+ case STYPE_RESIDUE : //if (res->chain)
+ SelectObject ( res,k1,sk,nsel );
+ break;
+ case STYPE_CHAIN : if (res->chain)
+ SelectObject ( res->chain,k1,
+ sk,nsel );
+ break;
+ case STYPE_MODEL : if (res->chain) {
+ if (res->chain->model)
+ SelectObject ( res->chain->model,
+ k1,sk,nsel );
+ }
+ default : ;
+ }
+ }
+ break;
+
+ case STYPE_CHAIN :
+ for (i=0;i<nSelItems[k2];i++) {
+ chain = (PChain)selection[k2][i];
+ if (chain)
+ switch (sType) {
+ case STYPE_ATOM : for (j=0;j<chain->nResidues;j++) {
+ res = chain->residue[j];
+ if (res)
+ for (l=0;l<res->nAtoms;l++) {
+ atom = res->atom[l];
+ if (atom) {
+ if (!atom->Ter)
+ SelectObject ( atom,k1,
+ sk,nsel );
+ }
+ }
+ }
+ break;
+ case STYPE_RESIDUE : for (j=0;j<chain->nResidues;j++) {
+ res = chain->residue[j];
+ if (res)
+ SelectObject ( res,k1,sk,nsel );
+ }
+ break;
+ case STYPE_CHAIN : //if (chain->model)
+ SelectObject ( chain,k1,sk,nsel );
+ break;
+ case STYPE_MODEL : if (chain->model)
+ SelectObject ( chain->model,k1,
+ sk,nsel );
+ default : ;
+ }
+ }
+ break;
+
+ case STYPE_MODEL :
+ for (i=0;i<nSelItems[k2];i++) {
+ model = (PModel)selection[k2][i];
+ if (model)
+ switch (sType) {
+ case STYPE_ATOM :
+ for (j=0;j<model->nChains;j++) {
+ chain = model->chain[j];
+ if (chain)
+ for (l=0;l<chain->nResidues;l++) {
+ res = chain->residue[l];
+ if (res)
+ for (n=0;n<res->nAtoms;n++) {
+ atom = res->atom[n];
+ if (atom) {
+ if (!atom->Ter)
+ SelectObject ( atom,k1,sk,nsel );
+ }
+ }
+ }
+ }
+ break;
+ case STYPE_RESIDUE :
+ for (j=0;j<model->nChains;j++) {
+ chain = model->chain[j];
+ if (chain)
+ for (l=0;l<chain->nResidues;l++) {
+ res = chain->residue[j];
+ if (res)
+ SelectObject ( res,k1,sk,nsel );
+ }
+ }
+ break;
+ case STYPE_CHAIN : for (j=0;j<model->nChains;j++) {
+ chain = model->chain[j];
+ if (chain)
+ SelectObject (chain,k1,sk,nsel);
+ }
+ break;
+ case STYPE_MODEL : SelectObject ( model,k1,sk,nsel );
+ default : ;
+ }
+ }
+ break;
+
+ default : ;
+
+ }
+
+ if (sKey==SKEY_AND)
+ for (i=0;i<nSelItems[k1];i++)
+ if (selection[k1][i])
+ selection[k1][i]->XadMask ( mask[k1] );
+
+ MakeSelIndex ( selHnd1,sType,nsel );
+
+ }
+
+ void SelManager::SelectProperty (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_PROPERTY propKey, // property key
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ SELECTION_KEY sKey // selection key
+ ) {
+ PModel mdl;
+ PChain chain;
+ PResidue res;
+ int i,k,selHnd1,nsel, m,c,r;
+ bool doSelect;
+ SELECTION_KEY sk;
+
+ if ((selHnd<=0) || (selHnd>nSelections) || (nAtoms<=0)) return;
+
+ k = selHnd-1;
+ if ((selType[k]==STYPE_UNDEFINED) || (sKey==SKEY_NEW))
+ selType[k] = sType;
+ else if (selType[k]!=sType) return;
+
+ if (sType!=STYPE_RESIDUE) {
+ selHnd1 = NewSelection();
+ if ((sKey==SKEY_AND) || (sKey==SKEY_CLR))
+ Select ( selHnd1,STYPE_RESIDUE,selHnd,SKEY_NEW );
+ } else
+ selHnd1 = selHnd;
+
+ k = selHnd1-1;
+ selType[k] = STYPE_RESIDUE;
+ sk = sKey;
+
+ switch (sKey) {
+ case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ sk = SKEY_OR;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k];
+ break;
+ case SKEY_AND : if (nSelItems[k]==0) return;
+ sk = SKEY_XAND;
+ nsel = 0;
+ break;
+ case SKEY_XOR : nsel = nSelItems[k]; break;
+ case SKEY_CLR : nsel = nSelItems[k];
+ if (nsel<=0) return;
+ break;
+ default : return;
+ }
+
+ if ((sKey==SKEY_AND) || (sKey==SKEY_CLR)) {
+
+ for (i=0;i<nSelItems[k];i++) {
+ res = (PResidue)selection[k][i];
+ if (res) {
+ switch (propKey) {
+ case SELPROP_Solvent : doSelect = res->isSolvent();
+ break;
+ case SELPROP_Aminoacid : doSelect = res->isAminoacid();
+ break;
+ case SELPROP_Nucleotide : doSelect = res->isNucleotide();
+ break;
+ case SELPROP_Sugar : doSelect = res->isSugar();
+ break;
+ case SELPROP_ModRes : doSelect = res->isModRes();
+ break;
+ default : doSelect = false;
+ }
+ if (doSelect) SelectObject ( res,k,sk,nsel );
+ }
+ }
+
+ if (sKey==SKEY_AND)
+ for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->XadMask ( mask[k] );
+
+ } else {
+
+ for (m=0;m<nModels;m++) {
+ mdl = model[m];
+ if (mdl) {
+ for (c=0;c<mdl->nChains;c++) {
+ chain = mdl->chain[c];
+ if (chain) {
+ for (r=0;r<chain->nResidues;r++) {
+ res = chain->residue[r];
+ if (res) {
+ switch (propKey) {
+ case SELPROP_Solvent : doSelect = res->isSolvent();
+ break;
+ case SELPROP_Aminoacid : doSelect = res->isAminoacid();
+ break;
+ case SELPROP_Nucleotide : doSelect = res->isNucleotide();
+ break;
+ case SELPROP_Sugar : doSelect = res->isSugar();
+ break;
+ case SELPROP_ModRes : doSelect = res->isModRes();
+ break;
+ default : doSelect = false;
+ }
+ if (doSelect) SelectObject ( res,k,sk,nsel );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+
+ MakeSelIndex ( selHnd1,STYPE_RESIDUE,nsel );
+
+ if (sType!=STYPE_RESIDUE) {
+ Select ( selHnd,sType,selHnd1,SKEY_NEW );
+ DeleteSelection ( selHnd1 );
+ }
+
+ }
+
+
+ void SelManager::SelectUDD (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ int UDDhandle, // UDD handle
+ int selMin, // lower selection boundary
+ int selMax, // upper selection boundary
+ SELECTION_KEY sKey // selection key
+ ) {
+ PModel mdl;
+ PChain chain;
+ PResidue res;
+ PAtom atom;
+ int i,k,nsel,iudd, n,c,r,a;
+ bool selAND;
+ SELECTION_KEY sk;
+
+ k = selHnd-1;
+ sk = sKey;
+
+ if ((selType[k]==STYPE_UNDEFINED) || (sKey==SKEY_NEW))
+ selType[k] = sType;
+ else if (selType[k]!=sType) return;
+
+
+ if ((selHnd<=0) || (selHnd>nSelections)) return;
+
+ switch (sType) {
+ case STYPE_ATOM : if ((UDDhandle & UDRF_ATOM)==0) return;
+ break;
+ case STYPE_RESIDUE : if ((UDDhandle & UDRF_RESIDUE)==0) return;
+ break;
+ case STYPE_CHAIN : if ((UDDhandle & UDRF_CHAIN)==0) return;
+ break;
+ case STYPE_MODEL : if ((UDDhandle & UDRF_MODEL)==0) return;
+ break;
+ default : return;
+ }
+
+
+ // if something goes wrong, sk should be assigned SKEY_OR if
+ // selKey is set to SKEY_NEW or SKEY_OR below
+ switch (sKey) {
+ case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k];
+ break;
+ case SKEY_AND : if (nSelItems[k]==0) return;
+ nsel = 0;
+ break;
+ case SKEY_XOR : nsel = nSelItems[k]; break;
+ case SKEY_CLR : nsel = nSelItems[k];
+ if (nsel<=0) return;
+ break;
+ default : return;
+ }
+
+ selAND = (sKey==SKEY_AND);
+
+
+ for (n=0;n<nModels;n++) {
+
+ mdl = model[n];
+ if (mdl) { // check for safety
+
+ if (sType==STYPE_MODEL) {
+
+ mdl->getUDData ( UDDhandle,iudd );
+ if ((selMin<=iudd) && (iudd<=selMax))
+ SelectObject ( mdl,k,sk,nsel );
+ else if (selAND)
+ mdl->RemoveMask ( mask[k] );
+
+ } else {
+
+ for (c=0;c<mdl->nChains;c++) {
+
+ chain = mdl->chain[c];
+ if (chain) { // again check for safety
+
+ if (sType==STYPE_CHAIN) {
+ chain->getUDData ( UDDhandle,iudd );
+ if ((selMin<=iudd) && (iudd<=selMax))
+ SelectObject ( chain,k,sk,nsel );
+ else if (selAND)
+ chain->RemoveMask ( mask[k] );
+
+ } else {
+
+ for (r=0;r<chain->nResidues;r++) {
+
+ res = chain->residue[r];
+ if (res) {
+
+ if (sType==STYPE_RESIDUE) {
+ res->getUDData ( UDDhandle,iudd );
+ if ((selMin<=iudd) && (iudd<=selMax))
+ SelectObject ( res,k,sk,nsel );
+ else if (selAND)
+ res->RemoveMask ( mask[k] );
+
+ } else {
+
+ for (a=0;a<res->nAtoms;a++) {
+ atom = res->atom[a];
+ if (atom) {
+ if (!atom->Ter) {
+ atom->getUDData ( UDDhandle,iudd );
+ if ((selMin<=iudd) && (iudd<=selMax))
+ SelectObject ( atom,k,sk,nsel );
+ else if (selAND)
+ atom->RemoveMask ( mask[k] );
+ }
+ }
+
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ MakeSelIndex ( selHnd,sType,nsel );
+
+ }
+
+
+ void SelManager::SelectUDD (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ int UDDhandle, // UDD handle
+ realtype selMin, // lower selection boundary
+ realtype selMax, // upper selection boundary
+ SELECTION_KEY sKey // selection key
+ ) {
+ PModel mdl;
+ PChain chain;
+ PResidue res;
+ PAtom atom;
+ realtype rudd;
+ int i,k,nsel, n,c,r,a;
+ bool selAND;
+ SELECTION_KEY sk;
+
+ k = selHnd-1;
+ sk = sKey;
+
+ if ((selType[k]==STYPE_UNDEFINED) || (sKey==SKEY_NEW))
+ selType[k] = sType;
+ else if (selType[k]!=sType) return;
+
+
+ if ((selHnd<=0) || (selHnd>nSelections)) return;
+
+ switch (sType) {
+ case STYPE_ATOM : if ((UDDhandle & UDRF_ATOM)==0) return;
+ break;
+ case STYPE_RESIDUE : if ((UDDhandle & UDRF_RESIDUE)==0) return;
+ break;
+ case STYPE_CHAIN : if ((UDDhandle & UDRF_CHAIN)==0) return;
+ break;
+ case STYPE_MODEL : if ((UDDhandle & UDRF_MODEL)==0) return;
+ break;
+ default : return;
+ }
+
+
+ // if something goes wrong, sk should be assigned SKEY_OR if
+ // selKey is set to SKEY_NEW or SKEY_OR below
+ switch (sKey) {
+ case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k];
+ break;
+ case SKEY_AND : if (nSelItems[k]==0) return;
+ nsel = 0;
+ break;
+ case SKEY_XOR : nsel = nSelItems[k]; break;
+ case SKEY_CLR : nsel = nSelItems[k];
+ if (nsel<=0) return;
+ break;
+ default : return;
+ }
+
+ selAND = (sKey==SKEY_AND);
+
+
+ for (n=0;n<nModels;n++) {
+
+ mdl = model[n];
+ if (mdl) { // check for safety
+
+ if (sType==STYPE_MODEL) {
+
+ mdl->getUDData ( UDDhandle,rudd );
+ if ((selMin<=rudd) && (rudd<=selMax))
+ SelectObject ( mdl,k,sk,nsel );
+ else if (selAND)
+ mdl->RemoveMask ( mask[k] );
+
+ } else {
+
+ for (c=0;c<mdl->nChains;c++) {
+
+ chain = mdl->chain[c];
+ if (chain) { // again check for safety
+
+ if (sType==STYPE_CHAIN) {
+ chain->getUDData ( UDDhandle,rudd );
+ if ((selMin<=rudd) && (rudd<=selMax))
+ SelectObject ( chain,k,sk,nsel );
+ else if (selAND)
+ chain->RemoveMask ( mask[k] );
+
+ } else {
+
+ for (r=0;r<chain->nResidues;r++) {
+
+ res = chain->residue[r];
+ if (res) {
+
+ if (sType==STYPE_RESIDUE) {
+ res->getUDData ( UDDhandle,rudd );
+ if ((selMin<=rudd) && (rudd<=selMax))
+ SelectObject ( res,k,sk,nsel );
+ else if (selAND)
+ res->RemoveMask ( mask[k] );
+
+ } else {
+
+ for (a=0;a<res->nAtoms;a++) {
+ atom = res->atom[a];
+ if (atom) {
+ if (!atom->Ter) {
+ atom->getUDData ( UDDhandle,rudd );
+ if ((selMin<=rudd) && (rudd<=selMax))
+ SelectObject ( atom,k,sk,nsel );
+ else if (selAND)
+ atom->RemoveMask ( mask[k] );
+ }
+ }
+
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ MakeSelIndex ( selHnd,sType,nsel );
+
+ }
+
+
+ bool selSUDD ( cpstr sudd, cpstr selStr, int cmpRule, int ssLen ) {
+ if (!sudd) return false;
+ switch (cmpRule) {
+ case UDSCR_LT : return (strcmp(sudd,selStr)<0);
+ case UDSCR_LE : return (strcmp(sudd,selStr)<=0);
+ case UDSCR_EQ : return (strcmp(sudd,selStr)==0);
+ case UDSCR_NE : return (strcmp(sudd,selStr)!=0);
+ case UDSCR_GE : return (strcmp(sudd,selStr)>=0);
+ case UDSCR_GT : return (strcmp(sudd,selStr)>=0);
+ case UDSCR_LTcase : return (strcasecmp(sudd,selStr)<0);
+ case UDSCR_LEcase : return (strcasecmp(sudd,selStr)<=0);
+ case UDSCR_EQcase : return (strcasecmp(sudd,selStr)==0);
+ case UDSCR_NEcase : return (strcasecmp(sudd,selStr)!=0);
+ case UDSCR_GEcase : return (strcasecmp(sudd,selStr)>=0);
+ case UDSCR_GTcase : return (strcasecmp(sudd,selStr)>=0);
+ case UDSCR_LTn : return (strncmp(sudd,selStr,ssLen)<0);
+ case UDSCR_LEn : return (strncmp(sudd,selStr,ssLen)<=0);
+ case UDSCR_EQn : return (strncmp(sudd,selStr,ssLen)==0);
+ case UDSCR_NEn : return (strncmp(sudd,selStr,ssLen)!=0);
+ case UDSCR_GEn : return (strncmp(sudd,selStr,ssLen)>=0);
+ case UDSCR_GTn : return (strncmp(sudd,selStr,ssLen)>=0);
+ case UDSCR_LTncase : return (strncasecmp(sudd,selStr,ssLen)<0);
+ case UDSCR_LEncase : return (strncasecmp(sudd,selStr,ssLen)<=0);
+ case UDSCR_EQncase : return (strncasecmp(sudd,selStr,ssLen)==0);
+ case UDSCR_NEncase : return (strncasecmp(sudd,selStr,ssLen)!=0);
+ case UDSCR_GEncase : return (strncasecmp(sudd,selStr,ssLen)>=0);
+ case UDSCR_GTncase : return (strncasecmp(sudd,selStr,ssLen)>=0);
+ case UDSCR_Substr : return (strstr(sudd,selStr)!=NULL);
+ case UDSCR_NoSubstr : return (strstr(sudd,selStr)==NULL);
+ case UDSCR_Substr1 : return (strstr(selStr,sudd)!=NULL);
+ case UDSCR_NoSubstr1 : return (strstr(selStr,sudd)==NULL);
+ default : return false;
+ }
+ }
+
+
+ void SelManager::SelectUDD (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ int UDDhandle, // UDD handle
+ cpstr selStr, // selection string
+ int cmpRule, // comparison rule
+ SELECTION_KEY sKey // selection key
+ ) {
+ PModel mdl;
+ PChain chain;
+ PResidue res;
+ PAtom atom;
+ int i,k,nsel,ssLen, n,c,r,a;
+ bool selAND;
+ SELECTION_KEY sk;
+
+ k = selHnd-1;
+ sk = sKey;
+
+ if ((selType[k]==STYPE_UNDEFINED) || (sKey==SKEY_NEW))
+ selType[k] = sType;
+ else if (selType[k]!=sType) return;
+
+
+ if ((selHnd<=0) || (selHnd>nSelections)) return;
+
+ switch (sType) {
+ case STYPE_ATOM : if ((UDDhandle & UDRF_ATOM)==0) return;
+ break;
+ case STYPE_RESIDUE : if ((UDDhandle & UDRF_RESIDUE)==0) return;
+ break;
+ case STYPE_CHAIN : if ((UDDhandle & UDRF_CHAIN)==0) return;
+ break;
+ case STYPE_MODEL : if ((UDDhandle & UDRF_MODEL)==0) return;
+ break;
+ default : return;
+ }
+
+
+ // if something goes wrong, sk should be assigned SKEY_OR if
+ // selKey is set to SKEY_NEW or SKEY_OR below
+ switch (sKey) {
+ case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k];
+ break;
+ case SKEY_AND : if (nSelItems[k]==0) return;
+ nsel = 0;
+ break;
+ case SKEY_XOR : nsel = nSelItems[k]; break;
+ case SKEY_CLR : nsel = nSelItems[k];
+ if (nsel<=0) return;
+ break;
+ default : return;
+ }
+
+ selAND = (sKey==SKEY_AND);
+ ssLen = strlen ( selStr );
+
+ for (n=0;n<nModels;n++) {
+
+ mdl = model[n];
+ if (mdl) { // check for safety
+
+ if (sType==STYPE_MODEL) {
+
+ if (selSUDD(mdl->getUDData(UDDhandle),selStr,
+ cmpRule,ssLen))
+ SelectObject ( mdl,k,sk,nsel );
+ else if (selAND)
+ mdl->RemoveMask ( mask[k] );
+
+ } else {
+
+ for (c=0;c<mdl->nChains;c++) {
+
+ chain = mdl->chain[c];
+ if (chain) { // again check for safety
+
+ if (sType==STYPE_CHAIN) {
+ if (selSUDD(chain->getUDData(UDDhandle),selStr,
+ cmpRule,ssLen))
+ SelectObject ( chain,k,sk,nsel );
+ else if (selAND)
+ chain->RemoveMask ( mask[k] );
+
+ } else {
+
+ for (r=0;r<chain->nResidues;r++) {
+
+ res = chain->residue[r];
+ if (res) {
+
+ if (sType==STYPE_RESIDUE) {
+ if (selSUDD(res->getUDData(UDDhandle),selStr,
+ cmpRule,ssLen))
+ SelectObject ( res,k,sk,nsel );
+ else if (selAND)
+ res->RemoveMask ( mask[k] );
+
+ } else {
+
+ for (a=0;a<res->nAtoms;a++) {
+ atom = res->atom[a];
+ if (atom) {
+ if (!atom->Ter) {
+ if (selSUDD(atom->getUDData(UDDhandle),selStr,
+ cmpRule,ssLen))
+ SelectObject ( atom,k,sk,nsel );
+ else if (selAND)
+ atom->RemoveMask ( mask[k] );
+ }
+ }
+
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ MakeSelIndex ( selHnd,sType,nsel );
+
+ }
+
+
+ void SelManager::SelectSphere (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ realtype x, // x-coordinate of the sphere's center
+ realtype y, // y-coordinate of the sphere's center
+ realtype z, // z-coordinate of the sphere's center
+ realtype r, // radius of the sphere
+ SELECTION_KEY sKey // selection key
+ ) {
+ // Selecting a sphere
+ PPAtom A;
+ PAtom atm;
+ PResidue res;
+ PChain chain;
+ PModel mdl;
+ realtype dx,dy,dz, r2;
+ int i,k, nat,nsel, im,ic,ir;
+ bool ASel, resSel,chainSel,modelSel,selAND;
+ SELECTION_KEY sk;
+
+ if ((selHnd<=0) || (selHnd>nSelections) || (r<=0.0)) return;
+
+ k = selHnd-1;
+ sk = sKey;
+ A = atom;
+ nat = nAtoms;
+
+ if ((selType[k]==STYPE_UNDEFINED) || (sKey==SKEY_NEW))
+ selType[k] = sType;
+ else if (selType[k]!=sType) return;
+
+ // if something goes wrong, sk should be assigned SKEY_OR if
+ // selKey is set to SKEY_NEW or SKEY_OR below
+ switch (sKey) {
+ case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k];
+ break;
+ case SKEY_AND : nsel = 0;
+ nat = nSelItems[k];
+ A = (PPAtom)selection[k];
+ break;
+ case SKEY_XOR : nsel = nSelItems[k];
+ break;
+ case SKEY_CLR : nsel = nSelItems[k];
+ nat = nSelItems[k];
+ A = (PPAtom)selection[k];
+ break;
+ default : return;
+ }
+
+ selAND = (sKey==SKEY_AND);
+
+ if ((nat<=0) || (!A)) return;
+
+ r2 = r*r;
+
+ if (sType==STYPE_ATOM) {
+
+ for (i=0;i<nat;i++)
+ if (A[i]) {
+ ASel = (sk!=SKEY_AND);
+ if ((!A[i]->Ter) && (A[i]->WhatIsSet & ASET_Coordinates)) {
+ dx = fabs(A[i]->x-x);
+ if (dx<=r) {
+ dy = fabs(A[i]->y-y);
+ if (dy<=r) {
+ dz = fabs(A[i]->z-z);
+ if (dz<=r) {
+ if (dx*dx+dy*dy+dz*dz<=r2) {
+ ASel = true;
+ SelectAtom ( A[i],k,sk,nsel );
+ }
+ }
+ }
+ }
+ }
+ if (!ASel) A[i]->RemoveMask ( mask[k] );
+ }
+
+ } else {
+
+ for (im=0;im<nModels;im++) {
+ mdl = model[im];
+ if (mdl) {
+ modelSel = false;
+ for (ic=0;ic<mdl->nChains;ic++) {
+ chain = mdl->chain[ic];
+ if (chain) {
+ chainSel = false;
+ for (ir=0;ir<chain->nResidues;ir++) {
+ res = chain->residue[ir];
+ if (res) {
+ resSel = false;
+ for (i=0;i<res->nAtoms;i++) {
+ atm = res->atom[i];
+ if (atm) {
+ ASel = false;
+ if ((!atm->Ter) &&
+ (atm->WhatIsSet & ASET_Coordinates)) {
+ dx = fabs(atm->x-x);
+ if (dx<=r) {
+ dy = fabs(atm->y-y);
+ if (dy<=r) {
+ dz = fabs(atm->z-z);
+ if (dz<=r) {
+ if (dx*dx+dy*dy+dz*dz<=r2) {
+ SelectObject ( sType,atm,k,sk,nsel );
+ ASel = true;
+ resSel = true;
+ chainSel = true;
+ modelSel = true;
+ }
+ }
+ }
+ }
+ }
+ if (ASel) break; // selType>=STYPE_RESIDUE
+ }
+ }
+ if ((!resSel) && selAND && (sType==STYPE_RESIDUE))
+ res->RemoveMask ( mask[k] );
+ if (chainSel && (sType>STYPE_RESIDUE)) break;
+ }
+ }
+ if ((!chainSel) && selAND && (sType==STYPE_CHAIN))
+ chain->RemoveMask ( mask[k] );
+ if (modelSel && (sType>STYPE_CHAIN)) break;
+ }
+ }
+ if ((!modelSel) && selAND && (sType==STYPE_MODEL))
+ mdl->RemoveMask ( mask[k] );
+ }
+ }
+
+ }
+
+ MakeSelIndex ( selHnd,sType,nsel );
+
+ }
+
+
+ void SelManager::SelectCylinder (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ realtype x1, // x-coordinate of the cylinder axis' 1st end
+ realtype y1, // y-coordinate of the cylinder axis' 1st end
+ realtype z1, // z-coordinate of the cylinder axis' 1st end
+ realtype x2, // x-coordinate of the cylinder axis' 2nd end
+ realtype y2, // y-coordinate of the cylinder axis' 2nd end
+ realtype z2, // z-coordinate of the cylinder axis' 2nd end
+ realtype r, // radius of the cylinder
+ SELECTION_KEY sKey // selection key
+ ) {
+ //
+ // Selecting a cylinder
+ //
+ // Method : given a line running through (x1,y1,z1) to (x2,y2,z2) on,
+ // a point (x,y,z) is then projected on it at distance
+ //
+ // c1 = (c^2-a^2+b^2)/(2c),
+ //
+ // from (x1,y1,z1), where
+ // 'a' is the distance between (x,y,z) and (x2,y2,z2)
+ // 'b' is the distance between (x,y,z) and (x1,y1,z1)
+ // 'c' is the distance between (x1,y1,z1) and (x2,y2,z2).
+ // The distance between point (x,y,z) and line is determined as
+ //
+ // h^2 = b^2 - c1^2
+ //
+ // If c1>=0 and c1<=c and h^2<=r^2 then point (x,y,z) is inside
+ // a cylinder of radius 'r' with axis running from point
+ // (x1,y1,z1) to (x2,y2,z2).
+ //
+ PPAtom A;
+ PAtom atm;
+ PResidue res;
+ PChain chain;
+ PModel mdl;
+ realtype dx,dy,dz, c,dc,c1,c2, a2,b2, r2;
+ int i,k, nat,nsel, im,ic,ir;
+ bool resSel,chainSel,modelSel,selAND;
+ SELECTION_KEY sk;
+
+ if ((selHnd<=0) || (selHnd>nSelections) || (r<=0.0)) return;
+
+ dx = x1-x2;
+ dy = y1-y2;
+ dz = z1-z2;
+ c2 = dx*dx + dy*dy + dz*dz;
+ if (c2<=0.0) return;
+ c = sqrt(c2);
+ dc = 2.0*c;
+ r2 = r*r;
+
+ k = selHnd-1;
+ sk = sKey;
+ A = atom;
+ nat = nAtoms;
+
+ if ((selType[k]==STYPE_UNDEFINED) || (sKey==SKEY_NEW))
+ selType[k] = sType;
+ else if (selType[k]!=sType) return;
+
+ // if something goes wrong, sk should be assigned SKEY_OR if
+ // selKey is set to SKEY_NEW or SKEY_OR below
+ switch (sKey) {
+ case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k];
+ break;
+ case SKEY_AND : nsel = 0;
+ nat = nSelItems[k];
+ A = (PPAtom)selection[k];
+ break;
+ case SKEY_XOR : nsel = nSelItems[k];
+ break;
+ case SKEY_CLR : nsel = nSelItems[k];
+ nat = nSelItems[k];
+ A = (PPAtom)selection[k];
+ break;
+ default : return;
+ }
+
+ selAND = (sKey==SKEY_AND);
+
+ if ((nat<=0) || (!A)) return;
+
+ if (sType==STYPE_ATOM) {
+
+ for (i=0;i<nat;i++)
+ if (A[i]) {
+ if ((!A[i]->Ter) && (A[i]->WhatIsSet & ASET_Coordinates)) {
+ dx = fabs(A[i]->x-x1);
+ dy = fabs(A[i]->y-y1);
+ dz = fabs(A[i]->z-z1);
+ a2 = dx*dx + dy*dy + dz*dz;
+ dx = fabs(A[i]->x-x2);
+ dy = fabs(A[i]->y-y2);
+ dz = fabs(A[i]->z-z2);
+ b2 = dx*dx + dy*dy + dz*dz;
+ c1 = (c2-a2+b2)/dc;
+ if ((0.0<=c1) && (c1<=c) && (b2-c1*c1<=r2))
+ SelectAtom ( A[i],k,sk,nsel );
+ else if (sk==SKEY_AND)
+ A[i]->RemoveMask ( mask[k] );
+ }
+ }
+
+ } else {
+
+ for (im=0;im<nModels;im++) {
+ mdl = model[im];
+ if (mdl) {
+ modelSel = false;
+ for (ic=0;ic<mdl->nChains;ic++) {
+ chain = mdl->chain[ic];
+ if (chain) {
+ chainSel = false;
+ for (ir=0;ir<chain->nResidues;ir++) {
+ res = chain->residue[ir];
+ if (res) {
+ resSel = false;
+ for (i=0;i<res->nAtoms;i++) {
+ atm = res->atom[i];
+ if (atm) {
+ if ((!atm->Ter) &&
+ (atm->WhatIsSet & ASET_Coordinates)) {
+ dx = fabs(atm->x-x1);
+ dy = fabs(atm->y-y1);
+ dz = fabs(atm->z-z1);
+ a2 = dx*dx + dy*dy + dz*dz;
+ dx = fabs(atm->x-x2);
+ dy = fabs(atm->y-y2);
+ dz = fabs(atm->z-z2);
+ b2 = dx*dx + dy*dy + dz*dz;
+ c1 = (c2-a2+b2)/dc;
+ if ((0.0<=c1) && (c1<=c) && (b2-c1*c1<=r2)) {
+ SelectObject ( sType,atm,k,sk,nsel );
+ resSel = true;
+ chainSel = true;
+ modelSel = true;
+ break; // selType>=STYPE_RESIDUE
+ }
+ }
+ }
+ }
+ if ((!resSel) && selAND && (sType==STYPE_RESIDUE))
+ res->RemoveMask ( mask[k] );
+ if (chainSel && (sType>STYPE_RESIDUE)) break;
+ }
+ }
+ if ((!chainSel) && selAND && (sType==STYPE_CHAIN))
+ chain->RemoveMask ( mask[k] );
+ if (modelSel && (sType>STYPE_CHAIN)) break;
+ }
+ }
+ if ((!modelSel) && selAND && (sType==STYPE_MODEL))
+ mdl->RemoveMask ( mask[k] );
+ }
+ }
+
+ }
+
+ MakeSelIndex ( selHnd,sType,nsel );
+
+ }
+
+
+ void SelManager::SelectSlab (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ realtype a, // a-parameter of the plane ax+by+cz=d
+ realtype b, // b-parameter of the plane ax+by+cz=d
+ realtype c, // c-parameter of the plane ax+by+cz=d
+ realtype d, // d-parameter of the plane ax+by+cz=d
+ realtype r, // distance to the plane
+ SELECTION_KEY sKey // selection key
+ ) {
+ //
+ // Selecting all atoms on a given distance from a plane
+ //
+ // Method : the distance between a point (x0,y0,z0) and a plane
+ // defined by equation
+ //
+ // a*x + b*y + c*z = d
+ //
+ // is found as
+ //
+ // h = (d-a*x0-b*y0-c*z0)/sqrt(a^2+b^2+c^2)
+ //
+ // If |h|<d then point (x0,y0,z0) belongs to the slab.
+ //
+ PPAtom A;
+ PAtom atm;
+ PResidue res;
+ PChain chain;
+ PModel mdl;
+ realtype v,h;
+ int i,k, nat,nsel, im,ic,ir;
+ bool resSel,chainSel,modelSel,selAND;
+ SELECTION_KEY sk;
+
+ if ((selHnd<=0) || (selHnd>nSelections) || (r<=0.0)) return;
+
+ v = sqrt(a*a + b*b + c*c);
+ if (v<=0.0) return;
+
+ k = selHnd-1;
+ sk = sKey;
+ A = atom;
+ nat = nAtoms;
+
+ if ((selType[k]==STYPE_UNDEFINED) || (sKey==SKEY_NEW))
+ selType[k] = sType;
+ else if (selType[k]!=sType) return;
+
+ // if something goes wrong, sk should be assigned SKEY_OR if
+ // selKey is set to SKEY_NEW or SKEY_OR below
+ switch (sKey) {
+ case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k];
+ break;
+ case SKEY_AND : nsel = 0;
+ nat = nSelItems[k];
+ A = (PPAtom)selection[k];
+ break;
+ case SKEY_XOR : nsel = nSelItems[k];
+ break;
+ case SKEY_CLR : nsel = nSelItems[k];
+ nat = nSelItems[k];
+ A = (PPAtom)selection[k];
+ break;
+ default : return;
+ }
+
+ selAND = (sKey==SKEY_AND);
+
+ if ((nat<=0) || (!A)) return;
+
+ if (sType==STYPE_ATOM) {
+
+ for (i=0;i<nat;i++)
+ if (A[i]) {
+ if ((!A[i]->Ter) && (A[i]->WhatIsSet & ASET_Coordinates)) {
+ h = fabs(d-a*A[i]->x-b*A[i]->y-c*A[i]->z)/v;
+ if (h<=r)
+ SelectAtom ( A[i],k,sk,nsel );
+ else if (sk==SKEY_AND)
+ A[i]->RemoveMask ( mask[k] );
+ }
+ }
+
+ } else {
+
+ for (im=0;im<nModels;im++) {
+ mdl = model[im];
+ if (mdl) {
+ modelSel = false;
+ for (ic=0;ic<mdl->nChains;ic++) {
+ chain = mdl->chain[ic];
+ if (chain) {
+ chainSel = false;
+ for (ir=0;ir<chain->nResidues;ir++) {
+ res = chain->residue[ir];
+ if (res) {
+ resSel = false;
+ for (i=0;i<res->nAtoms;i++) {
+ atm = res->atom[i];
+ if (atm) {
+ if ((!atm->Ter) &&
+ (atm->WhatIsSet & ASET_Coordinates)) {
+ h = fabs(d-a*A[i]->x-b*A[i]->y-c*A[i]->z)/v;
+ if (h<=r) {
+ SelectObject ( sType,atm,k,sk,nsel );
+ resSel = true;
+ chainSel = true;
+ modelSel = true;
+ break; // selType>=STYPE_RESIDUE
+ }
+ }
+ }
+ }
+ if ((!resSel) && selAND && (sType==STYPE_RESIDUE))
+ res->RemoveMask ( mask[k] );
+ if (chainSel && (sType>STYPE_RESIDUE)) break;
+ }
+ }
+ if ((!chainSel) && selAND && (sType==STYPE_CHAIN))
+ chain->RemoveMask ( mask[k] );
+ if (modelSel && (sType>STYPE_CHAIN)) break;
+ }
+ }
+ if ((!modelSel) && selAND && (sType==STYPE_MODEL))
+ mdl->RemoveMask ( mask[k] );
+ }
+ }
+
+ }
+
+ MakeSelIndex ( selHnd,sType,nsel );
+
+ }
+
+
+ void SelManager::SelectNeighbours (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ PPAtom sA, // array of already selected atoms
+ int alen, // length of A
+ realtype d1, // minimal distance to already selected atoms
+ realtype d2, // maximal distance to already selected atoms
+ SELECTION_KEY sKey // selection key
+ ) {
+ // Selecting all atoms on a given distance from already selected
+ PPAtom A;
+ PBrick B;
+ PAtom atm;
+ PResidue res;
+ PChain chain;
+ PModel mdl;
+ realtype x,y,z, dx,dy,dz, dst, d12,d22;
+ int i,j,k, dn, nx,ny,nz, nat,nsel, im,ic,ir;
+ int ix1,ix2,ix, iy1,iy2,iy, iz1,iz2,iz;
+ bool ASel,resSel,chainSel,modelSel,selAND;
+ SELECTION_KEY sk;
+
+ if ((selHnd<=0) || (selHnd>nSelections) ||
+ (d2<=0.0) || (d2<d1)) return;
+
+ k = selHnd-1;
+ sk = sKey;
+ A = atom;
+ nat = nAtoms;
+ d12 = d1*d1;
+ d22 = d2*d2;
+
+ if ((selType[k]==STYPE_UNDEFINED) || (sKey==SKEY_NEW))
+ selType[k] = sType;
+ else if (selType[k]!=sType) return;
+
+ if ((alen<1) || (!sA)) {
+ if ((sKey==SKEY_NEW) || (sKey==SKEY_AND)) {
+ for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ }
+ return;
+ }
+
+ // if something goes wrong, sk should be assigned SKEY_OR if
+ // selKey is set to SKEY_NEW or SKEY_OR below
+ switch (sKey) {
+ case SKEY_NEW : for (i=0;i<nSelItems[k];i++)
+ if (selection[k][i])
+ selection[k][i]->RemoveMask ( mask[k] );
+ nSelItems[k] = 0;
+ nsel = 0;
+ break;
+ case SKEY_OR : if (nSelItems[k]==0) sk = SKEY_NEW;
+ nsel = nSelItems[k];
+ break;
+ case SKEY_AND : nsel = 0;
+ nat = nSelItems[k];
+ A = (PPAtom)selection[k];
+ break;
+ case SKEY_XOR : nsel = nSelItems[k];
+ break;
+ case SKEY_CLR : nsel = nSelItems[k];
+ nat = nSelItems[k];
+ A = (PPAtom)selection[k];
+ break;
+ default : return;
+ }
+
+ selAND = (sk==SKEY_AND);
+
+ if ((nat<=0) || (!A)) return;
+
+ MakeBricks ( sA,alen,d2*1.5 );
+ dn = mround(d2/brick_size)+1;
+
+ if (brick && (sType==STYPE_ATOM)) {
+
+ for (i=0;i<nat;i++)
+ if (A[i]) {
+ if (!A[i]->Ter) {
+ ASel = false;
+ GetBrickCoor ( A[i],nx,ny,nz );
+ if (nx<0) nx++;
+ ix1 = IMax ( 0,nx-dn );
+ iy1 = IMax ( 0,ny-dn );
+ iz1 = IMax ( 0,nz-dn );
+ ix2 = IMin ( nbrick_x,nx+dn+1 );
+ iy2 = IMin ( nbrick_y,ny+dn+1 );
+ iz2 = IMin ( nbrick_z,nz+dn+1 );
+ x = A[i]->x;
+ y = A[i]->y;
+ z = A[i]->z;
+ for (ix=ix1;(ix<ix2) && (!ASel);ix++)
+ if (brick[ix])
+ for (iy=iy1;(iy<iy2) && (!ASel);iy++)
+ if (brick[ix][iy])
+ for (iz=iz1;(iz<iz2) && (!ASel);iz++) {
+ B = brick[ix][iy][iz];
+ if (B)
+ for (j=0;(j<B->nAtoms) && (!ASel);j++)
+ if (B->atom[j]!=A[i]) {
+ dx = fabs(x-B->atom[j]->x);
+ if (dx<=d2) {
+ dy = fabs(y-B->atom[j]->y);
+ if (dy<=d2) {
+ dz = fabs(z-B->atom[j]->z);
+ if (dz<=d2) {
+ dst = dx*dx+dy*dy+dz*dz;
+ if ((dst>=d12) && (dst<=d22)) {
+ ASel = true;
+ SelectAtom ( A[i],k,sk,nsel );
+ }
+ }
+ }
+ }
+ }
+ }
+ if ((!ASel) && selAND) A[i]->RemoveMask ( mask[k] );
+ }
+ }
+
+ } else if (brick) {
+
+ for (im=0;im<nModels;im++) {
+ mdl = model[im];
+ if (mdl) {
+ modelSel = false;
+ for (ic=0;ic<mdl->nChains;ic++) {
+ chain = mdl->chain[ic];
+ if (chain) {
+ chainSel = false;
+ for (ir=0;ir<chain->nResidues;ir++) {
+ res = chain->residue[ir];
+ if (res) {
+ resSel = false;
+ for (i=0;(i<res->nAtoms) && (!resSel);i++) {
+ atm = res->atom[i];
+ if (atm) {
+ if ((!atm->Ter) &&
+ (atm->WhatIsSet & ASET_Coordinates)) {
+ GetBrickCoor ( atm,nx,ny,nz );
+ if (nx<0) nx++;
+ ix1 = IMax ( 0,nx-dn );
+ iy1 = IMax ( 0,ny-dn );
+ iz1 = IMax ( 0,nz-dn );
+ ix2 = IMin ( nbrick_x,nx+dn+1 );
+ iy2 = IMin ( nbrick_y,ny+dn+1 );
+ iz2 = IMin ( nbrick_z,nz+dn+1 );
+ x = atm->x;
+ y = atm->y;
+ z = atm->z;
+ for (ix=ix1;(ix<ix2) && (!resSel);ix++)
+ if (brick[ix])
+ for (iy=iy1;(iy<iy2) && (!resSel);iy++)
+ if (brick[ix][iy])
+ for (iz=iz1;(iz<iz2) && (!resSel);iz++) {
+ B = brick[ix][iy][iz];
+ if (B)
+ for (j=0;(j<B->nAtoms) &&
+ (!resSel);j++)
+ if (B->atom[j]!=atm) {
+ dx = fabs(x-B->atom[j]->x);
+ if (dx<=d2) {
+ dy = fabs(y-B->atom[j]->y);
+ if (dy<=d2) {
+ dz = fabs(z-B->atom[j]->z);
+ if (dz<=d2) {
+ dst = dx*dx+dy*dy+dz*dz;
+ if ((dst>=d12) &&
+ (dst<=d22)) {
+ SelectObject ( sType,
+ atm,k,sk,nsel );
+ resSel = true;
+ chainSel = true;
+ modelSel = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ }
+ }
+ }
+ if ((!resSel) && selAND && (sType==STYPE_RESIDUE))
+ res->RemoveMask ( mask[k] );
+ if (chainSel && (sType>STYPE_RESIDUE)) break;
+ }
+ }
+ if ((!chainSel) && selAND && (sType==STYPE_CHAIN))
+ chain->RemoveMask ( mask[k] );
+ if (modelSel && (sType>STYPE_CHAIN)) break;
+ }
+ }
+ if ((!modelSel) && selAND && (sType==STYPE_MODEL))
+ mdl->RemoveMask ( mask[k] );
+ }
+ }
+
+ }
+
+ MakeSelIndex ( selHnd,sType,nsel );
+
+ }
+
+
+
+ int TakeChainID ( pstr & p, pstr chainID ) {
+ int RC,k;
+ chainID[0] = char(0);
+ if (*p) {
+ RC = 0;
+ if (*p==':') {
+ // starts with colon <=> empty chain ID
+ chainID[0] = char(0);
+ p++; // advance to residue number
+ } else if (p[1]==':') {
+ // second symbol is colon <=> regular chain ID
+ chainID[0] = *p;
+ chainID[1] = char(0);
+ p++;
+ p++; // advance to residue number
+ } else if (*p=='\'') {
+ // starts with a strip <=> assume empty chain ID
+ chainID[0] = char(0);
+ p++;
+ if (*p=='\'') {
+ // closing strip must be followed by colon
+ p++;
+ if (*p!=':') RC = -1;
+ } else {
+ // no concluding strip <=> could be a strip chain ID,
+ // although this must be captured by 2nd "if"
+ chainID[0] = '\'';
+ chainID[1] = char(0);
+ // assume that residue number is following the strip
+ }
+ } else if ((int(*p)>=int('0')) && (int(*p)<=int('9'))) {
+ // a digit without following semicolon looks very much
+ // like residue number with unspecified empty chain ID
+ chainID[0] = char(0);
+ // assume that p already points on residue number
+ } else {
+ // assume a long chain ID
+ k = 0;
+ while (*p && (*p!=':') && (k<(int)sizeof(ChainID)-1)) {
+ chainID[k++] = *p;
+ p++;
+ }
+ if (*p==':') {
+ chainID[k] = char(0);
+ } else {
+ // a mistake
+ chainID[0] = char(0);
+ RC = -1;
+ }
+ }
+ while (*p==' ') p++;
+ } else
+ RC = 1;
+ return RC;
+ }
+
+ int TakeResID( pstr & p, int & seqNum, pstr inscode ) {
+ char N[100];
+ int i,RC;
+ pstr endptr;
+ RC = 1;
+ inscode[0] = '*';
+ inscode[1] = char(0);
+ seqNum = ANY_RES;
+ if (((*p) &&
+ (int(*p)>=int('0')) && (int(*p)<=int('9'))) || (*p=='-')) {
+ N[0] = *p;
+ p++;
+ i = 1;
+ while ((*p) && (int(*p)>=int('0')) && (int(*p)<=int('9'))) {
+ N[i++] = *p;
+ p++;
+ }
+ N[i] = char(0);
+ seqNum = mround(strtod(N,&endptr));
+ if ((seqNum==0) && (endptr==N))
+ RC = -1;
+ else {
+ RC = 0;
+ if ((*p) && (*p!='-') && (*p!=',') && (*p!=' ')) {
+ inscode[0] = *p;
+ inscode[1] = char(0);
+ p++;
+ } else
+ inscode[0] = char(0);
+ if ((*p=='-') || (*p==',')) p++;
+ }
+ while (*p==' ') p++;
+ }
+ return RC;
+ }
+
+
+ int SelManager::SelectDomain ( int selHnd , cpstr domainRange,
+ SELECTION_TYPE sType,
+ SELECTION_KEY sKey,
+ int modelNo ) {
+ // domainRange is of the following format:
+ // "*", "(all)" - take all file
+ // "-" - take chain without chain ID
+ // "a:Ni-Mj,b:Kp-Lq,..." - take chain a residue number N
+ // insertion code i to residue number M
+ // insertion code j plus chain b
+ // residue number K insertion code p to
+ // residue number L insertion code q and
+ // so on.
+ // "a:,b:..." - take whole chains a and b and so on
+ // "a:,b:Kp-Lq,..." - any combination of the above.
+ ChainID chainID;
+ InsCode insCode1,insCode2;
+ pstr S,p;
+ int seqNum1,seqNum2,rc;
+ SELECTION_KEY selKey1;
+
+ if ((selHnd<=0) || (selHnd>nSelections)) return 1;
+
+ // leave only required residues
+
+ rc = 1;
+ if (!domainRange) rc = 0;
+ else if ((!domainRange[0]) || (domainRange[0]=='*')) rc = 0;
+ else if (!strcasecmp(domainRange,"(all)")) rc = 0;
+ if (!rc) {
+ // select all
+ Select ( selHnd,sType,modelNo,"*",ANY_RES,"*",ANY_RES,"*",
+ "*","*","*","*",sKey );
+ return 0;
+ }
+ if (!strcasecmp(domainRange,"-")) {
+ // select chain without chain ID
+ Select ( selHnd,sType,modelNo,"",ANY_RES,"*",ANY_RES,"*",
+ "*","*","*","*",sKey );
+ return 0;
+ }
+
+ S = new char[strlen(domainRange)+10];
+ strcpy ( S,domainRange );
+ DelSpaces ( S );
+ // UpperCase ( S );
+
+ p = S;
+ rc = 0;
+
+ selKey1 = sKey;
+
+ while ((*p) && (!rc)) {
+
+ if (TakeChainID(p,chainID)<0) rc = -1;
+ else if (TakeResID(p,seqNum1,insCode1)<0) rc = -2;
+ else if (TakeResID(p,seqNum2,insCode2)<0) rc = -3;
+ else {
+ Select ( selHnd,sType,modelNo,chainID,
+ seqNum1,insCode1,seqNum2,insCode2,
+ "*","*","*","*",selKey1 );
+ if (*p==',') p++;
+ if (selKey1==SKEY_NEW) selKey1 = SKEY_OR;
+ }
+
+ }
+
+ delete[] S;
+
+ return rc;
+
+ }
+
+
+ int SelManager::GetSelLength ( int selHnd ) {
+ if ((selHnd>0) && (selHnd<=nSelections))
+ return nSelItems[selHnd-1];
+ else return 0;
+ }
+
+
+ void SelManager::GetSelIndex ( int selHnd,
+ PPAtom & SelAtom,
+ int & nSelAtoms ) {
+ if ((selHnd>0) && (selHnd<=nSelections)) {
+ if (selType[selHnd-1]!=STYPE_ATOM) {
+ SelAtom = NULL;
+ nSelAtoms = 0;
+ } else {
+ SelAtom = (PPAtom)selection[selHnd-1];
+ nSelAtoms = nSelItems[selHnd-1];
+ }
+ } else {
+ SelAtom = NULL;
+ nSelAtoms = 0;
+ }
+ }
+
+ void SelManager::GetSelIndex ( int selHnd,
+ PPResidue & SelResidue,
+ int & nSelResidues ) {
+ if ((selHnd>0) && (selHnd<=nSelections)) {
+ if (selType[selHnd-1]!=STYPE_RESIDUE) {
+ SelResidue = NULL;
+ nSelResidues = 0;
+ } else {
+ SelResidue = (PPResidue)selection[selHnd-1];
+ nSelResidues = nSelItems[selHnd-1];
+ }
+ } else {
+ SelResidue = NULL;
+ nSelResidues = 0;
+ }
+ }
+
+ void SelManager::GetSelIndex ( int selHnd,
+ PPChain & SelChain,
+ int & nSelChains ) {
+ if ((selHnd>0) && (selHnd<=nSelections)) {
+ if (selType[selHnd-1]!=STYPE_CHAIN) {
+ SelChain = NULL;
+ nSelChains = 0;
+ } else {
+ SelChain = (PPChain)selection[selHnd-1];
+ nSelChains = nSelItems[selHnd-1];
+ }
+ } else {
+ SelChain = NULL;
+ nSelChains = 0;
+ }
+ }
+
+ void SelManager::GetSelIndex ( int selHnd,
+ PPModel & SelModel,
+ int & nSelModels ) {
+ if ((selHnd>0) && (selHnd<=nSelections)) {
+ if (selType[selHnd-1]!=STYPE_MODEL) {
+ SelModel = NULL;
+ nSelModels = 0;
+ } else {
+ SelModel = (PPModel)selection[selHnd-1];
+ nSelModels = nSelItems[selHnd-1];
+ }
+ } else {
+ SelModel = NULL;
+ nSelModels = 0;
+ }
+ }
+
+
+ void SelManager::GetAtomStatistics ( int selHnd, RAtomStat AS ) {
+ int i,k;
+ AS.Init();
+ if ((selHnd>0) && (selHnd<=nSelections)) {
+ k = selHnd-1;
+ switch (selType[k]) {
+ case STYPE_MODEL : if (selection[k])
+ for (i=0;i<nSelItems[k];i++)
+ ((PModel)selection[k][i])->
+ CalAtomStatistics ( AS );
+ break;
+ case STYPE_CHAIN : if (selection[k])
+ for (i=0;i<nSelItems[k];i++)
+ ((PChain)selection[k][i])->
+ CalAtomStatistics ( AS );
+ break;
+ case STYPE_RESIDUE : if (selection[k])
+ for (i=0;i<nSelItems[k];i++)
+ ((PResidue)selection[k][i])->
+ CalAtomStatistics ( AS );
+ break;
+ case STYPE_ATOM : if (selection[k])
+ for (i=0;i<nSelItems[k];i++)
+ ((PAtom)selection[k][i])->
+ CalAtomStatistics ( AS );
+ break;
+ default : break;
+ }
+ }
+ AS.Finish();
+ }
+
+
+ void SelManager::SelectAtom ( PAtom atom, int maskNo,
+ SELECTION_KEY sKey, int & nsel ) {
+ bool ASel;
+ ASel = atom->CheckMask ( mask[maskNo] );
+ switch (sKey) {
+ default :
+ case SKEY_NEW :
+ case SKEY_OR : if (!ASel) {
+ atom->SetMask ( mask[maskNo] );
+ nsel++;
+ }
+ break;
+ case SKEY_AND : if (ASel) nsel++;
+ break;
+ case SKEY_XOR : if (ASel) {
+ atom->RemoveMask ( mask[maskNo] );
+ nsel--;
+ } else {
+ atom->SetMask ( mask[maskNo] );
+ nsel++;
+ }
+ break;
+ case SKEY_CLR : if (ASel) {
+ atom->RemoveMask ( mask[maskNo] );
+ nsel--;
+ }
+ }
+ }
+
+
+ void SelManager::SelectObject ( SELECTION_TYPE sType,
+ PAtom atm,
+ int maskNo,
+ SELECTION_KEY sKey,
+ int & nsel ) {
+ PMask object;
+ switch (sType) {
+ default :
+ case STYPE_UNDEFINED : return;
+ case STYPE_ATOM : object = atm; break;
+ case STYPE_RESIDUE : object = atm->GetResidue(); break;
+ case STYPE_CHAIN : object = atm->GetChain (); break;
+ case STYPE_MODEL : object = atm->GetModel (); break;
+ }
+ if (!object) return;
+ SelectObject ( object,maskNo,sKey,nsel );
+ }
+
+
+ void SelManager::SelectObject ( PMask object, int maskNo,
+ SELECTION_KEY sKey, int & nsel ) {
+ bool ASel;
+ ASel = object->CheckMask ( mask[maskNo] );
+ switch (sKey) {
+ default :
+ case SKEY_NEW :
+ case SKEY_OR : if (!ASel) {
+ object->SetMask ( mask[maskNo] );
+ nsel++;
+ }
+ break;
+ case SKEY_AND : if (ASel) nsel++;
+ break;
+ case SKEY_XOR : if (ASel) {
+ object->RemoveMask ( mask[maskNo] );
+ nsel--;
+ } else {
+ object->SetMask ( mask[maskNo] );
+ nsel++;
+ }
+ break;
+ case SKEY_CLR : if (ASel) {
+ object->RemoveMask ( mask[maskNo] );
+ nsel--;
+ }
+ break;
+ case SKEY_XAND : if (ASel) {
+ object->RemoveMask ( mask[maskNo] );
+ nsel++;
+ }
+ }
+ }
+
+
+ void SelManager::DeleteSelObjects ( int selHnd ) {
+ PPModel model;
+ PPChain chain;
+ PPResidue res;
+ PPAtom atom;
+ int i,k,nSel;
+
+ if ((selHnd>0) && (selHnd<=nSelections)) {
+
+ k = selHnd-1;
+ nSel = nSelItems[k];
+ switch (selType[k]) {
+
+ case STYPE_MODEL : model = (PPModel)selection[k];
+ for (i=0;i<nSel;i++)
+ delete model[i];
+ break;
+
+ case STYPE_CHAIN : chain = (PPChain)selection[k];
+ for (i=0;i<nSel;i++)
+ delete chain[i];
+ break;
+
+ case STYPE_RESIDUE : res = (PPResidue)selection[k];
+ for (i=0;i<nSel;i++)
+ delete res[i];
+ break;
+
+ case STYPE_ATOM : atom = (PPAtom)selection[k];
+ for (i=0;i<nSel;i++)
+ delete atom[i];
+ break;
+
+ default : ;
+
+ }
+
+ if (selection[k]) delete[] selection[k];
+ selection[k] = NULL;
+ nSelItems[k] = 0;
+
+ }
+
+ }
+
+ // ------------------------------------------------------------------------
+
+ void SelManager::MakeSelIndex ( int selHnd,
+ SELECTION_TYPE sType, int nsel ) {
+ // if nsel is less than 0, the number of selected atoms will
+ // be calculated.
+ PModel mdl;
+ PChain chain;
+ PResidue res;
+ int k,i,j,n,ns,k1,k2, nns;
+
+ if ((selHnd>0) && (selHnd<=nSelections)) {
+ k1 = selHnd-1;
+ k2 = k1+1;
+ } else {
+ k1 = 0;
+ k2 = nSelections;
+ }
+
+ for (k=k1;k<k2;k++) {
+ if (nsel<0) {
+ ns = 0;
+ switch (sType) {
+ case STYPE_ATOM : for (i=0;i<nAtoms;i++)
+ if (atom[i])
+ if (atom[i]->CheckMask(mask[k])) ns++;
+ break;
+ case STYPE_RESIDUE : for (n=0;n<nModels;n++) {
+ mdl = model[n];
+ if (mdl)
+ for (i=0;i<mdl->nChains;i++) {
+ chain = mdl->chain[i];
+ if (chain)
+ for (j=0;j<chain->nResidues;j++) {
+ res = chain->residue[j];
+ if (res)
+ if (res->CheckMask(mask[k])) ns++;
+ }
+ }
+ }
+ break;
+ case STYPE_CHAIN : for (i=0;i<nModels;i++) {
+ mdl = model[i];
+ if (mdl)
+ for (j=0;j<mdl->nChains;j++) {
+ chain = mdl->chain[j];
+ if (chain)
+ if (chain->CheckMask(mask[k])) ns++;
+ }
+ }
+ break;
+ case STYPE_MODEL : for (i=0;i<nModels;i++)
+ if (model[i])
+ if (model[i]->CheckMask(mask[k])) ns++;
+ break;
+ default : ;
+ }
+ } else
+ ns = nsel;
+ if (selection[k]) delete[] selection[k];
+ if (ns>0) {
+ selection[k] = new PMask[ns];
+ nns = 0;
+ switch (sType) {
+ case STYPE_ATOM : for (i=0;i<nAtoms;i++)
+ if (atom[i]) {
+ if (atom[i]->CheckMask(mask[k])) {
+ selection[k][nns++] = atom[i];
+ if (nns>=ns) nns = ns-1;
+ }
+ }
+ break;
+ case STYPE_RESIDUE : for (n=0;n<nModels;n++) {
+ mdl = model[n];
+ if (mdl)
+ for (i=0;i<mdl->nChains;i++) {
+ chain = mdl->chain[i];
+ if (chain)
+ for (j=0;j<chain->nResidues;j++) {
+ res = chain->residue[j];
+ if (res)
+ if (res->CheckMask(mask[k])) {
+ selection[k][nns++] = res;
+ if (nns>=ns) nns = ns-1;
+ }
+ }
+ }
+ }
+ break;
+ case STYPE_CHAIN : for (i=0;i<nModels;i++) {
+ mdl = model[i];
+ if (mdl)
+ for (j=0;j<mdl->nChains;j++) {
+ chain = mdl->chain[j];
+ if (chain)
+ if (chain->CheckMask(mask[k])) {
+ selection[k][nns++] = chain;
+ if (nns>=ns) nns = ns-1;
+ }
+ }
+ }
+ break;
+ case STYPE_MODEL : for (i=0;i<nModels;i++)
+ if (model[i])
+ if (model[i]->CheckMask(mask[k])) {
+ selection[k][nns++] = model[i];
+ if (nns>=ns) nns = ns-1;
+ }
+ break;
+ default : ;
+ }
+
+ } else
+ selection[k] = NULL;
+
+ nSelItems[k] = ns;
+ }
+
+ }
+
+
+ // ------------------- Stream functions ----------------------
+
+
+ void SelManager::write ( io::RFile f ) {
+ int i,sType;
+ byte Version=1;
+
+ f.WriteByte ( &Version );
+
+ CoorManager::write ( f );
+
+ f.WriteInt ( &nSelections );
+ for (i=0;i<nSelections;i++) {
+ StreamWrite ( f,mask[i] );
+ f.WriteInt ( &(nSelItems[i]) );
+ sType = selType[i];
+ f.WriteInt ( &(sType) );
+ }
+
+ }
+
+ void SelManager::read ( io::RFile f ) {
+ int i,sType;
+ byte Version;
+
+ f.ReadByte ( &Version );
+
+ DeleteAllSelections();
+
+ CoorManager::read ( f );
+
+ f.ReadInt ( &nSelections );
+ if (nSelections>0) {
+ mask = new PMask [nSelections];
+ selection = new PPMask[nSelections];
+ nSelItems = new int [nSelections];
+ selType = new SELECTION_TYPE[nSelections];
+ for (i=0;i<nSelections;i++) {
+ mask[i] = NULL;
+ StreamRead ( f,mask[i] );
+ f.ReadInt ( &(nSelItems[i]) );
+ f.ReadInt ( &(sType) );
+ selType [i] = (SELECTION_TYPE)sType;
+ selection[i] = NULL;
+ if (mask[i])
+ MakeSelIndex ( i+1,selType[i],-1 );
+ else nSelItems[i] = 0;
+ }
+ }
+
+ }
+
+
+ MakeStreamFunctions(SelManager)
+
+} // namespace mmdb
+
diff --git a/mmdb2/mmdb_selmngr.h b/mmdb2/mmdb_selmngr.h
new file mode 100644
index 0000000..fab8499
--- /dev/null
+++ b/mmdb2/mmdb_selmngr.h
@@ -0,0 +1,634 @@
+// $Id: mmdb_selmngr.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 15.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : mmdb_selmngr <interface>
+// ~~~~~~~~~
+// Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::Manager ( MMDB atom selection manager )
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_SelMngr__
+#define __MMDB_SelMngr__
+
+#include "mmdb_coormngr.h"
+#include "mmdb_mask.h"
+
+namespace mmdb {
+
+ // ======================= SelManager ==========================
+
+ // Selection keys. These specify how the requested selection
+ // operation applies to the existing selection for the given mask:
+ // SKEY_NEW previous selection is wiped out
+ // SKEY_OR new selection is added to the already selected set;
+ // if no selection preexists, SKEY_NEW and SKEY_OR
+ // are equivalent. This key is the default one in
+ // all selection functions.
+ // SKEY_AND new selection is made on the already selected set;
+ // this corresponds to logical 'and' of former and
+ // current selections. If no selection preexists,
+ // no selection will be made.
+ // SKEY_XOR only those atoms will be left which are found
+ // in either former or newly selected sets, but not
+ // in both of them; this corresponds to logical
+ // 'exclusive or' of previous and current selections.
+ // If no selection preexists, it is equivalent to
+ // SKEY_OR.
+ enum SELECTION_KEY {
+ SKEY_NEW = 0,
+ SKEY_OR = 1,
+ SKEY_AND = 2,
+ SKEY_XOR = 3,
+ SKEY_CLR = 4,
+ SKEY_XAND = 100 // used internally
+ };
+
+ // Selection types
+ enum SELECTION_TYPE {
+ STYPE_INVALID = -1,
+ STYPE_UNDEFINED = 0,
+ STYPE_ATOM = 1,
+ STYPE_RESIDUE = 2,
+ STYPE_CHAIN = 3,
+ STYPE_MODEL = 4
+ };
+
+ // Residue properties for SelectProperties()
+ enum SELECTION_PROPERTY {
+ SELPROP_Solvent = 0,
+ SELPROP_Aminoacid = 1,
+ SELPROP_Nucleotide = 2,
+ SELPROP_Sugar = 3,
+ SELPROP_ModRes = 4
+ };
+
+ // comparison rules for SelectUDD function
+ enum UDD_CMP_RULE {
+ UDSCR_LT = 1,
+ UDSCR_LE = 2,
+ UDSCR_EQ = 3,
+ UDSCR_NE = 4,
+ UDSCR_GE = 5,
+ UDSCR_GT = 6,
+ UDSCR_LTcase = 7,
+ UDSCR_LEcase = 8,
+ UDSCR_EQcase = 9,
+ UDSCR_NEcase = 10,
+ UDSCR_GEcase = 11,
+ UDSCR_GTcase = 12,
+ UDSCR_LTn = 13,
+ UDSCR_LEn = 14,
+ UDSCR_EQn = 15,
+ UDSCR_NEn = 16,
+ UDSCR_GEn = 17,
+ UDSCR_GTn = 18,
+ UDSCR_LTncase = 19,
+ UDSCR_LEncase = 20,
+ UDSCR_EQncase = 21,
+ UDSCR_NEncase = 22,
+ UDSCR_GEncase = 23,
+ UDSCR_GTncase = 24,
+ UDSCR_Substr = 25,
+ UDSCR_NoSubstr = 26,
+ UDSCR_Substr1 = 27,
+ UDSCR_NoSubstr1 = 28
+ };
+
+ DefineClass(SelManager);
+ DefineStreamFunctions(SelManager);
+
+ class SelManager : public CoorManager {
+
+ public :
+
+ SelManager ();
+ SelManager ( io::RPStream Object );
+ ~ SelManager();
+
+
+ // ==================== Selecting atoms =======================
+
+ // NewSelection() creates a new selection mask and returns its
+ // handle. A handle is always a positive (non-zero) integer.
+ // Calling NewSelection() is the only way to create a new
+ // selection mask. Notice however that masks will be automatically
+ // copied from another MMDB (see Copy(..) in CMMDBManager) if
+ // coordinates are copied; if this is the case, the mask handles
+ // will be inherited from the source MMDB as well. The masks will
+ // also be automatically deleted (see Delete(..) in CMMDBManager())
+ // if coordinates are deleted.
+ int NewSelection ();
+
+ int GetSelType ( int selHnd ); // returns STYPE_XXXX
+
+ // DeleteSelection(..) deletes the specified selection mask
+ // and removes the corresponding selection attributes from
+ // all atoms, which were selected with this mask. If an atom
+ // was selected also with other mask(s), the other selection(s)
+ // will remain, provided that the corresponding masks are valid.
+ // After DeleteSelection() returns, the corresponding mask
+ // becomes invalid.
+ void DeleteSelection ( int selHnd );
+
+ // DeleteAllSelections() deletes all selection masks and
+ // unselects all atoms in the file. All mask handles become
+ // invalid.
+ void DeleteAllSelections();
+
+ // SelectAtoms(..) selects atoms in the serial number range
+ // of iSer1 to iSer2 by adding them to the set of atoms
+ // marked by the given mask. If iSer1=iSer2=0 then all atoms
+ // are selected. Each atom may be selected by a number of masks
+ // simultaneously.
+ void SelectAtoms ( int selHnd, int iSer1, int iSer2,
+ SELECTION_KEY selKey=SKEY_OR // selection key
+ );
+
+ // SelectAtoms(..) selects atoms with serial numbers given in
+ // vector asn[0..nsn-1].
+ void SelectAtoms ( int selHnd, ivector asn, int nsn,
+ SELECTION_KEY selKey=SKEY_OR // selection key
+ );
+
+ // UnselectAtoms(..) clears the specified mask for atoms in
+ // the serial number range of iSer1 to iSer2. If iSer1=iSer2=0
+ // then all atoms are cleared of the specified mask. If selHnd
+ // is set to 0, then the atoms are cleared of any mask.
+ void UnselectAtoms ( int selHnd, int iSer1, int iSer2 );
+
+ // SelectAtom(..) selects a single atom according to the value
+ // of selection key. If makeIndex is false, then the routine
+ // does not update the selection index. This saves time, but
+ // prevents GetSelIndex(..) from accessing all selected atoms.
+ // In order to update the index after all single-atom selections
+ // are done, use MakeSelIndex(selHnd) found next.
+ void SelectAtom ( int selHnd, PAtom A,
+ SELECTION_KEY selKey=SKEY_OR,
+ bool makeIndex=true );
+
+ // SelectResidue(..), SelectChain(..) and SelectModel(..)
+ // select a single residue, chain or model, or all their
+ // hierarchical descendants depending on the value of sType
+ // (i.e. atoms, residues (in chain and model) and chains
+ // (in model only). Ascending hierarchical objects should be
+ // selected explicitely, e.g. atom->GetResidue()->SelectResidue(..)
+ void SelectResidue ( int selHnd, PResidue Res,
+ SELECTION_TYPE sType,
+ SELECTION_KEY sKey,
+ bool makeIndex );
+ void SelectChain ( int selHnd, PChain chain,
+ SELECTION_TYPE sType,
+ SELECTION_KEY sKey,
+ bool makeIndex );
+ void SelectModel ( int selHnd, PModel mdl,
+ SELECTION_TYPE sType,
+ SELECTION_KEY sKey,
+ bool makeIndex );
+
+
+ // MakeSelIndex(.) calculates selection index for selection
+ // adressed by selHnd. All selection functions except the
+ // SelectAtom(..) above, update selection index automatically.
+ // This function is for use after a series of calls to
+ // SelectAtom(..) with makeIndex parameter set false. This
+ // combination of SelectAtom - MakeSelIndex considerably saves CPU
+ // at extensive selections.
+ // MakeSelIndex(.) returns the number of selected objects.
+ int MakeSelIndex ( int selHnd );
+ void MakeAllSelIndexes();
+
+ // Selecting by atom ID, space condition (a sphere) and some
+ // other bits.
+ void SelectAtoms (
+ int selHnd, // must be obtained from NewSelection()
+ int iModel, // model number; iModel=0 means
+ // 'any model'
+ cpstr Chains, // may be several chains "A,B,W"; "*"
+ // means 'any chain' (in selected
+ // model(s))
+ int ResNo1, // starting residue sequence number
+ cpstr Ins1, // starting residue insertion code; "*"
+ // means 'any code'
+ int ResNo2, // ending residue sequence number.
+ cpstr Ins2, // ending residue insertion code; "*"
+ // means 'any code'. Combination of
+ // ResNo1=ResNo2=ANY_RES and
+ // Ins1=Ins2="*" means 'any residue'
+ // (in selected chain(s))
+ cpstr RNames, // may be several residue names
+ // "ALA,GLU,CIS"; "*" means 'any
+ // residue name'
+ cpstr ANames, // may be several names "CA,CB"; "*"
+ // means 'any atom' (in selected
+ // residue(s))
+ cpstr Elements, // may be several element types
+ // 'H,C,O,CU'; "*" means 'any element'
+ cpstr altLocs, // may be several alternative
+ // locations 'A,B'; "*" means
+ // 'any alternative location'
+ cpstr Segments, // may be several segment IDs
+ // like "S1,S2,A234"; "*" means
+ // 'any segment'
+ cpstr Charges, // may be several charges like
+ // "+1,-2, "; "*" means 'any charge'
+ realtype occ1, // lowest occupancy
+ realtype occ2, // highest occupancy; occ1=occ2<0.0
+ // means "any occupancy"
+ realtype x0, // reference x-point
+ realtype y0, // reference y-point
+ realtype z0, // reference z-point
+ realtype d0, // selection distance from the
+ // reference point; d0<=0.0
+ // means "any distance" and values
+ // of x0, y0 and z0 are ignored
+ SELECTION_KEY selKey=SKEY_OR // selection key
+ );
+
+ // Selecting by just atom ID, no other conditions
+ void SelectAtoms (
+ int selHnd, // must be obtained from NewSelection()
+ int iModel, // model number; iModel=0 means
+ // 'any model'
+ cpstr Chains, // may be several chains "A,B,W"; "*"
+ // means 'any chain' (in selected
+ // model(s))
+ int ResNo1, // starting residue sequence number
+ cpstr Ins1, // starting residue insertion code; "*"
+ // means 'any code'
+ int ResNo2, // ending residue sequence number.
+ cpstr Ins2, // ending residue insertion code; "*"
+ // means 'any code'. Combination of
+ // ResNo1=ResNo2=ANY_RES and
+ // Ins1=Ins2="*" means 'any residue
+ // number' (in selected chain(s))
+ cpstr RNames, // may be several residue names
+ // "ALA,GLU,CIS"; "*" means 'any
+ // residue name'
+ cpstr ANames, // may be several names "CA,CB"; "*"
+ // means 'any atom' (in selected
+ // residue(s))
+ cpstr Elements, // may be several element types
+ // "H,C,O,CU"; "*" means 'any element'
+ cpstr altLocs, // may be several alternative
+ // locations 'A,B'; "*" means
+ // 'any alternative location'
+ SELECTION_KEY selKey=SKEY_OR // selection key
+ );
+
+
+ // Selecting by integer User-Defined Data
+ void SelectUDD (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ int UDDhandle, // UDD handle
+ int selMin, // lower selection boundary
+ int selMax, // upper selection boundary
+ SELECTION_KEY sKey // selection key
+ );
+ void SelectUDD (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ int UDDhandle, // UDD handle
+ realtype selMin, // lower selection boundary
+ realtype selMax, // upper selection boundary
+ SELECTION_KEY sKey // selection key
+ );
+ void SelectUDD (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ int UDDhandle, // UDD handle
+ cpstr selStr, // selection string
+ int cmpRule, // comparison rule
+ SELECTION_KEY sKey // selection key
+ );
+
+
+ // Selecting a sphere
+ void SelectSphere (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ realtype x, // x-coordinate of the sphere's center
+ realtype y, // y-coordinate of the sphere's center
+ realtype z, // z-coordinate of the sphere's center
+ realtype r, // radius of the sphere
+ SELECTION_KEY sKey=SKEY_OR // selection key
+ );
+
+ // Selecting a cylinder
+ void SelectCylinder (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ realtype x1, // x-coordinate of the cylinder axis' 1st end
+ realtype y1, // y-coordinate of the cylinder axis' 1st end
+ realtype z1, // z-coordinate of the cylinder axis' 1st end
+ realtype x2, // x-coordinate of the cylinder axis' 2nd end
+ realtype y2, // y-coordinate of the cylinder axis' 2nd end
+ realtype z2, // z-coordinate of the cylinder axis' 2nd end
+ realtype r, // radius of the cylinder
+ SELECTION_KEY sKey=SKEY_OR // selection key
+ );
+
+ // Selecting all atoms on a given distance from a plane
+ void SelectSlab (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ realtype a, // a-parameter of the plane ax+by+cz=d
+ realtype b, // b-parameter of the plane ax+by+cz=d
+ realtype c, // c-parameter of the plane ax+by+cz=d
+ realtype d, // d-parameter of the plane ax+by+cz=d
+ realtype r, // distance to the plane
+ SELECTION_KEY sKey=SKEY_OR // selection key
+ );
+
+ // Selecting all atoms on a given distance from already selected
+ void SelectNeighbours (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ PPAtom sA, // array of already selected atoms
+ int alen, // length of A
+ realtype d1, // minimal distance to already selected atoms
+ realtype d2, // maximal distance to already selected atoms
+ SELECTION_KEY sKey=SKEY_OR // selection key
+ );
+
+
+ int GetSelLength ( int selHnd );
+
+ // Getting an array of atoms selected for a certain mask
+ void GetSelIndex (
+ int selHnd, // selection mask
+ PPAtom & SelAtom, // continuous index of selected
+ // atoms; application must not
+ // dispose either index or atoms
+ int & nSelAtoms // length of index
+ // [0..nSelectedAtoms-1]
+ );
+
+ // Getting an array of residues selected for a certain mask
+ void GetSelIndex (
+ int selHnd, // selection mask
+ PPResidue & SelResidues, // continuous index of selected
+ // residues; application must
+ // not dispose either index or
+ // residues
+ int & nSelResidues // length of index
+ // [0..nSelResidues-1]
+ );
+
+ // Getting an array of chains selected for a certain mask
+ void GetSelIndex (
+ int selHnd, // selection mask
+ PPChain & SelChains, // continuous index of selected
+ // chains; application must not
+ // dispose either index or chains
+ int & nSelChains // length of index
+ // [0..nSelChains-1]
+ );
+
+ // Getting an array of models selected for a certain mask
+ void GetSelIndex (
+ int selHnd, // selection mask
+ PPModel & SelModels, // continuous index of selected
+ // models; application must not
+ // dispose either index or models
+ int & nSelModels // length of index
+ // [0..nSelModels-1]
+ );
+
+ void GetAtomStatistics ( int selHnd, RAtomStat AS );
+
+
+ // =============== General selection functions ================
+
+ // Selecting by atom ID, space condition (a sphere) and some
+ // other bits.
+ void Select (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ int iModel, // model number; iModel=0 means
+ // 'any model'
+ cpstr Chains, // may be several chains "A,B,W"; "*"
+ // means 'any chain' (in selected
+ // model(s))
+ int ResNo1, // starting residue sequence number
+ cpstr Ins1, // starting residue insertion code; "*"
+ // means 'any code'
+ int ResNo2, // ending residue sequence number.
+ cpstr Ins2, // ending residue insertion code; "*"
+ // means 'any code'. Combination of
+ // ResNo1=ResNo2=ANY_RES and
+ // Ins1=Ins2="*" means 'any residue'
+ // (in selected chain(s))
+ cpstr RNames, // may be several residue names
+ // "ALA,GLU,CIS"; "*" means
+ // 'any residue name'
+ cpstr ANames, // may be several names "CA,CB"; "*"
+ // means 'any atom' (in selected
+ // residue(s))
+ cpstr Elements, // may be several element types
+ // 'H,C,O,CU'; "*" means 'any element'
+ cpstr altLocs, // may be several alternative
+ // locations 'A,B'; "*" means
+ // 'any alternative location'
+ cpstr Segments, // may be several segment IDs like
+ // "S1,S2,A234"; "*" means
+ // 'any segment'
+ cpstr Charges, // may be several charges like
+ // "+1,-2, "; "*" means 'any charge'
+ realtype occ1, // lowest occupancy
+ realtype occ2, // highest occupancy; occ1=occ2<0.0
+ // means "any occupancy"
+ realtype x0, // reference x-point
+ realtype y0, // reference y-point
+ realtype z0, // reference z-point
+ realtype d0, // selection distance from the
+ // reference point; d0<=0.0
+ // means "any distance" and values
+ // of x0, y0 and z0 are ignored
+ SELECTION_KEY sKey=SKEY_OR // selection key
+ );
+
+
+ // Selecting by just atom ID, no other conditions
+ void Select (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ int iModel, // model number; iModel=0 means
+ // 'any model'
+ cpstr Chains, // may be several chains "A,B,W"; "*"
+ // means 'any chain' (in selected
+ // model(s))
+ int ResNo1, // starting residue sequence number
+ cpstr Ins1, // starting residue insertion code; "*"
+ // means 'any code'
+ int ResNo2, // ending residue sequence number.
+ cpstr Ins2, // ending residue insertion code; "*"
+ // means 'any code'. Combination of
+ // ResNo1=ResNo2=ANY_RES and
+ // Ins1=Ins2="*" means 'any residue
+ // number' (in selected chain(s))
+ cpstr RNames, // may be several residue names
+ // "ALA,GLU,CIS"; "*" means
+ // 'any residue name'
+ cpstr ANames, // may be several names "CA,CB"; "*"
+ // means 'any atom' (in selected
+ // residue(s))
+ cpstr Elements, // may be several element types
+ // "H,C,O,CU"; "*" means 'any element'
+ cpstr altLocs, // may be several alternative
+ // locations 'A,B'; "*" means
+ // 'any alternative location'
+ SELECTION_KEY sKey=SKEY_OR // selection key
+ );
+
+
+ // Selecting by coordinate ID.
+ // Examples:
+ //
+ // 1. /mdl/chn/s1.i1-s2.i2/at[el]:aloc
+ // 2. /mdl/chn/*(res).ic /at[el]:aloc
+ // 3. chn/*(res).ic /at[el]:aloc
+ // 4. s1.i1-s2.i2/at[el]:aloc
+ // 5. s1.i1 /at[el]:aloc
+ // 6. /mdl
+ // 7. chn
+ // 8. s1.i1-s2.i2
+ // 9. (res)
+ // 10. at[el]:aloc
+ // 11. chn//[el]
+ //
+ // mdl - the model's serial number or 0 or '*' for any model
+ // (default).
+ // chn - the chain ID or list of chains 'A,B,C' or '*' for
+ // any chain (default).
+ // s1,s2 - the starting and ending residue sequence numbers
+ // or '*' for any sequence number (default).
+ // i1,i2 - the residues insertion codes or '*' for any
+ // insertion code. If the sequence number other than
+ // '*' is specified, then insertion code defaults to ""
+ // (no insertion code), otherwise the default is '*'.
+ // at - atom name or list of atom names 'CA,N1,O' or '*'
+ // for any atom name (default)
+ // el - chemical element name or list of chemical element
+ // names 'C,N,O' or '*' for any chemical element name
+ // (default)
+ // aloc - the alternative location indicator or '*' for any
+ // alternate location. If the atom name and chemical
+ // element name is specified (both may be '*'), then
+ // the alternative location indicator defaults to ""
+ // (no alternate location), otherwise the default is
+ // '*'.
+ //
+ // All spaces are ignored.
+ //
+ // Returns -1 if numerical format of model is wrong, -2 if
+ // numerical format for sequence number is wrong, and 0
+ // otherwise.
+
+ int Select (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ cpstr CID, // coordinate ID
+ SELECTION_KEY sKey // selection key
+ );
+
+ // Propagating the selection up and down coordinate hierarchy
+ void Select (
+ int selHnd1, // must be obtained from NewSelection()
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ int selHnd2, // must be obtained from NewSelection()
+ // and have been used for selection
+ SELECTION_KEY sKey=SKEY_OR // selection key
+ );
+
+ void SelectProperty (
+ int selHnd, // must be obtained from NewSelection()
+ SELECTION_PROPERTY propKey, // property key SELPROP_XXXXXXX
+ SELECTION_TYPE sType, // selection type STYPE_XXXXX
+ SELECTION_KEY sKey // selection key
+ );
+
+ // In SelectDomain, domainRange is of the following format:
+ // "*", "(all)" - take all file
+ // "-" - take chain without chain ID
+ // "a:Ni-Mj,b:Kp-Lq,..." - take chain a residue number N
+ // insertion code i to residue numberM
+ // insertion code j plus chain b
+ // residue number K insertion code p to
+ // residue number L insertion code q
+ // and so on.
+ // "a:,b:..." - take whole chains a and b and so on
+ // "a:,b:Kp-Lq,..." - any combination of the above.
+ int SelectDomain ( int selHnd , cpstr domainRange,
+ SELECTION_TYPE sType,
+ SELECTION_KEY sKey,
+ int modelNo=1 );
+
+ void DeleteSelObjects ( int selHnd );
+
+
+ protected :
+
+ // --- SELECTION DATA NOT FOR PUBLIC ACCESS
+ int nSelections; // number of selections
+ PPMask mask; // vector of selections
+ SELECTION_TYPE *selType; // vector of selection types
+ ivector nSelItems; // numbers of selected items
+ PPMask * selection; // vector of selected items
+
+ // --------------- Stream I/O -----------------------------
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ void InitSelManager();
+ void SelectAtom ( PAtom atm, int maskNo,
+ SELECTION_KEY sKey, int & nsel );
+ void SelectObject ( SELECTION_TYPE sType, PAtom atm,
+ int maskNo, SELECTION_KEY sKey,
+ int & nsel );
+ void SelectObject ( PMask object, int maskNo,
+ SELECTION_KEY sKey, int & nsel );
+ void MakeSelIndex ( int selHnd, SELECTION_TYPE sType,
+ int nsel );
+
+ void ResetManager();
+
+ PMask GetSelMask ( int selHnd );
+
+ };
+
+} // namespace mmdb
+
+#endif
+
diff --git a/mmdb2/mmdb_seqsuperpose.cpp b/mmdb2/mmdb_seqsuperpose.cpp
new file mode 100755
index 0000000..7489850
--- /dev/null
+++ b/mmdb2/mmdb_seqsuperpose.cpp
@@ -0,0 +1,366 @@
+// $Id: mmdb_seqsuperpose.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 19.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : SeqSuperpose <implementation>
+// ~~~~~~~~~
+// **** Classes : mmdb::SeqSuperpose
+// ~~~~~~~~~
+//
+// (C) E.Krissinel 2005-2013
+//
+// =================================================================
+//
+
+#include <math.h>
+#include <string.h>
+
+#include "mmdb_tables.h"
+#include "mmdb_seqsuperpose.h"
+
+namespace mmdb {
+
+ // =================================================================
+
+ SeqSuperpose::SeqSuperpose() {
+ SeqSuperposeInit();
+ }
+
+ SeqSuperpose::~SeqSuperpose() {
+ FreeMemory();
+ }
+
+ void SeqSuperpose::SeqSuperposeInit() {
+ Align = NULL;
+ Mat4Init ( TMatrix ); // superposes Ca1 over Ca2: |T*Ca1 - Ca2|->min
+ Q = -0.5; // Q-score
+ rmsd = MaxReal; // rmsd
+ seqId = MaxReal; // sequence identity
+ _seqId = 0.0; // sequence identity in sequence alignment
+ Nalign = 0; // alignment length
+ c1 = NULL; // sup-n vector: Ca1[i]->Ca2[c1[i]] if c1[i]>=0
+ c2 = NULL; // sup-n vector: Ca2[i]->Ca1[c2[i]] if c2[i]>=0
+ cn1 = NULL; // temporary contact array #1
+ cn2 = NULL; // temporary contact array #2
+ Rmsd0 = 3.0; // quality optimization parameter
+ maxContact = 15.0; // maximal Calpha-pair contact parameter
+ contact = NULL;
+ ncontacts = 0;
+ }
+
+ void SeqSuperpose::FreeMemory() {
+ if (Align) {
+ delete Align;
+ Align = NULL;
+ }
+ FreeVectorMemory ( c1 ,0 );
+ FreeVectorMemory ( c2 ,0 );
+ FreeVectorMemory ( cn1,0 );
+ FreeVectorMemory ( cn2,0 );
+ if (contact) {
+ delete[] contact;
+ contact = NULL;
+ }
+ ncontacts = 0;
+ }
+
+ void makeAAString ( pstr & S, PPAtom C, int nat ) {
+ pstr rname;
+ ResName r1;
+ int i,j;
+ S = new char[nat+1];
+ j = 0;
+ for (i=0;i<nat;i++)
+ if (C[i]) {
+ rname = C[i]->GetResName();
+ if (rname) {
+ Get1LetterCode ( rname,r1 );
+ S[j++] = r1[0];
+ }
+ }
+ S[j] = char(0);
+ }
+
+
+ realtype SeqSuperpose::MatchQuality ( int Nalign, realtype Rmsd,
+ int nres1, int nres2 ) {
+ if (Nalign==0) return 0.0;
+ return MatchQuality2 ( Nalign,Rmsd*Rmsd*Nalign,nres1,nres2 );
+ }
+
+ realtype SeqSuperpose::MatchQuality2 ( int Nalign, realtype dist2,
+ int nres1, int nres2 ) {
+ realtype NormN,Na2,NormR;
+ NormN = nres1*nres2;
+ if (NormN<=0.0) return 0.0;
+ Na2 = Nalign*Nalign;
+ NormR = dist2/(Nalign*Rmsd0*Rmsd0);
+ return Na2/((1.0+NormR)*NormN);
+ }
+
+
+ void SeqSuperpose::MakeContacts ( mat44 & TM, realtype cont_est ) {
+ // Find the closest contacts atoms and makes the correspondence
+ // vectors cn1 and cn2
+ int i,j,i1,i2;
+
+ // 1. Find all contacts in the range of 0.0 - cont_est
+ if (contact) {
+ delete[] contact;
+ contact = NULL;
+ }
+ ncontacts = 0;
+ M->SeekContacts ( Ca2,nCa2,Ca1,nCa1,0.0,cont_est,0,
+ contact,ncontacts,0,&TM,0,
+ BRICK_ON_1 | BRICK_READY );
+
+ // 2. Leave only unique shortest contacts, that is, if Ca1[i]-Ca2[j]
+ // is the shortest contact for atom Ca1[i], it has also to be
+ // the shortest contact for atom Ca2[j].
+
+ if (ncontacts>0) {
+
+ SortContacts ( contact,ncontacts,CNSORT_DINC );
+
+ for (i=0;i<nCa1;i++)
+ cn1[i] = -1;
+ for (i=0;i<nCa2;i++)
+ cn2[i] = -1;
+
+ j = 0;
+ for (i=0;i<ncontacts;i++) {
+ i1 = contact[i].id2;
+ i2 = contact[i].id1;
+ if ((cn1[i1]<0) && (cn2[i2]<0)) {
+ // We only check for unmapped atoms in this version, so that
+ // chain misdirection and wide-angle contacts are accepted.
+ // However, the method itself is meant to be used only with
+ // highly similar chains, so we do not expect difficulties
+ // here. Our purpose here is to get maximum performance at
+ // high-quality input. See SSM code for more rigorous contact
+ // building.
+ if (j<i) contact[j].Copy ( contact[i] );
+ // close contact
+ cn1[i1] = i2;
+ cn2[i2] = i1;
+ j++;
+ }
+ }
+
+ ncontacts = j;
+
+ }
+
+ }
+
+ int SeqSuperpose::makeStructAlignment ( realtype seqThreshold,
+ bool keepBricks ) {
+ pstr S,T;
+ mat44 TM;
+ realtype dist2,maxRMSD2,Q1,Q0,dist20;
+ int i,i1,i2,nal,rc,iter,iter1;
+ char Space;
+
+ S = Align->GetAlignedS();
+ T = Align->GetAlignedT();
+
+ GetVectorMemory ( cn1,nCa1,0 );
+ GetVectorMemory ( c1 ,nCa1,0 );
+ for (i=0;i<nCa1;i++) {
+ cn1[i] = -1;
+ c1 [i] = -1;
+ }
+ GetVectorMemory ( cn2,nCa2,0 );
+ GetVectorMemory ( c2 ,nCa2,0 );
+ for (i=0;i<nCa2;i++) {
+ cn2[i] = -1;
+ c2 [i] = -1;
+ }
+
+ i = 0;
+ i1 = 0;
+ i2 = 0;
+ Space = Align->GetSpace();
+ while (S[i] && (i1<nCa1) && (i2<nCa2)) {
+ if ((S[i]==Space) && (T[i]!=Space)) i2++;
+ else if ((S[i]!=Space) && (T[i]==Space)) i1++;
+ else {
+ if (S[i]==T[i]) {
+ cn1[i1] = i2;
+ cn2[i2] = i1;
+ _seqId += 1.0;
+ }
+ i1++;
+ i2++;
+ }
+ i++;
+ }
+
+ _seqId /= IMax(nCa1,nCa2);
+
+ if (_seqId<seqThreshold) {
+ FreeVectorMemory ( cn1,0 );
+ FreeVectorMemory ( cn2,0 );
+ return SEQSP_SeqThreshold;
+ }
+
+ maxRMSD2 = maxContact*maxContact;
+
+ if ((!keepBricks) || (!M->areBricks()))
+ M->MakeBricks ( Ca2,nCa2,1.25*maxContact );
+
+ Q = -1.0;
+ Q0 = -1.0;
+ iter = 0;
+ iter1 = 0;
+
+ do {
+
+ Q = RMax ( Q,Q0 );
+ iter++;
+
+ rc = SuperposeAtoms ( TM,Ca1,nCa1,Ca2,cn1 );
+
+ if (rc==SPOSEAT_Ok) {
+
+ MakeContacts ( TM,maxContact );
+
+ dist2 = 0.0;
+ for (i=0;i<ncontacts;i++) {
+ contact[i].dist *= contact[i].dist;
+ dist2 += contact[i].dist;
+ }
+
+ dist20 = dist2;
+ nal = ncontacts;
+ Q0 = RMax ( Q0,MatchQuality2(ncontacts,dist2,nCa1,nCa2) );
+ if (ncontacts>0) {
+ i = ncontacts;
+ while (i>3) {
+ i--;
+ dist2 -= contact[i].dist;
+ if (dist2<=i*maxRMSD2) { // rmsd must be within the limits
+ Q1 = MatchQuality2 ( i,dist2,nCa1,nCa2 );
+ if (Q1>Q0) {
+ Q0 = Q1;
+ nal = i;
+ dist20 = dist2;
+ }
+ }
+ }
+ for (i=nal+1;i<ncontacts;i++) {
+ cn1[contact[i].id2] = -1;
+ cn2[contact[i].id1] = -1;
+ }
+ if (Q0>Q) {
+ for (i=0;i<nCa1;i++)
+ c1[i] = cn1[i];
+ for (i=0;i<nCa2;i++)
+ c2[i] = cn2[i];
+ Mat4Copy ( TM,TMatrix );
+ Nalign = nal;
+ rmsd = dist20;
+ iter1 = 0;
+ } else
+ iter1++;
+ }
+
+ }
+
+ if ((!rc) && (iter>100)) rc = SEQSP_IterLimit;
+
+ } while ((rc==SPOSEAT_Ok) && ((Q<Q0) || (iter1>=2)));
+
+ if (Nalign>0) {
+ SuperposeAtoms ( TMatrix,Ca1,nCa1,Ca2,c1 );
+ rmsd = sqrt(rmsd/Nalign); // rmsd
+ seqId = 0.0;
+ for (i=0;i<nCa1;i++)
+ if (c1[i]>=0) {
+ if (!strcasecmp(Ca1[i]->GetResName(),Ca2[c1[i]]->GetResName()))
+ seqId += 1.0;
+ }
+ seqId = seqId/Nalign;
+ } else {
+ rmsd = MaxReal;
+ seqId = 0.0;
+ }
+
+ FreeVectorMemory ( cn1,0 );
+ FreeVectorMemory ( cn2,0 );
+
+ if (!keepBricks) M->RemoveBricks();
+
+ return rc;
+
+ }
+
+
+ int SeqSuperpose::Superpose ( PManager MMDB,
+ PPAtom Calpha1, int nCalpha1,
+ PPAtom Calpha2, int nCalpha2,
+ realtype seqThreshold,
+ bool keepBricks ) {
+ pstr S,T;
+
+ Mat4Init ( TMatrix ); // superposes Ca1 over Ca2: |T*Ca1 - Ca2|->min
+ Q = 0.0; // Q-score
+ rmsd = MaxReal; // rmsd
+ seqId = MaxReal; // sequence identity in structure alignment
+ Nalign = 0; // alignment length in structure alignment
+
+ FreeVectorMemory ( c1,0 );
+ FreeVectorMemory ( c2,0 );
+
+ _seqId = IMin(nCalpha1,nCalpha2);
+ _seqId /= IMax(nCalpha1,nCalpha2);
+
+ if (_seqId<seqThreshold)
+ return SEQSP_SeqThreshold;
+
+ M = MMDB;
+ Ca1 = Calpha1;
+ nCa1 = nCalpha1;
+ Ca2 = Calpha2;
+ nCa2 = nCalpha2;
+
+ makeAAString ( S,Ca1,nCa1 );
+ makeAAString ( T,Ca2,nCa2 );
+
+ if (!Align) Align = new math::Alignment();
+
+ Align->Align ( S,T,math::ALIGN_FREEENDS );
+
+ if (S) delete[] S;
+ if (T) delete[] T;
+
+ return makeStructAlignment ( seqThreshold,keepBricks );
+
+ }
+
+} // namespace mmdb
+
diff --git a/mmdb2/mmdb_seqsuperpose.h b/mmdb2/mmdb_seqsuperpose.h
new file mode 100755
index 0000000..f841dea
--- /dev/null
+++ b/mmdb2/mmdb_seqsuperpose.h
@@ -0,0 +1,134 @@
+// $Id: mmdb_seqsuperpose.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 19.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : SeqSuperpose <interface>
+// ~~~~~~~~~
+// **** Classes : mmdb::SeqSuperpose
+// ~~~~~~~~~
+//
+// (C) E.Krissinel 2005-2013
+//
+// =================================================================
+//
+
+#ifndef __Seq_Superpose__
+#define __Seq_Superpose__
+
+#include "mmdb_manager.h"
+#include "mmdb_math_align.h"
+
+namespace mmdb {
+
+ // =================================================================
+
+ enum SEQSP_RC {
+ SEQSP_Ok = 0,
+ SEQSP_IterLimit = 100,
+ SEQSP_SeqThreshold = 101
+ };
+
+ DefineClass(SeqSuperpose);
+
+ class SeqSuperpose {
+
+ public :
+ mat44 TMatrix; // superposes Ca1 over Ca2: |T*Ca1 - Ca2|->min
+ realtype Q; // Q-score
+ realtype rmsd; // rmsd
+ realtype seqId; // sequence identity in structure alignment
+ realtype _seqId; // sequence identity in sequence alignment
+ int Nalign; // alignment length in structure alignment
+ ivector c1; // sup-n vector: Ca1[i]->Ca2[c1[i]] if c1[i]>=0
+ ivector c2; // sup-n vector: Ca2[i]->Ca1[c2[i]] if c2[i]>=0
+
+ SeqSuperpose();
+ ~SeqSuperpose();
+
+ // Given two sets of atoms, Calpha1 and Calpha2, Superpose(...)
+ // calculates the rotational-translational matrix TMatrix such
+ // that |TMatrix*Calpha1 - Calpha2| is minimal in least-square
+ // terms.
+ // In difference of a full-scale SSM, this simplified version
+ // uses initial superposition from sequence alignment, hence
+ // it should be applied only to similar chains where calculation
+ // time is crucial. seqThreshold specifies a threshold of
+ // sequence identity (0<=seqThreshold<=1), below which
+ // structural alignment is not performed and Superpose(..)
+ // returns SEQSP_SeqThreshold.
+ //
+ // If keepBricks is set True, then space bricks are not
+ // removed in MMDB and may be used in the next call if
+ // vector Calpha2 does not change. This saves computation
+ // time.
+ //
+ // The alignment results return in public fields above:
+ // TMatrix - transformation matrix (1 if not aligned)
+ // Q - quality Q-score (-1 if not aligned)
+ // rmsd - r.m.s.d (MaxReal if not aligned)
+ // seqId - sequence identity in structure alignment
+ // (0 if not aligned)
+ // Nalign - alignment length in structure alignment
+ // (0 if not aligned)
+ // c1,c2 - atom corrspondences:
+ // Calpha1[i] <=> Calpha2[c1[i]]
+ // Calpha2[i] <=> Calpha1[c2[i]]
+ //
+ // Upon success, Superpose(...) returns SEQSP_Ok
+ //
+ int Superpose ( PManager MMDB,
+ PPAtom Calpha1, int nCalpha1,
+ PPAtom Calpha2, int nCalpha2,
+ realtype seqThreshold,
+ bool keepBricks );
+
+ protected :
+ math::PAlignment Align;
+ PManager M; // pointers to
+ PPAtom Ca1,Ca2; // the input data
+ int nCa1,nCa2; // copy chain lengths
+ ivector cn1,cn2; // temporary contact arrays
+ realtype Rmsd0; // quality optimization parameter
+ realtype maxContact; // maximal Calpha-pair contact parameter
+ PContact contact;
+ int ncontacts;
+
+ void SeqSuperposeInit();
+ void FreeMemory ();
+ realtype MatchQuality ( int Nalign, realtype Rmsd,
+ int nres1, int nres2 );
+ realtype MatchQuality2 ( int Nalign, realtype dist2,
+ int nres1, int nres2 );
+ void MakeContacts ( mat44 & TM, realtype cont_est );
+ int makeStructAlignment ( realtype seqThreshold,
+ bool keepBricks );
+
+ };
+
+} // namespace mmdb
+
+#endif
diff --git a/mmdb2/mmdb_symop.cpp b/mmdb2/mmdb_symop.cpp
new file mode 100644
index 0000000..4b8198d
--- /dev/null
+++ b/mmdb2/mmdb_symop.cpp
@@ -0,0 +1,1001 @@
+// $Id: mmdb_symop.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_SymOp <implementation>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+//
+// **** Classes : mmdb::SymOp ( symmetry operators )
+// ~~~~~~~~~ mmdb::SymOps ( container of symmetry operators )
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "mmdb_symop.h"
+
+namespace mmdb {
+
+ // ==================== SymOp ========================
+
+ SymOp::SymOp() : io::Stream() {
+ InitSymOp();
+ }
+
+ SymOp::SymOp ( io::RPStream Object ) : io::Stream(Object) {
+ InitSymOp();
+ }
+
+ SymOp::~SymOp() {
+ FreeMemory();
+ }
+
+ void SymOp::InitSymOp() {
+ int i,j;
+ XYZOp = NULL;
+ for (i=0;i<4;i++) {
+ for (j=0;j<4;j++)
+ T[i][j] = 0.0;
+ T[i][i] = 1.0;
+ }
+ }
+
+ void SymOp::FreeMemory() {
+ if (XYZOp) delete[] XYZOp;
+ XYZOp = NULL;
+ }
+
+ int SymOp::SetSymOp ( cpstr XYZOperation ) {
+ int i,j;
+
+ CreateCopy ( XYZOp,XYZOperation );
+ DelSpaces ( XYZOp );
+
+ for (i=0;i<4;i++)
+ for (j=0;j<4;j++)
+ T[i][j] = 0.0;
+
+ i = GetOperation ( 0 );
+ if (!i) i = GetOperation ( 1 );
+ if (!i) i = GetOperation ( 2 );
+ T[3][3] = 1.0;
+
+ return i;
+
+ }
+
+ pstr SymOp::GetSymOp() {
+ if (XYZOp) return XYZOp;
+ else return pstr("");
+ }
+
+
+ int SymOp::GetOperation ( int n ) {
+ char L[100];
+ pstr p1,p2;
+ int len;
+ realtype V;
+
+ p1 = XYZOp;
+ p2 = strchr ( p1,',' );
+ if (!p2) return SYMOP_WrongSyntax;
+ if (n>0) {
+ p1 = p2+1;
+ p2 = strchr ( p1,',' );
+ if (!p2) return SYMOP_WrongSyntax;
+ }
+ if (n>1) {
+ p1 = p2+1;
+ p2 = NULL;
+ }
+
+ if (p2) *p2 = char(0);
+ strcpy ( L,p1 );
+ if (p2) *p2 = ',';
+
+ DelSpaces ( L );
+ if (!L[0]) return SYMOP_WrongSyntax;
+ UpperCase ( L );
+
+ len = strlen ( L );
+ T[n][0] = 0.0;
+ if (L[0]=='X') {
+ T[n][0] += 1.0;
+ L[0] = ' ';
+ }
+ do {
+ p1 = strstr ( L,"+X" );
+ if (p1) {
+ T[n][0] += 1.0;
+ strncpy ( p1," ",2 );
+ }
+ } while (p1);
+ do {
+ p1 = strstr ( L,"-X" );
+ if (p1) {
+ T[n][0] -= 1.0;
+ strncpy ( p1," ",2 );
+ }
+ } while (p1);
+
+ T[n][1] = 0.0;
+ if (L[0]=='Y') {
+ T[n][1] += 1.0;
+ L[0] = ' ';
+ }
+ do {
+ p1 = strstr ( L,"+Y" );
+ if (p1) {
+ T[n][1] += 1.0;
+ strncpy ( p1," ",2 );
+ }
+ } while (p1);
+ do {
+ p1 = strstr ( L,"-Y" );
+ if (p1) {
+ T[n][1] -= 1.0;
+ strncpy ( p1," ",2 );
+ }
+ } while (p1);
+
+ T[n][2] = 0.0;
+ if (L[0]=='Z') {
+ T[n][2] += 1.0;
+ L[0] = ' ';
+ }
+ do {
+ p1 = strstr ( L,"+Z" );
+ if (p1) {
+ T[n][2] += 1.0;
+ strncpy ( p1," ",2 );
+ }
+ } while (p1);
+ do {
+ p1 = strstr ( L,"-Z" );
+ if (p1) {
+ T[n][2] -= 1.0;
+ strncpy ( p1," ",2 );
+ }
+ } while (p1);
+
+ DelSpaces ( L );
+ if ((int)strlen(L)>=len) return SYMOP_NotAnOperation;
+
+ // translational part
+ p1 = L;
+ T[n][3] = strtod ( p1,&p2 );
+ if (*p2=='/') {
+ p1 = p2+1;
+ V = strtod ( p1,&p2 );
+ if (V==0.0) return SYMOP_ZeroDenominator;
+ T[n][3] /= V;
+ }
+
+ return SYMOP_Ok;
+
+ }
+
+ void MakeSign ( pstr S, realtype V, realtype & AV ) {
+ int l;
+ if (V>0.0) {
+ l = strlen ( S );
+ if (l>0) {
+ if (S[l-1]!=',') {
+ strcat ( S,"+" );
+ }
+ }
+ AV = V;
+ } else if (V<0.0) {
+ strcat ( S,"-" );
+ AV = -V;
+ } else {
+ AV = V;
+ return;
+ }
+ }
+
+
+ #define __eps 1.0e-5
+
+ void GenTranslation ( pstr S, realtype V ) {
+ realtype AV,nAV;
+ char N[50];
+ int n,d;
+
+ if (fabs(V)<=__eps) return;
+ MakeSign ( S,V,AV );
+
+ d = 0;
+ n = -1;
+ while ((d<=20) && (n<0)) {
+ d++;
+ nAV = AV*d;
+ n = mround(nAV);
+ if (fabs(nAV-n)>__eps) n = -1;
+ }
+
+ if (d<=1) sprintf ( N,"%i" ,n );
+ else if (n>=0) sprintf ( N,"%i/%i" ,n,d );
+ else sprintf ( N,"%-.10g",AV );
+ strcat ( S,N );
+
+ }
+
+ void GenTransformation ( pstr S, realtype V, pstr Axis ) {
+ realtype AV,nAV;
+ char N[50];
+ int n,d;
+
+ if (fabs(V)<=__eps) return;
+ MakeSign ( S,V,AV );
+
+ if (fabs(AV-1.0)>__eps) {
+
+ d = 0;
+ n = -1;
+ while ((d<=20) && (n<0)) {
+ d++;
+ nAV = AV*d;
+ n = mround(nAV);
+ if (fabs(nAV-n)>__eps) n = -1;
+ }
+
+ if (n>=0) sprintf ( N,"%i/%i*",n,d );
+ else sprintf ( N,"%-.10g*",AV );
+ strcat ( S,N );
+
+ }
+
+ strcat ( S,Axis );
+
+ }
+
+
+ /*
+ void GenTranslation ( pstr S, realtype V ) {
+ realtype AV,fAV;
+ int n,d;
+ char N[50];
+
+ if (V==0.0) return;
+ MakeSign ( S,V,AV );
+
+ n = mround(floor(AV+0.00000001));
+ fAV = AV-n;
+
+ if (fabs(fAV-0.5)<=__eps) { n += 1; d = 2; }
+ else if (fabs(fAV-0.25)<=__eps) { n += 1; d = 4; }
+ else if (fabs(fAV-0.75)<=__eps) { n += 3; d = 4; }
+ else if (fabs(fAV-0.33333333333)<=__eps) { n += 1; d = 3; }
+ else if (fabs(fAV-0.66666666666)<=__eps) { n += 2; d = 3; }
+ else if (fabs(fAV-0.16666666666)<=__eps) { n += 1; d = 6; }
+ else if (fabs(fAV-0.83333333333)<=__eps) { n += 5; d = 6; }
+ else d = 1;
+
+ N[0] = char(0);
+ if (d>1) sprintf ( N,"%i/%i",n,d );
+ else if (n>0) sprintf ( N,"%i",n );
+ else ParamStr ( N,pstr(""),AV );
+ strcat ( S,N );
+
+ }
+
+ void GenTransformation ( pstr S, realtype V, pstr Axis ) {
+ realtype AV;
+
+ if (V==0.0) return;
+ MakeSign ( S,V,AV );
+
+ if (fabs(AV-0.5)<=__eps) strcat ( S,"1/2*" );
+ else if (fabs(AV-0.25)<=__eps) strcat ( S,"1/4*" );
+ else if (fabs(AV-0.75)<=__eps) strcat ( S,"3/4*" );
+ else if (fabs(AV-0.33333333333)<=__eps) strcat ( S,"1/3*" );
+ else if (fabs(AV-0.66666666666)<=__eps) strcat ( S,"2/3*" );
+ else if (fabs(AV-0.16666666666)<=__eps) strcat ( S,"1/6*" );
+ else if (fabs(AV-0.83333333333)<=__eps) strcat ( S,"5/6*" );
+ else if (fabs(AV-1.0)>__eps) ParamStr ( S,pstr(""),AV,
+ 10,pstr("*") );
+
+ strcat ( S,Axis );
+
+ }
+
+ */
+
+ bool SymOp::CompileOpTitle ( pstr S ) {
+ return CompileOpTitle ( S,T,true );
+ }
+
+ bool SymOp::CompileOpTitle ( pstr S, mat44 symMat,
+ bool compare ) {
+ S[0] = char(0);
+ GenTransformation ( S,symMat[0][0],pstr("X") );
+ GenTransformation ( S,symMat[0][1],pstr("Y") );
+ GenTransformation ( S,symMat[0][2],pstr("Z") );
+ GenTranslation ( S,symMat[0][3] );
+ strcat ( S,"," );
+ GenTransformation ( S,symMat[1][0],pstr("X") );
+ GenTransformation ( S,symMat[1][1],pstr("Y") );
+ GenTransformation ( S,symMat[1][2],pstr("Z") );
+ GenTranslation ( S,symMat[1][3] );
+ strcat ( S,"," );
+ GenTransformation ( S,symMat[2][0],pstr("X") );
+ GenTransformation ( S,symMat[2][1],pstr("Y") );
+ GenTransformation ( S,symMat[2][2],pstr("Z") );
+ GenTranslation ( S,symMat[2][3] );
+ DelSpaces ( S );
+ if ((!compare) || (!strcmp(S,XYZOp))) return true;
+ else {
+ S[0] = char(0);
+ GenTranslation ( S,symMat[0][3] );
+ GenTransformation ( S,symMat[0][0],pstr("X") );
+ GenTransformation ( S,symMat[0][1],pstr("Y") );
+ GenTransformation ( S,symMat[0][2],pstr("Z") );
+ strcat ( S,"," );
+ GenTranslation ( S,symMat[1][3] );
+ GenTransformation ( S,symMat[1][0],pstr("X") );
+ GenTransformation ( S,symMat[1][1],pstr("Y") );
+ GenTransformation ( S,symMat[1][2],pstr("Z") );
+ strcat ( S,"," );
+ GenTranslation ( S,symMat[2][3] );
+ GenTransformation ( S,symMat[2][0],pstr("X") );
+ GenTransformation ( S,symMat[2][1],pstr("Y") );
+ GenTransformation ( S,symMat[2][2],pstr("Z") );
+ DelSpaces ( S );
+ if (!strcmp(S,XYZOp)) return true;
+ }
+ return false;
+ }
+
+ void SymOp::Transform ( realtype & x, realtype & y, realtype & z ) {
+ realtype x1,y1,z1;
+ x1 = T[0][0]*x + T[0][1]*y + T[0][2]*z + T[0][3];
+ y1 = T[1][0]*x + T[1][1]*y + T[1][2]*z + T[1][3];
+ z1 = T[2][0]*x + T[2][1]*y + T[2][2]*z + T[2][3];
+ x = x1;
+ y = y1;
+ z = z1;
+ }
+
+ void SymOp::GetTMatrix ( mat44 & TMatrix ) {
+ // copies T to TMatrix
+ int i,j;
+ for (i=0;i<4;i++)
+ for (j=0;j<4;j++)
+ TMatrix[i][j] = T[i][j];
+ }
+
+ void SymOp::SetTMatrix ( mat44 & TMatrix ) {
+ // copies TMatrix to T
+ int i,j;
+ for (i=0;i<4;i++)
+ for (j=0;j<4;j++)
+ T[i][j] = TMatrix[i][j];
+ }
+
+
+ void SymOp::Print() {
+ int i;
+ printf ( " operation '%s'\n",XYZOp );
+ for (i=0;i<4;i++)
+ printf ( " %10.3g %10.3g %10.3g %10.3g\n",
+ T[i][0],T[i][1],T[i][2],T[i][3] );
+ }
+
+ void SymOp::Copy ( PSymOp SymOp ) {
+ int i,j;
+ CreateCopy ( XYZOp,SymOp->XYZOp );
+ for (i=0;i<4;i++)
+ for (j=0;j<4;j++)
+ T[i][j] = SymOp->T[i][j];
+ }
+
+ void SymOp::write ( io::RFile f ) {
+ int i,j;
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.CreateWrite ( XYZOp );
+ for (i=0;i<4;i++)
+ for (j=0;j<4;j++)
+ f.WriteReal ( &(T[i][j]) );
+ }
+
+ void SymOp::read ( io::RFile f ) {
+ int i,j;
+ byte Version;
+ f.ReadByte ( &Version );
+ f.CreateRead ( XYZOp );
+ for (i=0;i<4;i++)
+ for (j=0;j<4;j++)
+ f.ReadReal ( &(T[i][j]) );
+ }
+
+ MakeStreamFunctions(SymOp)
+
+
+
+ // ==================== SymOps ========================
+
+ SymOps::SymOps() : io::Stream() {
+ InitSymOps();
+ }
+
+ SymOps::SymOps ( io::RPStream Object ) : io::Stream(Object) {
+ InitSymOps();
+ }
+
+ SymOps::~SymOps() {
+ FreeMemory();
+ }
+
+ void SymOps::InitSymOps() {
+ SpGroup = NULL;
+ Nops = 0;
+ symOp = NULL;
+ }
+
+ void SymOps::FreeMemory() {
+ int i;
+ if (SpGroup) delete[] SpGroup;
+ SpGroup = NULL;
+ if (symOp) {
+ for (i=0;i<Nops;i++)
+ if (symOp[i]) delete symOp[i];
+ delete[] symOp;
+ symOp = NULL;
+ }
+ Nops = 0;
+ }
+
+ #define symop_file cpstr("symop.lib")
+
+ int SymOps::SetGroupSymopLib ( cpstr SpaceGroup,
+ cpstr symop_lib ) {
+ char S[500];
+ char G[100];
+ pstr p;
+ io::File f;
+ int i,RC;
+
+ FreeMemory();
+
+ CreateCopy ( SpGroup,SpaceGroup );
+
+ if (!symop_lib) p = pstr(symop_file);
+ else if (!symop_lib[0]) p = pstr(symop_file);
+ else p = pstr(symop_lib);
+ f.assign ( p,true );
+ if (!f.reset(true)) {
+ p = getenv ( "SYMOP" );
+ if (p)
+ strcpy ( S,p );
+ else {
+ p = getenv ( "CLIBD" );
+ if (p) {
+ strcpy ( S,p );
+ if (S[strlen(S)-1]!='/') strcat ( S,"/" );
+ strcat ( S,"symop.lib" );
+ } else
+ strcpy ( S,"symop.lib" );
+ }
+ f.assign ( S,true );
+ if (!f.reset(true)) return SYMOP_NoLibFile;
+ }
+
+ strcpy ( G," '" );
+ strcat ( G,SpGroup );
+ strcat ( G,"'" );
+ S[0] = char(0);
+ while (!f.FileEnd() && (!strstr(S,G)))
+ f.ReadLine ( S,sizeof(S) );
+ if (f.FileEnd()) {
+ f.shut();
+ return SYMOP_UnknownSpaceGroup;
+ }
+
+ p = S;
+ while (*p==' ') p++;
+ p = strchr ( p,' ' );
+ if (p) Nops = mround(strtod(p,NULL));
+ if (Nops<=0) return SYMOP_NoSymOps;
+
+ symOp = new PSymOp[Nops];
+ RC = SYMOP_Ok;
+ for (i=0;(i<Nops) && (!RC);i++) {
+ f.ReadLine ( S,sizeof(S) );
+ symOp[i] = new SymOp();
+ RC = symOp[i]->SetSymOp ( S );
+ }
+
+ f.shut();
+
+ return RC;
+
+ }
+
+
+ #define syminfo_file cpstr("syminfo.lib")
+
+ int SymOps::SetGroup ( cpstr SpaceGroup,
+ cpstr syminfo_lib ) {
+ io::File f;
+ pstr p;
+ psvector lines,lines1;
+ char S[500];
+ char G[100];
+ char O[100];
+ mat44 T1,T2,T3;
+ int i,j,k,l,m,n,RC;
+ int nlines,npops,ncops;
+
+ FreeMemory();
+
+ npops = 0;
+ ncops = 0;
+
+ CreateCopy ( SpGroup,SpaceGroup );
+
+ if (!syminfo_lib) p = pstr(syminfo_file);
+ else if (!syminfo_lib[0]) p = pstr(syminfo_file);
+ else p = pstr(syminfo_lib);
+ f.assign ( p,true );
+ if (!f.reset(true)) {
+ p = getenv ( "SYMINFO" );
+ if (p)
+ strcpy ( S,p );
+ else {
+ p = getenv ( "CLIBD" );
+ if (p) {
+ strcpy ( S,p );
+ if (S[strlen(S)-1]!='/') strcat ( S,"/" );
+ strcat ( S,"syminfo.lib" );
+ } else
+ strcpy ( S,"syminfo.lib" );
+ }
+ f.assign ( S,true );
+ if (!f.reset(true)) return SYMOP_NoLibFile;
+ }
+
+
+ if (strncasecmp(SpGroup,"Hall:",5)) {
+ // normal space group symbol on input
+ strcpy ( G," '" );
+ strcat ( G,SpGroup );
+ strcat ( G,"'" );
+ S[0] = char(0);
+ while (!f.FileEnd() && !(strstr(S,G) && (strstr(S,"symbol xHM") ||
+ strstr(S,"symbol old"))))
+ f.ReadLine ( S,sizeof(S) );
+ } else {
+ // hall descriptor on input
+ strcpy ( G," ' " );
+ p = &(SpGroup[5]);
+ while (*p==' ') p++;
+ strcat ( G,p );
+ strcat ( G,"'" );
+ S[0] = char(0);
+ while (!f.FileEnd() && !(strstr(S,G) && strstr(S,"symbol Hall")))
+ f.ReadLine ( S,sizeof(S) );
+ }
+ if (f.FileEnd()) {
+ f.shut();
+ return SYMOP_UnknownSpaceGroup;
+ }
+
+ // found spacegroup, move to symop lines
+ while (!f.FileEnd() && (!strstr(S,"symop")))
+ f.ReadLine ( S,sizeof(S) );
+
+ nlines = 256;
+ GetVectorMemory ( lines,nlines,0 );
+ for (i=0;i<nlines;i++)
+ lines[i] = NULL;
+ n = 0;
+ CreateCopy ( lines[n++],S );
+
+ // count primitive operators
+ while (!f.FileEnd() && (strstr(S,"symop"))) {
+ npops++;
+ f.ReadLine ( S,sizeof(S) );
+ if (n>=nlines) {
+ nlines += + 256;
+ GetVectorMemory ( lines1,nlines,0 );
+ for (i=0;i<n;i++)
+ lines1[i] = lines[i];
+ for (i=n;i<nlines;i++)
+ lines1[i] = NULL;
+ FreeVectorMemory ( lines,0 );
+ lines = lines1;
+ }
+ CreateCopy ( lines[n++],S );
+ }
+
+ // count centering operators
+ while (!f.FileEnd() && (strstr(S,"cenop"))) {
+ ncops++;
+ f.ReadLine ( S,sizeof(S) );
+ if (n>=nlines) {
+ nlines += + 256;
+ GetVectorMemory ( lines1,nlines,0 );
+ for (i=0;i<n;i++)
+ lines1[i] = lines[i];
+ for (i=n;i<nlines;i++)
+ lines1[i] = NULL;
+ FreeVectorMemory ( lines,0 );
+ lines = lines1;
+ }
+ CreateCopy ( lines[n++],S );
+ }
+
+ Nops = npops*ncops;
+ symOp = new PSymOp[Nops];
+ RC = SYMOP_Ok;
+
+ n = 0; // start second pass here
+
+ // read primitive operators
+ for (i=0;(i<npops) && (!RC);i++) {
+ symOp[i] = new SymOp();
+ RC = symOp[i]->SetSymOp ( lines[n++]+6 );
+ }
+
+ // loop over non-trivial centering operators, and for each loop
+ // over primtive operators
+ for (i=1;(i<ncops) && (!RC);i++) {
+ n++; // this also skips the identity operator
+ for (j=0;(j<npops) && (!RC);j++) {
+ symOp[i*npops+j] = new SymOp();
+ RC = symOp[i*npops+j]->SetSymOp ( lines[n]+6 );
+ symOp[i*npops+j]->GetTMatrix(T1);
+ symOp[j]->GetTMatrix(T2);
+ for (k=0;k<4;k++)
+ for (l=0;l<4;l++) {
+ T3[k][l] = 0.0;
+ for (m=0;m<4;m++)
+ T3[k][l] += T1[k][m]*T2[m][l];
+ }
+ for (k=0;k<3;k++) // kdc fix
+ T3[k][3] -= floor ( T3[k][3] ); // kdc fix
+ symOp[i*npops+j]->CompileOpTitle ( O,T3,false );
+ symOp[i*npops+j]->SetSymOp ( O );
+ }
+ }
+
+ f.shut();
+
+ for (i=0;i<nlines;i++)
+ if (lines[i]) delete[] lines[i];
+ FreeVectorMemory ( lines,0 );
+
+ return RC;
+
+ }
+
+ /*
+ int SymOps::SetGroup ( cpstr SpaceGroup,
+ cpstr syminfo_lib ) {
+ CFile f;
+ pstr p;
+ char S[500];
+ char G[100];
+ char O[100];
+ mat44 T1,T2,T3;
+ int i,j,k,l,m,RC;
+ int npops,ncops;
+ long symop_start;
+ //fpos_t symop_start;
+
+ FreeMemory();
+
+ npops = 0;
+ ncops = 0;
+
+ CreateCopy ( SpGroup,SpaceGroup );
+
+ if (!syminfo_lib) p = pstr(syminfo_file);
+ else if (!syminfo_lib[0]) p = pstr(syminfo_file);
+ else p = pstr(syminfo_lib);
+ f.assign ( p,true );
+ if (!f.reset(true)) {
+ p = getenv ( "SYMINFO" );
+ if (p)
+ strcpy ( S,p );
+ else {
+ p = getenv ( "CLIBD" );
+ if (p) {
+ strcpy ( S,p );
+ if (S[strlen(S)-1]!='/') strcat ( S,"/" );
+ strcat ( S,"syminfo.lib" );
+ } else
+ strcpy ( S,"syminfo.lib" );
+ }
+ f.assign ( S,true );
+ if (!f.reset(true)) return SYMOP_NoLibFile;
+ }
+
+ if (strncasecmp(SpGroup,"Hall:",5)) {
+ // normal space group symbol on input
+ strcpy ( G," '" );
+ strcat ( G,SpGroup );
+ strcat ( G,"'" );
+ S[0] = char(0);
+ while (!f.FileEnd() && !(strstr(S,G) && (strstr(S,"symbol xHM") ||
+ strstr(S,"symbol old"))))
+ f.ReadLine ( S,sizeof(S) );
+ } else {
+ // hall descriptor on input
+ strcpy ( G," ' " );
+ p = &(SpGroup[5]);
+ while (*p==' ') p++;
+ strcat ( G,p );
+ strcat ( G,"'" );
+ S[0] = char(0);
+ while (!f.FileEnd() && !(strstr(S,G) && strstr(S,"symbol Hall")))
+ f.ReadLine ( S,sizeof(S) );
+ }
+ if (f.FileEnd()) {
+ f.shut();
+ return SYMOP_UnknownSpaceGroup;
+ }
+
+ // found spacegroup, move to symop lines
+ while (!f.FileEnd() && (!strstr(S,"symop"))) {
+ symop_start = f.Position();
+ //# fgetpos ( f.GetHandle(),&symop_start );
+ f.ReadLine ( S,sizeof(S) );
+ }
+ // count primitive operators
+ while (!f.FileEnd() && (strstr(S,"symop"))) {
+ npops++;
+ f.ReadLine ( S,sizeof(S) );
+ }
+ // count centering operators
+ while (!f.FileEnd() && (strstr(S,"cenop"))) {
+ ncops++;
+ f.ReadLine ( S,sizeof(S) );
+ }
+ Nops = npops*ncops;
+ f.seek(symop_start);
+ //# fsetpos ( f.GetHandle(),&symop_start );
+ SymOp = new PSymOp[Nops];
+ RC = SYMOP_Ok;
+
+ // read primitive operators
+ for (i=0;(i<npops) && (!RC);i++) {
+ f.ReadLine ( S,sizeof(S) );
+ SymOp[i] = new SymOp();
+ RC = SymOp[i]->SetSymOp ( S+6 );
+ }
+
+ // skip identity centering operator
+ f.ReadLine ( S,sizeof(S) );
+ // loop over non-trivial centering operators, and for each loop
+ // over primtive operators
+ for (i=1;(i<ncops) && (!RC);i++) {
+ f.ReadLine ( S,sizeof(S) );
+ for (j=0;(j<npops) && (!RC);j++) {
+ SymOp[i*npops+j] = new SymOp();
+ RC = SymOp[i*npops+j]->SetSymOp ( S+6 );
+
+ SymOp[i*npops+j]->GetTMatrix(T1);
+ SymOp[j]->GetTMatrix(T2);
+ for (k=0;k<4;k++)
+ for (l=0;l<4;l++) {
+ T3[k][l] = 0.0;
+ for (m=0;m<4;m++)
+ T3[k][l] += T1[k][m]*T2[m][l];
+ }
+ for (k=0;k<3;k++) // kdc fix
+ T3[k][3] -= floor ( T3[k][3] ); // kdc fix
+ SymOp[i*npops+j]->CompileOpTitle(O,T3,false);
+ SymOp[i*npops+j]->SetSymOp (O);
+ }
+ }
+
+ f.shut();
+
+ return RC;
+
+ }
+ */
+
+ void SymOps::Reset() {
+ // removes all symmetry operations
+ FreeMemory();
+ }
+
+ int SymOps::AddSymOp ( cpstr XYZOperation ) {
+ // adds a symmetry operation
+ PPSymOp symOp1;
+ int i;
+ symOp1 = new PSymOp[Nops+1];
+ for (i=0;i<Nops;i++)
+ symOp1[i] = symOp[i];
+ if (symOp) delete[] symOp;
+ symOp = symOp1;
+ i = Nops;
+ symOp[i] = new SymOp();
+ Nops++;
+ return symOp[i]->SetSymOp ( XYZOperation );
+ }
+
+ void SymOps::PutGroupName ( cpstr SpGroupName ) {
+ CreateCopy ( SpGroup,SpGroupName );
+ }
+
+
+ int SymOps::GetNofSymOps() {
+ // GetNofSymOps() returns Nops -- the number of symmetry operations
+ return Nops;
+ }
+
+ pstr SymOps::GetSymOp ( int Nop ) {
+ if ((0<=Nop) && (Nop<Nops)) return symOp[Nop]->GetSymOp();
+ else return pstr("");
+ }
+
+ int SymOps::Transform ( realtype & x, realtype & y, realtype & z,
+ int Nop ) {
+ // Transform(..) transforms the coordinates according to the
+ // symmetry operation Nop. The return code is non-zero if
+ // Nop is a wrong operation number (must range from 0 to Nops-1).
+ if ((Nop<0) || (Nop>=Nops)) return 1;
+ if (symOp[Nop]) {
+ symOp[Nop]->Transform ( x,y,z );
+ return 0;
+ } else
+ return 2;
+ }
+
+ int SymOps::GetTMatrix ( mat44 & TMatrix, int Nop ) {
+ // GetTMatrix(..) returns the coordinate transformation matrix
+ // for the symmetry operation Nop. The return code is non-zero if
+ // Nop is a wrong operation number (must range from 0 to Nops-1).
+ if ((Nop<0) || (Nop>=Nops)) return 1;
+ if (symOp[Nop]) {
+ symOp[Nop]->GetTMatrix ( TMatrix );
+ return 0;
+ } else
+ return 2;
+ }
+
+ void SymOps::Print() {
+ int i;
+ char S[200];
+ printf ( " SPACE GROUP '%s'\n",SpGroup );
+ for (i=0;i<Nops;i++) {
+ symOp[i]->Print();
+ if (symOp[i]->CompileOpTitle(S))
+ printf ( " CHECK STATUS: Ok\n" );
+ else printf ( " CHECK STATUS: Generated '%s'\n",S );
+ }
+ }
+
+
+ void SymOps::Copy ( PSymOps SymOps ) {
+ int i;
+ FreeMemory();
+ CreateCopy ( SpGroup,SymOps->SpGroup );
+ Nops = SymOps->Nops;
+ if (Nops>0) {
+ symOp = new PSymOp[Nops];
+ for (i=0;i<Nops;i++) {
+ symOp[i] = new SymOp();
+ symOp[i]->Copy ( SymOps->symOp[i] );
+ }
+ }
+ }
+
+
+ void SymOps::write ( io::RFile f ) {
+ int i;
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.CreateWrite ( SpGroup );
+ f.WriteInt ( &Nops );
+ for (i=0;i<Nops;i++)
+ StreamWrite ( f,symOp[i] );
+ }
+
+ void SymOps::read ( io::RFile f ) {
+ int i;
+ byte Version;
+ FreeMemory();
+ f.ReadByte ( &Version );
+ f.CreateRead ( SpGroup );
+ f.ReadInt ( &Nops );
+ if (Nops>0) {
+ symOp = new PSymOp[Nops];
+ for (i=0;i<Nops;i++) {
+ symOp[i] = NULL;
+ StreamRead ( f,symOp[i] );
+ }
+ }
+ }
+
+
+ MakeStreamFunctions(SymOps)
+
+} // namespace mmdb
+
+
+/*
+
+void TestSymOps() {
+pstr p,p1;
+int RC;
+char S[500];
+SymOps SymOps;
+CFile f;
+
+ p = getenv ( "PDB_ROOT" );
+ if (p) {
+ strcpy ( S,p );
+ strcat ( S,"/lib/" );
+ } else
+ S[0] = char(0);
+ strcat ( S,"symop.lib" );
+ f.assign ( S,true );
+ if (!f.reset()) {
+ printf ( " +++++ No symop.lib file found.\n" );
+ return;
+ }
+
+ while (!f.FileEnd()) {
+ f.ReadLine ( S,sizeof(S) );
+ if (S[0] && (S[0]!=' ')) {
+ p = strchr ( S,'\'' );
+ if (p) {
+ p++;
+ p1 = strchr ( p,'\'' );
+ if (!p1) p = NULL;
+ }
+ if (!p) {
+ printf ( " +++++ Strange line in symop.lib:\n"
+ "%s\n",S );
+ return;
+ }
+ *p1 = char(0);
+ RC = SymOps.SetGroup ( p );
+ printf ( " =========================================================\n"
+ " RC=%i\n",RC );
+ SymOps.Print();
+ }
+ }
+
+ return;
+
+}
+
+*/
diff --git a/mmdb2/mmdb_symop.h b/mmdb2/mmdb_symop.h
new file mode 100644
index 0000000..f5e7af0
--- /dev/null
+++ b/mmdb2/mmdb_symop.h
@@ -0,0 +1,168 @@
+// $Id: mmdb_symop.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_SymOp <interface>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+//
+// **** Classes : mmdb::SymOp ( symmetry operators )
+// ~~~~~~~~~ mmdb::SymOps ( container of symmetry operators )
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_SymOp__
+#define __MMDB_SymOp__
+
+#include "mmdb_io_stream.h"
+#include "mmdb_defs.h"
+
+namespace mmdb {
+
+ // ==================== SymOp ========================
+
+ DefineClass(SymOp);
+ DefineStreamFunctions(SymOp);
+
+ class SymOp : public io::Stream {
+
+ public :
+
+ SymOp ();
+ SymOp ( io::RPStream Object );
+ ~SymOp();
+
+ int SetSymOp ( cpstr XYZOperation );
+ pstr GetSymOp ();
+
+ void Transform ( realtype & x, realtype & y, realtype & z );
+
+ void GetTMatrix ( mat44 & TMatrix ); // copies T to TMatrix
+ void SetTMatrix ( mat44 & TMatrix ); // copies TMatrix to T
+
+ bool CompileOpTitle ( pstr S ); // makes XYZOp from matrix T
+ bool CompileOpTitle ( pstr S, mat44 symMat, bool compare );
+ void Print (); // prints operation and matrix
+
+ void Copy ( PSymOp symOp );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+ pstr XYZOp;
+ mat44 T;
+
+ void InitSymOp ();
+ void FreeMemory ();
+ int GetOperation ( int n );
+
+ };
+
+
+ // ==================== SymOps ========================
+
+ enum SYMOP_RC {
+ SYMOP_Ok = 0,
+ SYMOP_NoLibFile = -1,
+ SYMOP_UnknownSpaceGroup = -2,
+ SYMOP_NoSymOps = -3,
+ SYMOP_WrongSyntax = -4,
+ SYMOP_NotAnOperation = -5,
+ SYMOP_ZeroDenominator = -6
+ };
+
+ DefineClass(SymOps);
+ DefineStreamFunctions(SymOps);
+
+ class SymOps : public io::Stream {
+
+ public :
+
+ SymOps ();
+ SymOps ( io::RPStream Object );
+ ~SymOps();
+
+ virtual void FreeMemory();
+
+ int SetGroupSymopLib ( cpstr SpaceGroup,
+ cpstr symop_lib=NULL );
+ // Space Group is taken from symop.lib. Return Code:
+ // SYMOP_Ok <=> success
+
+ int SetGroup ( cpstr SpaceGroup,
+ cpstr syminfo_lib=NULL );
+ // Space Group is taken from syminfo.lib. Return Code:
+ // SYMOP_Ok <=> success
+
+ void Reset (); // removes all symmetry operations
+ virtual int AddSymOp ( cpstr XYZOperation ); // adds symmetry
+ // operation
+ void PutGroupName ( cpstr SpGroupName );
+
+ // GetNofSymOps() returns Nops -- the number of sym. operations
+ int GetNofSymOps ();
+ pstr GetSymOp ( int Nop );
+
+ // Transform(..) transforms the coordinates according to the
+ // symmetry operation Nop. The return code is non-zero if
+ // Nop is a wrong operation number (must range from 0 to Nops-1).
+ int Transform ( realtype & x, realtype & y, realtype & z,
+ int Nop );
+
+ // GetTMatrix(..) returns the coordinate transformation matrix
+ // for the symmetry operation Nop. The return code is non-zero if
+ // Nop is a wrong operation number (must range from 0 to Nops-1).
+ int GetTMatrix ( mat44 & TMatrix, int Nop );
+
+ void Print ();
+
+ virtual void Copy ( PSymOps symOps );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ pstr SpGroup;
+ int Nops;
+ PPSymOp symOp;
+
+ void InitSymOps();
+
+ };
+
+} // namespace mmdb
+
+// extern void TestSymOps();
+
+#endif
+
diff --git a/mmdb2/mmdb_tables.cpp b/mmdb2/mmdb_tables.cpp
new file mode 100644
index 0000000..d1e7c61
--- /dev/null
+++ b/mmdb2/mmdb_tables.cpp
@@ -0,0 +1,748 @@
+// $Id: mmdb_tables.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_Tables <implementation>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+//
+// **** Namespace : mmdb::
+//
+// **** Functions :
+// ~~~~~~~~~~~
+//
+// **** Constants : AName ( array of 2-character atom names )
+// ~~~~~~~~~~~ HAName ( array of 2=character heteroatom names )
+// RName ( 3-characters amino acid names )
+// RName1 ( 1-characters amino acid names )
+//
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include <string.h>
+
+#include "mmdb_tables.h"
+#include "mmdb_defs.h"
+
+namespace mmdb {
+
+ // ===============================================================
+
+ cpstr const ElementName[nElementNames] = {
+ " H", "HE",
+ "LI", "BE", " B", " C", " N", " O", " F", "NE",
+ "NA", "MG", "AL", "SI", " P", " S", "CL", "AR",
+ " K", "CA",
+ "SC", "TI", " V", "CR", "MN", "FE",
+ "CO", "NI", "CU", "ZN",
+ "GA", "GE", "AS", "SE", "BR", "KR",
+ "RB", "SR",
+ " Y", "ZR", "NB", "MO", "TC", "RU",
+ "RH", "PD", "AG", "CD",
+ "IN", "SN", "SB", "TE", " I", "XE",
+ "CS", "BA",
+ "LA", "CE", "PR", "ND", "PM", "SM", "EU",
+ "GD", "TB", "DY", "HO", "ER", "TM", "YB",
+ "LU", "HF", "TA", " W", "RE", "OS",
+ "IR", "PT", "AU", "HG",
+ "TL", "PB", "BI", "PO", "AT", "RN",
+ "FR", "RA",
+ "AC", "TH", "PA", " U", "NP", "PU", "AM",
+ "CM", "BK", "CF", "ES", "FM", "MD", "NO",
+ "LR", "RF", "DB", "SG", "BH", "HS",
+ "MT", "UN", "UU", "UB",
+ "UQ", "UH", "UO",
+ " D", "AN"
+ };
+
+ realtype const MolecWeight[nElementNames] = {
+ 1.0079, 4.0026,
+ 6.9410, 9.0122, 10.811, 12.011, 14.007, 15.999, 18.998, 20.180,
+ 22.990, 24.305, 26.982, 28.086, 30.974, 32.066, 35.453, 39.948,
+ 39.098, 40.078,
+ 44.956, 47.867, 50.942, 51.996, 54.938, 55.845,
+ 58.993, 58.693, 63.546, 65.390,
+ 69.723, 72.610, 74.922, 78.960, 79.904, 83.800,
+ 85.468, 87.620,
+ 88.906, 91.224, 92.906, 95.940, 97.907, 101.07,
+ 102.91, 106.42, 107.87, 112.41,
+ 114.82, 118.71, 121.76, 127.60, 126.90, 131.29,
+ 132.91, 137.33,
+ 138.91, 140.12, 140.91, 144.24, 144.91, 150.36, 151.96,
+ 157.25, 158.93, 162.50, 164.93, 167.26, 168.93, 173.04,
+ 174.97, 178.49, 180.95, 183.84, 186.21, 190.23,
+ 192.22, 195.08, 196.97, 200.59,
+ 204.38, 207.20, 208.98, 208.98, 209.99, 222.02,
+ 232.02, 226.03,
+ 227.03, 232.04, 231.04, 238.03, 237.05, 244.06, 243.06,
+ 247.07, 247.07, 251.08, 252.08, 257.10, 258.10, 259.10,
+ 262.11, 263.11, 262.11, 266.12, 264.12, 269.13,
+ 268.14, 272.15, 272.15, 277.00,
+ 289.00, 289.00, 293.00,
+ 2.0200, 3.0300
+ };
+
+
+ realtype const CovalentRadius[nElementNames] = {
+ 0.32, 0.93,
+ 1.23, 0.90, 0.82, 0.77, 0.75, 0.73, 0.72, 0.71,
+ 1.54, 1.36, 1.18, 1.11, 1.06, 1.02, 0.99, 0.98,
+ 2.03, 1.91,
+ 1.62, 1.45, 1.34, 1.18, 1.17, 1.17,
+ 1.16, 1.15, 1.17, 1.25,
+ 1.26, 1.22, 1.20, 1.16, 1.14, 1.12,
+ 2.16, 1.91,
+ 1.62, 1.45, 1.34, 1.30, 1.27, 1.25,
+ 1.25, 1.28, 1.34, 1.48,
+ 1.44, 1.41, 1.40, 1.36, 1.33, 1.31,
+ 2.35, 1.98,
+ 1.69, 1.44, 1.34, 1.30, 1.28, 1.26, 1.27,
+ 1.30, 1.34, 1.49, 1.48, 1.47, 1.46, 1.46,
+ 1.45, 1.43, 2.50, 2.40, 2.20, 1.65,
+ 1.65, 1.64, 1.63, 1.62,
+ 1.85, 1.61, 1.59, 1.59, 1.58, 1.57,
+ 1.56, 1.74,
+ 1.56, 1.65, 1.65, 1.42, 1.65, 1.65, 1.65,
+ 1.65, 1.65, 1.65, 1.65, 1.65, 1.65, 1.65,
+ 1.65, 0.32, 0.10, /**/
+ 0.20, 0.20, 0.20,
+ 0.20, 0.20, 0.20, 0.20,
+ 0.20, 0.20, 0.20,
+ 0.32, 0.32
+ };
+
+
+ realtype const VdWaalsRadius[nElementNames] = {
+ 1.20, 1.40,
+ 1.82, 1.78, 1.74, 1.70, 1.55, 1.52, 1.47, 1.54,
+ // ^^^^ ^^^^ <- only a guess
+ 2.27, 1.73, 1.80, 2.10, 1.80, 1.80, 1.75, 1.88,
+ // ^^^^
+ 2.75, 2.65,
+ // ^^^^
+ 2.55, 2.45, 2.35, 2.20, 1.73, 1.90,
+ // ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
+ 1.75, 1.63, 1.40, 1.39,
+ // ^^^^
+ 1.87, 1.86, 1.85, 1.90, 1.85, 2.02,
+ // ^^^^
+ 2.75, 2.65,
+ //^^^^ ^^^^
+ 2.55, 2.45, 2.35, 2.20, 2.05, 1.90,
+ // ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
+ 1.75, 1.63, 1.72, 1.58,
+ // ^^^^
+ 1.93, 2.17, 2.10, 2.06, 1.98, 2.16,
+ // ^^^^
+ 2.75, 2.75,
+ //^^^^ ^^^^
+ 2.75, 2.75, 2.75, 2.75, 2.75, 2.75, 2.75,
+ // ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
+ 2.75, 2.75, 2.75, 2.75, 2.75, 2.65, 2.55,
+ // ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
+ 2.45, 2.35, 2.25, 2.15, 2.05, 1.95,
+ // ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
+ 1.85, 1.75, 1.66, 1.55,
+ // ^^^^
+ 1.96, 2.02, 2.00, 2.00, 2.00, 2.00,
+ // ^^^^ ^^^^ ^^^^ ^^^^
+ 2.75, 2.75,
+ //^^^^ ^^^^
+ 2.50, 2.25, 1.95, 1.86, 1.80, 1.80, 1.80,
+ // ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
+ 1.80, 1.80, 1.80, 1.80, 1.80, 1.80, 1.80,
+ // ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
+ 1.80, 1.80, 1.80, 1.80, 1.80, 1.80,
+ // ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
+ 1.80, 1.80, 1.80, 1.80,
+ // ^^^^ ^^^^ ^^^^ ^^^^
+ 1.80, 1.80, 1.80,
+ // ^^^^ ^^^^ ^^^^
+ 1.30, 1.50
+ //^^^^ ^^^^
+ };
+
+ realtype const IonicRadius[nElementNames] = {
+ 0.79, 0.49, 2.05, 1.40, 1.17, 0.91, 0.75, 0.65, 0.57, 0.51,
+ 2.23, 1.72, 1.82, 1.46, 1.23, 1.09, 0.97, 0.88, 2.77, 2.23,
+ 2.09, 2.00, 1.92, 1.85, 1.79, 1.72, 1.67, 1.62, 1.57, 1.53,
+ 1.81, 1.52, 1.33, 1.22, 1.12, 1.03, 2.98, 2.45, 2.27, 2.16,
+ 2.09, 2.01, 1.95, 1.89, 1.83, 1.79, 1.75, 1.71, 2.00, 1.72,
+ 1.53, 1.42, 1.32, 1.24, 3.34, 2.78, 2.74, 2.16, 2.09, 2.02,
+ 1.97, 1.92, 1.87, 1.83, 1.79, 1.76, 2.08, 1.81, 1.63, 1.53,
+ 1.43, 1.34, 3.50, 3.00, 3.20, 2.70, 2.67, 2.64, 2.62, 2.59,
+ 2.56, 2.54, 2.51, 2.49, 2.47, 2.45, 2.42, 2.40, 2.25, 3.16,
+ 3.14, 3.11, 3.08, 3.05, 3.02, 2.99, 2.97, 2.95, 2.92, 2.90,
+ 2.87, 2.85
+ };
+
+ cpstr const ElementMetal[nElementMetals] = {
+ "LI", "BE", "NA", "MG", "AL", " K", "CA", "SC", "TI", " V",
+ "MN", "FE", "CO", "NI", "CU", "ZN", "GA", "RB", "SR", " Y",
+ "ZR", "NB", "MO", "TC", "RU", "RH", "PD", "AG", "CD", "IN",
+ "SN", "SB", "CS", "BA", "LA", "CE", "PR", "ND", "PM", "SM",
+ "EU", "GD", "TB", "DY", "HO", "ER", "TM", "YB", "LU", "HF",
+ "TA", " W", "RE", "OS", "IR", "PT", "AU", "HG", "TL", "PB",
+ "BI", "PO", "FR", "RA", "AC", "TH", "PA", " U", "NP", "PU",
+ "AM", "CM", "BK", "CF", "ES", "FM", "MD", "NO", "LR", "RF",
+ "DB", "SG", "BH", "HS", "MT", "UN", "UU", "UB", "UQ", "UH",
+ "UO"
+ };
+
+
+ cpstr const HydAtomName[nHydAtomNames] = {
+ "0H", "1H", "2H", "3H", "4H", "5H", "6H", "7H", "8H", "9H",
+ "HH", "*H", "'H", """H"
+ };
+
+
+
+ bool isMetal ( cpstr element ) {
+ char name[3];
+ bool isThere;
+ int i;
+ if (!element[1]) {
+ name[0] = ' ';
+ name[1] = element[0];
+ } else
+ strncpy ( name,element,2 );
+ name[2] = char(0);
+ isThere = false;
+ for (i=0;(i<nElementMetals) && (!isThere);i++)
+ isThere = (!strcmp(ElementMetal[i],name));
+ return isThere;
+ }
+
+ int getElementNo ( cpstr element ) {
+ int type=0;
+ char El[3];
+ if ((!element[1]) || (element[1]==' ')) {
+ El[0] = ' ';
+ El[1] = element[0];
+ } else {
+ El[0] = element[0];
+ El[1] = element[1];
+ }
+ El[2] = char(0);
+ UpperCase ( El );
+ while (type<nElementNames)
+ if (!strcmp(El,ElementName[type])) break;
+ else type++;
+ if (type>=nElementNames) return ELEMENT_UNKNOWN;
+ return type+1; // so that hydrogen is 1
+ }
+
+ realtype getMolecWeight ( cpstr element ) {
+ int type=0;
+ char El[3];
+ if ((!element[1]) || (element[1]==' ')) {
+ El[0] = ' ';
+ El[1] = element[0];
+ } else {
+ El[0] = element[0];
+ El[1] = element[1];
+ }
+ El[2] = char(0);
+ UpperCase ( El );
+ while (type<nElementNames)
+ if (!strcmp(El,ElementName[type])) break;
+ else type++;
+ if (type>=nElementNames) return 1.0;
+ return MolecWeight[type];
+ }
+
+ realtype getCovalentRadius ( cpstr element ) {
+ int type=0;
+ char El[3];
+ if ((!element[1]) || (element[1]==' ')) {
+ El[0] = ' ';
+ El[1] = element[0];
+ } else {
+ El[0] = element[0];
+ El[1] = element[1];
+ }
+ El[2] = char(0);
+ UpperCase ( El );
+ while (type<nElementNames)
+ if (!strcmp(El,ElementName[type])) break;
+ else type++;
+ if (type>=nElementNames) return 2.2*CovalentRadius[0];
+ return CovalentRadius[type];
+ }
+
+ realtype getVdWaalsRadius ( cpstr element ) {
+ int type=0;
+ char El[3];
+ if ((!element[1]) || (element[1]==' ')) {
+ El[0] = ' ';
+ El[1] = element[0];
+ } else {
+ El[0] = element[0];
+ El[1] = element[1];
+ }
+ El[2] = char(0);
+ UpperCase ( El );
+ while (type<nElementNames)
+ if (!strcmp(El,ElementName[type])) break;
+ else type++;
+ if (type>=nElementNames) return 1.8;
+ return VdWaalsRadius[type];
+ }
+
+ cpstr const ResidueName[nResNames] = {
+ "ALA", "ARG", "ASN", "ASP", "CYS", "CYH", "GLN",
+ "GLU", "GLY", "HIS", "ILE", "LEU", "LYS", "MET",
+ "PHE", "PRO", "SER", "THR", "TRP", "TYR", "VAL",
+ "HEM", "WAT", "SUL", "END", "DUM"
+ };
+
+ int getResidueNo ( cpstr resName ) {
+ int i,m;
+ m = -1;
+ for (i=0;(i<nResNames) && (m<0);i++)
+ if (!strcmp(resName,ResidueName[i]))
+ m = i;
+ return m;
+ }
+
+ char const ResidueName1[nResNames] = {
+ 'A', 'R', 'N', 'D', 'C', 'C', 'Q',
+ 'E', 'G', 'H', 'I', 'L', 'K', 'M',
+ 'F', 'P', 'S', 'T', 'W', 'Y', 'V',
+ 'X', 'O', 'U', 'Z', 'Z'
+ };
+
+
+ cpstr const StdSolventName[nSolventNames] = {
+ "ADE", "CYT", "GUA", "INO", "THY", "URA",
+ "WAT", "HOH", "TIP", "H2O", "DOD", "MOH"
+ };
+
+
+ AAProperty const AAProperties[nAminoacidNames] = {
+ { "ALA", 1.8, 0.0, 0.42 },
+ { "ARG", -4.5, 1.0, -1.37 },
+ { "ASN", -3.5, 0.0, -0.82 },
+ { "ASP", -3.5, -1.0, -1.05 },
+ { "ASX", -3.5, -0.5, -1.05 }, // by analogy
+ { "CYS", 2.5, 0.0, 1.34 },
+ { "CYH", 2.5, 0.0, 1.34 }, // by analogy
+ { "GLN", -3.5, 0.0, -0.30 },
+ { "GLU", -3.5, -1.0, -0.87 },
+ { "GLX", -3.5, -0.5, 0.0 }, // by analogy
+ { "GLY", -0.4, 0.0, 0.0 },
+ { "HIS", -3.2, 0.0, 0.18 },
+ { "ILE", 4.5, 0.0, 2.46 },
+ { "LEU", 3.8, 0.0, 2.32 },
+ { "LYS", -3.9, 1.0, -1.35 },
+ { "MET", 1.9, 0.0, 1.68 },
+ { "PHE", 2.8, 0.0, 2.44 },
+ { "PRO", -1.6, 0.0, 0.98 },
+ { "SER", -0.8, 0.0, -0.05 },
+ { "THR", -0.7, 0.0, 0.35 },
+ { "TRP", -0.9, 0.0, 3.07 },
+ { "TYR", -1.3, 0.0, 1.31 },
+ { "VAL", 4.2, 0.0, 1.66 }
+ };
+
+ realtype GetAAHydropathy ( cpstr resName ) {
+ int i1,j;
+ i1 = -1;
+ j = 0;
+ while (j<nAminoacidNames)
+ if (!strcasecmp(resName,AAProperties[j].name)) {
+ i1 = j;
+ break;
+ } else
+ j++;
+ if (i1<0) return -MaxReal;
+ return AAProperties[i1].hydropathy;
+ }
+
+ realtype GetAACharge ( cpstr resName ) {
+ int i1,j;
+ i1 = -1;
+ j = 0;
+ while (j<nAminoacidNames)
+ if (!strcasecmp(resName,AAProperties[j].name)) {
+ i1 = j;
+ break;
+ } else
+ j++;
+ if (i1<0) return 0.0;
+ return AAProperties[i1].charge;
+ }
+
+ realtype GetAASolvationEnergy ( cpstr resName ) {
+ int i1,j;
+ i1 = -1;
+ j = 0;
+ while (j<nAminoacidNames)
+ if (!strcasecmp(resName,AAProperties[j].name)) {
+ i1 = j;
+ break;
+ } else
+ j++;
+ if (i1<0) return 0.0;
+ return AAProperties[i1].relSolvEnergy;
+ }
+
+
+ int const AASimilarity[nAminoacidNames][nAminoacidNames] = {
+ /* A A A A A C C G G G G H I L L M P P S T T T V */
+ /* L R S S S Y Y L L L L I L E Y E H R E H R Y A */
+ /* A G N P X S H N U X Y S E U S T E O R R P R L */
+ { 5,0,0,0,0,0,0,0,0,2,2,0,2,2,0,2,2,2,1,1,2,2,2 }, /* ALA */
+ { 0,5,2,2,2,0,0,2,2,0,0,2,0,0,4,0,0,0,0,0,0,0,0 }, /* ARG */
+ { 0,2,5,3,5,0,0,3,3,0,0,0,0,0,2,0,0,0,0,0,0,0,0 }, /* ASN */
+ { 0,2,3,5,5,0,0,3,3,0,0,0,0,0,2,0,0,0,0,0,0,0,0 }, /* ASP */
+ { 0,2,5,5,5,0,0,3,3,0,0,0,0,0,2,0,0,0,0,0,0,0,0 }, /* ASX */
+ { 0,0,0,0,0,5,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* CYS */
+ { 0,0,0,0,0,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* CYH */
+ { 0,2,3,3,3,0,0,5,3,0,0,0,0,0,2,0,0,0,0,0,0,0,0 }, /* GLN */
+ { 0,2,3,3,3,0,0,3,5,0,0,0,0,0,2,0,0,0,0,0,0,0,0 }, /* GLU */
+ { 2,0,0,0,0,0,0,0,0,5,5,0,1,1,0,1,1,2,0,0,1,1,1 }, /* GLX */
+ { 2,0,0,0,0,0,0,0,0,5,5,0,1,1,0,1,1,2,0,0,1,1,1 }, /* GLY */
+ { 0,2,0,0,0,0,0,0,0,0,0,5,1,1,2,2,2,0,1,1,2,2,1 }, /* HIS */
+ { 2,0,0,0,0,0,0,0,0,1,1,1,5,4,0,4,4,0,0,0,4,4,4 }, /* ILE */
+ { 2,0,0,0,0,0,0,0,0,1,1,1,4,5,0,4,4,0,0,0,4,4,4 }, /* LEU */
+ { 0,4,2,2,2,0,0,2,2,0,0,2,0,0,5,0,0,0,0,0,0,0,0 }, /* LYS */
+ { 2,0,0,0,0,0,0,0,0,1,1,2,4,4,0,5,4,0,0,0,4,4,4 }, /* MET */
+ { 2,0,0,0,0,0,0,0,0,1,1,2,4,4,0,4,5,0,0,0,5,5,4 }, /* PHE */
+ { 2,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,5,0,0,0,0,0 }, /* PRO */
+ { 1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,5,3,0,0,0 }, /* SER */
+ { 1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,3,5,0,0,0 }, /* THR */
+ { 2,0,0,0,0,0,0,0,0,1,1,2,4,4,0,4,5,0,0,0,5,5,4 }, /* TRP */
+ { 2,0,0,0,0,0,0,0,0,1,1,2,4,4,0,4,5,0,0,0,5,5,4 }, /* TYR */
+ { 2,0,0,0,0,0,0,0,0,1,1,1,4,4,0,4,4,0,0,0,4,4,5 }, /* VAL */
+ };
+
+ int GetAAPIndex ( cpstr resName ) {
+ // 0..nAminoacidNames-1
+ int i,k;
+ k = -1;
+ for (i=0;(i<nAminoacidNames) && (k<0);i++)
+ if (!strcasecmp(resName,AAProperties[i].name))
+ k = i;
+ return k;
+ }
+
+
+ int GetAASimilarity ( cpstr resName1, cpstr resName2 ) {
+ int i1,i2,j;
+
+ i1 = -1;
+ j = 0;
+ while (j<nAminoacidNames)
+ if (!strcasecmp(resName1,AAProperties[j].name)) {
+ i1 = j;
+ break;
+ } else
+ j++;
+ if (i1<0) return -1;
+
+ i2 = -1;
+ j = 0;
+ while (j<nAminoacidNames)
+ if (!strcasecmp(resName2,AAProperties[j].name)) {
+ i2 = j;
+ break;
+ } else
+ j++;
+ if (i2<0) return -2;
+
+ return AASimilarity[i1][i2];
+
+ }
+
+
+
+
+
+ /*
+
+
+ pstr const AminoacidName[nAminoacidNames] = {
+ "ALA", "ARG", "ASN", "ASP", "ASX", "CYS", "CYH", "GLN",
+ "GLU", "GLX", "GLY", "HIS", "ILE", "LEU", "LYS", "MET",
+ "PHE", "PRO", "SER", "THR", "TRP", "TYR", "VAL"
+ };
+
+
+ // The higher is the hydropathy scale value, the more
+ // hydrophobic the residue is.
+ // Some sources suggest that sure hydrophilic residues
+ // are those with hydropathy scale value less than -1.5,
+ // while sure hydropoobic residues have hydropathy scale
+ // value greater than 0.0.
+ // The scale is after J. Kyte and R. F. Doolittle,
+ // A simple method for displaying the hydropathic character
+ // of a protein, J. Mol. Biol. (1982) 157, 105-132
+ realtype const AAHydropathyScale[nAminoacidNames] = {
+ 1.8, -4.5, -3.5, -3.5, -3.5, 2.5, 2.5, -3.5,
+ -3.5, -3.5, -0.4, -3.2, 4.5, 3.8, -3.9, 1.9,
+ 2.8, -1.6, -0.8, -0.7, -0.9, -1.3, 4.2
+ };
+
+ realtype GetAAHydropathy ( cpstr resName ) {
+ int i1,j;
+ i1 = -1;
+ j = 0;
+ while (j<nAminoacidNames)
+ if (!strcasecmp(resName,AminoacidName[j])) {
+ i1 = j;
+ break;
+ } else
+ j++;
+ if (i1<0) return -MaxReal;
+ return AAHydropathyScale[i1];
+ }
+
+ // Acid residues are those with negative charge
+ // Base residues are those with positive charge
+ realtype const AACharge[nAminoacidNames] = {
+ 0.0, 1.0, 0.0, -1.0, -0.5, 0.0, 0.0, 0.0,
+ -1.0, -0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
+ };
+
+ int GetAASimilarity ( cpstr resName1, cpstr resName2 ) {
+ int i1,i2,j;
+
+ i1 = -1;
+ j = 0;
+ while (j<nAminoacidNames)
+ if (!strcasecmp(resName1,AminoacidName[j])) {
+ i1 = j;
+ break;
+ } else
+ j++;
+ if (i1<0) return -1;
+
+ i2 = -1;
+ j = 0;
+ while (j<nAminoacidNames)
+ if (!strcasecmp(resName2,AminoacidName[j])) {
+ i2 = j;
+ break;
+ } else
+ j++;
+ if (i2<0) return -2;
+
+ return AASimilarity[i1][i2];
+
+ }
+
+ bool isAminoacid ( cpstr resName ) {
+ bool isThere;
+ int i;
+ isThere = false;
+ for (i=0;(i<nAminoacidNames) && (!isThere);i++)
+ isThere = (!strcmp(AminoacidName[i],resName));
+ return isThere;
+ }
+
+ */
+
+
+ cpstr const NucleotideName[nNucleotideNames] = {
+ "A", "C", "G", "I", "T", "U",
+ "+A", "+C", "+G", "+I", "+T", "+U",
+ "DA", "DC", "DG", "DI", "DT", "DU",
+ "RA", "RC", "RG", "RU", "5NC", "TYD"
+ };
+
+
+ bool isSolvent ( cpstr resName ) {
+ bool isThere;
+ int i;
+ isThere = false;
+ for (i=0;(i<nSolventNames) && (!isThere);i++)
+ isThere = (!strcmp(StdSolventName[i],resName));
+ return isThere;
+ }
+
+ bool isAminoacid ( cpstr resName ) {
+ bool isThere;
+ int i;
+ isThere = false;
+ for (i=0;(i<nAminoacidNames) && (!isThere);i++)
+ isThere = (!strcmp(AAProperties[i].name,resName));
+ return isThere;
+ }
+
+ bool isNucleotide ( cpstr resName ) {
+ bool isThere;
+ int i;
+ isThere = false;
+ for (i=0;(i<nNucleotideNames) && (!isThere);i++)
+ isThere = (!strcmp(NucleotideName[i],resName));
+ return isThere;
+ }
+
+ int isDNARNA ( cpstr resName ) {
+ bool isThere;
+ int i;
+ isThere = false;
+ for (i=0;(i<nNucleotideNames) && (!isThere);i++)
+ isThere = (!strcmp(NucleotideName[i],resName));
+ if (!isThere) return 0; // neither
+ if (resName[0]=='D') return 1; // DNA
+ return 2; // RNA
+ }
+
+ bool isSugar ( cpstr resName ) {
+ UNUSED_ARGUMENT(resName);
+ return false;
+ }
+
+
+ cpstr const Res1Code[] = {
+
+ // standard aminoacids
+
+ "ALA A", // Alanine
+ "ARG R", // Arginine
+ "ASN N", // Asparagine
+ "ASP D", // Aspartic acid (Aspartate)
+ "CYS C", // Cysteine
+ "GLN Q", // Glutamine
+ "GLU E", // Glutamic acid (Glutamate)
+ "GLY G", // Glycine
+ "HIS H", // Histidine
+ "ILE I", // Isoleucine
+ "LEU L", // Leucine
+ "LYS K", // Lysine
+ "MET M", // Methionine
+ "PHE F", // Phenylalanine
+ "PRO P", // Proline
+ "SER S", // Serine
+ "THR T", // Threonine
+ "TRP W", // Tryptophan
+ "TYR Y", // Tyrosine
+ "VAL V", // Valine
+ "ASX B", // Aspartic acid or Asparagine
+ "GLX Z", // Glutamine or Glutamic acid.
+ // ??? X Any amino acid.
+
+ // other
+
+ "1PA A", "1PI A", "2AS D", "2ML L", "2MR R", "3GA A",
+ "5HP E", "ACB D", "ACL R", "AGM R", "AHB D", "ALM A",
+ "ALN A", "ALO T", "ALT A", "ALY K", "APH A", "APM A",
+ "AR2 R", "ARM R", "ARO R", "ASA D", "ASB D", "ASI D",
+ "ASK D", "ASL D", "ASQ D", "AYA A", "B1F A", "B2A A",
+ "B2F A", "B2I I", "B2V V", "BAL A", "BCS C", "BFD D",
+ "BHD D", "BLE L", "BLY K", "BNN F", "BNO L", "BTA L",
+ "BTC C", "BTR W", "BUC C", "BUG L", "C5C C", "C6C C",
+ "CAF C", "CAS C", "CAY C", "CCS C", "CEA C", "CGU E",
+ "CHG G", "CHP G", "CLB A", "CLD A", "CLE L", "CME C",
+ "CMT C", "CSB C", "CSD A", "CSE C", "CSO C", "CSP C",
+ "CSR C", "CSS C", "CSW C", "CSX C", "CSY C", "CSZ C",
+ "CTH T", "CXM M", "CY1 C", "CYM C", "CZZ C", "DAH F",
+ "DAL A", "DAM A", "DAR R", "DAS D", "DBY Y", "DCY C",
+ "DGL E", "DGN Q", "DHI H", "DHN V", "DIL I", "DIV V",
+ "DLE L", "DLY K", "DNP A", "DOH D", "DPH F", "DPN F",
+ "DPR P", "DSE S", "DSN S", "DSP D", "DTH T", "DTR W",
+ "DTY Y", "DVA V", "EFC C", "EHP F", "EYS C", "FLA A",
+ "FLE L", "FME M", "FTY Y", "GGL E", "GHP G", "GSC G",
+ "GT9 C", "H5M P", "HAC A", "HAR R", "HIC H", "HIP H",
+ "HMR R", "HPH F", "HPQ F", "HTR W", "HV5 A", "HYP P",
+ "IAS N", "IIL I", "ILG Q", "IML I", "IN2 K", "ISO A",
+ "IVA V", "IYR Y", "KCX K", "KPH K", "LLY K", "LOL L",
+ "LPL L", "LTR W", "LYM K", "LYZ K", "M3L K", "MAA A",
+ "MAI R", "MEN N", "MGN Q", "MGY G", "MHL L", "MHO M",
+ "MHS H", "MIS S", "MLE L", "MLY K", "MLZ K", "MME M",
+ "MNL L", "MNV V", "MPQ G", "MSE M", "MSO M", "MTY Y",
+ "MVA V", "NAL A", "NAM A", "NCY C", "NEM H", "NEP H",
+ "NFA F", "NIT A", "NLE L", "NLN L", "NNH R", "NPH C",
+ "NVA V", "OAS S", "OCS C", "OCY C", "OMT M", "OPR R",
+ "PAQ F", "PBB C", "PCA E", "PEC C", "PGY G", "PHA F",
+ "PHD N", "PHI F", "PHL F", "PHM F", "PLE L", "POM P",
+ "PPH F", "PPN F", "PR3 C", "PRR A", "PRS P", "PTH Y",
+ "PTR Y", "PYA A", "RON V", "S1H S", "SAC S", "SAH C",
+ "SAM M", "SBD A", "SBL A", "SCH C", "SCS C", "SCY C",
+ "SEB S", "SEG A", "SEP S", "SET S", "SHC C", "SHP G",
+ "SLZ K", "SMC C", "SME M", "SNC C", "SOC C", "STY Y",
+ "SVA S", "TBG G", "TCR W", "THC T", "THO T", "TIH A",
+ "TNB C", "TPL W", "TPO T", "TPQ F", "TRF W", "TRG K",
+ "TRN W", "TRO W", "TYB Y", "TYI Y", "TYN Y", "TYQ Y",
+ "TYS Y", "TYY A", "VAD V", "VAF V", "YOF Y", ""
+
+ };
+
+
+ void Get1LetterCode ( cpstr res3name, pstr res1code ) {
+ char r[4];
+ int i;
+
+ strncpy ( r,res3name,3 );
+ r[3] = char(0);
+ UpperCase ( r );
+ i = 0;
+ res1code[0] = char(1);
+ while (Res1Code[i][0]) {
+ if (Res1Code[i][0]==r[0]) {
+ if (Res1Code[i][1]==r[1]) {
+ if (Res1Code[i][2]==r[2]) {
+ res1code[0] = Res1Code[i][4];
+ break;
+ }
+ }
+ }
+ i++;
+ }
+
+ if (res1code[0]!=char(1)) res1code[1] = char(0);
+ else if (isNucleotide(r)) strcpy ( res1code,r );
+ else strcpy ( res1code,"X" );
+
+ }
+
+
+ void Get3LetterCode ( cpstr res1name, pstr res3code ) {
+ int i;
+
+ strcpy ( res3code,"XXX" );
+ i = 0;
+ while (Res1Code[i][0]) {
+ if (Res1Code[i][4]==res1name[0]) {
+ res3code[0] = Res1Code[i][0];
+ res3code[1] = Res1Code[i][1];
+ res3code[2] = Res1Code[i][2];
+ break;
+ }
+ i++;
+ }
+
+ }
+
+} // namespace mmdb
diff --git a/mmdb2/mmdb_tables.h b/mmdb2/mmdb_tables.h
new file mode 100644
index 0000000..f2d4d9d
--- /dev/null
+++ b/mmdb2/mmdb_tables.h
@@ -0,0 +1,127 @@
+// $Id: mmdb_tables.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_Tables <interface>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+//
+// **** Namespace : mmdb::
+//
+// **** Functions :
+// ~~~~~~~~~~~
+//
+// **** Constants : AName ( array of 2-character atom names )
+// ~~~~~~~~~~~ HAName ( array of 2=character heteroatom names )
+// RName ( 3-characters amino acid names )
+// RName1 ( 1-characters amino acid names )
+//
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_Tables__
+#define __MMDB_Tables__
+
+#include "mmdb_mattype.h"
+
+namespace mmdb {
+
+ // =================================================================
+
+ const int nElementNames = 117;
+ const int nElementMetals = 91;
+ const int nHydAtomNames = 14;
+
+ extern cpstr const ElementName [nElementNames];
+ extern cpstr const ElementMetal [nElementMetals];
+ extern cpstr const HydAtomName [nHydAtomNames];
+ extern realtype const MolecWeight [nElementNames];
+ extern realtype const CovalentRadius[nElementNames];
+ extern realtype const VdWaalsRadius [nElementNames];
+ extern realtype const IonicRadius [nElementNames];
+
+ extern bool isMetal ( cpstr element );
+
+ const int ELEMENT_UNKNOWN = -1;
+
+ extern int getElementNo ( cpstr element );
+ extern realtype getMolecWeight ( cpstr element );
+ extern realtype getCovalentRadius ( cpstr element );
+ extern realtype getVdWaalsRadius ( cpstr element );
+
+ const int nResNames = 26;
+
+ extern cpstr const ResidueName [nResNames];
+ extern char const ResidueName1[nResNames];
+
+ extern int getResidueNo ( cpstr resName );
+
+ const realtype NAvogadro = 6.02214129e23;
+
+ const int nSolventNames = 12;
+ const int nAminoacidNames = 23;
+ const int nNucleotideNames = 24;
+
+ DefineStructure(AAProperty);
+
+ struct AAProperty {
+ char name[4];
+ realtype hydropathy;
+ realtype charge;
+ realtype relSolvEnergy;
+ };
+
+ extern AAProperty const AAProperties[nAminoacidNames];
+ extern int const AASimilarity[nAminoacidNames][nAminoacidNames];
+
+ extern int GetAAPIndex ( cpstr resName ); // 0..nAminoacidNames-1
+ extern realtype GetAAHydropathy ( cpstr resName ); // -4.5...+4.5
+ extern realtype GetAACharge ( cpstr resName );
+ extern realtype GetAASolvationEnergy ( cpstr resName );
+ extern int GetAASimilarity ( cpstr resName1,
+ cpstr resName2 ); // 0..5
+
+ extern cpstr const StdSolventName[nSolventNames];
+ extern cpstr const NucleotideName[nNucleotideNames];
+
+ extern bool isSolvent ( cpstr resName );
+ extern bool isAminoacid ( cpstr resName );
+ extern bool isNucleotide ( cpstr resName );
+ extern int isDNARNA ( cpstr resName ); // 0,1(DNA),2(RNA)
+ extern bool isSugar ( cpstr resName );
+
+ extern void Get1LetterCode ( cpstr res3name, pstr res1code );
+ extern void Get3LetterCode ( cpstr res1name, pstr res3code );
+
+} // namespace mmdb
+
+#endif
+
diff --git a/mmdb2/mmdb_title.cpp b/mmdb2/mmdb_title.cpp
new file mode 100644
index 0000000..b16f6e1
--- /dev/null
+++ b/mmdb2/mmdb_title.cpp
@@ -0,0 +1,2662 @@
+// $Id: mmdb_title.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 21.11.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_Title <implementation>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::TitleContainer (container of title classes)
+// ~~~~~~~~~ mmdb::ObsLine
+// mmdb::TitleLine
+// mmdb::Caveat
+// mmdb::Compound
+// mmdb::Source
+// mmdb::KeyWords
+// mmdb::ExpData
+// mmdb::MdlType
+// mmdb::Author
+// mmdb::RevData
+// mmdb::Supersede
+// mmdb::Journal
+// mmdb::Remark
+// mmdb::Biomolecule
+// mmdb::Title ( MMDB title section )
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "mmdb_title.h"
+#include "mmdb_cifdefs.h"
+
+namespace mmdb {
+
+ // ============== TitleContainer ====================
+
+ PContainerClass TitleContainer::MakeContainerClass ( int ClassID ) {
+ switch (ClassID) {
+ default :
+ case ClassID_Template : return
+ ClassContainer::MakeContainerClass(ClassID);
+ case ClassID_ObsLine : return new ObsLine ();
+ case ClassID_CAVEAT : return new Caveat ();
+ case ClassID_TitleLine : return new TitleLine();
+ case ClassID_Compound : return new Compound ();
+ case ClassID_Source : return new Source ();
+ case ClassID_ExpData : return new ExpData ();
+ case ClassID_Author : return new Author ();
+ case ClassID_RevData : return new RevData ();
+ case ClassID_Supersede : return new Supersede();
+ case ClassID_Journal : return new Journal ();
+ case ClassID_Remark : return new Remark ();
+ }
+ }
+
+ MakeStreamFunctions(TitleContainer)
+
+
+ // ================ ObsLine ===================
+
+ ObsLine::ObsLine() : ContainerClass() {
+ InitObsLine();
+ }
+
+ ObsLine::ObsLine ( cpstr S ) : ContainerClass() {
+ InitObsLine();
+ ConvertPDBASCII ( S );
+ }
+
+ ObsLine::ObsLine ( io::RPStream Object ) : ContainerClass(Object) {
+ InitObsLine();
+ }
+
+ ObsLine::~ObsLine() {}
+
+ void ObsLine::InitObsLine() {
+ int i;
+ strcpy ( repDate,"DD-MMM-YYYY" );
+ strcpy ( idCode, "----" );
+ for (i=0;i<8;i++)
+ strcpy ( rIdCode[i]," " );
+ }
+
+ void ObsLine::PDBASCIIDump ( pstr S, int N ) {
+ // makes the ASCII PDB OBSLTE line number N
+ // from the class' data
+ int i;
+ if (N==0) strcpy ( S,"OBSLTE " );
+ else sprintf ( S,"OBSLTE %2i",N+1 );
+ PadSpaces ( S,80 );
+ Date11to9 ( repDate,&(S[11]) );
+ strncpy ( &(S[21]),idCode,4 );
+ for (i=0;i<8;i++)
+ strncpy ( &(S[31+5*i]),rIdCode[i],4 );
+ }
+
+ void ObsLine::MakeCIF ( mmcif::PData CIF, int ) {
+ mmcif::PLoop Loop;
+ int RC,i,j;
+ char DateCIF[20];
+ RC = CIF->AddLoop ( CIFCAT_OBSLTE,Loop );
+ if (RC!=mmcif::CIFRC_Ok) {
+ // the category was (re)created, provide tags
+ Loop->AddLoopTag ( CIFTAG_ID );
+ Loop->AddLoopTag ( CIFTAG_DATE );
+ Loop->AddLoopTag ( CIFTAG_REPLACE_PDB_ID );
+ Loop->AddLoopTag ( CIFTAG_PDB_ID );
+ }
+ Date11toCIF ( repDate,DateCIF );
+ for (i=0;i<8;i++) {
+ j = 0;
+ while (rIdCode[i][j] && (rIdCode[i][j]==' ')) j++;
+ if (rIdCode[i][j]) {
+ Loop->AddString ( pstr("OBSLTE") );
+ Loop->AddString ( DateCIF );
+ Loop->AddString ( idCode );
+ Loop->AddString ( rIdCode[i] );
+ }
+ }
+ }
+
+ ERROR_CODE ObsLine::ConvertPDBASCII ( cpstr S ) {
+ int i;
+ Date9to11 ( &(S[11]),repDate );
+ strncpy ( idCode,&(S[21]),4 );
+ idCode[4] = char(0);
+ for (i=0;i<8;i++) {
+ strncpy ( rIdCode[i],&(S[31+i*5]),4 );
+ rIdCode[i][4] = char(0);
+ }
+ return Error_NoError;
+ }
+
+ ERROR_CODE ObsLine::GetCIF ( mmcif::PData CIF, int & n ) {
+ mmcif::PLoop Loop;
+ int i,RC;
+ pstr F,FDate,FID;
+ char DateCIF [20];
+ char DateCIF0[20];
+ IDCode idCode1;
+
+ Loop = CIF->GetLoop ( CIFCAT_OBSLTE );
+ if (!Loop) {
+ n = -1; // signal to finish processing of this structure
+ return Error_EmptyCIF;
+ }
+ i = 0;
+ do {
+ F = Loop->GetString ( CIFTAG_ID,n,RC );
+ if (RC) {
+ if (i==0) n = -1;
+ return Error_MissingCIFField;
+ }
+ if (F) {
+ if (!strcmp(F,"OBSLTE")) {
+ FDate = Loop->GetString ( CIFTAG_DATE,n,RC );
+ if ((!RC) && FDate)
+ strncpy ( DateCIF,FDate,15 );
+ else strcpy ( DateCIF,"YYYY-MMM-DD" );
+ FID = Loop->GetString ( CIFTAG_REPLACE_PDB_ID,n,RC );
+ if ((!RC) && FID)
+ strncpy ( idCode1,FID,sizeof(IDCode)-1 );
+ else idCode1[0] = char(0);
+ if (i==0) {
+ DateCIFto11 ( DateCIF,repDate );
+ DateCIF[11] = char(0);
+ strcpy ( idCode ,idCode1 );
+ strcpy ( DateCIF0,DateCIF );
+ } else if ((strcmp(DateCIF0,DateCIF)) ||
+ (strcmp(idCode,idCode1)))
+ return Error_MissingCIFField;
+ FID = Loop->GetString ( CIFTAG_PDB_ID,n,RC );
+ if ((!RC) && FID)
+ strncpy ( rIdCode[i],FID,sizeof(IDCode)-1 );
+ else rIdCode[i][0] = char(0);
+ Loop->DeleteField ( CIFTAG_ID ,n );
+ Loop->DeleteField ( CIFTAG_DATE ,n );
+ Loop->DeleteField ( CIFTAG_REPLACE_PDB_ID,n );
+ Loop->DeleteField ( CIFTAG_PDB_ID ,n );
+ i++;
+ }
+ }
+ n++;
+ } while (i<8);
+
+ return Error_NoError;
+
+ }
+
+ void ObsLine::Copy ( PContainerClass ObsLine ) {
+ int i;
+ strcpy ( repDate,PObsLine(ObsLine)->repDate );
+ strcpy ( idCode ,PObsLine(ObsLine)->idCode );
+ for (i=0;i<8;i++)
+ strcpy ( rIdCode[i],PObsLine(ObsLine)->rIdCode[i] );
+ }
+
+ void ObsLine::write ( io::RFile f ) {
+ int i;
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteTerLine ( repDate,false );
+ f.WriteTerLine ( idCode ,false );
+ for (i=0;i<8;i++)
+ f.WriteTerLine ( rIdCode[i],false );
+ }
+
+ void ObsLine::read ( io::RFile f ) {
+ int i;
+ byte Version;
+ f.ReadByte ( &Version );
+ f.ReadTerLine ( repDate,false );
+ f.ReadTerLine ( idCode ,false );
+ for (i=0;i<8;i++)
+ f.ReadTerLine ( rIdCode[i],false );
+ }
+
+ MakeStreamFunctions(ObsLine)
+
+
+ // =================== TitleLine ======================
+
+ TitleLine::TitleLine() : ContString() {
+ InitTitleLine();
+ }
+
+ TitleLine::TitleLine ( cpstr S ) : ContString() {
+ InitTitleLine();
+ ConvertPDBASCII ( S );
+ }
+
+ TitleLine::TitleLine ( io::RPStream Object ) : ContString(Object) {
+ InitTitleLine();
+ }
+
+ TitleLine::~TitleLine() {
+ }
+
+ void TitleLine::InitTitleLine() {
+ CreateCopy ( CIFCategory,CIFCAT_STRUCT );
+ CreateCopy ( CIFTag, CIFTAG_TITLE );
+ }
+
+ ERROR_CODE TitleLine::ConvertPDBASCII ( cpstr S ) {
+ if (strlen(S)>10)
+ CreateCopy ( Line,&(S[10]) );
+ else CreateCopy ( Line,pstr(" ") );
+ return Error_NoError;
+ }
+
+ void TitleLine::PDBASCIIDump ( pstr S, int N ) {
+ if (N==0) strcpy ( S,"TITLE " );
+ else sprintf ( S,"TITLE %2i",N+1 );
+ strcat ( S,Line );
+ }
+
+ void TitleLine::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ ContString::write ( f );
+ }
+
+ void TitleLine::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ ContString::read ( f );
+ }
+
+ MakeStreamFunctions(TitleLine)
+
+
+
+ // =================== Caveat ======================
+
+ Caveat::Caveat() : ContString() {
+ InitCaveat();
+ }
+
+ Caveat::Caveat ( cpstr S ) : ContString() {
+ InitCaveat();
+ ConvertPDBASCII ( S );
+ }
+
+ Caveat::Caveat ( io::RPStream Object ) : ContString(Object) {
+ InitCaveat();
+ }
+
+ Caveat::~Caveat() {}
+
+ void Caveat::InitCaveat() {
+ strcpy ( idCode,"----" );
+ CreateCopy ( CIFCategory,CIFCAT_DATABASE_PDB_CAVEAT );
+ CreateCopy ( CIFTag ,CIFTAG_TEXT );
+ }
+
+ ERROR_CODE Caveat::ConvertPDBASCII ( cpstr S ) {
+ if (strlen(S)>12) {
+ strncpy ( idCode,&(S[11]),4 );
+ idCode[4] = char(0);
+ if (strlen(S)>19)
+ CreateCopy ( Line,&(S[19]) );
+ else CreateCopy ( Line,pstr(" ") );
+ } else
+ CreateCopy ( Line,pstr(" ") );
+ return Error_NoError;
+ }
+
+ void Caveat::PDBASCIIDump ( pstr S, int N ) {
+ if (N==0) strcpy ( S,"CAVEAT " );
+ else sprintf ( S,"CAVEAT %2i ",N+1 );
+ strcat ( S,idCode );
+ strcat ( S," " );
+ strcat ( S,Line );
+ }
+
+ void Caveat::MakeCIF ( mmcif::PData CIF, int N ) {
+ char S[500];
+ CIF->PutString ( idCode,CIFCAT_DATABASE_PDB_CAVEAT,CIFTAG_ID,false );
+ strcpy ( S,"\n" );
+ strncat ( S,Line,sizeof(S)-2 );
+ S[sizeof(S)-1] = char(0);
+ CIF->PutString ( S,CIFCAT_DATABASE_PDB_CAVEAT,CIFTAG_TEXT,(N!=0) );
+ }
+
+/*
+ void Caveat::GetCIF1 ( mmcif::PData CIF, ERROR_CODE & Signal,
+ int & pos ) {
+ pstr F;
+ int RC;
+ F = CIF->GetString ( CIFCAT_DATABASE_PDB_CAVEAT,CIFTAG_ID,RC );
+ if ((!RC) && F) {
+ strncpy ( idCode,F,sizeof(IDCode) );
+ idCode[sizeof(IDCode)-1] = char(0);
+ }
+ ContString::GetCIF1 ( CIF,Signal,pos );
+ if (Signal<0)
+ CIF->DeleteField ( CIFCAT_DATABASE_PDB_CAVEAT,CIFTAG_ID );
+ }
+*/
+
+ void Caveat::Copy ( PContainerClass Caveat ) {
+ strcpy ( idCode,PCaveat(Caveat)->idCode );
+ ContString::Copy ( Caveat );
+ }
+
+ void Caveat::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteTerLine ( idCode,false );
+ ContString::write ( f );
+ }
+
+ void Caveat::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ f.ReadTerLine ( idCode,false );
+ ContString::read ( f );
+ }
+
+ MakeStreamFunctions(Caveat)
+
+
+
+ // =================== Compound ======================
+
+ Compound::Compound() : ContString() {
+ InitCompound();
+ }
+
+ Compound::Compound ( cpstr S ) : ContString() {
+ InitCompound();
+ ConvertPDBASCII ( S );
+ }
+
+ Compound::Compound ( io::RPStream Object ) : ContString(Object) {
+ InitCompound();
+ }
+
+ Compound::~Compound() {}
+
+ void Compound::InitCompound() {
+ CreateCopy ( CIFCategory,CIFCAT_STRUCT );
+ CreateCopy ( CIFTag ,CIFTAG_NDB_DESCRIPTOR );
+ }
+
+ ERROR_CODE Compound::ConvertPDBASCII ( cpstr S ) {
+ if (strlen(S)>10)
+ CreateCopy ( Line,&(S[10]) );
+ else CreateCopy ( Line,pstr(" ") );
+ return Error_NoError;
+ }
+
+ void Compound::PDBASCIIDump ( pstr S, int N ) {
+ if (N==0) strcpy ( S,"COMPND " );
+ else sprintf ( S,"COMPND %2i",N+1 );
+ strcat ( S,Line );
+ }
+
+ void Compound::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ ContString::write ( f );
+ }
+
+ void Compound::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ ContString::read ( f );
+ }
+
+ MakeStreamFunctions(Compound)
+
+
+
+ // =================== Source ======================
+
+ Source::Source() : ContString() {
+ InitSource();
+ }
+
+ Source::Source ( cpstr S ) : ContString() {
+ InitSource();
+ ConvertPDBASCII ( S );
+ }
+
+ Source::Source ( io::RPStream Object ) : ContString(Object) {
+ InitSource();
+ }
+
+ Source::~Source() {}
+
+ void Source::InitSource() {
+ CreateCopy ( CIFCategory,CIFCAT_STRUCT );
+ CreateCopy ( CIFTag ,CIFTAG_SOURCE );
+ }
+
+ ERROR_CODE Source::ConvertPDBASCII ( cpstr S ) {
+ if (strlen(S)>10)
+ CreateCopy ( Line,&(S[10]) );
+ else CreateCopy ( Line,pstr(" ") );
+ return Error_NoError;
+ }
+
+ void Source::PDBASCIIDump ( pstr S, int N ) {
+ if (N==0) strcpy ( S,"SOURCE " );
+ else sprintf ( S,"SOURCE %2i",N+1 );
+ strcat ( S,Line );
+ }
+
+ void Source::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ ContString::write ( f );
+ }
+
+ void Source::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ ContString::read ( f );
+ }
+
+ MakeStreamFunctions(Source)
+
+
+ // =================== KeyWords ======================
+
+ KeyWords::KeyWords() : io::Stream() {
+ Init();
+ }
+
+ KeyWords::KeyWords ( cpstr S ) : io::Stream() {
+ Init();
+ ConvertPDBASCII ( S );
+ }
+
+ KeyWords::KeyWords ( io::RPStream Object ) : io::Stream(Object) {
+ Init();
+ }
+
+ KeyWords::~KeyWords() {
+ Delete();
+ }
+
+ void KeyWords::Init() {
+ nKeyWords = 0;
+ KeyWord = NULL;
+ Cont = false;
+ }
+
+ void KeyWords::Delete() {
+ int i;
+ if (KeyWord) {
+ for (i=0;i<nKeyWords;i++)
+ if (KeyWord[i])
+ delete[] KeyWord[i];
+ delete[] KeyWord;
+ }
+ nKeyWords = 0;
+ KeyWord = NULL;
+ Cont = false;
+ }
+
+ int KeyWords::ConvertPDBASCII ( cpstr S ) {
+ // we anticipate that length of S is 80 characters
+ // -- pad with spaces if necessary
+ char L[85];
+ int i,k,m;
+ pstr * KW;
+
+ i = 10; // scan PDB line from ith character
+
+ k = nKeyWords;
+ if (!Cont) k++; // 1st keyword does not continue from previous line
+ m = 0;
+ while (S[i] && (i<70)) {
+ if (S[i]==',') k++; // count keywords
+ if (S[i]!=' ') m++; // count non-spaces to see if the line is empty
+ i++;
+ }
+
+ if (m==0) return 0; // empty line
+
+ KW = new pstr[k];
+ if (KeyWord) {
+ for (i=0;i<nKeyWords;i++)
+ KW[i] = KeyWord[i];
+ delete[] KeyWord;
+ }
+ for (i=nKeyWords;i<k;i++)
+ KW[i] = NULL; // null new pointers
+ KeyWord = KW;
+
+ i = 10;
+ if (Cont) nKeyWords--;
+ while (S[i] && (i<70)) {
+ while ((S[i]==' ') && (i<70)) i++; // skip leading spaces
+ if (Cont) {
+ strcpy ( L," " );
+ m = 1;
+ } else
+ m = 0;
+ while (S[i] && (S[i]!=',') && (i<70))
+ L[m++] = S[i++];
+ m--;
+ while ((m>0) && (L[m]==' ')) m--; // remove padding spaces
+ m++;
+ L[m] = char(0);
+ if (Cont) CreateConcat ( KeyWord[nKeyWords],L );
+ else CreateCopy ( KeyWord[nKeyWords],L );
+ if (S[i]==',') {
+ i++;
+ Cont = false;
+ } else
+ Cont = true;
+ nKeyWords++;
+ }
+
+ return 0;
+
+ }
+
+ void KeyWords::PDBASCIIDump ( io::RFile f ) {
+ int N,i,k,m1,m2,ms;
+ char S[85];
+ char c;
+ if (KeyWord) {
+ N = 0;
+ i = 0;
+ while (i<nKeyWords) {
+ if (N==0) strcpy ( S,"KEYWDS " );
+ else sprintf ( S,"KEYWDS %2i ",N+1 );
+ do {
+ while ((i<nKeyWords) && (!KeyWord[i])) i++;
+ if (i<nKeyWords) {
+ m1 = 0;
+ while (KeyWord[i][m1]) {
+ while (KeyWord[i][m1]==' ') m1++;
+ m2 = m1;
+ ms = -1;
+ while ((KeyWord[i][m2]) && ((m2-m1)<58)) {
+ if (KeyWord[i][m2]==' ') ms = m2;
+ m2++;
+ }
+ if ((ms<0) || ((m2-m1)<58)) ms = m2;
+ c = KeyWord[i][ms];
+ KeyWord[i][ms] = char(0);
+ strcat ( S,&(KeyWord[i][m1]) );
+ KeyWord[i][ms] = c;
+ m1 = ms;
+ if (c) {
+ PadSpaces ( S,80 );
+ f.WriteLine ( S );
+ N++;
+ sprintf ( S,"KEYWDS %2i ",N+1 );
+ }
+ }
+ i++;
+ if (i<nKeyWords) {
+ k = strlen(S) + strlen(KeyWord[i]) + 2;
+ if (i<nKeyWords)
+ strcat ( S,", " );
+ } else
+ k = 80;
+ } else
+ k = 80;
+ } while (k<70);
+ PadSpaces ( S,80 );
+ f.WriteLine ( S );
+ N++;
+ }
+ }
+ }
+
+ void KeyWords::MakeCIF ( mmcif::PData CIF ) {
+ int i,k;
+ char S[500];
+ strcpy ( S,"\n" );
+ for (i=0;i<nKeyWords;i++)
+ if (KeyWord[i]) {
+ k = strlen(KeyWord[i]);
+ if (strlen(S)+k>70) {
+ CIF->PutString ( S,CIFCAT_STRUCT_KEYWORDS,CIFTAG_TEXT,true );
+ if (k>(int)sizeof(S)) {
+ CIF->PutString ( KeyWord[i],CIFCAT_STRUCT_KEYWORDS,
+ CIFTAG_TEXT,true );
+ k = 0;
+ }
+ strcpy ( S,"\n" );
+ }
+ if (k>0) {
+ strcat ( S,KeyWord[i] );
+ if (i<nKeyWords-1) strcat ( S,", " );
+ }
+ }
+ if (strlen(S)>1)
+ CIF->PutString ( S,CIFCAT_STRUCT_KEYWORDS,CIFTAG_TEXT,true );
+ }
+
+ void KeyWords::GetCIF ( mmcif::PData CIF ) {
+ pstr F;
+ int i,j,k;
+ bool NB;
+ char c;
+ Delete();
+ F = CIF->GetString ( CIFCAT_STRUCT_KEYWORDS,CIFTAG_TEXT,i );
+ k = 0;
+ if ((!i) && F) {
+ i = 0;
+ NB = false;
+ while (F[i]) {
+ if (F[i]==',') {
+ nKeyWords++;
+ NB = false;
+ } else if (F[i]!=' ')
+ NB = true;
+ i++;
+ }
+ if (NB) nKeyWords++;
+ KeyWord = new pstr[nKeyWords];
+ i = 0;
+ while (F[i] && (k<nKeyWords)) {
+ while ((F[i]==' ') || (F[i]=='\n') || (F[i]=='\r')) i++;
+ j = i;
+ while (F[i] && (F[i]!=',')) i++;
+ c = F[i];
+ F[i] = char(0);
+ KeyWord[k] = NULL;
+ CreateCopy ( KeyWord[k],&(F[j]) );
+ j = 0;
+ while (KeyWord[k][j]) {
+ if ((KeyWord[k][j]=='\n') || (KeyWord[k][j]=='\r'))
+ KeyWord[k][j] = ' ';
+ j++;
+ }
+ F[i] = c;
+ k++;
+ if (F[i]) i++;
+ }
+ }
+ while (k<nKeyWords) KeyWord[k++] = NULL;
+ CIF->DeleteField ( CIFCAT_STRUCT_KEYWORDS,CIFTAG_TEXT );
+ }
+
+
+ void KeyWords::Copy ( PKeyWords KeyWords ) {
+ int i;
+ Delete();
+ nKeyWords = KeyWords->nKeyWords;
+ if (nKeyWords>0) {
+ KeyWord = new pstr[nKeyWords];
+ for (i=0;i<nKeyWords;i++) {
+ KeyWord[i] = NULL;
+ CreateCopy ( KeyWord[i],KeyWords->KeyWord[i] );
+ }
+ }
+ }
+
+ void KeyWords::write ( io::RFile f ) {
+ int i;
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &nKeyWords );
+ for (i=0;i<nKeyWords;i++)
+ f.CreateWrite ( KeyWord[i] );
+ }
+
+ void KeyWords::read ( io::RFile f ) {
+ int i;
+ byte Version;
+ Delete();
+ f.ReadByte ( &Version );
+ f.ReadInt ( &nKeyWords );
+ if (nKeyWords>0) {
+ KeyWord = new pstr[nKeyWords];
+ for (i=0;i<nKeyWords;i++) {
+ KeyWord[i] = NULL;
+ f.CreateRead ( KeyWord[i] );
+ }
+ }
+ }
+
+ MakeStreamFunctions(KeyWords)
+
+
+ // =================== ExpData ======================
+
+ ExpData::ExpData() : ContString() {
+ InitExpData();
+ }
+
+ ExpData::ExpData ( cpstr S ) : ContString() {
+ InitExpData();
+ ConvertPDBASCII ( S );
+ }
+
+ ExpData::ExpData ( io::RPStream Object ) : ContString(Object) {
+ InitExpData();
+ }
+
+ ExpData::~ExpData() {}
+
+ void ExpData::InitExpData() {
+ CreateCopy ( CIFCategory,CIFCAT_EXPTL );
+ CreateCopy ( CIFTag ,CIFTAG_METHOD );
+ }
+
+ ERROR_CODE ExpData::ConvertPDBASCII ( cpstr S ) {
+ if (strlen(S)>10)
+ CreateCopy ( Line,&(S[10]) );
+ else CreateCopy ( Line,pstr(" ") );
+ return Error_NoError;
+ }
+
+ void ExpData::PDBASCIIDump ( pstr S, int N ) {
+ if (N==0) strcpy ( S,"EXPDTA " );
+ else sprintf ( S,"EXPDTA %2i",N+1 );
+ strcat ( S,Line );
+ }
+
+ void ExpData::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ ContString::write ( f );
+ }
+
+ void ExpData::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ ContString::read ( f );
+ }
+
+ MakeStreamFunctions(ExpData)
+
+
+
+
+ // =================== MdlType ======================
+
+ MdlType::MdlType() : ContString() {
+ InitMdlType();
+ }
+
+ MdlType::MdlType ( cpstr S ) : ContString() {
+ InitMdlType();
+ ConvertPDBASCII ( S );
+ }
+
+ MdlType::MdlType ( io::RPStream Object ) : ContString(Object) {
+ InitMdlType();
+ }
+
+ MdlType::~MdlType() {}
+
+ void MdlType::InitMdlType() {
+ CreateCopy ( CIFCategory,CIFCAT_EXPTL );
+ CreateCopy ( CIFTag ,CIFTAG_METHOD );
+ }
+
+ ERROR_CODE MdlType::ConvertPDBASCII ( cpstr S ) {
+ if (strlen(S)>10)
+ CreateCopy ( Line,&(S[10]) );
+ else CreateCopy ( Line,pstr(" ") );
+ return Error_NoError;
+ }
+
+ void MdlType::PDBASCIIDump ( pstr S, int N ) {
+ if (N==0) strcpy ( S,"MDLTYP " );
+ else sprintf ( S,"MDLTYP %2i",N+1 );
+ strcat ( S,Line );
+ }
+
+ void MdlType::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ ContString::write ( f );
+ }
+
+ void MdlType::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ ContString::read ( f );
+ }
+
+ MakeStreamFunctions(MdlType)
+
+
+ // =================== Author ======================
+
+ Author::Author() : ContString() {
+ InitAuthor();
+ }
+
+ Author::Author ( cpstr S ) : ContString() {
+ InitAuthor();
+ ConvertPDBASCII ( S );
+ }
+
+ Author::Author ( io::RPStream Object ) : ContString(Object) {
+ InitAuthor();
+ }
+
+ Author::~Author() {}
+
+ void Author::InitAuthor() {
+ CreateCopy ( CIFCategory,CIFCAT_AUDIT_AUTHOR );
+ CreateCopy ( CIFTag ,CIFTAG_NAME );
+ }
+
+ ERROR_CODE Author::ConvertPDBASCII ( cpstr S ) {
+ if (strlen(S)>10)
+ CreateCopy ( Line,&(S[10]) );
+ else CreateCopy ( Line,pstr(" ") );
+ return Error_NoError;
+ }
+
+ void Author::PDBASCIIDump ( pstr S, int N ) {
+ if (N==0) strcpy ( S,"AUTHOR " );
+ else sprintf ( S,"AUTHOR %2i",N+1 );
+ strcat ( S,Line );
+ }
+
+ void Author::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ ContString::write ( f );
+ }
+
+ void Author::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ ContString::read ( f );
+ }
+
+ MakeStreamFunctions(Author)
+
+
+
+ // ================ RevData ===================
+
+ RevData::RevData() : ContainerClass() {
+ InitRevData();
+ }
+
+ RevData::RevData ( cpstr S ) : ContainerClass() {
+ InitRevData();
+ ConvertPDBASCII ( S );
+ }
+
+ RevData::RevData ( io::RPStream Object ) : ContainerClass(Object) {
+ InitRevData();
+ }
+
+ RevData::~RevData() {}
+
+ void RevData::InitRevData() {
+ int i;
+ modNum = 0;
+ strcpy ( modDate,"DD-MMM-YYYY" );
+ strcpy ( modId , "----" );
+ modType = -1;
+ for (i=0;i<4;i++)
+ strcpy ( record[i]," " );
+ Warning = 0;
+ }
+
+ void RevData::PDBASCIIDump ( pstr S, int N ) {
+ // makes the ASCII PDB REVDATA line number N
+ // from the class' data
+ int i;
+ if (N==0) sprintf ( S,"REVDAT %3i " ,modNum );
+ else sprintf ( S,"REVDAT %3i%2i",modNum,N+1 );
+ i = strlen(S);
+ while (i<80)
+ S[i++] = ' ';
+ S[i] = char(0);
+ Date11to9 ( modDate,&(S[13]) );
+ strncpy ( &(S[23]),modId,5 );
+ S[31] = char(modType+int('0'));
+ for (i=0;i<4;i++)
+ strncpy ( &(S[39+i*7]),record[i],6 );
+ }
+
+ void RevData::MakeCIF ( mmcif::PData CIF, int N ) {
+ mmcif::PLoop Loop;
+ int RC,i,j;
+ char DateCIF[20];
+ RC = CIF->AddLoop ( CIFCAT_DATABASE_PDB_REV,Loop );
+ if ((RC!=mmcif::CIFRC_Ok) || (N==0)) {
+ // the category was (re)created, privide tags
+ Loop->AddLoopTag ( CIFTAG_NUM );
+ Loop->AddLoopTag ( CIFTAG_DATE );
+ Loop->AddLoopTag ( CIFTAG_REPLACES );
+ Loop->AddLoopTag ( CIFTAG_MOD_TYPE );
+ Loop->AddLoopTag ( CIFTAG_RCSB_RECORD_REVISED_1 );
+ Loop->AddLoopTag ( CIFTAG_RCSB_RECORD_REVISED_2 );
+ Loop->AddLoopTag ( CIFTAG_RCSB_RECORD_REVISED_3 );
+ Loop->AddLoopTag ( CIFTAG_RCSB_RECORD_REVISED_4 );
+ }
+ Date11toCIF ( modDate,DateCIF );
+ Loop->AddInteger ( modNum );
+ Loop->AddString ( DateCIF );
+ Loop->AddString ( modId );
+ Loop->AddInteger ( modType );
+ for (i=0;i<4;i++) {
+ j = 0;
+ while (record[i][j] && (record[i][j]==' ')) j++;
+ if (record[i][j]) Loop->AddString ( record[i] );
+ else Loop->AddString ( NULL );
+ }
+
+ }
+
+ ERROR_CODE RevData::GetCIF ( mmcif::PData CIF, int & n ) {
+ mmcif::PLoop Loop;
+ int RC;
+ pstr F;
+
+ Loop = CIF->GetLoop ( CIFCAT_DATABASE_PDB_REV );
+ if (!Loop) {
+ n = -1;
+ return Error_EmptyCIF;
+ }
+
+ RC = Loop->GetInteger ( modNum,CIFTAG_NUM,n,true );
+ if (RC==mmcif::CIFRC_WrongIndex) {
+ n = -1;
+ return Error_EmptyCIF;
+ }
+ if (RC==mmcif::CIFRC_WrongFormat) {
+ sprintf ( CIFErrorLocation,"loop %s.%s row %i",
+ CIFCAT_DATABASE_PDB_REV,CIFTAG_NUM,n );
+ n = -Error_UnrecognizedInteger-1;
+ return Error_UnrecognizedInteger;
+ }
+
+ F = Loop->GetString ( CIFTAG_DATE,n,RC );
+ if ((!RC) && F) DateCIFto11 ( F,modDate );
+ F = Loop->GetString ( CIFTAG_REPLACES,n,RC );
+ if ((!RC) && F) strcpy ( modId,F );
+ RC = Loop->GetInteger ( modType,CIFTAG_MOD_TYPE,n,true );
+ if (RC==mmcif::CIFRC_WrongFormat) {
+ sprintf ( CIFErrorLocation,"loop %s.%s row %i",
+ CIFCAT_DATABASE_PDB_REV,CIFTAG_MOD_TYPE,n );
+ n = -Error_UnrecognizedInteger-1;
+ return Error_UnrecognizedInteger;
+ }
+
+ F = Loop->GetString ( CIFTAG_RCSB_RECORD_REVISED_1,n,RC );
+ if ((!RC) && F) strcpy ( record[0],F );
+ F = Loop->GetString ( CIFTAG_RCSB_RECORD_REVISED_2,n,RC );
+ if ((!RC) && F) strcpy ( record[1],F );
+ F = Loop->GetString ( CIFTAG_RCSB_RECORD_REVISED_3,n,RC );
+ if ((!RC) && F) strcpy ( record[2],F );
+ F = Loop->GetString ( CIFTAG_RCSB_RECORD_REVISED_4,n,RC );
+ if ((!RC) && F) strcpy ( record[3],F );
+
+ Loop->DeleteField ( CIFTAG_DATE ,n );
+ Loop->DeleteField ( CIFTAG_REPLACES ,n );
+ Loop->DeleteField ( CIFTAG_RCSB_RECORD_REVISED_1,n );
+ Loop->DeleteField ( CIFTAG_RCSB_RECORD_REVISED_2,n );
+ Loop->DeleteField ( CIFTAG_RCSB_RECORD_REVISED_3,n );
+ Loop->DeleteField ( CIFTAG_RCSB_RECORD_REVISED_4,n );
+
+ n++;
+
+ return Error_NoError;
+
+ }
+
+ ERROR_CODE RevData::ConvertPDBASCII ( cpstr S ) {
+ int i;
+ pstr endptr;
+ char N[20];
+ Warning = 0;
+ strncpy ( N,&(S[7]),3 );
+ N[3] = char(0);
+ modNum = mround(strtod(N,&endptr));
+ if (endptr==N) Warning |= REVDAT_WARN_MODNUM;
+ Date9to11 ( &(S[13]),modDate );
+ strncpy ( modId,&(S[23]),5 );
+ modId[5] = char(0);
+ modType = int(S[31]) - int('0');
+ if (modType>9) Warning |= REVDAT_WARN_MODTYPE;
+ for (i=0;i<4;i++) {
+ strncpy ( record[i],&(S[39+i*7]),6 );
+ record[i][6] = char(0);
+ }
+ return Error_NoError;
+ }
+
+ void RevData::Copy ( PContainerClass RevData ) {
+ int i;
+ modNum = PRevData(RevData)->modNum;
+ modType = PRevData(RevData)->modType;
+ strcpy ( modDate,PRevData(RevData)->modDate );
+ strcpy ( modId ,PRevData(RevData)->modId );
+ for (i=0;i<4;i++)
+ strcpy ( record[i],PRevData(RevData)->record[i] );
+ }
+
+ void RevData::write ( io::RFile f ) {
+ int i;
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &modNum );
+ f.WriteInt ( &modType );
+ f.WriteWord ( &Warning );
+ f.WriteTerLine ( modDate,false );
+ f.WriteTerLine ( modId ,false );
+ for (i=0;i<4;i++)
+ f.WriteTerLine ( record[i],false );
+ }
+
+ void RevData::read ( io::RFile f ) {
+ int i;
+ byte Version;
+ f.ReadByte ( &Version );
+ f.ReadInt ( &modNum );
+ f.ReadInt ( &modType );
+ f.ReadWord ( &Warning );
+ f.ReadTerLine ( modDate,false );
+ f.ReadTerLine ( modId ,false );
+ for (i=0;i<4;i++)
+ f.ReadTerLine ( record[i],false );
+ }
+
+ MakeStreamFunctions(RevData)
+
+
+
+ // ================ Supersede ===================
+
+ Supersede::Supersede() : ContainerClass() {
+ InitSupersede();
+ }
+
+ Supersede::Supersede ( cpstr S ) : ContainerClass() {
+ InitSupersede();
+ ConvertPDBASCII ( S );
+ }
+
+ Supersede::Supersede ( io::RPStream Object ) : ContainerClass(Object) {
+ InitSupersede();
+ }
+
+ Supersede::~Supersede() {}
+
+ void Supersede::InitSupersede() {
+ int i;
+ strcpy ( sprsdeDate,"DD-MMM-YYYY" );
+ strcpy ( idCode, "----" );
+ for (i=0;i<8;i++)
+ strcpy ( sIdCode[i]," " );
+ }
+
+ void Supersede::PDBASCIIDump ( pstr S, int N ) {
+ // makes the ASCII PDB OBSLTE line number N
+ // from the class' data
+ int i;
+ if (N==0) strcpy ( S,"SPRSDE " );
+ else sprintf ( S,"SPRSDE %2i",N+1 );
+ i = strlen(S);
+ while (i<80)
+ S[i++] = ' ';
+ S[i] = char(0);
+ if (N==0) {
+ Date11to9 ( sprsdeDate,&(S[11]) );
+ strncpy ( &(S[21]),idCode,4 );
+ }
+ for (i=0;i<8;i++)
+ strncpy ( &(S[31+5*i]),sIdCode[i],4 );
+ }
+
+ void Supersede::MakeCIF ( mmcif::PData CIF, int ) {
+ mmcif::PLoop Loop;
+ int RC,i,j;
+ char DateCIF[20];
+ RC = CIF->AddLoop ( CIFCAT_SPRSDE,Loop );
+ if (RC!=mmcif::CIFRC_Ok) {
+ // the category was (re)created, privide tags
+ Loop->AddLoopTag ( CIFTAG_ID );
+ Loop->AddLoopTag ( CIFTAG_DATE );
+ Loop->AddLoopTag ( CIFTAG_REPLACE_PDB_ID );
+ Loop->AddLoopTag ( CIFTAG_PDB_ID );
+ }
+ Date11toCIF ( sprsdeDate,DateCIF );
+ for (i=0;i<8;i++) {
+ j = 0;
+ while (sIdCode[i][j] && (sIdCode[i][j]==' ')) j++;
+ if (sIdCode[i][j]) {
+ Loop->AddString ( pstr("SPRSDE") );
+ Loop->AddString ( DateCIF );
+ Loop->AddString ( idCode );
+ Loop->AddString ( sIdCode[i] );
+ }
+ }
+ }
+
+ ERROR_CODE Supersede::ConvertPDBASCII ( cpstr S ) {
+ int i;
+ if (S[9]==' ') {
+ Date9to11 ( &(S[11]),sprsdeDate );
+ strncpy ( idCode,&(S[21]),4 );
+ idCode[4] = char(0);
+ }
+ for (i=0;i<8;i++) {
+ strncpy ( sIdCode[i],&(S[31+i*5]),4 );
+ sIdCode[i][4] = char(0);
+ }
+ return Error_NoError;
+ }
+
+ ERROR_CODE Supersede::GetCIF ( mmcif::PData CIF, int & n ) {
+ mmcif::PLoop Loop;
+ int i,RC;
+ pstr F,FDate,FID;
+ char DateCIF [20];
+ char DateCIF0[20];
+ IDCode idCode1;
+
+ Loop = CIF->GetLoop ( CIFCAT_SPRSDE );
+ if (!Loop) {
+ n = -1; // signal to finish processing of this structure
+ return Error_EmptyCIF;
+ }
+ i = 0;
+ do {
+ F = Loop->GetString ( CIFTAG_ID,n,RC );
+ if (RC) {
+ if (i==0) {
+ n = -1;
+ return Error_EmptyCIF;
+ } else
+ return Error_NoError;
+ }
+ if (F) {
+ if (!strcmp(F,"SPRSDE")) {
+ FDate = Loop->GetString ( CIFTAG_DATE,n,RC );
+ if ((!RC) && FDate)
+ strncpy ( DateCIF,FDate,15 );
+ else strcpy ( DateCIF,"YYYY-MMM-DD" );
+ FID = Loop->GetString ( CIFTAG_REPLACE_PDB_ID,n,RC );
+ if ((!RC) && FID)
+ strncpy ( idCode1,FID,sizeof(IDCode)-1 );
+ else idCode1[0] = char(0);
+ if (i==0) {
+ DateCIFto11 ( DateCIF,sprsdeDate );
+ DateCIF[11] = char(0);
+ strcpy ( idCode ,idCode1 );
+ strcpy ( DateCIF0,DateCIF );
+ } else if ((strcmp(DateCIF0,DateCIF)) ||
+ (strcmp(idCode,idCode1)))
+ return Error_NoError;
+ FID = Loop->GetString ( CIFTAG_PDB_ID,n,RC );
+ if ((!RC) && FID)
+ strncpy ( sIdCode[i],FID,sizeof(IDCode)-1 );
+ else sIdCode[i][0] = char(0);
+ Loop->DeleteField ( CIFTAG_ID ,n );
+ Loop->DeleteField ( CIFTAG_DATE ,n );
+ Loop->DeleteField ( CIFTAG_REPLACE_PDB_ID,n );
+ Loop->DeleteField ( CIFTAG_PDB_ID ,n );
+ i++;
+ }
+ }
+ n++;
+ } while (i<8);
+
+ return Error_NoError;
+
+ }
+
+ void Supersede::Copy ( PContainerClass Supersede ) {
+ int i;
+ strcpy ( sprsdeDate,PSupersede(Supersede)->sprsdeDate );
+ strcpy ( idCode ,PSupersede(Supersede)->idCode );
+ for (i=0;i<8;i++)
+ strcpy ( sIdCode[i],PSupersede(Supersede)->sIdCode[i] );
+ }
+
+ void Supersede::write ( io::RFile f ) {
+ int i;
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteTerLine ( sprsdeDate,false );
+ f.WriteTerLine ( idCode ,false );
+ for (i=0;i<8;i++)
+ f.WriteTerLine ( sIdCode[i],false );
+ }
+
+ void Supersede::read ( io::RFile f ) {
+ int i;
+ byte Version;
+ f.ReadByte ( &Version );
+ f.ReadTerLine ( sprsdeDate,false );
+ f.ReadTerLine ( idCode ,false );
+ for (i=0;i<8;i++)
+ f.ReadTerLine ( sIdCode[i],false );
+ }
+
+ MakeStreamFunctions(Supersede)
+
+
+ // =================== Journal ======================
+
+ Journal::Journal() : ContString() {
+ InitJournal();
+ }
+
+ Journal::Journal ( cpstr S ) : ContString() {
+ InitJournal();
+ ConvertPDBASCII ( S );
+ }
+
+ Journal::Journal ( io::RPStream Object ) : ContString(Object) {
+ InitJournal();
+ }
+
+ Journal::~Journal() {}
+
+ void Journal::InitJournal() {
+ CreateCopy ( CIFCategory,CIFCAT_CITATION );
+ CreateCopy ( CIFTag ,CIFTAG_TEXT );
+ }
+
+ ERROR_CODE Journal::ConvertPDBASCII ( cpstr S ) {
+ if (strlen(S)>10)
+ CreateCopy ( Line,&(S[10]) );
+ else CreateCopy ( Line,pstr(" ") );
+ return Error_NoError;
+ }
+
+ void Journal::PDBASCIIDump ( pstr S, int ) {
+ strcpy ( S,"JRNL " );
+ strcat ( S,Line );
+ }
+
+ void Journal::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ ContString::write ( f );
+ }
+
+ void Journal::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ ContString::read ( f );
+ }
+
+ MakeStreamFunctions(Journal)
+
+
+
+ // =================== Remark ======================
+
+ Remark::Remark() : ContainerClass() {
+ InitRemark();
+ }
+
+ Remark::Remark ( cpstr S ) : ContainerClass() {
+ InitRemark();
+ ConvertPDBASCII ( S );
+ }
+
+ Remark::Remark ( io::RPStream Object ) : ContainerClass(Object) {
+ InitRemark();
+ }
+
+ Remark::~Remark() {
+ if (remark) delete[] remark;
+ }
+
+ void Remark::InitRemark() {
+ remarkNum = 0;
+ remark = NULL;
+ }
+
+ ERROR_CODE Remark::ConvertPDBASCII ( cpstr S ) {
+ int i;
+ GetInteger ( remarkNum,&(S[7]),3 );
+ if (remarkNum==MinInt4) CreateCopy ( remark,S );
+ else if (strlen(S)>11) CreateCopy ( remark,&(S[11]) );
+ else CreateCopy ( remark,pstr(" ") );
+ i = strlen(remark)-1;
+ while ((i>0) && (remark[i]==' ')) i--;
+ remark[i+1] = char(0);
+ return Error_NoError;
+ }
+
+ void Remark::PDBASCIIDump ( pstr S, int ) {
+ if (remarkNum==MinInt4)
+ strcpy ( S,remark );
+ else {
+ strcpy ( S,"REMARK" );
+ PadSpaces ( S,80 );
+ PutInteger ( &(S[7]) ,remarkNum,3 );
+ strncpy ( &(S[11]),remark,IMin(68,strlen(remark)) );
+ }
+ }
+
+ void Remark::MakeCIF ( mmcif::PData CIF, int N ) {
+ mmcif::PLoop Loop;
+ int RC;
+ RC = CIF->AddLoop ( CIFCAT_NDB_DATABASE_REMARK,Loop );
+ if ((RC!=mmcif::CIFRC_Ok) || (N==0)) {
+ // the category was (re)created, privide tags
+ Loop->AddLoopTag ( CIFTAG_ID );
+ Loop->AddLoopTag ( CIFTAG_TEXT );
+ }
+ if (remarkNum==MinInt4) Loop->AddString ( NULL );
+ else Loop->AddInteger ( remarkNum );
+ Loop->AddString ( remark );
+ }
+
+ ERROR_CODE Remark::GetCIF ( mmcif::PData CIF, int & n ) {
+ mmcif::PLoop Loop;
+ int RC;
+
+ Loop = CIF->GetLoop ( CIFCAT_NDB_DATABASE_REMARK );
+ if (!Loop) {
+ n = -1;
+ return Error_EmptyCIF;
+ }
+ if (n>=Loop->GetLoopLength() ) {
+ n = -1;
+ return Error_EmptyCIF;
+ }
+
+ RC = Loop->GetInteger ( remarkNum,CIFTAG_ID,n,true );
+ if (RC==mmcif::CIFRC_WrongFormat) {
+ sprintf ( CIFErrorLocation,"loop %s.%s row %i",
+ CIFCAT_NDB_DATABASE_REMARK,CIFTAG_ID,n );
+ n = -Error_UnrecognizedInteger-1;
+ return Error_UnrecognizedInteger;
+ } else if (RC)
+ remarkNum = MinInt4;
+ Loop->GetString ( remark,CIFTAG_TEXT,n,true );
+
+ n++;
+
+ return Error_NoError;
+
+ }
+
+ void Remark::Copy ( PContainerClass RemarkClass ) {
+ remarkNum = PRemark(RemarkClass)->remarkNum;
+ CreateCopy ( remark,PRemark(RemarkClass)->remark );
+ }
+
+ void Remark::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &remarkNum );
+ f.CreateWrite ( remark );
+ }
+
+ void Remark::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ f.ReadInt ( &remarkNum );
+ f.CreateRead ( remark );
+ }
+
+ MakeStreamFunctions(Remark)
+
+
+ // ================= Biomolecule =====================
+
+ #define R350_ERRBIOMT (-3)
+ #define R350_ERROR (-2)
+ #define R350_END (-1)
+ #define R350_NONE 0
+ #define R350_BIOMOLECULE 1
+ #define R350_CHAINS 2
+ #define R350_BIOMT 3
+
+ void getRemarkKey ( RPRemark rem, int & lkey ) {
+ if (rem) {
+ if (rem->remarkNum!=350) lkey = R350_END;
+ else if (rem->remark) {
+ if (strcasestr(rem->remark,"BIOMOLECULE:"))
+ lkey = R350_BIOMOLECULE;
+ else if (strcasestr(rem->remark,"CHAINS:"))
+ lkey = R350_CHAINS;
+ else if (strcasestr(rem->remark,"BIOMT1") ||
+ strcasestr(rem->remark,"BIOMT2") ||
+ strcasestr(rem->remark,"BIOMT3"))
+ lkey = R350_BIOMT;
+ else
+ lkey = R350_NONE;
+ }
+ }
+ }
+
+ int lookupRemarks ( int & i, RPRemark rem,
+ RTitleContainer Remark ) {
+ int l,lkey;
+
+ l = Remark.Length();
+ lkey = R350_NONE;
+ while ((i<l) && (lkey==R350_NONE)) {
+ getRemarkKey ( rem,lkey );
+ if (lkey==R350_NONE) {
+ i++;
+ rem = (PRemark)Remark.GetContainerClass ( i );
+ }
+ }
+
+ return lkey;
+
+ }
+
+
+
+ BMApply::BMApply() : io::Stream() {
+ InitBMApply();
+ }
+
+ BMApply::BMApply ( io::RPStream Object ) : io::Stream ( Object ) {
+ InitBMApply();
+ }
+
+ BMApply::~BMApply() {
+ FreeMemory();
+ }
+
+ void BMApply::InitBMApply() {
+ chain = NULL;
+ nChains = 0;
+ tm = NULL;
+ nMatrices = 0;
+ }
+
+ void BMApply::FreeMemory() {
+ if (chain) delete[] chain;
+ if (tm) delete[] tm;
+ chain = NULL;
+ nChains = 0;
+ tm = NULL;
+ nMatrices = 0;
+ }
+
+ int BMApply::addChains ( int & i, RPRemark rem,
+ RTitleContainer Remark ) {
+ PChainID ch1;
+ pstr p;
+ int l,lkey,nAdd,j;
+
+ l = Remark.Length();
+ lkey = R350_NONE;
+
+ while ((i<l) && (lkey==R350_NONE)) {
+
+ p = strcasestr ( rem->remark,"CHAINS:" );
+ if (p) p += 7;
+ else {
+ p = rem->remark;
+ while (*p==' ') p++;
+ if ((p[1]!=',') && (p[1]!=' ')) p = NULL;
+ }
+
+ if (p) {
+ nAdd = strlen(p)/2 + 3;
+ ch1 = chain;
+ chain = new ChainID[nChains+nAdd];
+ for (j=0;j<nChains;j++)
+ strcpy ( chain[j],ch1[j] );
+ if (ch1) delete[] ch1;
+
+ while (*p) {
+ while ((*p==' ') || (*p==',')) p++;
+ if (*p) {
+ if ((p[1]==',') || (p[1]==' ') || (p[1]==char(0))) {
+ chain[nChains][0] = *p;
+ chain[nChains][1] = char(0);
+ nChains++;
+ p++;
+ } else
+ break;
+ }
+ }
+ }
+
+ do {
+ i++;
+ if (i<l) {
+ rem = (PRemark)Remark.GetContainerClass ( i );
+ if (rem) {
+ if (rem->remarkNum!=350) lkey = R350_END;
+ else getRemarkKey ( rem,lkey );
+ }
+ } else
+ lkey = R350_END;
+ } while ((!rem) && (lkey==R350_NONE));
+
+ }
+
+ return lkey;
+
+ }
+
+ int getBIOMT ( RPRemark rem, int biomtNo, mat44 & t,
+ RTitleContainer Remark, int & i ) {
+ char PN[20];
+ pstr p1,p2;
+ int l,j,lkey;
+
+ sprintf ( PN,"BIOMT%1i",biomtNo );
+ p1 = strcasestr ( rem->remark,PN );
+ if (!p1) return R350_ERRBIOMT;
+
+ p1 += 6;
+ while (*p1==' ') p1++;
+ while (*p1 && (*p1!=' ')) p1++;
+
+ l = biomtNo - 1;
+ t[l][0] = strtod ( p1,&p2 );
+ if (p1==p2) return R350_ERRBIOMT;
+ t[l][1] = strtod ( p2,&p1 );
+ if (p1==p2) return R350_ERRBIOMT;
+ t[l][2] = strtod ( p1,&p2 );
+ if (p1==p2) return R350_ERRBIOMT;
+ t[l][3] = strtod ( p2,&p1 );
+ if (p1==p2) return R350_ERRBIOMT;
+
+ if (biomtNo==3) {
+ for (j=0;j<3;j++)
+ t[3][j] = 0.0;
+ t[3][3] = 1.0;
+ }
+
+ l = Remark.Length();
+ lkey = R350_BIOMT;
+ do {
+ i++;
+ if (i<l) {
+ rem = (PRemark)Remark.GetContainerClass ( i );
+ if (rem) {
+ if (rem->remarkNum!=350) lkey = R350_END;
+ else getRemarkKey ( rem,lkey );
+ }
+ } else
+ lkey = R350_END;
+ } while ((lkey==R350_NONE) || ((!rem) && (lkey==R350_BIOMT)));
+
+ return lkey;
+
+ }
+
+ int BMApply::addMatrices ( int & i, RPRemark rem,
+ RTitleContainer Remark ) {
+ pmat44 tm1;
+ int l,lkey,j,k1,k2,nAlloc;
+
+ l = Remark.Length();
+ lkey = R350_BIOMT;
+ nAlloc = nMatrices;
+
+ while ((i<l) && (lkey==R350_BIOMT)) {
+
+ if (nMatrices>=nAlloc) {
+ nAlloc = nMatrices + 10;
+ tm1 = tm;
+ tm = new mat44[nAlloc];
+ for (j=0;j<nMatrices;j++)
+ for (k1=0;k1<4;k1++)
+ for (k2=0;k2<4;k2++)
+ tm[j][k1][k2] = tm1[j][k1][k2];
+ if (tm1) delete[] tm1;
+ }
+
+ lkey = getBIOMT ( rem,1,tm[nMatrices],Remark,i );
+ if (lkey==R350_BIOMT)
+ lkey = getBIOMT ( rem,2,tm[nMatrices],Remark,i );
+ if (lkey==R350_BIOMT)
+ lkey = getBIOMT ( rem,3,tm[nMatrices],Remark,i );
+ nMatrices++;
+
+ }
+
+ return lkey;
+
+ }
+
+ void BMApply::Copy ( PBMApply BMA ) {
+ // if BMA is NULL, then empties the class
+ int i,j,k;
+
+ FreeMemory();
+
+ if (BMA) {
+
+ nChains = BMA->nChains;
+ if (nChains>0) {
+ chain = new ChainID[nChains];
+ for (i=0;i<nChains;i++)
+ strcpy ( chain[i],BMA->chain[i] );
+ }
+
+ nMatrices = BMA->nMatrices;
+ if (nMatrices>0) {
+ tm = new mat44[nMatrices];
+ for (i=0;i<nMatrices;i++)
+ for (j=0;j<4;j++)
+ for (k=0;k<4;k++)
+ tm[i][j][k] = BMA->tm[i][j][k];
+ }
+ }
+
+ }
+
+ void BMApply::write ( io::RFile f ) {
+ int i,j,k;
+ f.WriteInt ( &nChains );
+ for (i=0;i<nChains;i++)
+ f.WriteTerLine ( chain[i],false );
+ f.WriteInt ( &nMatrices );
+ for (i=0;i<nMatrices;i++)
+ for (j=0;j<3;j++)
+ for (k=0;k<4;k++)
+ f.WriteReal ( &(tm[i][j][k]) );
+ }
+
+ void BMApply::read ( io::RFile f ) {
+ int i,j,k;
+ FreeMemory();
+ f.ReadInt ( &nChains );
+ if (nChains>0) {
+ chain = new ChainID[nChains];
+ for (i=0;i<nChains;i++)
+ f.ReadTerLine ( chain[i],false );
+ }
+ f.ReadInt ( &nMatrices );
+ if (nMatrices>0) {
+ tm = new mat44[nMatrices];
+ for (i=0;i<nMatrices;i++) {
+ for (j=0;j<3;j++) {
+ for (k=0;k<4;k++)
+ f.ReadReal ( &(tm[i][j][k]) );
+ tm[i][3][j] = 0.0;
+ }
+ tm[i][3][3] = 1.0;
+ }
+ }
+ }
+
+ MakeStreamFunctions(BMApply)
+
+
+ Biomolecule::Biomolecule() : io::Stream() {
+ InitBiomolecule();
+ }
+
+ Biomolecule::Biomolecule ( io::RPStream Object )
+ : io::Stream ( Object ) {
+ InitBiomolecule();
+ }
+
+ Biomolecule::~Biomolecule() {
+ FreeMemory();
+ }
+
+ void Biomolecule::InitBiomolecule() {
+ bmApply = NULL;
+ nBMAs = 0;
+ }
+
+ void Biomolecule::FreeMemory() {
+ int i;
+ if (bmApply) {
+ for (i=0;i<nBMAs;i++)
+ if (bmApply[i]) delete bmApply[i];
+ delete[] bmApply;
+ bmApply = NULL;
+ }
+ nBMAs = 0;
+ }
+
+
+ PBMApply Biomolecule::addBMApply() {
+ PPBMApply bmA1;
+ int i;
+ bmA1 = bmApply;
+ bmApply = new PBMApply[nBMAs+1];
+ for (i=0;i<nBMAs;i++)
+ bmApply[i] = bmA1[i];
+ if (bmA1) delete[] bmA1;
+ bmApply[nBMAs] = new BMApply();
+ nBMAs++;
+ return bmApply[nBMAs-1];
+ }
+
+ int Biomolecule::Size() {
+ int i,k;
+ k = 0;
+ for (i=0;i<nBMAs;i++)
+ k += bmApply[i]->nChains*bmApply[i]->nMatrices;
+ return k;
+ }
+
+ bool Biomolecule::checkComposition ( PChainID chID, ivector occ,
+ ivector wocc, int n ) {
+ // chID[n] is list of chain IDs
+ // occ[n] is list of chain occurencies
+ // wocc[n] is working array
+ int i,j,k,k1;
+ bool cmp;
+
+ for (i=0;i<n;i++)
+ wocc[i] = 0;
+
+ cmp = true;
+
+ for (i=0;(i<nBMAs) && cmp;i++)
+ for (j=0;(j<bmApply[i]->nChains) && cmp;j++) {
+ k1 = -1;
+ for (k=0;(k<n) && (k1<0);k++)
+ if (!strcmp(chID[k],bmApply[i]->chain[j]))
+ k1 = k;
+ if (k1<0) cmp = false; // chain not found in the list
+ else wocc[k1] += bmApply[i]->nMatrices;
+ }
+
+ for (i=0;(i<n) && cmp;i++)
+ if (occ[i]!=wocc[i]) cmp = false;
+
+ return cmp;
+
+ }
+
+ void Biomolecule::Copy ( PBiomolecule B ) {
+ // if B is NULL, then empties the class
+ int i;
+
+ FreeMemory();
+
+ if (B) {
+
+ nBMAs = B->nBMAs;
+ if (nBMAs>0) {
+ bmApply = new PBMApply[nBMAs];
+ for (i=0;i<nBMAs;i++)
+ if (B->bmApply[i]) {
+ bmApply[i] = new BMApply();
+ bmApply[i]->Copy ( B->bmApply[i] );
+ } else
+ bmApply[i] = NULL;
+ }
+
+ }
+
+ }
+
+ void Biomolecule::write ( io::RFile f ) {
+ int i;
+ f.WriteInt ( &nBMAs );
+ for (i=0;i<nBMAs;i++)
+ StreamWrite ( f,bmApply[i] );
+ }
+
+ void Biomolecule::read ( io::RFile f ) {
+ int i;
+ FreeMemory();
+ f.ReadInt ( &nBMAs );
+ if (nBMAs>0) {
+ bmApply = new PBMApply[nBMAs];
+ for (i=0;i<nBMAs;i++) {
+ bmApply[i] = NULL;
+ StreamRead ( f,bmApply[i] );
+ }
+ }
+ }
+
+ MakeStreamFunctions(Biomolecule)
+
+
+ // ===================== Title =======================
+
+ Title::Title() : io::Stream() {
+ Init();
+ }
+
+ Title::Title ( io::RPStream Object ) : io::Stream(Object) {
+ Init();
+ }
+
+ void Title::Init() {
+
+ // Header data
+ classification = NULL;
+ depDate[0] = char(0);
+ idCode [0] = char(0);
+ resolution = -2.0;
+ col73 = false;
+
+ biomolecule = NULL;
+ nBiomolecules = 0;
+
+ }
+
+ Title::~Title() {
+ FreeMemory ( false );
+ }
+
+ void Title::FreeMemory ( bool keepBiomolecules ) {
+
+ if (classification) delete[] classification;
+ classification = NULL;
+ resolution = -2.0;
+
+ obsData .FreeContainer();
+ title .FreeContainer();
+ caveat .FreeContainer();
+ compound .FreeContainer();
+ source .FreeContainer();
+ keyWords .Delete ();
+ expData .FreeContainer();
+ mdlType .FreeContainer();
+ author .FreeContainer();
+ revData .FreeContainer();
+ supersede.FreeContainer();
+ journal .FreeContainer();
+ remark .FreeContainer();
+
+ col73 = false;
+
+ if (!keepBiomolecules)
+ FreeBiomolecules();
+
+ }
+
+ void Title::FreeBiomolecules() {
+ int i;
+ if (biomolecule) {
+ for (i=0;i<nBiomolecules;i++)
+ if (biomolecule[i]) delete biomolecule[i];
+ delete[] biomolecule;
+ biomolecule = NULL;
+ }
+ nBiomolecules = 0;
+ }
+
+
+ void Title::SetHeader ( cpstr Classification,
+ cpstr DepDate,
+ cpstr IDCode ) {
+ // fills the PDB file header
+ CreateCopy ( classification ,Classification );
+ strncpy ( depDate,DepDate,sizeof(depDate) );
+ strncpy ( idCode ,IDCode ,sizeof(idCode) );
+ depDate[sizeof(depDate)-1] = char(0);
+ idCode [sizeof(idCode) -1] = char(0);
+ }
+
+ ERROR_CODE Title::ConvertPDBString ( pstr PDBString ) {
+ // Interprets the ASCII PDB line belonging to the title section
+ // and fills the corresponding fields.
+ // Returns zero if the line was converted, otherwise returns a
+ // non-negative value of Error_XXXX.
+ // PDBString must be not shorter than 81 characters.
+ int i;
+ char c;
+ PContainerClass ContainerClass;
+
+ // pad input line with spaces, if necessary
+ PadSpaces ( PDBString,80 );
+
+ if (!strncmp(PDBString,"HEADER",6)) {
+
+ i = 49;
+ while ((i>=10) && (PDBString[i]==' ')) i--;
+ i++;
+ c = PDBString[i];
+ PDBString[i] = char(0);
+ CreateCopy ( classification,&(PDBString[10]) );
+ PDBString[i] = c;
+
+ Date9to11 ( &(PDBString[50]),depDate );
+
+ strncpy ( idCode,&(PDBString[62]),4 );
+ idCode[4] = char(0);
+
+ } else if (!strncmp(PDBString,"OBSLTE",6)) {
+
+ ContainerClass = new ObsLine(PDBString);
+ obsData.AddData ( ContainerClass );
+
+ } else if (!strncmp(PDBString,"TITLE ",6)) {
+
+ ContainerClass = new TitleLine(PDBString);
+ title.AddData ( ContainerClass );
+
+ } else if (!strncmp(PDBString,"CAVEAT",6)) {
+
+ ContainerClass = new Caveat(PDBString);
+ caveat.AddData ( ContainerClass );
+
+ } else if (!strncmp(PDBString,"COMPND",6)) {
+
+ ContainerClass = new Compound(PDBString);
+ compound.AddData ( ContainerClass );
+
+ } else if (!strncmp(PDBString,"SOURCE",6)) {
+
+ ContainerClass = new Source(PDBString);
+ source.AddData ( ContainerClass );
+
+ } else if (!strncmp(PDBString,"KEYWDS",6)) {
+
+ keyWords.ConvertPDBASCII ( PDBString );
+
+ } else if (!strncmp(PDBString,"EXPDTA",6)) {
+
+ ContainerClass = new ExpData(PDBString);
+ expData.AddData ( ContainerClass );
+
+ } else if (!strncmp(PDBString,"MDLTYPE",6)) {
+
+ ContainerClass = new MdlType(PDBString);
+ mdlType.AddData ( ContainerClass );
+
+ } else if (!strncmp(PDBString,"AUTHOR",6)) {
+
+ ContainerClass = new Author(PDBString);
+ author.AddData ( ContainerClass );
+
+ } else if (!strncmp(PDBString,"REVDAT",6)) {
+
+ ContainerClass = new RevData(PDBString);
+ revData.AddData ( ContainerClass );
+
+ } else if (!strncmp(PDBString,"SPRSDE",6)) {
+
+ ContainerClass = new Supersede(PDBString);
+ supersede.AddData ( ContainerClass );
+
+ } else if (!strncmp(PDBString,"JRNL ",6)) {
+
+ ContainerClass = new Journal(PDBString);
+ journal.AddData ( ContainerClass );
+
+ } else if (!strncmp(PDBString,"REMARK",6)) {
+
+ ContainerClass = new Remark(PDBString);
+ remark.AddData ( ContainerClass );
+
+ } else if (!strncmp(PDBString,"SPLIT ",6)) {
+ // do nothing at the moment
+ } else
+ return Error_WrongSection;
+
+ // check for ID code in columns 73-80
+
+ if (!col73) {
+ if (('0'<=idCode[0]) && (idCode[0]<='9')) {
+ if (!strncasecmp(idCode,&(PDBString[72]),4))
+ col73 = true;
+ }
+ }
+
+ return Error_NoError;
+
+ }
+
+ realtype Title::GetResolution() {
+ // returns -1.0 if there is no resolution record in the file
+ PRemark rem;
+ pstr p,eptr;
+ int i,l;
+ if (resolution>-1.5) return resolution;
+ l = remark.Length();
+ for (i=0;(i<l) && (resolution<-1.5);i++) {
+ rem = (PRemark)remark.GetContainerClass ( i );
+ if (rem) {
+ if (rem->remarkNum==2) {
+ if (rem->remark) {
+ p = strcasestr ( rem->remark,"RESOLUTION" );
+ if (p) {
+ while ((*p) && (*p!=' ')) p++;
+ if (*p) {
+ resolution = strtod ( p,&eptr );
+ if ((resolution<0.0) || (eptr==p))
+ resolution = -1.0;
+ }
+ }
+ }
+ } else if (rem->remarkNum>2)
+ resolution = -1.0;
+ }
+ }
+ return resolution;
+ }
+
+ PBiomolecule Title::addBiomolecule() {
+ PPBiomolecule BM1;
+ int i;
+ BM1 = biomolecule;
+ biomolecule = new PBiomolecule[nBiomolecules+1];
+ for (i=0;i<nBiomolecules;i++)
+ biomolecule[i] = BM1[i];
+ if (BM1) delete[] BM1;
+ biomolecule[nBiomolecules] = new Biomolecule();
+ nBiomolecules++;
+ return biomolecule[nBiomolecules-1];
+ }
+
+ int Title::ParseBiomolecules() {
+ PRemark rem;
+ PBiomolecule BMol;
+ PBMApply BMA;
+ int i,l, lkey;
+
+ FreeBiomolecules();
+
+ l = remark.Length();
+ i = 0;
+ lkey = 0;
+ while ((i<l) && (!lkey)) {
+ rem = (PRemark)remark.GetContainerClass ( i );
+ if (rem) {
+ if (rem->remarkNum==350) lkey = 1;
+ else if (rem->remarkNum>350) lkey = -1;
+ }
+ if (!lkey) i++;
+ }
+
+ BMol = NULL;
+ BMA = NULL;
+
+ while (lkey>0) {
+
+ rem = (PRemark)remark.GetContainerClass ( i );
+ lkey = lookupRemarks ( i,rem,remark );
+
+ switch (lkey) {
+ case R350_BIOMOLECULE : BMol = addBiomolecule();
+ i++;
+ break;
+ case R350_CHAINS : if (BMol) {
+ BMA = BMol->addBMApply();
+ while (lkey==R350_CHAINS)
+ lkey = BMA->addChains(i,rem,remark);
+ } else
+ lkey = R350_ERROR;
+ break;
+ case R350_BIOMT : if (BMA)
+ lkey = BMA->addMatrices(i,rem,remark);
+ else
+ lkey = R350_ERROR;
+ break;
+ default : i++;
+ }
+
+ }
+
+ if (lkey<=R350_ERROR) {
+ FreeBiomolecules();
+ return lkey;
+ }
+
+ return nBiomolecules;
+
+ }
+
+ int Title::GetNofBiomolecules() {
+ return nBiomolecules;
+ }
+
+ void Title::GetBiomolecules ( PPBiomolecule & BM, int & nBMs ) {
+ BM = biomolecule;
+ nBMs = nBiomolecules;
+ }
+
+ PBiomolecule Title::GetBiomolecule ( int bmNo ) { // bmno=0,1,..
+ if ((0<=bmNo) && (bmNo<nBiomolecules))
+ return biomolecule[bmNo];
+ return NULL;
+ }
+
+
+ ERROR_CODE Title::GetCIF ( mmcif::PData CIF ) {
+ pstr S;
+ ERROR_CODE RC;
+
+ S = NULL;
+ CIF->GetDataName ( S,true );
+ if (!S) CIF->GetString ( S,CIFCAT_DATABASE,CIFTAG_ENTRY_ID,true );
+ if (!S) CIF->GetString ( S,CIFCAT_DATABASE,CIFTAG_CODE_NDB,true );
+ if (!S) CIF->GetString ( S,CIFCAT_DATABASE,CIFTAG_CODE_PDB,true );
+ if (S) {
+ strncpy ( idCode,S,sizeof(IDCode)-1 );
+ idCode[sizeof(IDCode)-1] = char(0);
+ delete[] S;
+ S = NULL;
+ CIF->DeleteField ( CIFCAT_DATABASE,CIFTAG_ENTRY_ID );
+ CIF->DeleteField ( CIFCAT_DATABASE,CIFTAG_CODE_NDB );
+ CIF->DeleteField ( CIFCAT_DATABASE,CIFTAG_CODE_PDB );
+ } else
+ idCode[0] = char(0);
+ CIF->GetString ( classification,CIFCAT_STRUCT_KEYWORDS,
+ CIFTAG_NDB_KEYWORDS,true );
+ CIF->GetString ( S,CIFCAT_DATABASE,CIFTAG_DATE_ORIGINAL,true );
+ if (S) {
+ DateCIFto11 ( S,depDate );
+ delete[] S;
+ S = NULL;
+ } else
+ depDate[0] = char(0);
+
+ if (CIF->GetReal(resolution,CIFCAT_REFINE,
+ CIFTAG_LS_D_RES_HIGH,false)!=mmcif::CIFRC_Ok)
+ resolution = -2.0;
+
+ obsData .GetCIF ( CIF,ClassID_ObsLine );
+ title .GetCIF ( CIF,ClassID_TitleLine );
+ caveat .GetCIF ( CIF,ClassID_CAVEAT );
+ compound.GetCIF ( CIF,ClassID_Compound );
+ source .GetCIF ( CIF,ClassID_Source );
+ keyWords.GetCIF ( CIF );
+ expData .GetCIF ( CIF,ClassID_ExpData );
+ mdlType .GetCIF ( CIF,ClassID_MdlType );
+ author .GetCIF ( CIF,ClassID_Author );
+ RC = revData.GetCIF ( CIF,ClassID_RevData );
+ if (RC!=Error_NoError) {
+ supersede.GetCIF ( CIF,ClassID_Supersede );
+ journal .GetCIF ( CIF,ClassID_Journal );
+ RC = remark.GetCIF ( CIF,ClassID_Remark );
+ }
+ return RC;
+
+ }
+
+ void Title::MakePDBHeaderString ( pstr PDBString ) {
+ // makes the ASCII PDB HEADER line from the class' data
+ int i;
+
+ if (classification) {
+
+ strcpy ( PDBString,"HEADER " );
+ strcat ( PDBString,classification );
+ i = strlen(PDBString);
+ while (i<80)
+ PDBString[i++] = ' ';
+ PDBString[IMin(i,80)] = char(0);
+ Date11to9 ( depDate,&(PDBString[50]) );
+ strncpy ( &(PDBString[62]),idCode,4 );
+
+ } else
+ strcpy ( PDBString,
+ "HEADER XXXXXXXXXXXXXXXXXXXXXXXXXXXX XX-XXX-XX ----" );
+
+ }
+
+ pstr Title::GetStructureTitle ( pstr & S ) {
+ // GetStructureTitle() returns the contents of TITLE record
+ // unfolded into single line. If Title is missing, returns
+ // contents of COMPND(:MOLECULE). If COMPND is missing, returns
+ // HEADER. If Header is missing, returns PDB code. If no PDB
+ // code is there, returns "Not available".
+ PTitleLine TLine;
+ PCompound CLine;
+ pstr p;
+ int i,cl,l;
+ bool B;
+
+ if (S) delete[] S;
+ S = NULL;
+
+ cl = title.Length();
+ if (cl>0) {
+ l = 0;
+ for (i=0;i<cl;i++) {
+ TLine = PTitleLine(title.GetContainerClass(i));
+ if (TLine) l += strlen_des(TLine->Line)+5;
+ }
+ S = new char[l];
+ S[0] = char(0);
+ for (i=0;i<cl;i++) {
+ TLine = PTitleLine(title.GetContainerClass(i));
+ if (TLine) {
+ if (i>0) strcat ( S," " );
+ strcat_des ( S,TLine->Line );
+ }
+ }
+ } else {
+ cl = compound.Length();
+ if (cl>0) {
+ l = 0;
+ p = NULL;
+ B = true;
+ for (i=0;(i<cl) && B;i++) {
+ CLine = PCompound(compound.GetContainerClass(i));
+ if (CLine) {
+ if (!p) {
+ p = strstr(CLine->Line,"MOLECULE:");
+ if (p) l += strlen_des(&(p[9]))+5;
+ } else {
+ p = strstr(CLine->Line,"MOLECULE:");
+ if (p)
+ l += strlen_des(&(p[9]))+5;
+ else {
+ p = strchr(CLine->Line,':');
+ if (!p) {
+ l += strlen_des(CLine->Line)+5;
+ p = CLine->Line;
+ } else
+ B = false;
+ }
+ }
+ }
+ }
+ if (l>0) {
+ S = new char[l];
+ S[0] = char(0);
+ p = NULL;
+ B = true;
+ for (i=0;(i<cl) && B;i++) {
+ CLine = PCompound(compound.GetContainerClass(i));
+ if (CLine) {
+ if (!p) {
+ p = strstr(CLine->Line,"MOLECULE:");
+ if (p) strcat_des ( S,&(p[9]) );
+ } else {
+ p = strstr(CLine->Line,"MOLECULE:");
+ if (p)
+ strcat_des ( S,&(p[9]) );
+ else {
+ p = strchr(CLine->Line,':');
+ if (!p) {
+ strcat_des ( S,CLine->Line );
+ p = CLine->Line;
+ } else
+ B = false;
+ }
+ }
+ l = strlen(S)-1;
+ if (S[l]==';') S[l] = char(0);
+ }
+ }
+ } else {
+ l = 0;
+ for (i=0;i<cl;i++) {
+ CLine = PCompound(compound.GetContainerClass(i));
+ if (CLine) l += strlen_des(CLine->Line)+5;
+ }
+ S = new char[l];
+ S[0] = char(0);
+ for (i=0;i<cl;i++) {
+ CLine = PCompound(compound.GetContainerClass(i));
+ if (CLine) {
+ if (i>0) strcat ( S," " );
+ strcat_des ( S,CLine->Line );
+ }
+ }
+ }
+ } else if (classification)
+ CreateCopy ( S,classification );
+ else if (idCode[0])
+ CreateCopy ( S,idCode );
+ else
+ CreateCopy ( S,pstr("Not available") );
+ }
+
+ if (!S[0]) CreateCopy ( S,pstr("Not available") );
+
+ return S;
+
+ }
+
+ void Title::PDBASCIIDump ( io::RFile f ) {
+ char PDBString[100];
+ if (classification) {
+ MakePDBHeaderString ( PDBString );
+ f.WriteLine ( PDBString );
+ }
+ obsData .PDBASCIIDump ( f );
+ title .PDBASCIIDump ( f );
+ caveat .PDBASCIIDump ( f );
+ compound .PDBASCIIDump ( f );
+ source .PDBASCIIDump ( f );
+ keyWords .PDBASCIIDump ( f );
+ expData .PDBASCIIDump ( f );
+ mdlType .PDBASCIIDump ( f );
+ author .PDBASCIIDump ( f );
+ revData .PDBASCIIDump ( f );
+ supersede.PDBASCIIDump ( f );
+ journal .PDBASCIIDump ( f );
+ remark .PDBASCIIDump ( f );
+ }
+
+
+ void Title::MakeCIF ( mmcif::PData CIF ) {
+ char DateCIF[20];
+
+ if (idCode[0]) {
+ CIF->PutDataName ( idCode );
+ CIF->PutString ( idCode, CIFCAT_DATABASE,CIFTAG_ENTRY_ID );
+ CIF->PutString ( idCode, CIFCAT_DATABASE,CIFTAG_CODE_NDB );
+ CIF->PutString ( idCode, CIFCAT_DATABASE,CIFTAG_CODE_PDB );
+ } else {
+ CIF->PutDataName ( pstr("") );
+ CIF->PutString ( NULL, CIFCAT_DATABASE,CIFTAG_ENTRY_ID );
+ CIF->PutString ( NULL, CIFCAT_DATABASE,CIFTAG_CODE_NDB );
+ CIF->PutString ( NULL, CIFCAT_DATABASE,CIFTAG_CODE_PDB );
+ }
+ CIF->PutString ( classification, CIFCAT_STRUCT_KEYWORDS,
+ CIFTAG_NDB_KEYWORDS );
+ if (depDate[0]) {
+ Date11toCIF ( depDate,DateCIF );
+ CIF->PutString ( DateCIF,CIFCAT_DATABASE,CIFTAG_DATE_ORIGINAL );
+ } else
+ CIF->PutString ( NULL,CIFCAT_DATABASE,CIFTAG_DATE_ORIGINAL );
+
+ CIF->PutReal ( resolution,CIFCAT_REFINE,CIFTAG_LS_D_RES_HIGH,3 );
+
+ obsData .MakeCIF ( CIF );
+ title .MakeCIF ( CIF );
+ caveat .MakeCIF ( CIF );
+ compound .MakeCIF ( CIF );
+ source .MakeCIF ( CIF );
+ keyWords .MakeCIF ( CIF );
+ expData .MakeCIF ( CIF );
+ mdlType .MakeCIF ( CIF );
+ author .MakeCIF ( CIF );
+ revData .MakeCIF ( CIF );
+ supersede.MakeCIF ( CIF );
+ journal .MakeCIF ( CIF );
+ remark .MakeCIF ( CIF );
+
+ }
+
+ void Title::Copy ( PTitle TS ) {
+ int i;
+
+ FreeBiomolecules();
+
+ if (TS) {
+
+ CreateCopy ( classification,TS->classification );
+ strcpy ( depDate ,TS->depDate );
+ strcpy ( idCode ,TS->idCode );
+ resolution = TS->resolution;
+
+ obsData .Copy ( &(TS->obsData) );
+ title .Copy ( &(TS->title) );
+ caveat .Copy ( &(TS->caveat) );
+ compound .Copy ( &(TS->compound) );
+ source .Copy ( &(TS->source) );
+ keyWords .Copy ( &(TS->keyWords) );
+ expData .Copy ( &(TS->expData) );
+ mdlType .Copy ( &(TS->mdlType) );
+ author .Copy ( &(TS->author) );
+ revData .Copy ( &(TS->revData) );
+ supersede.Copy ( &(TS->supersede) );
+ journal .Copy ( &(TS->journal) );
+ remark .Copy ( &(TS->remark) );
+
+ nBiomolecules = TS->nBiomolecules;
+ if (nBiomolecules>0) {
+ biomolecule = new PBiomolecule[nBiomolecules];
+ for (i=0;i<nBiomolecules;i++)
+ if (TS->biomolecule[i]) {
+ biomolecule[i] = new Biomolecule();
+ biomolecule[i]->Copy ( TS->biomolecule[i] );
+ } else
+ biomolecule[i] = NULL;
+ }
+
+ } else {
+
+ if (classification) delete[] classification;
+ classification = NULL;
+ resolution = -2.0;
+ obsData .FreeContainer();
+ title .FreeContainer();
+ caveat .FreeContainer();
+ compound .FreeContainer();
+ source .FreeContainer();
+ keyWords .Delete ();
+ expData .FreeContainer();
+ mdlType .FreeContainer();
+ author .FreeContainer();
+ revData .FreeContainer();
+ supersede.FreeContainer();
+ journal .FreeContainer();
+ remark .FreeContainer();
+
+ }
+
+ }
+
+ void Title::TrimInput ( pstr PDBString ) {
+ if (col73) {
+ if (!strncasecmp(idCode,&(PDBString[72]),4))
+ PDBString[72] = char(0);
+ }
+ PadSpaces ( PDBString,80 );
+ }
+
+ void Title::write ( io::RFile f ) {
+ // writes header to PDB binary file
+ int i;
+ byte Version=3;
+
+ f.WriteByte ( &Version );
+
+ // Header data
+ f.CreateWrite ( classification );
+ f.WriteTerLine ( depDate,false );
+ f.WriteTerLine ( idCode ,false );
+ f.WriteReal ( &resolution );
+
+ obsData .write ( f ); // Obsoletion data
+ title .write ( f ); // Title
+ caveat .write ( f ); // Error data
+ compound .write ( f ); // Compound
+ source .write ( f ); // Source
+ keyWords .write ( f ); // Key words
+ expData .write ( f ); // Experimental data
+ mdlType .write ( f ); // Model descriptions
+ author .write ( f ); // Author data
+ revData .write ( f ); // Revision data
+ supersede.write ( f ); // Supersede records
+ journal .write ( f ); // Journal records
+ remark .write ( f ); // Remarks
+
+ f.WriteInt ( &nBiomolecules );
+ for (i=0;i<nBiomolecules;i++)
+ StreamWrite ( f,biomolecule[i] );
+
+ }
+
+ void Title::read ( io::RFile f ) {
+ // reads header from PDB binary file
+ int i;
+ byte Version;
+
+ f.ReadByte ( &Version );
+
+ // Header data
+ f.CreateRead ( classification );
+ f.ReadTerLine ( depDate,false );
+ f.ReadTerLine ( idCode ,false );
+ if (Version>1)
+ f.ReadReal ( &resolution );
+ else
+ resolution = -2.0;
+
+ obsData .read ( f ); // Obsoletion data
+ title .read ( f ); // Title
+ caveat .read ( f ); // Error data
+ compound .read ( f ); // Compound
+ source .read ( f ); // Source
+ keyWords .read ( f ); // Key words
+ expData .read ( f ); // Experimental data
+ if (Version>2)
+ mdlType.read ( f ); // Model descriptions
+ author .read ( f ); // Author data
+ revData .read ( f ); // Revision data
+ supersede.read ( f ); // Supersede records
+ journal .read ( f ); // Journal records
+ remark .read ( f ); // Remarks
+
+ FreeBiomolecules();
+ if (Version>1) {
+ f.ReadInt ( &nBiomolecules );
+ if (nBiomolecules>0) {
+ biomolecule = new PBiomolecule[nBiomolecules];
+ for (i=0;i<nBiomolecules;i++) {
+ biomolecule[i] = NULL;
+ StreamRead ( f,biomolecule[i] );
+ }
+ }
+ }
+
+ }
+
+ MakeStreamFunctions(Title)
+
+} // namespace mmdb
+
+
+// ===================================================================
+
+/*
+void TestHeader() {
+PTitle Hdr;
+char S[81],S1[81];
+
+ Hdr = new Title();
+
+ Hdr->SetHeader ( pstr("MUSCLE PROTEIN"),pstr("02-JUN-1993"),pstr("1MYS") );
+ Hdr->MakePDBHeaderString ( S );
+ printf ( "1234567890123456789012345678901234567890"
+ "1234567890123456789012345678901234567890\n" );
+ printf ( S );
+ printf ( "\n" );
+
+ strcpy ( S,
+// 1234567890123456789012345678901234567890123456789012345678901234567890
+ "HEADER HYDROLASE (CARBOXYLIC ESTER) 07-APR-01 2PHI" );
+
+ Hdr->ConvertPDBString ( S );
+ Hdr->MakePDBHeaderString ( S1 );
+ printf ( "1234567890123456789012345678901234567890"
+ "1234567890123456789012345678901234567890\n" );
+ printf ( S1 );
+ printf ( "\n" );
+
+ Hdr->SetHeader (
+ pstr("MUSCLE PROTEIN;**A VERY LONG TITLE TEST;**ARBITRARY LENGTH"),
+ pstr("02-JUN-1993"),pstr("1MYS") );
+ Hdr->MakePDBHeaderString ( S );
+ printf ( "1234567890123456789012345678901234567890"
+ "1234567890123456789012345678901234567890\n" );
+ printf ( S );
+ printf ( "\n" );
+
+ delete Hdr;
+
+ printf ( " header deleted \n" );
+
+}
+
+void TestTitle() {
+// reads PDB title from file 'in.title'
+// and rewrites it into 'out.title' and 'abin.title'
+CFile f;
+char S[81];
+PTitle Title;
+
+ Title = new Title();
+
+ f.assign ( pstr("in.title"),true );
+ if (f.reset()) {
+ while (!f.FileEnd()) {
+ f.ReadLine ( S,sizeof(S) );
+ Title->ConvertPDBString ( S );
+ }
+ f.shut();
+ } else {
+ printf ( " Can't open input file 'in.title' \n" );
+ delete Title;
+ return;
+ }
+
+ f.assign ( pstr("out.title"),true );
+ if (f.rewrite()) {
+ Title->PDBASCIIDump ( f );
+ f.shut();
+ } else {
+ printf ( " Can't open output file 'out.title' \n" );
+ delete Title;
+ return;
+ }
+
+
+
+ f.assign ( pstr("mmdb.title.bin"),false );
+ if (f.rewrite()) {
+ Title->write ( f );
+ f.shut();
+ } else {
+ printf ( " Can't open binary file for writing.\n" );
+ delete Title;
+ return;
+ }
+
+ delete Title;
+ printf ( " Title deleted.\n" );
+
+ Title = new Title();
+ if (f.reset()) {
+ Title->read ( f );
+ f.shut();
+ } else {
+ printf ( " Can't open binary file for reading.\n" );
+ delete Title;
+ return;
+ }
+
+ f.assign ( pstr("abin.title"),true );
+ if (f.rewrite()) {
+ Title->PDBASCIIDump ( f );
+ f.shut();
+ } else {
+ printf ( " Can't open output file 'abin.title' \n" );
+ }
+
+ delete Title;
+
+}
+
+
+*/
diff --git a/mmdb2/mmdb_title.h b/mmdb2/mmdb_title.h
new file mode 100644
index 0000000..1e00d38
--- /dev/null
+++ b/mmdb2/mmdb_title.h
@@ -0,0 +1,696 @@
+// $Id: mmdb_title.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_Title <interface>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::TitleContainer (container of title classes)
+// ~~~~~~~~~ mmdb::ObsLine
+// mmdb::TitleLine
+// mmdb::Caveat
+// mmdb::Compound
+// mmdb::Source
+// mmdb::KeyWords
+// mmdb::ExpData
+// mmdb::MdlType
+// mmdb::Author
+// mmdb::RevData
+// mmdb::Supersede
+// mmdb::Journal
+// mmdb::Remark
+// mmdb::Biomolecule
+// mmdb::Title ( MMDB title section )
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_Title__
+#define __MMDB_Title__
+
+#include "mmdb_io_stream.h"
+#include "mmdb_defs.h"
+#include "mmdb_utils.h"
+#include "mmdb_mmcif_.h"
+
+namespace mmdb {
+
+ // ====================== TitleContainer =======================
+
+ DefineClass(TitleContainer);
+ DefineStreamFunctions(TitleContainer);
+
+ class TitleContainer : public ClassContainer {
+
+ public :
+
+ TitleContainer () : ClassContainer() {}
+ TitleContainer ( io::RPStream Object )
+ : ClassContainer ( Object ) {}
+ ~TitleContainer() {}
+
+ PContainerClass MakeContainerClass ( int ClassID );
+
+ };
+
+
+ // ================== ObsLine ========================
+
+ DefineClass(ObsLine);
+ DefineStreamFunctions(ObsLine);
+
+ class ObsLine : public ContainerClass {
+
+ public :
+
+ Date repDate; // date of replacement
+ IDCode idCode; // ID code of replaced entry
+ IDCode rIdCode[8]; // ID codes of entries that replaced this one
+
+ ObsLine ();
+ ObsLine ( cpstr S );
+ ObsLine ( io::RPStream Object );
+ ~ObsLine();
+
+ void PDBASCIIDump ( pstr S, int N );
+ void MakeCIF ( mmcif::PData CIF, int N );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ ERROR_CODE GetCIF ( mmcif::PData CIF, int & n );
+ CLASS_ID GetClassID () { return ClassID_ObsLine; }
+
+ void Copy ( PContainerClass ObsLine );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitObsLine();
+
+ };
+
+
+ // ==================== TitleLine =====================
+
+ DefineClass(TitleLine);
+ DefineStreamFunctions(TitleLine);
+
+ class TitleLine : public ContString {
+
+ public :
+
+ TitleLine ();
+ TitleLine ( cpstr S );
+ TitleLine ( io::RPStream Object );
+ ~TitleLine();
+
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ void PDBASCIIDump ( pstr S, int N );
+ bool PDBASCIIDump1 ( io::RFile ) { return false; }
+ CLASS_ID GetClassID () { return ClassID_TitleLine; }
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitTitleLine();
+
+ };
+
+
+ // ==================== Caveat =====================
+
+ DefineClass(Caveat);
+ DefineStreamFunctions(Caveat);
+
+ class Caveat : public ContString {
+
+ public :
+
+ IDCode idCode; // ID code of the entry
+
+ Caveat ();
+ Caveat ( cpstr S );
+ Caveat ( io::RPStream Object );
+ ~Caveat();
+
+ void PDBASCIIDump ( pstr S, int N );
+ bool PDBASCIIDump1 ( io::RFile ) { return false; }
+ void MakeCIF ( mmcif::PData CIF, int N );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+
+// virtual void GetCIF1 ( mmcif::PData CIF, ERROR_CODE & Signal,
+// int & pos );
+
+ CLASS_ID GetClassID () { return ClassID_CAVEAT; }
+
+ void Copy ( PContainerClass Caveat );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitCaveat();
+
+ };
+
+
+ // ==================== Compound =====================
+
+ DefineClass(Compound);
+ DefineStreamFunctions(Compound);
+
+ class Compound : public ContString {
+
+ public :
+
+ Compound ();
+ Compound ( cpstr S );
+ Compound ( io::RPStream Object );
+ ~Compound();
+
+ void PDBASCIIDump ( pstr S, int N );
+ bool PDBASCIIDump1 ( io::RFile ) { return false; }
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ CLASS_ID GetClassID () { return ClassID_Compound; }
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitCompound();
+
+ };
+
+
+ // ==================== Source =====================
+
+ DefineClass(Source);
+ DefineStreamFunctions(Source);
+
+ class Source : public ContString {
+
+ public :
+
+ Source ();
+ Source ( cpstr S );
+ Source ( io::RPStream Object );
+ ~Source();
+
+ void PDBASCIIDump ( pstr S, int N );
+ bool PDBASCIIDump1 ( io::RFile ) { return false; }
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ CLASS_ID GetClassID () { return ClassID_Source; }
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitSource();
+
+ };
+
+
+ // ==================== KeyWords =====================
+
+ DefineClass(KeyWords);
+ DefineStreamFunctions(KeyWords);
+
+ class KeyWords : public io::Stream {
+
+ public :
+ int nKeyWords; // number of key words
+ psvector KeyWord; // key word array
+
+ KeyWords ();
+ KeyWords ( cpstr S );
+ KeyWords ( io::RPStream Object );
+ ~KeyWords();
+
+ void Delete ();
+
+ void PDBASCIIDump ( io::RFile f );
+ void MakeCIF ( mmcif::PData CIF );
+
+ int ConvertPDBASCII ( cpstr S );
+ void GetCIF ( mmcif::PData CIF );
+
+ void Copy ( PKeyWords KeyWords );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+ bool Cont;
+
+ void Init();
+
+ };
+
+
+ // ==================== ExpData =====================
+
+ DefineClass(ExpData);
+ DefineStreamFunctions(ExpData);
+
+ class ExpData : public ContString {
+
+ public :
+
+ ExpData ();
+ ExpData ( cpstr S );
+ ExpData ( io::RPStream Object );
+ ~ExpData();
+
+ void PDBASCIIDump ( pstr S, int N );
+ bool PDBASCIIDump1 ( io::RFile ) { return false; }
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ CLASS_ID GetClassID () { return ClassID_ExpData; }
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitExpData();
+
+ };
+
+
+ // ==================== MdlType =====================
+
+ DefineClass(MdlType);
+ DefineStreamFunctions(MdlType);
+
+ class MdlType : public ContString {
+
+ public :
+
+ MdlType ();
+ MdlType ( cpstr S );
+ MdlType ( io::RPStream Object );
+ ~MdlType();
+
+ void PDBASCIIDump ( pstr S, int N );
+ bool PDBASCIIDump1 ( io::RFile ) { return false; }
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ CLASS_ID GetClassID () { return ClassID_MdlType; }
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitMdlType();
+
+ };
+
+
+ // ==================== Author =====================
+
+ DefineClass(Author);
+ DefineStreamFunctions(Author);
+
+ class Author : public ContString {
+
+ public :
+
+ Author ();
+ Author ( cpstr S );
+ Author ( io::RPStream Object );
+ ~Author();
+
+ void PDBASCIIDump ( pstr S, int N );
+ bool PDBASCIIDump1 ( io::RFile ) { return false; }
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ CLASS_ID GetClassID () { return ClassID_Author; }
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitAuthor();
+
+ };
+
+
+ // ==================== RevData =====================
+
+ DefineClass(RevData);
+ DefineStreamFunctions(RevData);
+
+ enum REVDAT_WARNING {
+ REVDAT_WARN_MODNUM = 0x00000001,
+ REVDAT_WARN_MODTYPE = 0x00000002
+ };
+
+ class RevData : public ContainerClass {
+
+ public :
+ int modNum;
+ Date modDate;
+ char modId[13];
+ int modType;
+ RecName record[4];
+ word Warning;
+
+ RevData ();
+ RevData ( cpstr S );
+ RevData ( io::RPStream Object );
+ ~RevData();
+
+ void PDBASCIIDump ( pstr S, int N );
+ void MakeCIF ( mmcif::PData CIF, int N );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ ERROR_CODE GetCIF ( mmcif::PData CIF, int & n );
+ CLASS_ID GetClassID () { return ClassID_RevData; }
+
+ void Copy ( PContainerClass RevData );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitRevData();
+
+ };
+
+
+ // ================== Supersede ========================
+
+ DefineClass(Supersede);
+ DefineStreamFunctions(Supersede);
+
+ class Supersede : public ContainerClass {
+
+ public :
+ Date sprsdeDate; // date of supersede
+ IDCode idCode; // ID code of the entry
+ IDCode sIdCode[8]; // ID codes of superseded entries
+
+ Supersede ();
+ Supersede ( cpstr S );
+ Supersede ( io::RPStream Object );
+ ~Supersede();
+
+ void PDBASCIIDump ( pstr S, int N );
+ void MakeCIF ( mmcif::PData CIF, int N );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ ERROR_CODE GetCIF ( mmcif::PData CIF, int & n );
+ CLASS_ID GetClassID () { return ClassID_Supersede; }
+
+ void Copy ( PContainerClass Supersede );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitSupersede();
+
+ };
+
+
+ // ==================== Journal =====================
+
+ DefineClass(Journal);
+ DefineStreamFunctions(Journal);
+
+ class Journal : public ContString {
+
+ public :
+
+ Journal ();
+ Journal ( cpstr S );
+ Journal ( io::RPStream Object );
+ ~Journal();
+
+ void PDBASCIIDump ( pstr S, int N );
+ bool PDBASCIIDump1 ( io::RFile ) { return false; }
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ CLASS_ID GetClassID () { return ClassID_Journal; }
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitJournal();
+
+ };
+
+
+ // ==================== Remark =====================
+
+ DefineClass(Remark);
+ DefineStreamFunctions(Remark);
+
+ class Remark : public ContainerClass {
+
+ public :
+
+ int remarkNum; // remark id
+ pstr remark; // remark line
+
+ Remark ();
+ Remark ( cpstr S );
+ Remark ( io::RPStream Object );
+ ~Remark();
+
+ void PDBASCIIDump ( pstr S, int N );
+ void MakeCIF ( mmcif::PData CIF, int N );
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ ERROR_CODE GetCIF ( mmcif::PData CIF, int & n );
+ CLASS_ID GetClassID () { return ClassID_Remark; }
+
+ void Copy ( PContainerClass RemarkClass );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+
+ void InitRemark();
+
+ };
+
+ // ================= Biomolecule =====================
+
+ DefineClass(BMApply);
+ DefineStreamFunctions(BMApply);
+
+ class BMApply : public io::Stream {
+
+ public :
+ PChainID chain;
+ int nChains;
+ pmat44 tm;
+ int nMatrices;
+
+ BMApply ();
+ BMApply ( io::RPStream Object );
+ ~BMApply();
+
+ void FreeMemory();
+
+ int addChains ( int & i, RPRemark rem, RTitleContainer Remark );
+ int addMatrices ( int & i, RPRemark rem, RTitleContainer Remark );
+
+ void Copy ( PBMApply BMA ); // if BMA is NULL, then empties
+ // the class
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+ void InitBMApply();
+
+ };
+
+
+ DefineClass(Biomolecule);
+ DefineStreamFunctions(Biomolecule);
+
+ class Biomolecule : public io::Stream {
+
+ public :
+ PPBMApply bmApply;
+ int nBMAs;
+
+ Biomolecule ();
+ Biomolecule ( io::RPStream Object );
+ ~Biomolecule();
+
+ void FreeMemory();
+
+ PBMApply addBMApply();
+
+ int Size();
+ bool checkComposition ( PChainID chID, ivector occ,
+ ivector wocc, int n );
+
+ void Copy ( PBiomolecule B ); // if B is NULL, then empties
+ // the class
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+ void InitBiomolecule();
+
+ };
+
+ // ================= Title =======================
+
+ DefineClass(Title);
+ DefineStreamFunctions(Title);
+
+ class Title : public io::Stream {
+
+ friend class Model;
+ friend class Chain;
+ friend class Root;
+
+ public :
+
+ Title ();
+ Title ( io::RPStream Object );
+ ~Title();
+
+ void FreeMemory ( bool keepBiomolecules );
+
+ // Fills the PDB file header
+ void SetHeader ( cpstr Classification, // any length is Ok
+ cpstr DepDate, // DD-MMM-YYYY
+ cpstr ID_Code ); // not more than 11 chars
+
+ // Interprets the ASCII PDB line belonging to the title section
+ // and fills the corresponding fields.
+ // Returns zero if the line was converted, otherwise returns a
+ // non-negative value of Error_XXXX.
+ // PDBString must be not shorter than 81 characters.
+ ERROR_CODE ConvertPDBString ( pstr PDBString );
+
+ // MakePDBString() makes the ASCII PDB HEADER line from the
+ // class data. PDBString must be not shorter than 81 characters.
+ void MakePDBHeaderString ( pstr PDBString );
+
+ // GetStructureTitle() returns the contents of TITLE record
+ // unfolded into single line. If Title is missing, returns
+ // contents of COMPND(:MOLECULE). If COMPND is missing, returns
+ // HEADER. If Header is missing, returns PDB code. If no PDB
+ // code is there, returns "Not available".
+ pstr GetStructureTitle ( pstr & S );
+
+ PTitleContainer GetObsData () { return &obsData; }
+ PTitleContainer GetCaveat () { return &caveat; }
+ PTitleContainer GetCompound() { return &compound; }
+ PTitleContainer GetSource () { return &source; }
+ PKeyWords GetKeyWords() { return &keyWords; }
+ PTitleContainer GetExpData () { return &expData; }
+ PTitleContainer GetMdlType () { return &mdlType; }
+ PTitleContainer GetRemarks () { return &remark; }
+ PTitleContainer GetJournal () { return &journal; }
+
+ realtype GetResolution(); // -1.0 mean no resolution record in file
+
+ int ParseBiomolecules(); // returns the number of biomolecules,
+ // -2 for general format error
+ // -3 for errors in BIOMT records
+
+ int GetNofBiomolecules();
+ void GetBiomolecules ( PPBiomolecule & BM, int & nBMs );
+ PBiomolecule GetBiomolecule ( int bmNo ); // bmno=0,1,..
+ // returns NULL if bmNo is incorrect
+
+ void PDBASCIIDump ( io::RFile f );
+ void MakeCIF ( mmcif::PData CIF );
+
+ // GetCIF(..) returns the same code as ConvertPDBString(..)
+ // save for Error_WrongSection
+ ERROR_CODE GetCIF ( mmcif::PData CIF );
+
+ inline pstr GetIDCode() { return idCode; }
+ inline bool GetCol73 () { return col73; }
+ void TrimInput ( pstr PDBString );
+
+ void Copy ( PTitle TS ); // if TS is NULL, then empties
+ // the class
+
+ void write ( io::RFile f ); // writes header to PDB binary file
+ void read ( io::RFile f ); // reads header from PDB binary file
+
+ protected :
+
+ // Header data
+ pstr classification; // classification of the molecule
+ Date depDate; // deposition date DD-MMM-YYYY
+ IDCode idCode; // unique PDB identifier
+ realtype resolution; // resolution
+ bool col73; // True if columns 73-80 contain PDB ID
+
+ TitleContainer obsData; // obsoletion data
+ TitleContainer title; // title data
+ TitleContainer caveat; // error data
+ TitleContainer compound; // compound data
+ TitleContainer source; // source
+ KeyWords keyWords; // key words
+ TitleContainer expData; // experimental data
+ TitleContainer mdlType; // model desctiptions
+ TitleContainer author; // author data
+ TitleContainer revData; // revision data
+ TitleContainer supersede; // supersede records
+ TitleContainer journal; // journal records
+ TitleContainer remark; // remark records
+
+ PPBiomolecule biomolecule;
+ int nBiomolecules;
+
+ void Init();
+ void FreeBiomolecules();
+
+ PBiomolecule addBiomolecule();
+
+ };
+
+ extern void TestHeader();
+ extern void TestTitle (); // reads PDB title from file 'in.title'
+ // and rewrites it into 'out.title' and
+ // 'abin.title'
+
+} // namespace mmdb
+
+
+#endif
+
diff --git a/mmdb2/mmdb_uddata.cpp b/mmdb2/mmdb_uddata.cpp
new file mode 100644
index 0000000..1bfcc09
--- /dev/null
+++ b/mmdb2/mmdb_uddata.cpp
@@ -0,0 +1,534 @@
+// $Id: mmdb_uddata.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDBF_UDData <implementation>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+//
+// **** Classes : mmdb::UDData ( user-defined data )
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include <string.h>
+
+#include "mmdb_uddata.h"
+
+namespace mmdb {
+
+ // ======================== UDRegister ==========================
+
+ #define nUDRTypes 5
+
+ UDRegister::UDRegister() : io::Stream() {
+ InitUDRegister();
+ }
+
+ UDRegister::UDRegister ( io::RPStream Object ) : io::Stream(Object) {
+ InitUDRegister();
+ }
+
+ UDRegister::~UDRegister() {
+ FreeUDRegister();
+ }
+
+ void UDRegister::InitUDRegister() {
+ int i;
+ for (i=0;i<nUDRTypes;i++) {
+ nIUDR[i] = 0;
+ nRUDR[i] = 0;
+ nSUDR[i] = 0;
+ IUDRegister[i] = NULL;
+ RUDRegister[i] = NULL;
+ SUDRegister[i] = NULL;
+ }
+ }
+
+ void UDRegister::FreeUDRegister() {
+ int i,j;
+
+ for (j=0;j<nUDRTypes;j++) {
+
+ if (IUDRegister[j]) {
+ for (i=0;i<nIUDR[j];i++)
+ if (IUDRegister[j][i]) delete[] IUDRegister[j][i];
+ delete[] IUDRegister[j];
+ IUDRegister[j] = NULL;
+ }
+ nIUDR[j] = 0;
+
+ if (RUDRegister[j]) {
+ for (i=0;i<nRUDR[j];i++)
+ if (RUDRegister[j][i]) delete[] RUDRegister[j][i];
+ delete[] RUDRegister[j];
+ RUDRegister[j] = NULL;
+ }
+ nRUDR[j] = 0;
+ if (SUDRegister[j]) {
+ for (i=0;i<nRUDR[j];i++)
+ if (SUDRegister[j][i]) delete[] SUDRegister[j][i];
+ delete[] SUDRegister[j];
+ SUDRegister[j] = NULL;
+ }
+ nSUDR[j] = 0;
+
+ }
+
+ }
+
+ int UDRegister::RegisterUDData ( psvector & UDRegister,
+ int & nUDR,
+ cpstr UDDataID ) {
+ psvector UDReg;
+ int i,UDDhandle,n;
+
+ n = -1;
+ UDDhandle = 0;
+ for (i=0;(i<nUDR) && (!UDDhandle);i++)
+ if (UDRegister[i]) {
+ if (!strcmp(UDDataID,UDRegister[i]))
+ UDDhandle = i+1;
+ } else
+ n = i;
+
+ if (!UDDhandle) {
+ if (n<0) {
+ UDReg = new pstr[nUDR+1];
+ for (i=0;i<nUDR;i++)
+ UDReg[i] = UDRegister[i];
+ UDReg[nUDR] = NULL;
+ if (UDRegister) delete[] UDRegister;
+ UDRegister = UDReg;
+ n = nUDR;
+ nUDR++;
+ }
+ CreateCopy ( UDRegister[n],UDDataID );
+ UDDhandle = n+1;
+ }
+
+ return UDDhandle;
+
+ }
+
+ static int UDRegisterFlag[nUDRTypes] = {
+ UDRF_ATOM,
+ UDRF_RESIDUE,
+ UDRF_CHAIN,
+ UDRF_MODEL,
+ UDRF_HIERARCHY
+ };
+
+
+ int UDRegister::RegisterUDInteger ( UDR_TYPE udr_type,
+ cpstr UDDataID ) {
+ if ((udr_type>=0) && (udr_type<nUDRTypes))
+ return RegisterUDData ( IUDRegister[udr_type],
+ nIUDR[udr_type],UDDataID ) |
+ UDRegisterFlag[udr_type];
+ else
+ return UDDATA_WrongUDRType;
+ }
+
+ int UDRegister::RegisterUDReal ( UDR_TYPE udr_type,
+ cpstr UDDataID ) {
+ if ((udr_type>=0) && (udr_type<nUDRTypes))
+ return RegisterUDData ( RUDRegister[udr_type],
+ nRUDR[udr_type],UDDataID ) |
+ UDRegisterFlag[udr_type];
+ else
+ return UDDATA_WrongUDRType;
+ }
+
+ int UDRegister::RegisterUDString ( UDR_TYPE udr_type,
+ cpstr UDDataID ) {
+ if ((udr_type>=0) && (udr_type<nUDRTypes))
+ return RegisterUDData ( SUDRegister[udr_type],
+ nSUDR[udr_type],UDDataID ) |
+ UDRegisterFlag[udr_type];
+ else
+ return UDDATA_WrongUDRType;
+ }
+
+ int UDRegister::GetUDDHandle ( UDR_TYPE udr_type,
+ cpstr UDDataID ) {
+ int i,UDDhandle;
+
+ if ((udr_type>=0) && (udr_type<nUDRTypes)) {
+
+ UDDhandle = 0;
+
+ for (i=0;(i<nIUDR[udr_type]) && (!UDDhandle);i++)
+ if (IUDRegister[udr_type][i]) {
+ if (!strcmp(UDDataID,IUDRegister[udr_type][i]))
+ UDDhandle = i+1;
+ }
+ for (i=0;(i<nRUDR[udr_type]) && (!UDDhandle);i++)
+ if (RUDRegister[udr_type][i]) {
+ if (!strcmp(UDDataID,RUDRegister[udr_type][i]))
+ UDDhandle = i+1;
+ }
+ for (i=0;(i<nSUDR[udr_type]) && (!UDDhandle);i++)
+ if (SUDRegister[udr_type][i]) {
+ if (!strcmp(UDDataID,SUDRegister[udr_type][i]))
+ UDDhandle = i+1;
+ }
+
+ if (UDDhandle) return UDDhandle | UDRegisterFlag[udr_type];
+ else return UDDhandle;
+
+ } else
+ return UDDATA_WrongUDRType;
+
+ }
+
+
+ void UDRegister::write ( io::RFile f ) {
+ int i,j;
+ byte Version=1;
+ f.WriteByte ( &Version );
+ for (j=0;j<nUDRTypes;j++) {
+ f.WriteInt ( &nIUDR[j] );
+ for (i=0;i<nIUDR[j];i++)
+ f.CreateWrite ( IUDRegister[j][i] );
+ f.WriteInt ( &nRUDR[j] );
+ for (i=0;i<nRUDR[j];i++)
+ f.CreateWrite ( RUDRegister[j][i] );
+ f.WriteInt ( &nSUDR[j] );
+ for (i=0;i<nSUDR[j];i++)
+ f.CreateWrite ( SUDRegister[j][i] );
+ }
+ }
+
+ void UDRegister::read ( io::RFile f ) {
+ int i,j;
+ byte Version;
+ f.ReadByte ( &Version );
+ FreeUDRegister();
+ for (j=0;j<nUDRTypes;j++) {
+ f.ReadInt ( &nIUDR[j] );
+ if (nIUDR[j]>0) {
+ IUDRegister[j] = new pstr[nIUDR[j]];
+ for (i=0;i<nIUDR[j];i++) {
+ IUDRegister[j][i] = NULL;
+ f.CreateRead ( IUDRegister[j][i] );
+ }
+ }
+ f.ReadInt ( &nRUDR[j] );
+ if (nRUDR[j]>0) {
+ RUDRegister[j] = new pstr[nRUDR[j]];
+ for (i=0;i<nRUDR[j];i++) {
+ RUDRegister[j][i] = NULL;
+ f.CreateRead ( RUDRegister[j][i] );
+ }
+ }
+ f.ReadInt ( &nSUDR[j] );
+ if (nSUDR[j]>0) {
+ SUDRegister[j] = new pstr[nSUDR[j]];
+ for (i=0;i<nSUDR[j];i++) {
+ SUDRegister[j][i] = NULL;
+ f.CreateRead ( SUDRegister[j][i] );
+ }
+ }
+ }
+ }
+
+
+ MakeStreamFunctions(UDRegister)
+
+
+
+ // ========================== UDData ============================
+
+ UDData::UDData() : Mask() {
+ InitUDData();
+ }
+
+ UDData::UDData ( io::RPStream Object ) : Mask(Object) {
+ InitUDData();
+ }
+
+ UDData::~UDData() {
+ FreeUDDMemory();
+ }
+
+ void UDData::InitUDData() {
+ IUData = NULL;
+ RUData = NULL;
+ SUData = NULL;
+ }
+
+ void UDData::FreeUDDMemory() {
+ int i,l;
+ FreeVectorMemory ( IUData,0 );
+ FreeVectorMemory ( RUData,0 );
+ if (SUData) {
+ l = getNofSUData();
+ for (i=0;i<=l;i++)
+ if (SUData[i]) delete[] SUData[i];
+ delete[] SUData;
+ }
+ IUData = NULL;
+ RUData = NULL;
+ SUData = NULL;
+ }
+
+ int UDData::getNofIUData() {
+ if (!IUData) return 0;
+ return IUData[0];
+ }
+
+ int UDData::getNofRUData() {
+ if (!RUData) return 0;
+ return mround(RUData[0]);
+ }
+
+ int UDData::getNofSUData() {
+ if (!SUData) return 0;
+ if (!SUData[0]) return 0;
+ return (int(SUData[0][0]) << 24) +
+ (int(SUData[0][1]) << 16) +
+ (int(SUData[0][2]) << 8) +
+ int(SUData[0][3]);
+ }
+
+ void UDData::setNofSUData ( int newN ) {
+ if (!SUData) return;
+ if (!SUData[0]) return;
+ SUData[0][3] = byte( newN & 0x000000FF);
+ SUData[0][2] = byte((newN & 0x0000FF00) >> 8);
+ SUData[0][1] = byte((newN & 0x00FF0000) >> 16);
+ SUData[0][0] = byte((newN & 0xFF000000) >> 24);
+ }
+
+
+ int UDData::putUDData ( int UDDhandle, int iudd ) {
+ ivector IUD;
+ int i,l,udh;
+ udh = UDDhandle & UDRF_MASK;
+ if (udh<1) return UDDATA_WrongHandle;
+ l = getNofIUData();
+ if (udh>l) {
+ GetVectorMemory ( IUD,udh+1,0 );
+ IUD[0] = udh;
+ for (i=1;i<=l;i++)
+ IUD[i] = IUData[i];
+ for (i=l+1;i<udh;i++)
+ IUD[i] = MinInt4;
+ FreeVectorMemory ( IUData,0 );
+ IUData = IUD;
+ }
+ IUData[udh] = iudd;
+ return UDDATA_Ok;
+ }
+
+ int UDData::putUDData ( int UDDhandle, realtype rudd ) {
+ rvector RUD;
+ int i,l,udh;
+ udh = UDDhandle & UDRF_MASK;
+ if (udh<1) return UDDATA_WrongHandle;
+ l = getNofRUData();
+ if (udh>l) {
+ GetVectorMemory ( RUD,udh+1,0 );
+ RUD[0] = udh;
+ for (i=1;i<=l;i++)
+ RUD[i] = RUData[i];
+ for (i=l+1;i<udh;i++)
+ RUD[i] = -MaxReal;
+ FreeVectorMemory ( RUData,0 );
+ RUData = RUD;
+ }
+ RUData[udh] = rudd;
+ return UDDATA_Ok;
+ }
+
+ int UDData::putUDData ( int UDDhandle, cpstr sudd ) {
+ psvector SUD;
+ int i,l,udh;
+ udh = UDDhandle & UDRF_MASK;
+ if (udh<1) return UDDATA_WrongHandle;
+ l = getNofSUData();
+ if (udh>l) {
+ if (l>0) {
+ GetVectorMemory ( SUD,udh+1,0 );
+ for (i=0;i<=l;i++)
+ SUD[i] = SUData[i];
+ for (i=l+1;i<=udh;i++)
+ SUD[i] = NULL;
+ FreeVectorMemory ( SUData,0 );
+ SUData = SUD;
+ } else {
+ GetVectorMemory ( SUData,udh+1,0 );
+ SUData[0] = new char[4];
+ for (i=1;i<=udh;i++)
+ SUData[i] = NULL;
+ }
+ setNofSUData ( udh );
+ }
+ CreateCopy ( SUData[udh],sudd );
+ return UDDATA_Ok;
+ }
+
+ int UDData::getUDData ( int UDDhandle, int & iudd ) {
+ int l,udh;
+ iudd = 0;
+ udh = UDDhandle & UDRF_MASK;
+ if (udh<1) return UDDATA_WrongHandle;
+ l = getNofIUData();
+ if (udh>l) return UDDATA_NoData;
+ iudd = IUData[udh];
+ if (iudd==MinInt4) return UDDATA_NoData;
+ return UDDATA_Ok;
+ }
+
+ int UDData::getUDData ( int UDDhandle, realtype & rudd ) {
+ int l,udh;
+ rudd = 0.0;
+ udh = UDDhandle & UDRF_MASK;
+ if (udh<1) return UDDATA_WrongHandle;
+ l = getNofRUData();
+ if (udh>l) return UDDATA_NoData;
+ rudd = RUData[udh];
+ if (rudd==-MaxReal) return UDDATA_NoData;
+ return UDDATA_Ok;
+ }
+
+ int UDData::getUDData ( int UDDhandle, pstr sudd, int maxLen ) {
+ int l,udh;
+ sudd[0] = char(0);
+ udh = UDDhandle & UDRF_MASK;
+ if (udh<1) return UDDATA_WrongHandle;
+ l = getNofSUData();
+ if (udh>l) return UDDATA_NoData;
+ if (!SUData[udh]) return UDDATA_NoData;
+ strcpy_n0 ( sudd,SUData[udh],maxLen-1 );
+ return UDDATA_Ok;
+ }
+
+ pstr UDData::getUDData ( int UDDhandle, int * retcode ) {
+ int l,udh;
+ udh = UDDhandle & UDRF_MASK;
+ if (udh<1) {
+ if (retcode) *retcode = UDDATA_WrongHandle;
+ return NULL;
+ }
+ l = getNofSUData();
+ if (udh>l) {
+ if (retcode) *retcode = UDDATA_NoData;
+ return NULL;
+ }
+ if (!SUData[udh]) {
+ if (retcode) *retcode = UDDATA_NoData;
+ return NULL;
+ }
+ if (retcode) *retcode = UDDATA_Ok;
+ return SUData[udh];
+ }
+
+ int UDData::getUDData ( int UDDhandle, pstr & sudd ) {
+ int l,udh;
+ udh = UDDhandle & UDRF_MASK;
+ if (udh<1) {
+ if (sudd) {
+ delete[] sudd;
+ sudd = NULL;
+ }
+ return UDDATA_WrongHandle;
+ }
+ l = getNofSUData();
+ if (udh>l) {
+ if (sudd) {
+ delete[] sudd;
+ sudd = NULL;
+ }
+ return UDDATA_NoData;
+ }
+ if (!SUData[udh]) {
+ if (sudd) {
+ delete[] sudd;
+ sudd = NULL;
+ }
+ return UDDATA_NoData;
+ }
+ CreateCopy ( sudd,SUData[udh] );
+ return UDDATA_Ok;
+ }
+
+
+ void UDData::write ( io::RFile f ) {
+ int i,l;
+ byte Version=1;
+
+ f.WriteByte ( &Version );
+
+ Mask::write ( f );
+
+ if (IUData) l = IUData[0];
+ else l = -1;
+ f.WriteVector ( IUData,l+1,0 );
+ if (RUData) l = mround(RUData[0]);
+ else l = -1;
+ f.WriteVector ( RUData,l+1,0 );
+ l = getNofSUData();
+ f.WriteInt ( &l );
+ for (i=1;i<=l;i++)
+ f.CreateWrite ( SUData[i] );
+ }
+
+ void UDData::read ( io::RFile f ) {
+ int i,l;
+ byte Version;
+
+ f.ReadByte ( &Version );
+
+ FreeUDDMemory();
+
+ Mask::read ( f );
+
+ f.CreateReadVector ( IUData,0 );
+ f.CreateReadVector ( RUData,0 );
+ f.ReadInt ( &l );
+ if (l>0) {
+ SUData = new pstr[l+1];
+ SUData[0] = new char[4];
+ setNofSUData ( l );
+ for (i=1;i<=l;i++) {
+ SUData[i] = NULL;
+ f.CreateRead ( SUData[i] );
+ }
+ }
+ }
+
+
+ MakeStreamFunctions(UDData)
+
+} // namespace mmdb
+
diff --git a/mmdb2/mmdb_uddata.h b/mmdb2/mmdb_uddata.h
new file mode 100644
index 0000000..c591891
--- /dev/null
+++ b/mmdb2/mmdb_uddata.h
@@ -0,0 +1,154 @@
+// $Id: mmdb_uddata.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDBF_UDData <interface>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+//
+// **** Classes : mmdb::UDData ( user-defined data )
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_UDData__
+#define __MMDB_UDData__
+
+#include "mmdb_mask.h"
+
+namespace mmdb {
+
+ // ======================= UDRegister =========================
+
+ enum UDR_TYPE {
+ UDR_ATOM = 0,
+ UDR_RESIDUE = 1,
+ UDR_CHAIN = 2,
+ UDR_MODEL = 3,
+ UDR_HIERARCHY = 4
+ };
+
+ enum UDD_FLAG {
+ UDRF_ATOM = 0x01000000,
+ UDRF_RESIDUE = 0x02000000,
+ UDRF_CHAIN = 0x04000000,
+ UDRF_MODEL = 0x08000000,
+ UDRF_HIERARCHY = 0x10000000,
+ UDRF_MASK = 0x00FFFFFF
+ };
+
+ DefineClass(UDRegister);
+ DefineStreamFunctions(UDRegister);
+
+ class UDRegister : public io::Stream {
+
+ public :
+
+ UDRegister ();
+ UDRegister ( io::RPStream Object );
+ ~UDRegister();
+
+ int RegisterUDInteger ( UDR_TYPE udr_type, cpstr UDDataID );
+ int RegisterUDReal ( UDR_TYPE udr_type, cpstr UDDataID );
+ int RegisterUDString ( UDR_TYPE udr_type, cpstr UDDataID );
+ int GetUDDHandle ( UDR_TYPE udr_type, cpstr UDDataID );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+ int nIUDR[5],nRUDR[5],nSUDR[5];
+ psvector IUDRegister[5];
+ psvector RUDRegister[5];
+ psvector SUDRegister[5];
+
+ void InitUDRegister ();
+ void FreeUDRegister ();
+ int RegisterUDData ( psvector & UDRegister,
+ int & nUDR,
+ cpstr UDDataID );
+
+ };
+
+
+ // ========================== UDData ===========================
+
+ enum UDDATA_RC {
+ UDDATA_Ok = 0,
+ UDDATA_WrongHandle = -1,
+ UDDATA_WrongUDRType = -2,
+ UDDATA_NoData = -3
+ };
+
+ DefineClass(UDData);
+ DefineStreamFunctions(UDData);
+
+ class UDData : public Mask {
+
+ friend class SelManager;
+
+ public :
+
+ UDData ();
+ UDData ( io::RPStream Object );
+ ~UDData();
+
+ protected :
+ ivector IUData;
+ rvector RUData;
+ psvector SUData;
+
+ void InitUDData ();
+ void FreeUDDMemory();
+ int getNofIUData ();
+ int getNofRUData ();
+ int getNofSUData ();
+ void setNofSUData ( int newN );
+
+ int putUDData ( int UDDhandle, int iudd );
+ int putUDData ( int UDDhandle, realtype rudd );
+ int putUDData ( int UDDhandle, cpstr sudd );
+
+ int getUDData ( int UDDhandle, int & iudd );
+ int getUDData ( int UDDhandle, realtype & rudd );
+ int getUDData ( int UDDhandle, pstr sudd, int maxLen );
+ pstr getUDData ( int UDDhandle, int * retcode=NULL );
+ int getUDData ( int UDDhandle, pstr & sudd );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ };
+
+} // namespace mmdb
+
+#endif
+
diff --git a/mmdb2/mmdb_utils.cpp b/mmdb2/mmdb_utils.cpp
new file mode 100644
index 0000000..a39f79b
--- /dev/null
+++ b/mmdb2/mmdb_utils.cpp
@@ -0,0 +1,1994 @@
+// $Id: mmdb_utils.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2008.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDBF_Utils <implementation>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+//
+// **** Classes : mmdb::ContainerClass ( containered class template )
+// ~~~~~~~~~ mmdb::ContString ( containered string )
+// mmdb::ClassContainer ( container of classes )
+// mmdb::AtomPath ( atom path ID )
+// mmdb::QuickSort ( quick sort of integers )
+//
+// **** Functions : Date9to11 ( DD-MMM-YY -> DD-MMM-YYYY )
+// ~~~~~~~~~~~ Date11to9 ( DD-MMM-YYYY -> DD-MMM-YY )
+// Date9toCIF ( DD-MMM-YY -> YYYY-MM-DD )
+// Date11toCIF( DD-MMM-YYYY -> YYYY-MM-DD )
+// DateCIFto9 ( YYYY-MM-DD -> DD-MMM-YY )
+// DateCIFto11( YYYY-MM-DD -> DD-MMM-YYYY )
+// GetInteger ( reads integer from a string )
+// GetReal ( reads real from a string )
+// GetIntIns ( reads integer and insert code )
+// PutInteger ( writes integer into a string )
+// PutRealF ( writes real in F-form into a string )
+// PutIntIns ( writes integer and insert code )
+// CIFGetInteger ( reads and deletes int from CIF )
+// CIFGetReal ( reads and deletes real from CIF )
+// CIFGetString ( reads and deletes string from CIF)
+// CIFGetInteger1 (reads and del-s int from CIF loop)
+// CIFGetReal1 (reads and del-s int from CIF loop)
+// Mat4Inverse ( inversion of 4x4 matrices )
+// GetErrorDescription (ascii line to an Error_XXXXX)
+// ParseAtomID ( parses atom ID line )
+// ParseResID ( parses residue ID line )
+// ParseAtomPath ( parses full atom path )
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include <string.h>
+#include <math.h>
+#include <stdlib.h>
+
+#include "mmdb_utils.h"
+#include "hybrid_36.h"
+
+namespace mmdb {
+
+ // ====================== Date functions =======================
+
+ static cpstr Month[12] = {
+ "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
+ "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
+ };
+
+ static cpstr nMonth[12] = {
+ "01", "02", "03", "04", "05", "06",
+ "07", "08", "09", "10", "11", "12"
+ };
+
+ void Date9to11 ( cpstr Date9, pstr Date11 ) {
+ // converts DD-MMM-YY to DD-MMM-YYYY
+ int i;
+ i = 0;
+ while ((i<12) && (strncmp(Month[i],&(Date9[3]),3))) i++;
+ if (i<12) { // DD-MMM-YY -> DD-MMM-YYYY
+ strncpy ( Date11,Date9,7 );
+ if (Date9[7]!='0') strncpy ( &(Date11[7]),"19",2 );
+ else strncpy ( &(Date11[7]),"20",2 );
+ strncpy ( &(Date11[9]),&(Date9[7]),2 );
+ Date11[2] = '-';
+ Date11[6] = '-';
+ Date11[11] = char(0);
+ } else { // DD-MM-YY -> DD-MMM-YYYY
+ strncpy ( Date11,Date9,3 );
+ i = 0;
+ while ((i<12) && (strncmp(nMonth[i],&(Date9[3]),2))) i++;
+ if (i<12) {
+ strncpy ( &(Date11[3]),Month[i],3 );
+ if (Date9[6]!='0') strncpy ( &(Date11[7]),"19",2 );
+ else strncpy ( &(Date11[7]),"20",2 );
+ strncpy ( &(Date11[9]),&(Date9[6]),2 );
+ Date11[2] = '-';
+ Date11[6] = '-';
+ Date11[11] = char(0);
+ } else
+ strcpy ( Date11," " );
+ }
+ }
+
+ void Date11to9 ( cpstr Date11, pstr Date9 ) {
+ // converts DD-MMM-YYYY to DD-MMM-YY
+ int i;
+ i = 0;
+ while ((i<12) && (strncmp(Month[i],&(Date11[3]),3))) i++;
+ if (i<12) { // DD-MMM-YYYY -> DD-MMM-YY
+ strncpy ( Date9,Date11,7 );
+ strncpy ( &(Date9[7]),&(Date11[9]),2 );
+ Date9[2] = '-';
+ Date9[6] = '-';
+ } else { // DD-MM-YYYY -> DD-MMM-YY
+ strncpy ( Date9,Date11,3 );
+ i = 0;
+ while ((i<12) && (strncmp(nMonth[i],&(Date11[3]),2))) i++;
+ if (i<12) {
+ strncpy ( &(Date9[3]),Month[i],3 );
+ strncpy ( &(Date9[7]),&(Date11[8]),2 );
+ Date9[2] = '-';
+ Date9[6] = '-';
+ } else
+ strcpy ( Date9," " );
+ }
+ }
+
+ void Date9toCIF ( cpstr Date9, pstr DateCIF ) {
+ // DD-MMM-YY -> YYYY-MM-DD )
+ int i;
+ i = 0;
+ while ((i<12) && (strncmp(Month[i],&(Date9[3]),3))) i++;
+ if (i<12) { // DD-MMM-YY -> YYYY-MM-DD
+ if (Date9[7]!='0') strcpy ( DateCIF,"19" );
+ else strcpy ( DateCIF,"20" );
+ strncpy ( &(DateCIF[2]),&(Date9[7]),2 );
+ strncpy ( &(DateCIF[5]),nMonth[i],2 );
+ } else { // DD-MM-YY -> YYYY-MM-DD
+ if (Date9[6]!='0') strcpy ( DateCIF,"19" );
+ else strcpy ( DateCIF,"20" );
+ strncpy ( &(DateCIF[2]),&(Date9[6]),2 );
+ strncpy ( &(DateCIF[5]),&(Date9[3]),2 );
+ }
+ DateCIF[4] = '-';
+ DateCIF[7] = '-';
+ strncpy ( &(DateCIF[8]),Date9,2 );
+ DateCIF[10] = char(0);
+ }
+
+ void Date11toCIF ( cpstr Date11, pstr DateCIF ) {
+ // DD-MMM-YYYY -> YYYY-MM-DD
+ int i;
+ i = 0;
+ while ((i<12) && (strncmp(Month[i],&(Date11[3]),3))) i++;
+ if (i<12) {
+ strncpy ( DateCIF,&(Date11[7]),4 );
+ strncpy ( &(DateCIF[5]),nMonth[i],2 );
+ } else {
+ strncpy ( DateCIF,&(Date11[6]),4 );
+ strncpy ( &(DateCIF[5]),&(Date11[3]),2 );
+ }
+ DateCIF[4] = '-';
+ DateCIF[7] = '-';
+ strncpy ( &(DateCIF[8]),Date11,2 );
+ DateCIF[10] = char(0);
+ }
+
+ void DateCIFto9 ( cpstr DateCIF, pstr Date9 ) {
+ // YYYY-MM-DD -> DD-MMM-YY
+ int i;
+ strncpy ( Date9,&(DateCIF[8]),2 );
+ Date9[2] = '-';
+ i = 0;
+ while ((i<12) && (strncmp(nMonth[i],&(DateCIF[5]),2))) i++;
+ if (i<12) strncpy ( &(Date9[3]),Month[i],3 );
+ else {
+ strncpy ( &(Date9[3]),&(DateCIF[5]),2 );
+ Date9[5] = 'X';
+ }
+ Date9[6] = '-';
+ strncpy ( &(Date9[7]),&(DateCIF[2]),2 );
+ // DateCIF[9] = char(0);
+ }
+
+ void DateCIFto11 ( cpstr DateCIF, pstr Date11 ) {
+ // YYYY-MM-DD -> DD-MMM-YYYY
+ int i;
+ strncpy ( Date11,&(DateCIF[8]),2 );
+ Date11[2] = '-';
+ i = 0;
+ while ((i<12) && (strncmp(nMonth[i],&(DateCIF[5]),2))) i++;
+ if (i<12) strncpy ( &(Date11[3]),Month[i],3 );
+ else {
+ strncpy ( &(Date11[3]),&(DateCIF[5]),2 );
+ Date11[5] = 'X';
+ }
+ Date11[6] = '-';
+ strncpy ( &(Date11[7]),DateCIF,4 );
+ // DateCIF[11] = char(0);
+ }
+
+
+ // =============== Format functions ===================
+
+ bool GetInteger ( int & N, cpstr S, int M ) {
+ // Returns true if S contains an integer number in its
+ // first M characters. This number is returned in N.
+ // The return is false if no integer number may be
+ // recognized. In this case, N is assigned MinInt4 value.
+ pstr endptr;
+ char L[50];
+ strncpy ( L,S,M );
+ L[M] = char(0);
+ N = mround(strtod(L,&endptr));
+ if ((N==0) && (endptr==L)) {
+ N = MinInt4; // no number
+ return false;
+ } else
+ return true;
+ }
+
+ bool GetReal ( realtype & R, cpstr S, int M ) {
+ // Returns true if S contains a real number in its
+ // first M characters. This number is returned in R.
+ // The return is false if no real number may be
+ // recognized. In this case, R is assigned -MaxReal value.
+ pstr endptr;
+ char L[50];
+ strncpy ( L,S,M );
+ L[M] = char(0);
+ R = strtod(L,&endptr);
+ if ((R==0.0) && (endptr==L)) {
+ R = -MaxReal; // no number
+ return false;
+ } else
+ return true;
+ }
+
+ bool GetIntIns ( int & N, pstr ins, cpstr S, int M ) {
+ // Returns true if S contains an integer number in its
+ // first M characters. This number is returned in N. In addition
+ // to that, GetIntIns() retrieves the insertion code which may
+ // follow the integer and returns it in "ins" (1 character +
+ // terminating 0).
+ // The return is false if no integer number may be
+ // recognized. In this case, N is assigned MinInt4 value,
+ // "ins" just returns (M+1)th symbol of S (+terminating 0).
+ pstr endptr;
+ char L[50];
+
+ if (S[M]!=' ') {
+ ins[0] = S[M];
+ ins[1] = char(0);
+ } else
+ ins[0] = char(0);
+
+ strncpy ( L,S,M );
+ L[M] = char(0);
+ if ((M==4) && ((S[0]>='A') || ((S[0]=='-') && (S[1]>='A'))))
+ hy36decode ( M,L,M,&N);
+ else {
+ endptr = NULL;
+ N = mround(strtod(L,&endptr));
+ if ((N==0) && (endptr==L)) {
+ N = MinInt4; // no number
+ return false;
+ }
+ }
+
+ return true;
+
+ }
+
+ void PutInteger ( pstr S, int N, int M ) {
+ // Integer N is converted into ASCII string of length M
+ // and pasted onto first M characters of string S. No
+ // terminating zero is added.
+ // If N is set to MinInt4, then first M characters of
+ // string S are set to the space character.
+ char L[50];
+ int i;
+ if (N==MinInt4)
+ for (i=0;i<M;i++)
+ S[i] = ' ';
+ else {
+ sprintf ( L,"%*i",M,N );
+ strncpy ( S,L,M );
+ }
+ }
+
+ void PutRealF ( pstr S, realtype R, int M, int L ) {
+ // Real R is converted into ASCII string of length M
+ // and pasted onto first M characters of string S. No
+ // terminating zero is added. The conversion is done
+ // according to fixed format FM.L
+ // If R is set to -MaxReal, then first M characters of
+ // string S are set to the space character.
+ char N[50];
+ int i;
+ if (R==-MaxReal)
+ for (i=0;i<M;i++)
+ S[i] = ' ';
+ else {
+ sprintf ( N,"%*.*f",M,L,R );
+ strncpy ( S,N,M );
+ }
+ }
+
+ ERROR_CODE CIFGetIntegerD ( int & I, mmcif::PLoop Loop, cpstr Tag,
+ int defValue ) {
+ int Signal;
+ ERROR_CODE RC;
+ Signal = 0;
+ RC = CIFGetInteger ( I,Loop,Tag,Signal );
+ if (RC)
+ I = defValue;
+ return RC;
+ }
+
+ ERROR_CODE CIFGetInteger ( int & I, mmcif::PLoop Loop, cpstr Tag,
+ int & Signal ) {
+ pstr F;
+ int RC;
+ RC = Loop->GetInteger ( I,Tag,Signal,true );
+ if (RC==mmcif::CIFRC_WrongFormat) {
+ F = Loop->GetString ( Tag,Signal,RC );
+ if (F) sprintf ( CIFErrorLocation,"loop %s.%s row %i data %s",
+ Loop->GetCategoryName(),Tag,Signal,F );
+ else sprintf ( CIFErrorLocation,"loop %s.%s row %i data [NULL]",
+ Loop->GetCategoryName(),Tag,Signal );
+ Signal = -Error_UnrecognizedInteger-1;
+ return Error_UnrecognizedInteger;
+ }
+ if (RC==mmcif::CIFRC_WrongIndex) {
+ Signal = -1;
+ return Error_NoData;
+ }
+ if (RC) {
+ F = Loop->GetString ( Tag,Signal,RC );
+ if (F) sprintf ( CIFErrorLocation,"loop %s.%s row %i data %s",
+ Loop->GetCategoryName(),Tag,Signal,F );
+ else sprintf ( CIFErrorLocation,"loop %s.%s row %i data [NULL]",
+ Loop->GetCategoryName(),Tag,Signal );
+ Signal = -Error_NoData-1;
+ return Error_NoData;
+ }
+ return Error_NoError;
+ }
+
+
+ ERROR_CODE CIFGetInteger1 ( int & I, mmcif::PLoop Loop, cpstr Tag,
+ int nrow ) {
+ pstr F;
+ int RC;
+ RC = Loop->GetInteger ( I,Tag,nrow,true );
+ if (RC==mmcif::CIFRC_WrongFormat) {
+ F = Loop->GetString ( Tag,nrow,RC );
+ if (F) sprintf ( CIFErrorLocation,"loop %s.%s row %i data %s",
+ Loop->GetCategoryName(),Tag,nrow,F );
+ else sprintf ( CIFErrorLocation,"loop %s.%s row %i data [NULL]",
+ Loop->GetCategoryName(),Tag,nrow );
+ return Error_UnrecognizedInteger;
+ }
+ if (RC==mmcif::CIFRC_WrongIndex)
+ return Error_NoData;
+ if (RC) {
+ F = Loop->GetString ( Tag,nrow,RC );
+ if (F) sprintf ( CIFErrorLocation,"loop %s.%s row %i data %s",
+ Loop->GetCategoryName(),Tag,nrow,F );
+ else sprintf ( CIFErrorLocation,"loop %s.%s row %i data [NULL]",
+ Loop->GetCategoryName(),Tag,nrow );
+ return Error_NoData;
+ }
+ return Error_NoError;
+ }
+
+
+ ERROR_CODE CIFGetReal ( realtype & R, mmcif::PLoop Loop, cpstr Tag,
+ int & Signal ) {
+ pstr F;
+ int RC;
+ RC = Loop->GetReal ( R,Tag,Signal,true );
+ if (RC==mmcif::CIFRC_WrongFormat) {
+ F = Loop->GetString ( Tag,Signal,RC );
+ if (F) sprintf ( CIFErrorLocation,"loop %s.%s row %i data %s",
+ Loop->GetCategoryName(),Tag,Signal,F );
+ else sprintf ( CIFErrorLocation,"loop %s.%s row %i data [NULL]",
+ Loop->GetCategoryName(),Tag,Signal );
+ Signal = -Error_UnrecognizedReal-1;
+ return Error_UnrecognizedReal;
+ }
+ if (RC==mmcif::CIFRC_WrongIndex) {
+ Signal = -1;
+ return Error_NoData;
+ }
+ if (RC) {
+ F = Loop->GetString ( Tag,Signal,RC );
+ if (F) sprintf ( CIFErrorLocation,"loop %s.%s row %i data %s",
+ Loop->GetCategoryName(),Tag,Signal,F );
+ else sprintf ( CIFErrorLocation,"loop %s.%s row %i data [NULL]",
+ Loop->GetCategoryName(),Tag,Signal );
+ Signal = -Error_NoData-1;
+ return Error_NoData;
+ }
+ return Error_NoError;
+ }
+
+
+ ERROR_CODE CIFGetReal1 ( realtype & R, mmcif::PLoop Loop, cpstr Tag,
+ int nrow ) {
+ pstr F;
+ int RC;
+ RC = Loop->GetReal ( R,Tag,nrow,true );
+ if (RC==mmcif::CIFRC_WrongFormat) {
+ F = Loop->GetString ( Tag,nrow,RC );
+ if (F) sprintf ( CIFErrorLocation,"loop %s.%s row %i data %s",
+ Loop->GetCategoryName(),Tag,nrow,F );
+ else sprintf ( CIFErrorLocation,"loop %s.%s row %i data [NULL]",
+ Loop->GetCategoryName(),Tag,nrow );
+ return Error_UnrecognizedReal;
+ }
+ if (RC==mmcif::CIFRC_WrongIndex)
+ return Error_NoData;
+ if (RC) {
+ F = Loop->GetString ( Tag,nrow,RC );
+ if (F) sprintf ( CIFErrorLocation,"loop %s.%s row %i data %s",
+ Loop->GetCategoryName(),Tag,nrow,F );
+ else sprintf ( CIFErrorLocation,"loop %s.%s row %i data [NULL]",
+ Loop->GetCategoryName(),Tag,nrow );
+ return Error_NoData;
+ }
+ return Error_NoError;
+ }
+
+
+ ERROR_CODE CIFGetString ( pstr S, mmcif::PLoop Loop, cpstr Tag,
+ int row, int SLen, cpstr DefS ) {
+ pstr F;
+ int RC;
+ F = Loop->GetString ( Tag,row,RC );
+ if ((!RC) && F) {
+ strncpy ( S,F,SLen-1 );
+ Loop->DeleteField ( Tag,row );
+ return Error_NoError;
+ } else {
+ strcpy ( S,DefS );
+ return Error_EmptyCIFLoop;
+ }
+ }
+
+
+ ERROR_CODE CIFGetInteger ( int & I, mmcif::PStruct Struct, cpstr Tag,
+ bool Remove ) {
+ pstr F;
+ int RC;
+ RC = Struct->GetInteger ( I,Tag,Remove );
+ if (RC==mmcif::CIFRC_WrongFormat) {
+ F = Struct->GetString ( Tag,RC );
+ if (F) sprintf ( CIFErrorLocation,"structure %s.%s data %s",
+ Struct->GetCategoryName(),Tag,F );
+ else sprintf ( CIFErrorLocation,"structure %s.%s data [NULL]",
+ Struct->GetCategoryName(),Tag );
+ return Error_UnrecognizedInteger;
+ }
+ if (RC) {
+ F = Struct->GetString ( Tag,RC );
+ if (F) sprintf ( CIFErrorLocation,"structure %s.%s data %s",
+ Struct->GetCategoryName(),Tag,F );
+ else sprintf ( CIFErrorLocation,"structure %s.%s data [NULL]",
+ Struct->GetCategoryName(),Tag );
+ return Error_NoData;
+ }
+ return Error_NoError;
+ }
+
+ ERROR_CODE CIFGetReal ( realtype & R, mmcif::PStruct Struct, cpstr Tag,
+ bool Remove ) {
+ pstr F;
+ int RC;
+ RC = Struct->GetReal ( R,Tag,Remove );
+ if (RC==mmcif::CIFRC_WrongFormat) {
+ F = Struct->GetString ( Tag,RC );
+ if (F) sprintf ( CIFErrorLocation,"structure %s.%s data %s",
+ Struct->GetCategoryName(),Tag,F );
+ else sprintf ( CIFErrorLocation,"structure %s.%s data [NULL]",
+ Struct->GetCategoryName(),Tag );
+ return Error_UnrecognizedReal;
+ }
+ if (RC) {
+ F = Struct->GetString ( Tag,RC );
+ if (F) sprintf ( CIFErrorLocation,"structure %s.%s data %s",
+ Struct->GetCategoryName(),Tag,F );
+ else sprintf ( CIFErrorLocation,"structure %s.%s data [NULL]",
+ Struct->GetCategoryName(),Tag );
+ return Error_NoData;
+ }
+ return Error_NoError;
+ }
+
+ ERROR_CODE CIFGetString ( pstr S, mmcif::PStruct Struct, cpstr Tag,
+ int SLen, cpstr DefS, bool Remove ) {
+ pstr F;
+ int RC;
+ F = Struct->GetString ( Tag,RC );
+ if ((!RC) && F) {
+ strcpy_n0 ( S,F,SLen-1 );
+ if (Remove) Struct->DeleteField ( Tag );
+ return Error_NoError;
+ } else {
+ strcpy ( S,DefS );
+ return Error_EmptyCIFStruct;
+ }
+ }
+
+
+ void PutIntIns ( pstr S, int N, int M, cpstr ins ) {
+ // Integer N is converted into ASCII string of length M
+ // and pasted onto first M characters of string S. No
+ // terminating zero is added. The insert code ins is put
+ // immediately after the integer.
+ // If N is set to MinInt4, then first M+1 characters of
+ // string S are set to space, and no insert code are
+ // appended.
+ char L[50];
+ int i;
+
+ if (N==MinInt4) {
+ for (i=0;i<=M;i++)
+ S[i] = ' ';
+ } else {
+ if ((M!=4) || ((N>=-999) && (N<=9999)))
+ sprintf ( L,"%*i",M,N );
+ else hy36encode ( M,N,L );
+ strcpy_n1 ( S,L,M );
+ if (ins[0]) S[M] = ins[0];
+ }
+
+ }
+
+
+ void Mat4Inverse ( mat44 & A, mat44 & AI ) {
+ // *** FORMER RBRINV(A,AI) ***
+ // Function to invert 4*4 matrices (AI=A^{-1})
+ mat44 c;
+ mat33 x;
+ realtype s,s1;
+ int ii,jj,i,i1,j,j1;
+
+ // ---- Get cofactors of 'a' in array 'c'
+
+ s1 = 1.0;
+ for (ii=0;ii<4;ii++) {
+ s = s1;
+ for (jj=0;jj<4;jj++) {
+ i = -1;
+ for (i1=0;i1<4;i1++)
+ if (i1!=ii) {
+ i++;
+ j = -1;
+ for (j1=0;j1<4;j1++)
+ if (j1!=jj) {
+ j++;
+ x[i][j] = A[i1][j1];
+ }
+ }
+ c[ii][jj] = s*(x[0][0]*(x[1][1]*x[2][2]-x[1][2]*x[2][1]) +
+ x[0][1]*(x[1][2]*x[2][0]-x[1][0]*x[2][2]) +
+ x[0][2]*(x[1][0]*x[2][1]-x[1][1]*x[2][0]));
+ s = -s;
+ }
+ s1 = -s1;
+ }
+
+ // ---- Calculate determinant
+
+ s = 0.0;
+ for (i=0;i<4;i++)
+ s += A[i][0]*c[i][0];
+
+ // ---- Get inverse matrix
+
+ if (s!=0.0)
+ for (i=0;i<4;i++)
+ for (j=0;j<4;j++)
+ AI[i][j] = c[j][i]/s;
+
+ }
+
+ realtype Mat3Inverse ( mat33 & A, mat33 & AI ) {
+ mat33 c,x;
+ realtype s;
+ int ii,jj,i,i1,j,j1;
+
+ // Get cofactors of 'a' in array 'c'
+
+ s = 1.0;
+ for (ii=0;ii<3;ii++)
+ for (jj=0;jj<3;jj++) {
+ i = -1;
+ for (i1=0;i1<3;i1++)
+ if (i1!=ii) {
+ i++;
+ j = -1;
+ for (j1=0;j1<3;j1++)
+ if (j1!=jj) {
+ j++;
+ x[i][j] = A[i1][j1];
+ }
+ }
+ c[ii][jj] = s*(x[0][0]*x[1][1]-x[0][1]*x[1][0]);
+ s = -s;
+ }
+
+ // Calculate determinant
+
+ s = 0.0;
+ for (i=0;i<3;i++)
+ s += A[i][0]*c[i][0];
+
+ // Get inverse matrix
+
+ if (s!=0.0)
+ for (i=0;i<3;i++)
+ for (j=0;j<3;j++)
+ AI[i][j] = c[j][i]/s;
+
+ return s;
+
+ }
+
+ void Mat4Mult ( mat44 & A, mat44 & B, mat44 & C ) {
+ // Calculates A=B*C
+ int i,j,k;
+ for (i=0;i<4;i++)
+ for (j=0;j<4;j++) {
+ A[i][j] = 0.0;
+ for (k=0;k<4;k++)
+ A[i][j] += B[i][k]*C[k][j];
+ }
+ }
+
+ void Mat4Div1 ( mat44 & A, mat44 & B, mat44 & C ) {
+ // Calculates A=B^{-1}*C
+ mat44 B1;
+ int i,j,k;
+ B1[0][0] = 1.0; // in order to supress warnings from some
+ // stupid compilers
+ Mat4Inverse ( B,B1 );
+ for (i=0;i<4;i++)
+ for (j=0;j<4;j++) {
+ A[i][j] = 0.0;
+ for (k=0;k<4;k++)
+ A[i][j] += B1[i][k]*C[k][j];
+ }
+ }
+
+ void Mat4Div2 ( mat44 & A, mat44 & B, mat44 & C ) {
+ // Calculates A=B*C^{-1}
+ mat44 C1;
+ int i,j,k;
+ C1[0][0] = 1.0; // in order to supress warnings from some
+ // stupid compilers
+ Mat4Inverse ( C,C1 );
+ for (i=0;i<4;i++)
+ for (j=0;j<4;j++) {
+ A[i][j] = 0.0;
+ for (k=0;k<4;k++)
+ A[i][j] += B[i][k]*C1[k][j];
+ }
+ }
+
+ void Mat4Init ( mat44 & A ) {
+ int i,j;
+ for (i=0;i<4;i++) {
+ for (j=0;j<4;j++)
+ A[i][j] = 0.0;
+ A[i][i] = 1.0;
+ }
+ }
+
+ realtype Mat4RotDet ( mat44 & T ) {
+ // returns determinant of the rotation part
+ return T[0][0]*T[1][1]*T[2][2] +
+ T[0][1]*T[1][2]*T[2][0] +
+ T[1][0]*T[2][1]*T[0][2] -
+ T[0][2]*T[1][1]*T[2][0] -
+ T[0][0]*T[1][2]*T[2][1] -
+ T[2][2]*T[0][1]*T[1][0];
+ }
+
+ bool isMat4Unit ( mat44 & A, realtype eps, bool rotOnly ) {
+ // returns true if A is a unit 4x4 matrix
+ int i,j,k;
+ bool B;
+
+ if (rotOnly) k = 3;
+ else k = 4;
+
+ B = true;
+ for (i=0;(i<k) && B;i++)
+ for (j=0;(j<k) && B;j++)
+ if (i==j) B = (fabs(1.0-A[i][j])<eps);
+ else B = (fabs(A[i][j])<eps);
+
+ return B;
+
+ }
+
+ void Mat3Init ( mat33 & A ) {
+ int i,j;
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++)
+ A[i][j] = 0.0;
+ A[i][i] = 1.0;
+ }
+ }
+
+ void Mat4Copy ( mat44 & A, mat44 & ACopy ) {
+ int i,j;
+ for (i=0;i<4;i++)
+ for (j=0;j<4;j++)
+ ACopy[i][j] = A[i][j];
+ }
+
+ void Mat3Copy ( mat33 & A, mat33 & ACopy ) {
+ int i,j;
+ for (i=0;i<3;i++)
+ for (j=0;j<3;j++)
+ ACopy[i][j] = A[i][j];
+ }
+
+ bool isMat4Eq ( mat44 & A, mat44 & B, realtype eps,
+ bool rotOnly ) {
+ // returns true if A is equal to B within precision eps
+ int i,j,k;
+ bool Eq;
+
+ if (rotOnly) k = 3;
+ else k = 4;
+
+ Eq = true;
+ for (i=0;(i<k) && Eq;i++)
+ for (j=0;(j<k) && Eq;j++)
+ Eq = (fabs(A[i][j]-B[i][j])<eps);
+
+ return Eq;
+
+ }
+
+
+ void TransformXYZ ( mat44 & T, realtype & X, realtype & Y,
+ realtype & Z ) {
+ realtype x1,y1,z1;
+ x1 = T[0][0]*X + T[0][1]*Y + T[0][2]*Z + T[0][3];
+ y1 = T[1][0]*X + T[1][1]*Y + T[1][2]*Z + T[1][3];
+ z1 = T[2][0]*X + T[2][1]*Y + T[2][2]*Z + T[2][3];
+ X = x1;
+ Y = y1;
+ Z = z1;
+ }
+
+ realtype TransformX ( mat44 & T, realtype X, realtype Y,
+ realtype Z ) {
+ return T[0][0]*X + T[0][1]*Y + T[0][2]*Z + T[0][3];
+ }
+
+ realtype TransformY ( mat44 & T, realtype X, realtype Y,
+ realtype Z ) {
+ return T[1][0]*X + T[1][1]*Y + T[1][2]*Z + T[1][3];
+ }
+
+ realtype TransformZ ( mat44 & T, realtype X, realtype Y,
+ realtype Z ) {
+ return T[2][0]*X + T[2][1]*Y + T[2][2]*Z + T[2][3];
+ }
+
+
+
+
+ char CIFErrorLocation[200] = "no error";
+
+ static cpstr msWrongSection =
+ "Wrong section. The sections in PDB file may be put in wrong order.";
+ static cpstr msWrongChainID =
+ "Wrong chain ID. The input may have changed to another chain.";
+ static cpstr msWrongEntryID =
+ "Entry ID does not match the header.";
+
+ static cpstr msSEQRES_serNum =
+ "Serial numbers of SEQRES records do not increment by 1.";
+ static cpstr msSEQRES_numRes =
+ "Different SEQRES records show different numbers of residues.";
+ static cpstr msSEQRES_extraRes =
+ "SEQRES records contain more residues than specified.";
+
+ static cpstr msNCSM_Unrecognized =
+ "Unrecognized numerical input in MTRIXn.";
+ static cpstr msNCSM_AlreadySet =
+ "Duplicate MTRIXn record.";
+ static cpstr msNCSM_WrongSerial =
+ "Serial number in MTRIXn record is wrong.";
+ static cpstr msNCSM_UnmatchIG =
+ "Different MTRIXn record show different iGiven flag.";
+
+ static cpstr msATOM_Unrecognized =
+ "Numerical information in ATOM record is not recognized.";
+ static cpstr msATOM_AlreadySet =
+ "Atom is already in the system.";
+ static cpstr msATOM_NoResidue =
+ "No residue is found for atom.";
+ static cpstr msATOM_Unmatch =
+ "Unmatch in different records for the same atom.";
+
+ static cpstr msCantOpenFile = "File can not be opened.";
+ static cpstr msUnrecognizedInteger =
+ "Wrong ASCII format of an integer.";
+ static cpstr msWrongModelNo = "Wrong model number.";
+ static cpstr msDuplicatedModel = "Duplicate model number.";
+ static cpstr msNoModel = "No model defined.";
+ static cpstr msForeignFile =
+ "Attempt to read unknown-type file.";
+ static cpstr msWrongEdition =
+ "Attempt to read a higher-version file.";
+
+ static cpstr msNoData = "Expected data field not found.";
+ static cpstr msUnrecognizedReal = "Wrong ASCII format of a real.";
+ static cpstr msNotACIFFile =
+ "Not a CIF file ('data_' missing).";
+ static cpstr msUnrecognCIFItems =
+ "Unrecognized item(s) in CIF file.";
+ static cpstr msMissingCIFField = "Expected CIF item(s) missing.";
+ static cpstr msEmptyCIFLoop = "Empty CIF loop encountered.";
+ static cpstr msUnexpEndOfCIF = "Unexpected end of CIF file.";
+ static cpstr msMissgCIFLoopField = "Inconsistent CIF loop.";
+ static cpstr msNotACIFStructure =
+ "Wrong use of CIF structure (as a loop?).";
+ static cpstr msNotACIFLoop =
+ "Wrong use of CIF loop (as a structure?).";
+
+ static cpstr msNoSheetID = "No Sheet ID on PDB ASCII card.";
+ static cpstr msWrongSheetID = "Wrong Sheet ID.";
+ static cpstr msWrongStrandNo =
+ "Wrong Strand number on PDB SHEET card.";
+
+ static cpstr msWrongNumberOfStrands =
+ "Wrong number of strands in CIF file.";
+ static cpstr msWrongSheetOrder = "Incomplete _struct_sheet_order.";
+ static cpstr msHBondInconsistency =
+ "Inconsistency in _struct_sheet_hbond.";
+
+ static cpstr msEmptyResidueName =
+ "No residue name on PDB ATOM or TER card.";
+ static cpstr msDuplicateSeqNum =
+ "Duplicate sequence number and insertion code.";
+
+ static cpstr msEmptyFile = "Non-existent or empty file.";
+
+ static cpstr msNoLogicalName = "Logical file name not found.";
+
+
+ cpstr GetErrorDescription ( ERROR_CODE ErrorCode ) {
+
+ switch (ErrorCode) {
+
+ case Error_NoError : return "No errors.";
+
+ case Error_WrongSection : return msWrongSection;
+ case Error_WrongChainID : return msWrongChainID;
+ case Error_WrongEntryID : return msWrongEntryID;
+
+ case Error_SEQRES_serNum : return msSEQRES_serNum;
+ case Error_SEQRES_numRes : return msSEQRES_numRes;
+ case Error_SEQRES_extraRes : return msSEQRES_extraRes;
+
+ case Error_NCSM_Unrecognized : return msNCSM_Unrecognized;
+ case Error_NCSM_AlreadySet : return msNCSM_AlreadySet;
+ case Error_NCSM_WrongSerial : return msNCSM_WrongSerial;
+ case Error_NCSM_UnmatchIG : return msNCSM_UnmatchIG;
+
+ case Error_ATOM_Unrecognized : return msATOM_Unrecognized;
+ case Error_ATOM_AlreadySet : return msATOM_AlreadySet;
+ case Error_ATOM_NoResidue : return msATOM_NoResidue;
+ case Error_ATOM_Unmatch : return msATOM_Unmatch;
+
+ case Error_CantOpenFile : return msCantOpenFile;
+ case Error_UnrecognizedInteger : return msUnrecognizedInteger;
+ case Error_WrongModelNo : return msWrongModelNo;
+ case Error_DuplicatedModel : return msDuplicatedModel;
+ case Error_NoModel : return msNoModel;
+ case Error_ForeignFile : return msForeignFile;
+ case Error_WrongEdition : return msWrongEdition;
+
+ case Error_NoData : return msNoData;
+ case Error_UnrecognizedReal : return msUnrecognizedReal;
+ case Error_NotACIFFile : return msNotACIFFile;
+ case Error_UnrecognCIFItems : return msUnrecognCIFItems;
+ case Error_MissingCIFField : return msMissingCIFField;
+ case Error_EmptyCIFLoop : return msEmptyCIFLoop;
+ case Error_UnexpEndOfCIF : return msUnexpEndOfCIF;
+ case Error_MissgCIFLoopField : return msMissgCIFLoopField;
+ case Error_NotACIFStructure : return msNotACIFStructure;
+ case Error_NotACIFLoop : return msNotACIFLoop;
+
+ case Error_NoSheetID : return msNoSheetID;
+ case Error_WrongSheetID : return msWrongSheetID;
+ case Error_WrongStrandNo : return msWrongStrandNo;
+
+ case Error_WrongNumberOfStrands : return msWrongNumberOfStrands;
+ case Error_WrongSheetOrder : return msWrongSheetOrder;
+ case Error_HBondInconsistency : return msHBondInconsistency;
+
+ case Error_EmptyResidueName : return msEmptyResidueName;
+ case Error_DuplicateSeqNum : return msDuplicateSeqNum;
+
+ case Error_EmptyFile : return msEmptyFile;
+
+ case Error_NoLogicalName : return msNoLogicalName;
+
+ default : return "Unknown error.";
+
+ }
+ }
+
+
+ // ============== ContainerClass ====================
+
+ ContainerClass::ContainerClass() : io::Stream() {
+ ContinuationNo = 0;
+ }
+
+ ContainerClass::ContainerClass ( io::RPStream Object )
+ : io::Stream(Object) {
+ ContinuationNo = 0;
+ }
+
+ bool ContainerClass::Append ( PContainerClass CC ) {
+ return (CC->ContinuationNo>1);
+ }
+
+
+ // =================== ContString =====================
+
+ ContString::ContString() : ContainerClass() {
+ InitString();
+ }
+
+ ContString::ContString ( cpstr S ) : ContainerClass() {
+ InitString();
+ ConvertPDBASCII ( S );
+ }
+
+ ContString::ContString ( io::RPStream Object )
+ : ContainerClass(Object) {
+ InitString();
+ }
+
+ ContString::~ContString() {
+ if (Line) delete[] Line;
+ if (CIFCategory) delete[] CIFCategory;
+ if (CIFTag) delete[] CIFTag;
+ }
+
+ void ContString::InitString() {
+ Line = NULL;
+ CIFCategory = NULL;
+ CIFTag = NULL;
+ }
+
+ ERROR_CODE ContString::ConvertPDBASCII ( cpstr S ) {
+ CreateCopy ( Line,S );
+ return Error_NoError;
+ }
+
+ void ContString::PDBASCIIDump ( pstr S, int ) {
+ if (Line) strcpy ( S,Line );
+ else strcpy ( S,"" );
+ }
+
+ bool ContString::PDBASCIIDump1 ( io::RFile f ) {
+ if (Line) f.WriteLine ( Line );
+ else f.LF();
+ return true;
+ }
+
+/*
+ void ContString::GetCIF1 ( mmcif::PData CIF, ERROR_CODE & Signal,
+ int & pos ) {
+ pstr F;
+ int i,RC;
+ char c;
+ if ((!CIFCategory) || (!CIFTag)) {
+ Signal = Error_EmptyCIF;
+ return;
+ }
+ F = CIF->GetString ( CIFCategory,CIFTag,RC );
+ if (RC || (!F)) {
+ Signal = Error_EmptyCIF;
+ return;
+ }
+ if (Signal>=(int)strlen(F)) {
+ CIF->DeleteField ( CIFCategory,CIFTag );
+ Signal = Error_EmptyCIF;
+ return;
+ }
+// i = Signal;
+// while (F[i] && (F[i]!='\n') && (F[i]!='\r')) i++;
+// if ((Signal==0) && (i==0)) {
+// i++;
+// if (((F[Signal]=='\n') && (F[i]=='\r')) ||
+// ((F[Signal]=='\r') && (F[i]=='\n'))) i++;
+// Signal = i;
+// while (F[i] && (F[i]!='\n') && (F[i]!='\r')) i++;
+// }
+// c = F[i];
+// F[i] = char(0);
+// CreateCopy ( Line,&(F[Signal]) );
+// if (c) {
+// F[i] = c;
+// Signal = i+1;
+// if (((c=='\n') && (F[Signal]=='\r')) ||
+// ((c=='\r') && (F[Signal]=='\n'))) Signal++;
+// } else
+// CIF->DeleteField ( CIFCategory,CIFTag );
+ i = pos;
+ while (F[i] && (F[i]!='\n') && (F[i]!='\r')) i++;
+ if ((pos==0) && (i==0)) {
+ i++;
+ if (((F[pos]=='\n') && (F[i]=='\r')) ||
+ ((F[pos]=='\r') && (F[i]=='\n'))) i++;
+ pos = i;
+ while (F[i] && (F[i]!='\n') && (F[i]!='\r')) i++;
+ }
+ c = F[i];
+ F[i] = char(0);
+ CreateCopy ( Line,&(F[pos]) );
+ if (c) {
+ F[i] = c;
+ pos = i+1;
+ if (((c=='\n') && (F[pos]=='\r')) ||
+ ((c=='\r') && (F[pos]=='\n'))) pos++;
+ } else
+ CIF->DeleteField ( CIFCategory,CIFTag );
+ }
+*/
+
+ void ContString::MakeCIF ( mmcif::PData CIF, int N ) {
+ pstr S;
+ if ((!CIFCategory) || (!CIFTag)) return;
+ S = new char[strlen(Line)+5];
+ strcpy ( S,"\n" );
+ strcat ( S,Line );
+ CIF->PutString ( S,CIFCategory,CIFTag,(N!=0) );
+ delete[] S;
+ }
+
+ bool ContString::Append ( PContainerClass CC ) {
+ if (ContainerClass::Append(CC)) {
+ if (!Line) {
+ Line = PContString(CC)->Line;
+ PContString(CC)->Line = NULL;
+ } else
+ CreateConcat ( Line,pstr("\n"),PContString(CC)->Line );
+ return true;
+ }
+ return false;
+ }
+
+ void ContString::Copy ( PContainerClass CString ) {
+ CreateCopy ( Line,PContString(CString)->Line );
+ }
+
+ void ContString::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.CreateWrite ( Line );
+ f.CreateWrite ( CIFCategory );
+ f.CreateWrite ( CIFTag );
+ }
+
+ void ContString::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ f.CreateRead ( Line );
+ f.CreateRead ( CIFCategory );
+ f.CreateRead ( CIFTag );
+ }
+
+ MakeStreamFunctions(ContString)
+
+
+
+ // ============== ClassContainer ====================
+
+ MakeStreamFunctions(ContainerClass)
+
+ ClassContainer::ClassContainer() : io::Stream() {
+ Init();
+ }
+
+ ClassContainer::ClassContainer ( io::RPStream Object )
+ : io::Stream(Object) {
+ Init();
+ }
+
+ void ClassContainer::Init() {
+ length = 0;
+ Container = NULL;
+ }
+
+ ClassContainer::~ClassContainer() {
+ FreeContainer();
+ }
+
+ void ClassContainer::FreeContainer() {
+ int i;
+ if (Container) {
+ for (i=0;i<length;i++)
+ if (Container[i])
+ delete Container[i];
+ delete[] Container;
+ }
+ Container = NULL;
+ length = 0;
+ }
+
+ void ClassContainer::AddData ( PContainerClass Data ) {
+ int i;
+ PPContainerClass C1;
+ if (!Data) return;
+ if (length>0) {
+ i = length-1;
+ while (i>=0) {
+ if (!Container[i]) i--;
+ else if (Container[i]->GetClassID()!=Data->GetClassID()) i--;
+ else break;
+ }
+ if (i>=0) {
+ if (Container[i]->Append(Data)) {
+ delete Data;
+ return;
+ }
+ }
+ }
+ C1 = new PContainerClass[length+1];
+ for (i=0;i<length;i++)
+ C1[i] = Container[i];
+ C1[length] = Data;
+ if (Container) delete[] Container;
+ Container = C1;
+ length++;
+ }
+
+ void ClassContainer::PDBASCIIDump ( io::RFile f ) {
+ char S[500];
+ int i,j;
+ for (i=0;i<length;i++)
+ if (Container[i]) {
+ if (!Container[i]->PDBASCIIDump1(f)) {
+ Container[i]->PDBASCIIDump ( S,i );
+ j = strlen(S);
+ while (j<80) S[j++] = ' ';
+ S[80] = char(0);
+ f.WriteLine ( S );
+ }
+ }
+ }
+
+ ERROR_CODE ClassContainer::GetCIF ( mmcif::PData CIF, int ClassID ) {
+ PContainerClass ContainerClass;
+ int n;
+ ERROR_CODE rc;
+ n = -1;
+ do {
+ ContainerClass = MakeContainerClass ( ClassID );
+ rc = ContainerClass->GetCIF ( CIF,n );
+ if (rc==Error_NoError)
+ AddData ( ContainerClass );
+ } while (rc==Error_NoError);
+ delete ContainerClass;
+ if (rc==Error_EmptyCIF)
+ rc = Error_NoError;
+ return rc;
+ }
+
+ void ClassContainer::MakeCIF ( mmcif::PData CIF ) {
+ int i;
+ for (i=0;i<length;i++)
+ if (Container[i])
+ Container[i]->MakeCIF ( CIF,i );
+ }
+
+ void ClassContainer::write ( io::RFile f ) {
+ int i,ClassID;
+ byte Version=1;
+ f.WriteByte ( &Version );
+ f.WriteInt ( &length );
+ for (i=0;i<length;i++)
+ if (Container[i]) {
+ ClassID = Container[i]->GetClassID();
+ f.WriteInt ( &ClassID );
+ Container[i]->write ( f );
+ } else {
+ ClassID = -1;
+ f.WriteInt ( &ClassID );
+ }
+ }
+
+ PContainerClass ClassContainer::MakeContainerClass ( int ClassID ) {
+ if (ClassID==ClassID_String) return new ContString();
+ return new ContainerClass();
+ }
+
+ PContainerClass ClassContainer::GetContainerClass (int ContClassNo) {
+ if ((ContClassNo<0) || (ContClassNo>=length)) return NULL;
+ return Container[ContClassNo];
+ }
+
+ void ClassContainer::Copy ( PClassContainer CContainer ) {
+ int i;
+ FreeContainer();
+ if (CContainer) {
+ length = CContainer->length;
+ if (length>0) {
+ Container = new PContainerClass[length];
+ for (i=0;i<length;i++)
+ if (CContainer->Container[i]) {
+ Container[i] = MakeContainerClass (
+ CContainer->Container[i]->GetClassID() );
+ Container[i]->Copy ( CContainer->Container[i] );
+ } else
+ Container[i] = NULL;
+ }
+ }
+ }
+
+ void ClassContainer::read ( io::RFile f ) {
+ int i,ClassID;
+ byte Version;
+ FreeContainer();
+ f.ReadByte ( &Version );
+ f.ReadInt ( &length );
+ if (length>0) {
+ Container = new PContainerClass[length];
+ for (i=0;i<length;i++) {
+ f.ReadInt ( &ClassID );
+ if (ClassID>=0) {
+ Container[i] = MakeContainerClass ( ClassID );
+ Container[i]->read ( f );
+ } else
+ Container[i] = NULL;
+ }
+ }
+ }
+
+ MakeStreamFunctions(ClassContainer)
+
+
+
+ // ====================== ID parsers ==========================
+
+
+ AtomPath::AtomPath() : io::Stream() {
+ InitAtomPath();
+ }
+
+ AtomPath::AtomPath ( cpstr ID ) : io::Stream() {
+ InitAtomPath();
+ SetPath ( ID );
+ }
+
+ AtomPath::AtomPath ( io::RPStream Object ) : io::Stream(Object) {
+ InitAtomPath();
+ }
+
+ AtomPath::~AtomPath() {}
+
+ void AtomPath::InitAtomPath() {
+ modelNo = 0;
+ chainID [0] = char(0);
+ seqNum = MinInt4;
+ insCode [0] = char(0);
+ resName [0] = char(0);
+ atomName[0] = char(0);
+ element [0] = char(0);
+ altLoc [0] = char(0);
+ isSet = 0;
+ }
+
+ int AtomPath::SetPath ( cpstr ID ) {
+ // 1. If ID starts with '/':
+ // /mdl/chn/seq(res).i/atm[elm]:a
+ //
+ // 2. If ID starts with a letter:
+ // chn/seq(res).i/atm[elm]:a
+ //
+ // 3. If ID starts with a number:
+ // seq(res).i/atm[elm]:a
+ //
+ // 4. If ID contains colon ':' then
+ // it may be just
+ // atm[elm]:a
+ //
+ // All spaces are ignored. isSet
+ // sets bit for each element present.
+ // Any element may be a wildcard '*'.
+ // Wildcard for model will set modelNo=0,
+ // for sequence number will set
+ // seqNum=MinInt4.
+ //
+ // Returns:
+ // 0 <-> Ok
+ // -1 <-> wrong numerical format for model
+ // -2 <-> wrong numerical format for sequence number
+ //
+ char N[100];
+ pstr p,p1;
+ int i,k;
+
+ isSet = 0; // clear all bits.
+
+ p = pstr(ID);
+ while (*p==' ') p++;
+
+ if (!(*p)) return 0;
+
+ if (*p=='/') {
+ // model number
+ p++;
+ i = 0;
+ while ((*p) && (*p!='/')) {
+ if (*p!=' ') N[i++] = *p;
+ p++;
+ }
+ N[i] = char(0);
+ if ((!N[0]) || (N[0]=='*')) modelNo = 0;
+ else {
+ modelNo = mround(strtod(N,&p1));
+ if ((modelNo==0) && (p1==N)) return -1;
+ }
+ isSet |= APATH_ModelNo;
+ if (*p!='/') return 0;
+ p++;
+ while (*p==' ') p++;
+ }
+
+ if ((*p<'0') || (*p>'9')) {
+ // chain ID
+ i = 0;
+ k = sizeof(ChainID)-1;
+ while ((*p) && (*p!='/')) {
+ if ((*p!=' ') && (i<k)) chainID[i++] = *p;
+ p++;
+ }
+ chainID[i] = char(0);
+ if (!chainID[0]) {
+ chainID[0] = '*';
+ chainID[1] = char(0);
+ }
+ isSet |= APATH_ChainID;
+ if (*p!='/') return 0;
+ p++;
+ while (*p==' ') p++;
+ }
+
+ if (((*p>='0') && (*p<='9')) || (*p=='-') ||
+ (*p=='(') || (*p=='.')) {
+ // sequence number, residue name and insertion code
+ i = 0;
+ while ((*p) && (*p!='/')) {
+ if (*p!=' ') N[i++] = *p;
+ p++;
+ }
+ N[i] = char(0);
+ i = ParseResID ( N,seqNum,insCode,resName );
+ if (i==2) return -2;
+ isSet |= APATH_SeqNum | APATH_InsCode | APATH_ResName;
+ if (*p!='/') return 0;
+ p++;
+ while (*p==' ') p++;
+ }
+
+ if (strchr(p,':') || strchr(p,'[')) {
+ // atom name, chemical element and alternative location
+ i = 0;
+ while (*p) {
+ if (*p!=' ') N[i++] = *p;
+ p++;
+ }
+ N[i] = char(0);
+ ParseAtomID ( N,atomName,element,altLoc );
+ isSet |= APATH_AtomName | APATH_Element | APATH_AltLoc;
+ }
+
+ return 0;
+
+ }
+
+ void AtomPath::write ( io::RFile f ) {
+ byte Version=1;
+ f.WriteByte ( &Version );
+ io::Stream::write ( f );
+ f.WriteInt ( &modelNo );
+ f.WriteInt ( &seqNum );
+ f.WriteInt ( &isSet );
+ f.WriteTerLine ( chainID ,false );
+ f.WriteTerLine ( insCode ,false );
+ f.WriteTerLine ( resName ,false );
+ f.WriteTerLine ( atomName,false );
+ f.WriteTerLine ( element ,false );
+ f.WriteTerLine ( altLoc ,false );
+ }
+
+ void AtomPath::read ( io::RFile f ) {
+ byte Version;
+ f.ReadByte ( &Version );
+ io::Stream::read ( f );
+ f.ReadInt ( &modelNo );
+ f.ReadInt ( &seqNum );
+ f.ReadInt ( &isSet );
+ f.ReadTerLine ( chainID ,false );
+ f.ReadTerLine ( insCode ,false );
+ f.ReadTerLine ( resName ,false );
+ f.ReadTerLine ( atomName,false );
+ f.ReadTerLine ( element ,false );
+ f.ReadTerLine ( altLoc ,false );
+ }
+
+
+ MakeStreamFunctions(AtomPath)
+
+
+
+ // --------------------------------------------------------
+
+ QuickSort::QuickSort() : io::Stream() {
+ selSortLimit = 15;
+ data = NULL;
+ dlen = 0;
+ }
+
+ QuickSort::QuickSort ( io::RPStream Object )
+ : io::Stream(Object) {
+ selSortLimit = 15;
+ data = NULL;
+ dlen = 0;
+ }
+
+ int QuickSort::Compare ( int i, int j ) {
+ // sort by increasing data[i]
+ if (((ivector)data)[i]<((ivector)data)[j]) return -1;
+ if (((ivector)data)[i]>((ivector)data)[j]) return 1;
+ return 0;
+ }
+
+ void QuickSort::Swap ( int i, int j ) {
+ int b;
+ b = ((ivector)data)[i];
+ ((ivector)data)[i] = ((ivector)data)[j];
+ ((ivector)data)[j] = b;
+ }
+
+ void QuickSort::SelectionSort ( int left, int right ) {
+ int i,j,imin;
+ for (i=left;i<right;i++) {
+ imin = i;
+ for (j=i+1;j<=right;j++)
+ if (Compare(j,imin)<0) imin = j;
+ Swap ( i,imin );
+ }
+ }
+
+ int QuickSort::Partition ( int left, int right ) {
+ int lv = left;
+ int lm = left-1;
+ int rm = right+1;
+ do {
+ do
+ rm--;
+ while ((rm>0) && (Compare(rm,lv)>0));
+ do
+ lm++;
+ while ((lm<dlen) && (Compare(lm,lv)<0));
+ if (lm<rm) {
+ if (lv==lm) lv = rm;
+ else if (lv==rm) lv = lm;
+ Swap ( lm,rm );
+ }
+ } while (lm<rm);
+ return rm;
+ }
+
+ void QuickSort::Quicksort ( int left, int right ) {
+ int split_pt;
+ if (left<(right-selSortLimit)) {
+ split_pt = Partition ( left,right );
+ Quicksort ( left,split_pt );
+ Quicksort ( split_pt+1,right );
+ } else
+ SelectionSort ( left,right );
+ }
+
+ void QuickSort::Sort ( void * sortdata, int data_len ) {
+ data = sortdata;
+ dlen = data_len-1;
+ if (data) Quicksort ( 0,data_len-1 );
+ }
+
+ // --------------------------------------------------------
+
+ void takeWord ( pstr & p, pstr wrd, cpstr ter, int l ) {
+ pstr p1;
+ int i;
+ p1 = strpbrk ( p,ter );
+ if (!p1)
+ p1 = p + strlen(p);
+ i = 0;
+ while ((p!=p1) && (i<l)) {
+ wrd[i++] = *p;
+ p++;
+ }
+ if (i>=l) i = l-1;
+ wrd[i] = char(0);
+ p = p1;
+ }
+
+
+ void ParseAtomID ( cpstr ID, AtomName aname, Element elname,
+ AltLoc aloc ) {
+ pstr p;
+
+ p = pstr(ID);
+ while (*p==' ') p++;
+
+ strcpy ( aname ,"*" );
+ strcpy ( elname,"*" );
+ if (*p) aloc[0] = char(0);
+ else strcpy ( aloc,"*" );
+
+ takeWord ( p,aname,pstr("[: "),sizeof(AtomName) );
+
+ if (*p=='[') {
+ p++;
+ takeWord ( p,elname,pstr("]: "),sizeof(Element) );
+ if (*p==']') p++;
+ }
+
+ if (*p==':') {
+ p++;
+ takeWord ( p,aloc,pstr(" "),sizeof(AltLoc) );
+ }
+
+ }
+
+ int ParseResID ( cpstr ID, int & sn, InsCode inscode,
+ ResName resname ) {
+ int RC;
+ pstr p,p1;
+ char N[100];
+
+ RC = 0;
+
+ p = pstr(ID);
+ while (*p==' ') p++;
+
+ sn = ANY_RES;
+ strcpy ( inscode,"*" );
+ strcpy ( resname,"*" );
+
+ N[0] = char(0);
+ takeWord ( p,N,pstr("(./ "),sizeof(N) );
+ if ((!N[0]) || (N[0]=='*')) {
+ sn = ANY_RES;
+ RC = 1;
+ }
+ if (!RC) {
+ sn = mround(strtod(N,&p1));
+ if (p1==N) RC = 2;
+ else inscode[0] = char(0);
+ }
+
+ if (*p=='(') {
+ p++;
+ takeWord ( p,resname,pstr(")./ "),sizeof(ResName) );
+ if (*p==')') p++;
+ }
+
+ if (*p=='.') {
+ p++;
+ takeWord ( p,inscode,pstr("/ "),sizeof(InsCode) );
+ }
+
+ return RC;
+
+ }
+
+ int ParseAtomPath ( cpstr ID,
+ int & mdl,
+ ChainID chn,
+ int & sn,
+ InsCode ic,
+ ResName res,
+ AtomName atm,
+ Element elm,
+ AltLoc aloc,
+ PAtomPath DefPath ) {
+ // /mdl/chn/seq(res).i/atm[elm]:a, may be partial
+ char N[100];
+ pstr p,p1;
+ int i,RC;
+ bool wasRes;
+
+ wasRes = false;
+
+ RC = 0;
+
+ p = pstr(ID);
+ while (*p==' ') p++;
+
+ mdl = 0;
+ if (*p=='/') {
+ p++;
+ N[0] = char(0);
+ takeWord ( p,N,pstr("/"),sizeof(N) );
+ if ((!N[0]) || (N[0]=='*')) mdl = 0;
+ else {
+ mdl = mround(strtod(N,&p1));
+ if ((mdl==0) && (p1==N)) return -1;
+ }
+ } else if (DefPath) {
+ if (DefPath->isSet & APATH_ModelNo)
+ mdl = DefPath->modelNo;
+ }
+
+ strcpy ( chn,"*" );
+ if (*p=='/') p++;
+ if ((*p<'0') || (*p>'9')) {
+ p1 = p;
+ chn[0] = char(0);
+ takeWord ( p,chn,pstr("/"),sizeof(ChainID) );
+ if (strpbrk(chn,"(.[:-")) { // this was not a chain ID!
+ if (DefPath) {
+ if (DefPath->isSet & APATH_ChainID)
+ strcpy ( chn,DefPath->chainID );
+ } else
+ strcpy ( chn,"*" );
+ p = p1;
+ }
+ } else if (DefPath) {
+ if (DefPath->isSet & APATH_ChainID)
+ strcpy ( chn,DefPath->chainID );
+ }
+
+ if (*p=='/') p++;
+ sn = ANY_RES;
+ strcpy ( ic ,"*" );
+ strcpy ( res,"*" );
+ if (((*p>='0') && (*p<='9')) || (*p=='-') ||
+ (*p=='(') || (*p=='.')) {
+ wasRes = true;
+ N[0] = char(0);
+ takeWord ( p,N,pstr("/"),sizeof(N) );
+ i = ParseResID ( N,sn,ic,res );
+ if (i==2) return -2;
+ } else if (DefPath) {
+ wasRes = (*p=='/');
+ if (DefPath->isSet & APATH_SeqNum)
+ sn = DefPath->seqNum;
+ if (DefPath->isSet & APATH_InsCode)
+ strcpy ( ic,DefPath->insCode );
+ if (DefPath->isSet & APATH_ResName)
+ strcpy ( res,DefPath->resName );
+ }
+
+ if (*p=='/') p++;
+ strcpy ( atm ,"*" );
+ strcpy ( elm ,"*" );
+ strcpy ( aloc,"*" );
+ if (wasRes || strchr(p,':') || strchr(p,'[')) {
+ ParseAtomID ( p,atm,elm,aloc );
+ } else if (DefPath) {
+ if (DefPath->isSet & APATH_AtomName)
+ strcpy ( atm,DefPath->atomName );
+ if (DefPath->isSet & APATH_Element)
+ strcpy ( elm,DefPath->element );
+ if (DefPath->isSet & APATH_ResName)
+ strcpy ( aloc,DefPath->altLoc );
+ }
+
+ if (mdl<=0) RC |= APATH_WC_ModelNo;
+ if (chn[0]=='*') RC |= APATH_WC_ChainID;
+ if (sn==ANY_RES) RC |= APATH_WC_SeqNum;
+ if (ic[0]=='*') RC |= APATH_WC_InsCode;
+ if (res[0]=='*') RC |= APATH_WC_ResName;
+ if (atm[0]=='*') RC |= APATH_WC_AtomName;
+ if (elm[0]=='*') RC |= APATH_WC_Element;
+ if (aloc[0]=='*') RC |= APATH_WC_AltLoc;
+
+ if (RC & (APATH_WC_ModelNo | APATH_WC_ChainID |
+ APATH_WC_SeqNum | APATH_WC_InsCode |
+ APATH_WC_AtomName | APATH_WC_AltLoc))
+ RC |= APATH_Incomplete;
+
+ return RC;
+
+ }
+
+
+ int ParseSelectionPath (
+ cpstr CID,
+ int & iModel,
+ pstr Chains,
+ int & sNum1,
+ InsCode ic1,
+ int & sNum2,
+ InsCode ic2,
+ pstr RNames,
+ pstr ANames,
+ pstr Elements,
+ pstr altLocs
+ ) {
+ int l,j;
+ pstr p,p1;
+ pstr N;
+ int seqNum [2];
+ InsCode insCode[2];
+ pstr ID;
+ bool wasModel,wasChain,wasRes,haveNeg;
+
+ l = IMax(10,strlen(CID))+1;
+ ID = new char[l];
+ N = new char[l];
+
+ p = pstr(CID);
+ p1 = ID;
+ while (*p) {
+ if (*p!=' ') {
+ *p1 = *p;
+ p1++;
+ }
+ p++;
+ }
+ *p1 = char(0);
+
+ p = ID;
+
+ iModel = 0;
+ strcpy ( Chains,"*" );
+ seqNum[0] = ANY_RES;
+ seqNum[1] = ANY_RES;
+ strcpy ( insCode[0],"*" );
+ strcpy ( insCode[1],"*" );
+ strcpy ( RNames ,"*" );
+ strcpy ( ANames ,"*" );
+ strcpy ( Elements ,"*" );
+ strcpy ( altLocs ,"*" );
+
+ wasModel = false;
+ wasChain = false;
+ wasRes = false;
+
+ if (*p=='/') {
+ // CID starts with the slash -- take model number first
+ p++;
+ N[0] = char(0);
+ takeWord ( p,N,pstr("/"),l );
+ if ((!N[0]) || (N[0]=='*')) iModel = 0;
+ else {
+ iModel = mround(strtod(N,&p1));
+ if ((iModel==0) && (p1==N)) return -1;
+ }
+ if (*p=='/') p++;
+ wasModel = true;
+ }
+
+ if ((*p) && (wasModel || (*p<'0') || (*p>'9'))) {
+ p1 = p;
+ Chains[0] = char(0);
+ takeWord ( p,Chains,pstr("/"),l );
+ if (strpbrk(Chains,"(.[:-")) { // this was not a chain ID!
+ strcpy ( Chains,"*" );
+ p = p1;
+ } else
+ wasChain = true;
+ if (*p=='/') p++;
+ }
+
+ if ((*p) && (wasChain || ((*p>='0') && (*p<='9')) || (*p=='-') ||
+ (*p=='(') || (*p=='.') || (*p=='*'))) {
+ j = 0;
+ do {
+ // take the sequence number
+ haveNeg = false;
+ if (*p=='-') {
+ haveNeg = true;
+ p++;
+ }
+ N[0] = char(0);
+ takeWord ( p,N,pstr("(.-/"),l );
+ if ((!N[0]) || (N[0]=='*'))
+ seqNum[j] = ANY_RES;
+ else {
+ seqNum[j] = mround(strtod(N,&p1));
+ if (p1==N) return -2;
+ if (haveNeg) seqNum[j] = - seqNum[j];
+ }
+ // take the residue list
+ if (*p=='(') {
+ p++;
+ takeWord ( p,RNames,pstr(").-/"),l );
+ if (*p==')') p++;
+ }
+ // take the insertion code
+ if (seqNum[j]!=ANY_RES)
+ insCode[j][0] = char(0);
+ if (*p=='.') {
+ p++;
+ takeWord ( p,insCode[j],pstr("-/"),sizeof(InsCode) );
+ }
+ if (*p=='-') {
+ p++;
+ j++;
+ } else {
+ if (j==0) {
+ seqNum[1] = seqNum[0];
+ strcpy ( insCode[1],insCode[0] );
+ }
+ j = 10;
+ }
+ } while (j<2);
+ wasRes = true;
+ } else
+ wasRes = (*p=='/');
+
+ if (*p=='/') p++;
+ if ((*p) && (wasRes || strchr(p,':') || strchr(p,'['))) {
+ if (*p) altLocs[0] = char(0);
+ takeWord ( p,ANames,pstr("[:"),l );
+ if (!ANames[0]) strcpy ( ANames,"*" );
+ if (*p=='[') {
+ p++;
+ takeWord ( p,Elements,pstr("]:"),l );
+ if (*p==']') p++;
+ }
+ if (*p==':') {
+ p++;
+ takeWord ( p,altLocs,pstr(" "),l );
+ }
+ }
+
+ /*
+ printf ( " iModel = %i\n"
+ " Chains = '%s'\n"
+ " seqNum1 = %i\n"
+ " insCode1 = '%s'\n"
+ " seqNum2 = %i\n"
+ " insCode2 = '%s'\n"
+ " RNames = '%s'\n"
+ " ANames = '%s'\n"
+ " Elements = '%s'\n"
+ " altLocs = '%s'\n",
+ iModel,Chains,seqNum[0],insCode[0],
+ seqNum[1],insCode[1],RNames,ANames,
+ Elements,altLocs );
+ */
+
+ sNum1 = seqNum[0];
+ sNum2 = seqNum[1];
+ strcpy ( ic1,insCode[0] );
+ strcpy ( ic2,insCode[1] );
+
+ delete[] ID;
+ delete[] N;
+
+ return 0;
+
+ }
+
+
+ void MakeSelectionPath (
+ pstr CID,
+ int iModel,
+ cpstr Chains,
+ int sNum1,
+ const InsCode ic1,
+ int sNum2,
+ const InsCode ic2,
+ cpstr RNames,
+ cpstr ANames,
+ cpstr Elements,
+ cpstr altLocs
+ ) {
+ char S[100];
+ int k;
+
+ if (iModel>0) {
+ sprintf ( CID,"/%i",iModel );
+ k = 1;
+ } else {
+ CID[0] = char(0);
+ k = 0;
+ }
+
+ if (Chains[0]!='*') {
+ if (k>0) strcat ( CID,"/" );
+ strcat ( CID,Chains );
+ k = 2;
+ }
+
+ if ((sNum1!=-MaxInt4) || (ic1[0]!='*')) {
+ if (k>0) {
+ if (k<2) strcat ( CID,"/*" );
+ strcat ( CID,"/" );
+ }
+ if (sNum1>-MaxInt4) sprintf ( S,"%i",sNum1 );
+ else strcpy ( S,"*" );
+ if (ic1[0]!='*') {
+ strcat ( S,"." );
+ strcat ( S,ic1 );
+ }
+ strcat ( CID,S );
+
+ if ((sNum2!=-MaxInt4) || (ic2[0]!='*')) {
+ strcat ( CID,"-" );
+ if (sNum1>-MaxInt4) sprintf ( S,"%i",sNum2 );
+ else strcpy ( S,"*" );
+ if (ic2[0]!='*') {
+ strcat ( S,"." );
+ strcat ( S,ic2 );
+ }
+ strcat ( CID,S );
+ }
+
+ k = 3;
+
+ }
+
+ if (RNames[0]!='*') {
+ if (k<1) strcat ( CID,"(" );
+ else if (k<2) strcat ( CID,"*/*(" );
+ else if (k<3) strcat ( CID,"/*(" );
+ strcat ( CID,RNames );
+ strcat ( CID,")" );
+ k = 4;
+ }
+
+ if (ANames[0]!='*') {
+ if (k<1) strcat ( CID,"/*/*/*/" ); // full path
+ else if (k<2) strcat ( CID,"/*/*/" ); // /mdl + /*/*/
+ else if (k<3) strcat ( CID,"/*/" ); // /mdl/chn + /*/
+ else if (k<4) strcat ( CID,"/" ); // /mdl/chn/res + /
+ strcat ( CID,ANames );
+ strcat ( CID,")" );
+ k = 5;
+ }
+
+ if (Elements[0]!='*') {
+ if (k<1) strcat ( CID,"[" );
+ else if (k<2) strcat ( CID,"/*/*/*[" );
+ else if (k<3) strcat ( CID,"/*/*[" );
+ else if (k<4) strcat ( CID,"/*[" );
+ else if (k<5) strcat ( CID,"[" );
+ strcat ( CID,Elements );
+ strcat ( CID,"]" );
+ k = 6;
+ }
+
+ if (altLocs[0]!='*') {
+ if (k<1) strcat ( CID,":" );
+ else if (k<2) strcat ( CID,"/*/*/*:" );
+ else if (k<3) strcat ( CID,"/*/*:" );
+ else if (k<4) strcat ( CID,"/*:" );
+ else if (k<6) strcat ( CID,":" );
+ strcat ( CID,altLocs );
+ }
+
+ }
+
+} // namespace mmdb
+
diff --git a/mmdb2/mmdb_utils.h b/mmdb2/mmdb_utils.h
new file mode 100644
index 0000000..e17ed74
--- /dev/null
+++ b/mmdb2/mmdb_utils.h
@@ -0,0 +1,633 @@
+// $Id: mmdb_utils.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2008.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 12.09.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDBF_Utils <interface>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+//
+// **** Classes : mmdb::ContainerClass ( containered class template )
+// ~~~~~~~~~ mmdb::ContString ( containered string )
+// mmdb::ClassContainer ( container of classes )
+// mmdb::AtomPath ( atom path ID )
+// mmdb::QuickSort ( quick sort of integers )
+//
+// **** Functions : Date9to11 ( DD-MMM-YY -> DD-MMM-YYYY )
+// ~~~~~~~~~~~ Date11to9 ( DD-MMM-YYYY -> DD-MMM-YY )
+// Date9toCIF ( DD-MMM-YY -> YYYY-MM-DD )
+// Date11toCIF( DD-MMM-YYYY -> YYYY-MM-DD )
+// DateCIFto9 ( YYYY-MM-DD -> DD-MMM-YY )
+// DateCIFto11( YYYY-MM-DD -> DD-MMM-YYYY )
+// GetInteger ( reads integer from a string )
+// GetReal ( reads real from a string )
+// GetIntIns ( reads integer and insert code )
+// PutInteger ( writes integer into a string )
+// PutRealF ( writes real in F-form into a string )
+// PutIntIns ( writes integer and insert code )
+// CIFGetInteger ( reads and deletes int from CIF )
+// CIFGetReal ( reads and deletes real from CIF )
+// CIFGetString ( reads and deletes string from CIF)
+// CIFGetInteger1 (reads and del-s int from CIF loop)
+// CIFGetReal1 (reads and del-s int from CIF loop)
+// Mat4Inverse ( inversion of 4x4 matrices )
+// GetErrorDescription (ascii line to an Error_XXXXX)
+// ParseAtomID ( parses atom ID line )
+// ParseResID ( parses residue ID line )
+// ParseAtomPath ( parses full atom path )
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_Utils__
+#define __MMDB_Utils__
+
+#include "mmdb_io_stream.h"
+#include "mmdb_mmcif_.h"
+#include "mmdb_defs.h"
+
+namespace mmdb {
+
+ // ================== Date functions ===================
+
+ // converts DD-MMM-YY to DD-MMM-YYYY; appends terminating zero
+ extern void Date9to11 ( cpstr Date9, pstr Date11 );
+
+ // converts DD-MMM-YYYY to DD-MMM-YY; does not append terminating zero
+ extern void Date11to9 ( cpstr Date11, pstr Date9 );
+
+ // converts DD-MMM-YY to YYYY-MM-DD; appends terminating zero
+ extern void Date9toCIF ( cpstr Date9, pstr DateCIF );
+
+ // converts DD-MMM-YYYY to YYYY-MM-DD; appends terminating zero
+ extern void Date11toCIF ( cpstr Date11, pstr DateCIF );
+
+ // converts YYYY-MM-DD to DD-MMM-YY; appends terminating zero
+ extern void DateCIFto9 ( cpstr DateCIF, pstr Date9 );
+
+ // converts YYYY-MM-DD to DD-MMM-YYYY; appends terminating zero
+ extern void DateCIFto11 ( cpstr DateCIF, pstr Date11 );
+
+
+ // ================= Format functions ==================
+
+ // Returns true if S contains an integer number in its
+ // first M characters. This number is returned in N.
+ // The return is false if no integer number may be
+ // recognized. In this case, N is assigned MinInt4 value.
+ extern bool GetInteger ( int & N, cpstr S, int M );
+
+ // Returns true if S contains a real number in its
+ // first M characters. This number is returned in R.
+ // The return is false if no real number may be
+ // recognized. In this case, R is assigned -MaxReal value.
+ extern bool GetReal ( realtype & R, cpstr S, int M );
+
+ // Returns true if S contains an integer number in its
+ // first M characters. This number is returned in N. In addition
+ // to that, GetIntIns() retrieves the insertion code which may
+ // follow the integer and returns it in "ins" (1 character +
+ // terminating 0).
+ // The return is false if no integer number may be
+ // recognized. In this case, N is assigned MinInt4 value,
+ // "ins" just returns (M+1)th symbol of S (+terminating 0).
+ extern bool GetIntIns ( int & N, pstr ins, cpstr S, int M );
+
+ // Integer N is converted into ASCII string of length M
+ // and pasted onto first M characters of string S. No
+ // terminating zero is added.
+ // If N is set to MinInt4, then first M characters of
+ // string S are set to space.
+ extern void PutInteger ( pstr S, int N, int M );
+
+ // Real R is converted into ASCII string of length M
+ // and pasted onto first M characters of string S. No
+ // terminating zero is added. The conversion is done
+ // according to fixed format FM.L
+ // If R is set to -MaxReal, then first M characters of
+ // string S are set to the space character.
+ extern void PutRealF ( pstr S, realtype R, int M, int L );
+
+ // Integer N is converted into ASCII string of length M
+ // and pasted onto first M characters of string S. No
+ // terminating zero is added. The insert code ins is put
+ // immediately after the integer.
+ // If N is set to MinInt4, then first M+1 characters of
+ // string S are set to space, and no insert code are
+ // appended.
+ extern void PutIntIns ( pstr S, int N, int M, cpstr ins );
+
+
+ // CIFInteger(..), CIFReal(..) and CIFGetString(..) automate
+ // extraction and analysis of data from CIF file. If the data
+ // is erroneous or absent, they store an error message in
+ // CIFErrorLocation string (below) and return non-zero.
+ extern ERROR_CODE CIFGetInteger ( int & I, mmcif::PStruct Struct,
+ cpstr Tag,
+ bool Remove=true );
+ extern ERROR_CODE CIFGetReal ( realtype & R, mmcif::PStruct Struct,
+ cpstr Tag,
+ bool Remove=true );
+ extern ERROR_CODE CIFGetString ( pstr S, mmcif::PStruct Struct,
+ cpstr Tag, int SLen,
+ cpstr DefS,
+ bool Remove=true );
+
+ extern ERROR_CODE CIFGetInteger ( int & I, mmcif::PLoop Loop, cpstr Tag,
+ int & Signal );
+ extern ERROR_CODE CIFGetIntegerD ( int & I, mmcif::PLoop Loop, cpstr Tag,
+ int defValue=MinInt4 );
+ extern ERROR_CODE CIFGetInteger1 ( int & I, mmcif::PLoop Loop, cpstr Tag,
+ int nrow );
+
+ extern ERROR_CODE CIFGetReal ( realtype & R, mmcif::PLoop Loop,
+ cpstr Tag, int & Signal );
+ extern ERROR_CODE CIFGetReal1 ( realtype & R, mmcif::PLoop Loop,
+ cpstr Tag, int nrow );
+
+ extern ERROR_CODE CIFGetString ( pstr S, mmcif::PLoop Loop, cpstr Tag,
+ int row, int SLen, cpstr DefS );
+
+ // Calculates AI=A^{-1}
+ extern void Mat4Inverse ( mat44 & A, mat44 & AI );
+ // Calculates A=B*C
+ extern void Mat4Mult ( mat44 & A, mat44 & B, mat44 & C );
+ // Calculates A=B^{-1}*C
+ extern void Mat4Div1 ( mat44 & A, mat44 & B, mat44 & C );
+ // Calculates A=B*C^{-1}
+ extern void Mat4Div2 ( mat44 & A, mat44 & B, mat44 & C );
+ // Calculates determinant of the rotation part
+ extern realtype Mat4RotDet ( mat44 & T );
+
+ // Sets up a unit matrix
+ extern void Mat4Init ( mat44 & A );
+ extern void Mat3Init ( mat33 & A );
+
+ // Calculates AI=A^{-1}, returns determinant
+ extern realtype Mat3Inverse ( mat33 & A, mat33 & AI );
+
+ extern bool isMat4Unit ( mat44 & A, realtype eps, bool rotOnly );
+
+ // Copies A into AC
+ extern void Mat4Copy ( mat44 & A, mat44 & ACopy );
+ extern void Mat3Copy ( mat33 & A, mat33 & ACopy );
+ extern bool isMat4Eq ( mat44 & A, mat44 & B, realtype eps,
+ bool rotOnly );
+
+ extern void TransformXYZ ( mat44 & T,
+ realtype & X, realtype & Y, realtype & Z );
+ extern realtype TransformX ( mat44 & T,
+ realtype X, realtype Y, realtype Z );
+ extern realtype TransformY ( mat44 & T,
+ realtype X, realtype Y, realtype Z );
+ extern realtype TransformZ ( mat44 & T,
+ realtype X, realtype Y, realtype Z );
+
+
+ extern char CIFErrorLocation[200];
+
+ // Returns ASCII string explaining the nature of
+ // Error_xxxx error code.
+ extern cpstr GetErrorDescription ( ERROR_CODE ErrorCode );
+
+
+
+ // ================ ContainerClass ====================
+
+ DefineClass(ContainerClass);
+ DefineStreamFunctions(ContainerClass);
+
+ class ContainerClass : public io::Stream {
+
+ friend class ClassContainer;
+
+ public :
+
+ ContainerClass ();
+ ContainerClass ( io::RPStream Object );
+ ~ContainerClass() {}
+
+ // ConvertPDBASCII(..) will return one of the Error_XXXXX
+ // constants, see <mmdb_defs.h>
+ virtual ERROR_CODE ConvertPDBASCII ( cpstr )
+ { return Error_NoError; }
+ virtual void PDBASCIIDump ( pstr, int ) {}
+ virtual bool PDBASCIIDump1 ( io::RFile ) { return false; }
+ virtual void MakeCIF ( mmcif::PData, int ) {}
+
+ // Append(..) should return true if CC is appended to this class.
+ // If this is not the case, CC is merely put on the top of
+ // container.
+ // Note: Append(..) detects the necessity to append CC and
+ // performs all the necessary actions for that. The rest of CC
+ // will be disposed by Class Container.
+ // Note: Class Container checks every new class, which is
+ // being added to it (see CClassContainer::AddData(..)), only
+ // against the top of container.
+ virtual bool Append ( PContainerClass CC );
+
+ // GetCIF(..) extracts any necessary information from CIF and
+ // returns in Signal:
+ // Error_noError : the information was successfully extracted,
+ // this instance of container class should be
+ // stored, and unchanged value of Signal should
+ // be passed to the next (newly created) instance
+ // of this container class.
+ // Error_EmptyCIF : there is no information for this type of
+ // containers to extract. This instance of
+ // container class should be deleted and input
+ // for this type of container class terminated.
+ // Other : the corresponding error. This instance of
+ // container class should be deleted and the
+ // whole input stopped.
+ virtual ERROR_CODE GetCIF ( mmcif::PData, int & n )
+ { n = -1; return Error_EmptyCIF; }
+ virtual CLASS_ID GetClassID () { return ClassID_Template; }
+
+ virtual void Copy ( PContainerClass ) {}
+
+ void write ( io::RFile ) {}
+ void read ( io::RFile ) {}
+
+ protected :
+ int ContinuationNo;
+
+ };
+
+
+ // ======================== ContString =========================
+
+ DefineClass(ContString);
+ DefineStreamFunctions(ContString);
+
+ class ContString : public ContainerClass {
+
+ public :
+
+ pstr Line; // a string
+
+ ContString ();
+ ContString ( cpstr S );
+ ContString ( io::RPStream Object );
+ ~ContString();
+
+ ERROR_CODE ConvertPDBASCII ( cpstr S );
+ void PDBASCIIDump ( pstr S, int N );
+ bool PDBASCIIDump1 ( io::RFile f );
+ void MakeCIF ( mmcif::PData CIF, int N );
+// void GetCIF1 ( mmcif::PData CIF, ERROR_CODE & Signal,
+// int & pos );
+ bool Append ( PContainerClass ContString );
+ CLASS_ID GetClassID () { return ClassID_String; }
+
+ void Copy ( PContainerClass CString );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+ pstr CIFCategory,CIFTag;
+
+ void InitString();
+
+ };
+
+
+ // ============== ClassContainer ====================
+
+ DefineClass(ClassContainer);
+ DefineStreamFunctions(ClassContainer);
+
+ class ClassContainer : public io::Stream {
+
+ public :
+
+ ClassContainer ();
+ ClassContainer ( io::RPStream Object );
+ ~ClassContainer ();
+
+ void FreeContainer ();
+ void AddData ( PContainerClass Data );
+ virtual void PDBASCIIDump ( io::RFile f );
+ virtual void MakeCIF ( mmcif::PData CIF );
+ // GetCIF(..) will return one of the Error_XXXXX constants,
+ // see <mmdb_defs.h>
+ virtual ERROR_CODE GetCIF ( mmcif::PData CIF, int ClassID );
+ virtual PContainerClass MakeContainerClass ( int ClassID );
+
+ // Copy will empty the class if parameter is set to NULL
+ virtual void Copy ( PClassContainer CContainer );
+
+ inline int Length() { return length; }
+ PContainerClass GetContainerClass ( int ContClassNo );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+ int length;
+ PPContainerClass Container;
+
+ void Init();
+
+ };
+
+
+ // ====================== ID parsers ==========================
+
+ DefineClass(AtomPath);
+ DefineStreamFunctions(AtomPath);
+
+ enum APATH_FLAG {
+ APATH_ModelNo = 0x00000001,
+ APATH_ChainID = 0x00000002,
+ APATH_SeqNum = 0x00000004,
+ APATH_InsCode = 0x00000008,
+ APATH_ResName = 0x00000010,
+ APATH_AtomName = 0x00000020,
+ APATH_Element = 0x00000040,
+ APATH_AltLoc = 0x00000080,
+ APATH_Incomplete = 0x00000100,
+ APATH_WC_ModelNo = 0x00001000,
+ APATH_WC_ChainID = 0x00002000,
+ APATH_WC_SeqNum = 0x00004000,
+ APATH_WC_InsCode = 0x00008000,
+ APATH_WC_ResName = 0x00010000,
+ APATH_WC_AtomName = 0x00020000,
+ APATH_WC_Element = 0x00040000,
+ APATH_WC_AltLoc = 0x00080000
+ };
+
+ class AtomPath : public io::Stream {
+
+ public :
+
+ int modelNo;
+ ChainID chainID;
+ int seqNum;
+ InsCode insCode;
+ ResName resName;
+ AtomName atomName;
+ Element element;
+ AltLoc altLoc;
+ int isSet;
+
+ AtomPath ();
+ AtomPath ( cpstr ID );
+ AtomPath ( io::RPStream Object );
+ ~AtomPath ();
+
+ // SetPath(..) parses the Atom Path ID string, which
+ // may be incomplete. Below {..} means blocks that
+ // may be omitted; any elements within such blocks
+ // may be omitted as well.
+ //
+ // 1. If ID starts with '/' then the ID must be of
+ // the following form:
+ // /mdl{/chn{/seq(res).i{/atm[elm]:a}}}
+ //
+ // 2. If ID starts with a letter:
+ // chn{/seq(res).i{/atm[elm]:a}}
+ //
+ // 3. If ID starts with a number or '(':
+ // seq(res).i{/atm[elm]:a}
+ //
+ // 4. If ID contains colon ':' or '[' then
+ // it may be just
+ // atm[elm]:a
+ //
+ // The following are valid samples of IDs:
+ //
+ // /1 model number 1
+ // /1/A/23(GLU).A/CA[C]:A model number 1, chain A,
+ // residue 23 GLU insertion code A, C-alpha
+ // atom in alternative location A
+ // A/23 residue 23 of chain A
+ // CA[C]: atom C-alpha
+ // [C] a carbon
+ // *[C]:* same as above
+ // :A an atom with insertion code A
+ // 5 residue number 5
+ // (GLU) residue GLU
+ //
+ // All spaces are ignored. SetPath(..) sets bit of isSet
+ // for each element present. Any element may be a wildcard
+ // '*'. Wildcard for model will set modelNo=0, for sequence
+ // number will set seqNum=MinInt4.
+ //
+ // Returns:
+ // 0 <-> Ok
+ // -1 <-> wrong numerical format for model
+ // -2 <-> wrong numerical format for sequence number
+ int SetPath ( cpstr ID );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected :
+ void InitAtomPath();
+
+ };
+
+
+ // --------------------------------------------------------------
+
+ DefineClass(QuickSort);
+
+ class QuickSort : public io::Stream {
+
+ public :
+ QuickSort ();
+ QuickSort ( io::RPStream Object );
+ ~QuickSort() {}
+ virtual int Compare ( int i, int j );
+ virtual void Swap ( int i, int j );
+ void Sort ( void * sortdata, int data_len );
+
+ protected :
+ int selSortLimit,dlen;
+ void * data;
+
+ void SelectionSort ( int left, int right );
+ int Partition ( int left, int right );
+ void Quicksort ( int left, int right );
+
+ };
+
+
+ // --------------------------------------------------------------
+
+ extern void takeWord ( pstr & p, pstr wrd, cpstr ter, int l );
+
+ // ParseAtomID(..) reads the atom ID of the following form:
+ // {name} {[element]} {:altcode}
+ // (here {} means that the item may be omitted; any field may have
+ // value of wildcard '*'), and returns the atom name in aname,
+ // element name - in elname, and alternate location code - in aloc.
+ // Except for the alternate location code, missing items are
+ // replaced by wildcards. Missing alternate location code is
+ // returned as empty string "".
+ // Leading spaces are allowed; any other space will terminate
+ // the parsing.
+ // The followings are perfectly valid atom IDs:
+ // CA[C]:A (carbon C_alpha in location A)
+ // CA[*]:A (either C_alpha or Ca in location A)
+ // CA:A (same as above)
+ // CA (either C_alpha or Ca with no location indicator)
+ // CA[] (same as above)
+ // CA[C]: (C_alpha with no location indicator)
+ // [C] (any carbon with no location indicator)
+ // [C]:* (any carbon with any location indicator)
+ // *[C]:* (same as above)
+ // :A (any atom in location A)
+ // *[*]:A (same as above)
+ // *[*]:* (any atom)
+ // * (any atom with no alternate location indicator)
+ extern void ParseAtomID ( cpstr ID, AtomName aname,
+ Element elname, AltLoc aloc );
+
+ // ParseResID(..) reads the residue ID of the following form:
+ // {seqnum} {(name)} {.inscode}
+ // (here {} means that the item may be omitted; any field may have
+ // value of wildcard '*'), and returns the sequence number in sn,
+ // insertion code - in inscode, and residue name - in resname.
+ // If a wildcard was specified for the sequence number, then
+ // ParseResID(..) returns 1. Missing residue name is replaced by
+ // the wildcard '*', and misisng insertion code is returned as empty
+ // string "".
+ // Leading spaces are allowed; any other space will terminate
+ // the parsing.
+ // Return 0 means Ok, 1 - wildcard for the sequence number,
+ // 2 - an error in numerical format of the sequence number
+ // (other items are parsed).
+ // The followings are perfectly valid residue IDs:
+ // 27(ALA).A (residue 27A ALA)
+ // 27().A (residue 27A)
+ // 27(*).A (same as above)
+ // 27.A (same as above)
+ // 27 (residue 27)
+ // 27(). (same as above)
+ // (ALA) (any ALA without insertion code)
+ // (ALA). (same as above)
+ // (ALA).* (any ALA)
+ // *(ALA).* (any ALA)
+ // .A (any residue with insertion code A)
+ // *(*).A (same as above)
+ // *(*).* (any residue)
+ // * (any residue with no insertion code)
+ extern int ParseResID ( cpstr ID, int & sn,
+ InsCode inscode, ResName resname );
+
+
+ // ParseAtomPath(..) parses an atom path string of the following
+ // structure:
+ // /mdl/chn/seq(res).i/atm[elm]:a
+ // where all items may be represented by a wildcard '*' and
+ // mdl - model number (mandatory); at least model #1 is always
+ // present; returned in mdl; on a wildcard mdl is set to 0
+ // chn - chain identifier ( mandatory); returned in chn; on a
+ // wildcard chn is set to '*'
+ // seq - residue sequence number (mandatory); returned in sn;
+ // on a wild card ParseAtomPath(..) returns 1
+ // (res) - residue name in round brackets (may be omitted);
+ // returnded in res; on a wildcard res is set to '*'
+ // .i - insert code after a dot; if '.i' or 'i' is missing
+ // then a residue without an insertion code is looked for;
+ // returned in ic; on a wildcard (any insertion code would
+ // do) ic is set to '*'
+ // atm - atom name (mandatory); returned in atm; on a wildcard
+ // atm is set to '*'
+ // [elm] - chemical element code in square brackets; it may
+ // be omitted but could be helpful for e.g.
+ // distinguishing C_alpha and CA; returned in elm;
+ // in a wildcard elm is set to '*'
+ // :a - alternate location indicator after colon; if
+ // ':a' or 'a' is missing then an atom without
+ // alternate location indicator is looked for; returned
+ // in aloc; on a wildcard (any alternate code would do)
+ // aloc is set to '*'.
+ // All spaces are ignored, all identifiers should be in capital
+ // letters (comparisons are case-sensitive).
+ // The atom path string may be incomplete. If DefPath is supplied,
+ // the function will try to get missing elements from there. If
+ // missing items may not be found in DefPath, they are replaced by
+ // wildcards.
+ // ParseAtomPath(..) returns the following bits:
+ // 0 - Ok
+ // APATH_Incomplete - if path contains wildcards. Wildcards for
+ // residue name and chemical element will be
+ // ignored here if sequence number and
+ // atom name, correspondingly, are provided.
+ // APATH_WC_XXXXX - wildcard for different elements
+ // -1 - wrong numerical format for model (fatal)
+ // -2 - wrong numerical format for seqNum (fatal)
+
+ extern int ParseAtomPath ( cpstr ID,
+ int & mdl,
+ ChainID chn,
+ int & sn,
+ InsCode ic,
+ ResName res,
+ AtomName atm,
+ Element elm,
+ AltLoc aloc,
+ PAtomPath DefPath=NULL );
+
+
+
+ extern int ParseSelectionPath ( cpstr CID,
+ int & iModel,
+ pstr Chains,
+ int & sNum1,
+ InsCode ic1,
+ int & sNum2,
+ InsCode ic2,
+ pstr RNames,
+ pstr ANames,
+ pstr Elements,
+ pstr altLocs );
+
+
+
+ extern void MakeSelectionPath ( pstr CID,
+ int iModel,
+ cpstr Chains,
+ int sNum1,
+ const InsCode ic1,
+ int sNum2,
+ const InsCode ic2,
+ cpstr RNames,
+ cpstr ANames,
+ cpstr Elements,
+ cpstr altLocs );
+
+} // namespace mmdb
+
+#endif
+
diff --git a/mmdb2/mmdb_xml_.cpp b/mmdb2/mmdb_xml_.cpp
new file mode 100644
index 0000000..da0c532
--- /dev/null
+++ b/mmdb2/mmdb_xml_.cpp
@@ -0,0 +1,986 @@
+// $Id: mmdb_xml_.cpp $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 06.12.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_XML <implementation>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::xml::XMLObject
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "mmdb_xml_.h"
+
+namespace mmdb {
+
+ namespace xml {
+
+ // ====================== XMLObject ==========================
+
+ XMLObject::XMLObject() : io::Stream() {
+ InitXMLObject();
+ }
+
+ XMLObject::XMLObject ( cpstr Tag ) : io::Stream() {
+ InitXMLObject();
+ SetTag ( Tag );
+ }
+
+ XMLObject::XMLObject ( cpstr Tag, cpstr Data ) : io::Stream() {
+ InitXMLObject();
+ SetTag ( Tag );
+ SetData ( Data );
+ }
+
+ XMLObject::XMLObject ( cpstr Tag, realtype V, int length )
+ : io::Stream() {
+ InitXMLObject();
+ SetTag ( Tag );
+ SetData ( V,length );
+ }
+
+ XMLObject::XMLObject ( cpstr Tag, int iV, int length )
+ : io::Stream() {
+ InitXMLObject();
+ SetTag ( Tag );
+ SetData ( iV,length );
+ }
+
+ XMLObject::XMLObject ( cpstr Tag, bool bV ) : io::Stream() {
+ InitXMLObject();
+ SetTag ( Tag );
+ SetData ( bV );
+ }
+
+ XMLObject::XMLObject ( cpstr Tag, PXMLObject XMLObject )
+ : io::Stream() {
+ InitXMLObject();
+ SetTag ( Tag );
+ AddObject ( XMLObject );
+ }
+
+
+ XMLObject::XMLObject ( io::RPStream Object ) : io::Stream(Object) {
+ InitXMLObject();
+ }
+
+ XMLObject::~XMLObject() {
+ FreeMemory();
+ }
+
+ void XMLObject::InitXMLObject() {
+ parent = NULL;
+ objTag = NULL;
+ objData = NULL;
+ nObjects = 0;
+ nAlloc = 0;
+ object = NULL;
+ nAttributes = 0;
+ nAttrAlloc = 0;
+ attr_name = NULL;
+ attr_value = NULL;
+ }
+
+ void XMLObject::FreeMemory() {
+ int i;
+
+ if (objTag) delete[] objTag;
+ if (objData) delete[] objData;
+
+ objTag = NULL;
+ objData = NULL;
+
+ if (object) {
+ for (i=0;i<nAlloc;i++)
+ if (object[i]) delete object[i];
+ delete[] object;
+ }
+
+ nObjects = 0;
+ nAlloc = 0;
+ object = NULL;
+
+ if (attr_name) {
+ for (i=0;i<nAttrAlloc;i++) {
+ if (attr_name [i]) delete[] attr_name [i];
+ if (attr_value[i]) delete[] attr_value[i];
+ }
+ FreeVectorMemory ( attr_name ,0 );
+ FreeVectorMemory ( attr_value,0 );
+ }
+
+ nAttributes = 0;
+ nAttrAlloc = 0;
+ attr_name = NULL;
+ attr_value = NULL;
+
+ }
+
+ void XMLObject::SetTag ( cpstr Tag ) {
+ pstr p,t;
+ int n;
+
+ // count ampersands
+ p = pstr(Tag);
+ n = 0;
+ while (*p) {
+ if (*p=='&') n++;
+ p++;
+ }
+ // calculate the tag length
+ n = n*4 + strlen(Tag) + 1;
+ // substract leading underscores
+ p = pstr(Tag);
+ while (*p=='_') {
+ p++;
+ n--;
+ }
+ // allocate tag space
+ if (objTag) delete[] objTag;
+ objTag = new char[n];
+ // copy tag, replacing square brackets and ampersands
+ t = objTag;
+ while (*p) {
+ if (*p=='[') {
+ *t = '-';
+ t++;
+ } else if (*p==']') {
+ if ((p[1]) && (p[1]!='[')) {
+ *t = '-';
+ t++;
+ }
+ } else if (*p=='&') {
+ strcpy ( t,"_and_" );
+ if (p[1]) t += 5;
+ else t += 4;
+ } else {
+ *t = *p;
+ t++;
+ }
+ p++;
+ }
+ *t = char(0);
+ }
+
+ void XMLObject::AddAttribute ( cpstr name, cpstr value ) {
+ psvector an,av;
+ int i;
+
+ if (nAttributes>=nAttrAlloc) {
+ nAttrAlloc = nAttributes + 10;
+ GetVectorMemory ( an,nAttrAlloc,0 );
+ GetVectorMemory ( av,nAttrAlloc,0 );
+ for (i=0;i<nAttrAlloc;i++) {
+ an[i] = NULL;
+ av[i] = NULL;
+ }
+ for (i=0;i<nAttributes;i++) {
+ CreateCopy ( an[i],attr_name [i] );
+ CreateCopy ( av[i],attr_value[i] );
+ if (attr_name [i]) delete[] attr_name [i];
+ if (attr_value[i]) delete[] attr_value[i];
+ }
+ FreeVectorMemory ( attr_name ,0 );
+ FreeVectorMemory ( attr_value,0 );
+ attr_name = an;
+ attr_value = av;
+ }
+
+ CreateCopy ( attr_name [nAttributes],name );
+ CreateCopy ( attr_value[nAttributes],value );
+ nAttributes++;
+
+ }
+
+ void XMLObject::AddAttribute ( cpstr name, const int iV ) {
+ char S[100];
+ sprintf ( S,"%i",iV );
+ AddAttribute ( name,S );
+ }
+
+ void XMLObject::AddAttribute ( cpstr name, const bool bV ) {
+ if (bV) AddAttribute ( name,"Yes" );
+ else AddAttribute ( name,"No" );
+ }
+
+ void XMLObject::SetData ( cpstr Data ) {
+ pstr p,d;
+ int n;
+ // count ampersands
+ p = pstr(Data);
+ n = 0;
+ while (*p) {
+ if (*p=='&') n += 4;
+ p++;
+ }
+ // calculate the Data length
+ n += strlen(Data) + 1; // eugene
+ // allocate data space
+ if (objData) delete[] objData;
+ objData = new char[n];
+ // copy data, preceeding ampersands with the escape
+ p = pstr(Data);
+ d = objData;
+ while (*p) {
+ if (*p=='&') {
+ d[0] = '&';
+ d[1] = 'a';
+ d[2] = 'm';
+ d[3] = 'p';
+ d[4] = ';';
+ d += 5;
+ } else {
+ *d = *p;
+ d++;
+ }
+ p++;
+ }
+ *d = char(0);
+ }
+
+ void XMLObject::AddData ( cpstr Data ) {
+ pstr d1,d2;
+ d1 = objData;
+ objData = NULL;
+ SetData ( Data );
+ d2 = objData;
+ objData = NULL;
+ CreateConcat ( objData,d1,d2 );
+ }
+
+ void XMLObject::SetData ( const realtype V, const int length ) {
+ char N[500];
+ sprintf ( N,"%-.*g",length,V );
+ CreateCopy ( objData,N );
+ }
+
+ void XMLObject::SetData ( const int iV, const int length ) {
+ char N[500];
+ sprintf ( N,"%*i",length,iV );
+ CreateCopy ( objData,N );
+ }
+
+ void XMLObject::SetData ( const bool bV ) {
+ if (bV) CreateCopy ( objData,pstr("Yes") );
+ else CreateCopy ( objData,pstr("No") );
+ }
+
+
+ int XMLObject::AddMMCIFCategory ( mmcif::PCategory mmCIFCat ) {
+ if (mmCIFCat->GetCategoryID()==mmcif::MMCIF_Loop)
+ return AddMMCIFLoop ( mmcif::PLoop(mmCIFCat) );
+ if (mmCIFCat->GetCategoryID()==mmcif::MMCIF_Struct)
+ return AddMMCIFStruct ( mmcif::PStruct(mmCIFCat) );
+ return -1;
+ }
+
+ pstr getCCIFTag ( pstr & ccifTag, cpstr Tag ) {
+ if (Tag[0]=='_') return CreateCopCat ( ccifTag,pstr("ccif") ,Tag );
+ else return CreateCopCat ( ccifTag,pstr("ccif_"),Tag );
+ }
+
+ int XMLObject::AddMMCIFStruct ( mmcif::PStruct mmCIFStruct ) {
+ PXMLObject XMLObject1,XMLObject2;
+ pstr SName,Tag,Field, ccifTag;
+ int nTags,i,k;
+
+ XMLObject1 = this;
+
+ ccifTag = NULL;
+
+ SName = mmCIFStruct->GetCategoryName();
+ if (SName) {
+ if (SName[0]!=char(1))
+ XMLObject1 = new XMLObject ( getCCIFTag(ccifTag,SName) );
+ }
+
+ k = 0;
+ nTags = mmCIFStruct->GetNofTags();
+ for (i=0;i<nTags;i++) {
+ Tag = mmCIFStruct->GetTag ( i );
+ if (Tag) {
+ XMLObject2 = new XMLObject ( getCCIFTag(ccifTag,Tag) );
+ Field = mmCIFStruct->GetField ( i );
+ if (Field) {
+ if (Field[0]!=char(2)) XMLObject2->SetData ( Field );
+ else XMLObject2->SetData ( &(Field[1]) );
+ }
+ XMLObject1->AddObject ( XMLObject2 );
+ k++;
+ }
+ }
+
+ if (SName) {
+ if (SName[0]!=char(1))
+ AddObject ( XMLObject1 );
+ }
+
+ if (ccifTag) delete[] ccifTag;
+
+ return k;
+
+ }
+
+ int XMLObject::AddMMCIFLoop ( mmcif::PLoop mmCIFLoop ) {
+ PXMLObject XMLObject1,XMLObject2,XMLObject3;
+ pstr SName,Tag,Field,ccifTag;
+ int nTags,nRows,i,j,k;
+
+ XMLObject1 = this;
+
+ ccifTag = NULL;
+
+ SName = mmCIFLoop->GetCategoryName();
+ if (SName) {
+ if (SName[0]!=char(1))
+ XMLObject1 = new XMLObject ( getCCIFTag(ccifTag,SName) );
+ }
+
+ k = 0;
+ nTags = mmCIFLoop->GetNofTags ();
+ nRows = mmCIFLoop->GetLoopLength();
+ for (i=0;i<nRows;i++) {
+ XMLObject2 = new XMLObject ( pstr("row"),
+ new XMLObject(pstr("_sernum_"),i+1) );
+ for (j=0;j<nTags;j++) {
+ Tag = mmCIFLoop->GetTag ( j );
+ if (Tag) {
+ XMLObject3 = new XMLObject ( getCCIFTag(ccifTag,Tag) );
+ Field = mmCIFLoop->GetField ( i,j );
+ if (Field) {
+ if (Field[0]!=char(2)) XMLObject3->SetData ( Field );
+ else XMLObject3->SetData ( &(Field[1]) );
+ }
+ XMLObject2->AddObject ( XMLObject3 );
+ k++;
+ }
+ }
+ XMLObject1->AddObject ( XMLObject2 );
+ }
+
+ if (SName) {
+ if (SName[0]!=char(1))
+ AddObject ( XMLObject1 );
+ }
+
+ if (ccifTag) delete[] ccifTag;
+
+ return k;
+
+ }
+
+ int XMLObject::AddMMCIFData ( mmcif::PData mmCIFData ) {
+ mmcif::PCategory mmCIFCat;
+ int nCats,i,k,n;
+ nCats = mmCIFData->GetNumberOfCategories();
+ k = 0;
+ n = 0;
+ for (i=0;(i<nCats) && (n>=0);i++) {
+ mmCIFCat = mmCIFData->GetCategory ( i );
+ if (mmCIFCat) {
+ if (mmCIFCat->GetCategoryID()==mmcif::MMCIF_Loop)
+ n = AddMMCIFLoop ( mmcif::PLoop(mmCIFCat) );
+ else if (mmCIFCat->GetCategoryID()==mmcif::MMCIF_Struct)
+ n = AddMMCIFStruct ( mmcif::PStruct(mmCIFCat) );
+ else
+ n = -1;
+ if (n>=0) k += n;
+ }
+ }
+ if (n<0) return -(k+1);
+ return k;
+ }
+
+ pstr XMLObject::GetData ( cpstr Tag, int objNo ) {
+ PXMLObject XMLObject;
+ XMLObject = GetObject ( Tag,objNo );
+ if (XMLObject) return XMLObject->objData;
+ return NULL;
+ }
+
+ XML_RC XMLObject::GetData ( pstr & Data, cpstr Tag, int objNo ) {
+ PXMLObject XMLObject;
+ XMLObject = GetObject ( Tag,objNo );
+ if (XMLObject) {
+ Data = XMLObject->objData;
+ return XMLRC_Ok;
+ } else {
+ Data = NULL;
+ return XMLRC_NoTag;
+ }
+ }
+
+ XML_RC XMLObject::GetData ( realtype & V, cpstr Tag, int objNo ) {
+ pstr d,p;
+ XML_RC rc;
+ rc = GetData ( d,Tag,objNo );
+ if (d) {
+ V = strtod(d,&p);
+ if ((V==0.0) && (p==d)) rc = XMLRC_RFormatError;
+ else rc = XMLRC_Ok;
+ } else if (!rc)
+ rc = XMLRC_NoTag;
+ return rc;
+ }
+
+ XML_RC XMLObject::GetData ( int & iV, cpstr Tag, int objNo ) {
+ pstr d,p;
+ XML_RC rc;
+ rc = GetData ( d,Tag,objNo );
+ if (d) {
+ iV = mround(strtod(d,&p));
+ if ((iV==0) && (p==d)) rc = XMLRC_IFormatError;
+ else rc = XMLRC_Ok;
+ } else if (!rc)
+ rc = XMLRC_NoTag;
+ return rc;
+ }
+
+ XML_RC XMLObject::GetData ( bool & bV, cpstr Tag, int objNo ) {
+ pstr d;
+ XML_RC rc;
+ rc = GetData ( d,Tag,objNo );
+ if (d) {
+ if (!strcasecmp(d,"Yes"))
+ bV = true;
+ else {
+ bV = false;
+ if (strcasecmp(d,"No")) rc = XMLRC_OFormatError;
+ }
+ } else if (rc==XMLRC_Ok)
+ rc = XMLRC_NoTag;
+ return rc;
+ }
+
+ PXMLObject XMLObject::GetObject ( cpstr Tag, int objNo ) {
+ // allow for "tag1>tag2>tag3>..."
+ PXMLObject XMLObject;
+ pstr p,p1;
+ int i,j,k,l;
+ XMLObject = this;
+ if (Tag) {
+ p = pstr(Tag);
+ do {
+ p1 = p;
+ l = 0;
+ while (*p1 && (*p1!='>')) {
+ p1++;
+ l++;
+ }
+ if (l>0) {
+ k = -1;
+ j = 0;
+ for (i=0;(i<XMLObject->nObjects) && (k<0);i++)
+ if (XMLObject->object[i]) {
+ if (!strncmp(XMLObject->object[i]->objTag,p,l)) {
+ j++;
+ if (j==objNo) k = i;
+ }
+ }
+ if (k<0) {
+ XMLObject = NULL;
+ l = 0;
+ } else {
+ XMLObject = XMLObject->object[k];
+ if (*p1) p = p1 + 1;
+ else l = 0;
+ }
+ }
+ } while (l>0);
+ }
+ return XMLObject;
+ }
+
+ PXMLObject XMLObject::GetFirstObject() {
+ if (nObjects>0) return object[0];
+ return NULL;
+ }
+
+ PXMLObject XMLObject::GetLastObject() {
+ if (nObjects>0) return object[nObjects-1];
+ return NULL;
+ }
+
+ PXMLObject XMLObject::GetObject ( int objectNo ) {
+ if ((0<=objectNo) && (objectNo<nObjects))
+ return object[objectNo];
+ return NULL;
+ }
+
+ void XMLObject::AddObject ( PXMLObject XMLObject, int lenInc ) {
+ PPXMLObject obj1;
+ int i;
+
+ if (!XMLObject) return;
+
+ if (nObjects>=nAlloc) {
+ nAlloc += lenInc;
+ obj1 = new PXMLObject[nAlloc];
+ for (i=0;i<nObjects;i++)
+ obj1[i] = object[i];
+ for (i=nObjects;i<nAlloc;i++)
+ obj1[i] = NULL;
+ if (object) delete[] object;
+ object = obj1;
+ }
+
+ if (object[nObjects]) delete object[nObjects];
+ object[nObjects] = XMLObject;
+ XMLObject->SetParent ( this );
+ nObjects++;
+
+ }
+
+
+ void XMLObject::InsertObject ( PXMLObject XMLObject, int pos,
+ int lenInc ) {
+ PPXMLObject obj1;
+ int i;
+
+ if (!XMLObject) return;
+ if (pos>=nObjects) {
+ AddObject ( XMLObject,lenInc );
+ return;
+ }
+
+ if (nObjects>=nAlloc) {
+ nAlloc += lenInc;
+ obj1 = new PXMLObject[nAlloc];
+ for (i=0;i<nObjects;i++)
+ obj1[i] = object[i];
+ for (i=nObjects;i<nAlloc;i++)
+ obj1[i] = NULL;
+ if (object) delete[] object;
+ object = obj1;
+ }
+
+ for (i=nObjects;i>pos;i--)
+ object[i] = object[i-1];
+
+ object[pos] = XMLObject;
+ XMLObject->SetParent ( this );
+ nObjects++;
+
+ }
+
+ XML_RC XMLObject::WriteObject ( cpstr FName, int pos, int indent ) {
+ io::File f;
+ f.assign ( FName,true );
+ if (f.rewrite()) {
+ WriteObject ( f,pos,indent );
+ f.shut();
+ return XMLRC_Ok;
+ }
+ return XMLRC_CantOpenFile;
+ }
+
+ void XMLObject::WriteObject ( io::RFile f, int pos, int indent ) {
+ int i,pos1,lm,rm,tl;
+ pstr indstr,p,p1,q;
+ bool sngline;
+
+ if (objTag) {
+
+ pos1 = pos + indent;
+ indstr = new char[pos1+1];
+ for (i=0;i<pos1;i++) indstr[i] = ' ';
+ indstr[pos1] = char(0);
+
+ indstr[pos] = char(0);
+ f.Write ( indstr );
+ f.Write ( pstr("<") );
+ f.Write ( objTag );
+ for (i=0;i<nAttributes;i++) {
+ f.Write ( " " );
+ f.Write ( attr_name[i] );
+ f.Write ( "=\"" );
+ f.Write ( attr_value[i] );
+ f.Write ( "\"" );
+ }
+ if ((!objData) && (nObjects<=0)) {
+ f.WriteLine ( pstr("/>") );
+ delete[] indstr;
+ return;
+ }
+ f.Write ( pstr(">") );
+
+ sngline = false;
+ if (objData) {
+ rm = 72; // right margin
+ lm = IMin ( pos1,36 ); // left margin
+ tl = strlen(objTag);
+ if ((pos+tl+2+(int)strlen(objData)<rm-tl-2) &&
+ (nObjects<=0)) {
+ // single-line output
+ sngline = true;
+ f.Write ( objData );
+ } else {
+ // multiple-line output with indentation
+ indstr[pos] = ' ';
+ indstr[lm] = char(0);
+ f.LF();
+ p = objData;
+ do {
+ p1 = p;
+ i = lm;
+ q = NULL;
+ while ((*p1) && ((i<rm) || (!q))) {
+ if (*p1==' ') q = p1;
+ p1++;
+ i++;
+ }
+ f.Write ( indstr );
+ if (*p1) { // wrap data
+ *q = char(0);
+ f.WriteLine ( p );
+ *q = ' ';
+ p = q;
+ while (*p==' ') p++;
+ if (*p==char(0)) p = NULL;
+
+ } else { // data exchausted
+ f.WriteLine ( p );
+ p = NULL;
+ }
+ } while (p);
+ indstr[lm] = ' ';
+ indstr[pos] = char(0);
+ }
+ } else
+ f.LF();
+
+ for (i=0;i<nObjects;i++)
+ if (object[i])
+ object[i]->WriteObject ( f,pos+indent,indent );
+
+ if (!sngline) f.Write ( indstr );
+ f.Write ( pstr("</") );
+ f.Write ( objTag );
+ f.WriteLine ( pstr(">") );
+
+ delete[] indstr;
+
+ }
+
+ }
+
+
+ XML_RC XMLObject::ReadObject ( cpstr FName ) {
+ io::File f;
+ char S[500];
+ int i;
+ XML_RC rc;
+
+ f.assign ( FName,true );
+ if (f.reset(true)) {
+ S[0] = char(0);
+ i = 0;
+ rc = ReadObject ( f,S,i,sizeof(S) );
+ f.shut();
+ } else
+ rc = XMLRC_NoFile;
+
+ if (rc!=XMLRC_Ok) FreeMemory();
+
+ return rc;
+
+ }
+
+ XML_RC XMLObject::ReadObject ( io::RFile f, pstr S,
+ int & pos, int slen ) {
+ PXMLObject xmlObject;
+ pstr S1;
+ int k,k1,k2;
+ XML_RC rc;
+ bool Done;
+
+ FreeMemory();
+
+ rc = XMLRC_Ok;
+
+ k1 = -1;
+ k2 = -1;
+ while ((!f.FileEnd()) && (k1<0)) {
+ k = strlen(S);
+ while ((pos<k) && (k1<0))
+ if (S[pos]=='<') {
+ if (S[pos+1]=='?') // in this version, ignore <?xxx ?>
+ // constructions
+ pos++;
+ else if (S[pos+1]!='<')
+ k1 = pos;
+ else pos += 2;
+ } else
+ pos++;
+ if (k1>=0) {
+ k2 = -1;
+ while ((pos<k) && (k2<0))
+ if (S[pos]=='>') {
+ if (S[pos+1]!='>') k2 = pos;
+ else pos += 2;
+ } else
+ pos++;
+ if (k2<0) rc = XMLRC_BrokenTag;
+ }
+ if (k1<0) {
+ f.ReadLine ( S,slen );
+ pos = 0;
+ }
+ }
+
+ if (k1<0) return XMLRC_NoTag;
+ if (rc!=XMLRC_Ok) return rc;
+
+ pos++;
+ if (S[k2-1]=='/') { // <Tag/>
+ S[k2-1] = char(0);
+ CreateCopy ( objTag,&(S[k1+1]) );
+ return XMLRC_Ok;
+ }
+
+ S[k2] = char(0);
+ CreateCopy ( objTag,&(S[k1+1]) );
+ S[k2] = '>';
+
+ S1 = new char[slen+1];
+ Done = false;
+ while ((!f.FileEnd()) && (!Done)) {
+ k = strlen(S);
+ while ((pos<k) && (!Done)) {
+ k1 = pos;
+ k2 = -1;
+ while ((pos<k) && (k2<0))
+ if (S[pos]=='<') {
+ if (S[pos+1]!='<') k2 = pos;
+ else pos +=2;
+ } else
+ pos++;
+ if (k2>=0) S[k2] = char(0);
+ strcpy_des ( S1,&(S[k1]) );
+ if (S1[0]) {
+ if (objData) CreateConcat ( objData,pstr(" "),S1 );
+ else CreateConcat ( objData,S1 );
+ }
+ if (k2>=0) {
+ S[k2] = '<';
+ if (S[k2+1]!='/') {
+ xmlObject = new XMLObject();
+ AddObject ( xmlObject );
+ rc = xmlObject->ReadObject ( f,S,pos,slen );
+ Done = (rc!=XMLRC_Ok);
+ } else {
+ Done = true;
+ k1 = k2+2;
+ k2 = -1;
+ while ((pos<k) && (k2<0))
+ if (S[pos]=='>') {
+ if (S[pos+1]!='>') k2 = pos;
+ else pos += 2;
+ } else
+ pos++;
+ if (k2<0)
+ rc = XMLRC_BrokenTag;
+ else {
+ S[k2] = char(0);
+ if (strcmp(objTag,&(S[k1]))) rc = XMLRC_UnclosedTag;
+ else pos++;
+ }
+ }
+ }
+ }
+ if (!Done) {
+ f.ReadLine ( S,slen );
+ pos = 0;
+ }
+ }
+
+ delete[] S1;
+
+ // this keeps pairs <tag></tag> instead of replacing them for <tag/>
+ // on output
+ if ((!objData) && (nObjects<=0))
+ CreateCopy ( objData,pstr("") );
+
+ if (rc!=XMLRC_Ok) FreeMemory();
+ return rc;
+
+ }
+
+
+ void XMLObject::Copy ( PXMLObject xmlObject ) {
+ int i;
+
+ FreeMemory();
+
+ CreateCopy ( objTag ,xmlObject->objTag );
+ CreateCopy ( objData,xmlObject->objData );
+
+ nObjects = xmlObject->nObjects;
+ nAlloc = nObjects;
+ if (nObjects>0) {
+ object = new PXMLObject[nObjects];
+ for (i=0;i<nObjects;i++)
+ if (xmlObject->object[i]) {
+ object[i] = new XMLObject();
+ object[i]->Copy ( xmlObject->object[i] );
+ } else
+ object[i] = NULL;
+ }
+
+ nAttributes = xmlObject->nAttributes;
+ nAttrAlloc = nAttributes;
+ if (nAttributes>0) {
+ GetVectorMemory ( attr_name ,nAttrAlloc,0 );
+ GetVectorMemory ( attr_value,nAttrAlloc,0 );
+ for (i=0;i<nAttributes;i++) {
+ attr_name [i] = NULL;
+ attr_value[i] = NULL;
+ CreateCopy ( attr_name [i],xmlObject->attr_name [i] );
+ CreateCopy ( attr_value[i],xmlObject->attr_value[i] );
+ }
+ }
+
+ }
+
+
+ void XMLObject::write ( io::RFile f ) {
+ int i;
+ f.CreateWrite ( objTag );
+ f.CreateWrite ( objData );
+ f.WriteInt ( &nObjects );
+ for (i=0;i<nObjects;i++)
+ StreamWrite ( f,object[i] );
+ f.WriteInt ( &nAttributes );
+ for (i=0;i<nAttributes;i++) {
+ f.CreateWrite ( attr_name [i] );
+ f.CreateWrite ( attr_value[i] );
+ }
+ }
+
+ void XMLObject::read ( io::RFile f ) {
+ int i;
+
+ FreeMemory();
+
+ f.CreateRead ( objTag );
+ f.CreateRead ( objData );
+
+ f.ReadInt ( &nObjects );
+ nAlloc = nObjects;
+ if (nObjects>0) {
+ object = new PXMLObject[nObjects];
+ for (i=0;i<nObjects;i++) {
+ object[i] = NULL;
+ StreamRead ( f,object[i] );
+ }
+ }
+
+ f.ReadInt ( &nAttributes );
+ nAttrAlloc = nAttributes;
+ if (nAttributes>0) {
+ GetVectorMemory ( attr_name ,nAttrAlloc,0 );
+ GetVectorMemory ( attr_value,nAttrAlloc,0 );
+ for (i=0;i<nAttributes;i++) {
+ attr_name [i] = NULL;
+ attr_value[i] = NULL;
+ f.CreateRead ( attr_name [i] );
+ f.CreateRead ( attr_value[i] );
+ }
+ }
+
+ }
+
+
+ MakeStreamFunctions(XMLObject)
+
+
+
+ PXMLObject mmCIF2XML ( mmcif::PData mmCIFData, int * rc ) {
+ PXMLObject xmlObject;
+ pstr dataName;
+ int k;
+ xmlObject = NULL;
+ if (rc) *rc = -2;
+ if (mmCIFData) {
+ dataName = mmCIFData->GetDataName();
+ if (dataName) {
+ if (dataName[0])
+ xmlObject = new XMLObject ( dataName );
+ }
+ if (!xmlObject)
+ xmlObject = new XMLObject ( pstr("no_data_name") );
+ k = xmlObject->AddMMCIFData ( mmCIFData );
+ if (rc) *rc = k;
+ }
+ return xmlObject;
+ }
+
+ PXMLObject mmCIF2XML ( cpstr XMLName, mmcif::PFile mmCIFFile,
+ int * rc ) {
+ PXMLObject xmlObject1,xmlObject2;
+ mmcif::PData mmCIFData;
+ int nData,i,k,rc1;
+ xmlObject1 = new XMLObject ( XMLName );
+ if (rc) *rc = -1;
+ if (mmCIFFile) {
+ nData = mmCIFFile->GetNofData();
+ k = 0;
+ rc1 = 0;
+ for (i=0;(i<nData) && (rc1>=0);i++) {
+ mmCIFData = mmCIFFile->GetCIFData ( i );
+ if (mmCIFData) {
+ xmlObject2 = mmCIF2XML ( mmCIFData,&rc1 );
+ if (xmlObject2) {
+ if (rc1>=0) {
+ xmlObject1->AddObject ( xmlObject2 );
+ k += rc1;
+ } else
+ delete xmlObject2;
+ }
+ }
+ }
+ if (rc1<0) {
+ delete xmlObject1;
+ if (rc) *rc = -2;
+ } else if (rc)
+ *rc = k;
+ }
+ return xmlObject1;
+ }
+
+
+ } // namespace xml
+
+} // namespace mmdb
diff --git a/mmdb2/mmdb_xml_.h b/mmdb2/mmdb_xml_.h
new file mode 100644
index 0000000..540334c
--- /dev/null
+++ b/mmdb2/mmdb_xml_.h
@@ -0,0 +1,162 @@
+// $Id: mmdb_xml_.h $
+// =================================================================
+//
+// CCP4 Coordinate Library: support of coordinate-related
+// functionality in protein crystallography applications.
+//
+// Copyright (C) Eugene Krissinel 2000-2013.
+//
+// This library is free software: you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 3, modified in accordance with the provisions
+// of the license to address the requirements of UK law.
+//
+// You should have received a copy of the modified GNU Lesser
+// General Public License along with this library. If not, copies
+// may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// =================================================================
+//
+// 06.12.13 <-- Date of Last Modification.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// -----------------------------------------------------------------
+//
+// **** Module : MMDB_XML <interface>
+// ~~~~~~~~~
+// **** Project : MacroMolecular Data Base (MMDB)
+// ~~~~~~~~~
+// **** Classes : mmdb::xml::XMLObject
+// ~~~~~~~~~
+//
+// (C) E. Krissinel 2000-2013
+//
+// =================================================================
+//
+
+#ifndef __MMDB_XML__
+#define __MMDB_XML__
+
+#include "mmdb_mmcif_.h"
+
+namespace mmdb {
+
+ namespace xml {
+
+
+ // ====================== XMLObject ==========================
+
+ enum XML_RC {
+ XMLRC_Ok = 0,
+ XMLRC_NoFile = 1,
+ XMLRC_CantOpenFile = 2,
+ XMLRC_NoTag = 3,
+ XMLRC_BrokenTag = 4,
+ XMLRC_UnclosedTag = 5,
+ XMLRC_RFormatError = 6,
+ XMLRC_IFormatError = 7,
+ XMLRC_OFormatError = 8
+ };
+
+ DefineClass(XMLObject);
+ DefineStreamFunctions(XMLObject);
+
+ class XMLObject : public io::Stream {
+
+ public :
+
+ XMLObject ();
+ XMLObject ( cpstr Tag );
+ XMLObject ( cpstr Tag, cpstr Data );
+ XMLObject ( cpstr Tag, realtype V, int length=11 );
+ XMLObject ( cpstr Tag, int iV, int length=0 );
+ XMLObject ( cpstr Tag, bool bV );
+ XMLObject ( cpstr Tag, PXMLObject XMLObject );
+ XMLObject ( io::RPStream Object );
+ ~XMLObject();
+
+ void SetTag ( cpstr Tag );
+ void AddAttribute ( cpstr name, cpstr value );
+ void AddAttribute ( cpstr name, const int iV );
+ void AddAttribute ( cpstr name, const bool bV );
+ void SetData ( cpstr Data );
+ void AddData ( cpstr Data );
+ void SetData ( const realtype V, const int length=11 );
+ void SetData ( const int iV, const int length=0 );
+ void SetData ( const bool bV );
+
+ int AddMMCIFCategory ( mmcif::PCategory mmCIFCat );
+ int AddMMCIFStruct ( mmcif::PStruct mmCIFStruct );
+ int AddMMCIFLoop ( mmcif::PLoop mmCIFLoop );
+ int AddMMCIFData ( mmcif::PData mmCIFData );
+
+ inline pstr GetTag() { return objTag; }
+
+ // Here and below the functions allow for "tag1>tag2>tag3>..."
+ // as a composite multi-level tag, e.g. the above may stand for
+ // <tag1><tag2><tag3>data</tag3></tag2></tag1>. NULL tag
+ // corresponds to "this" object.
+ // objNo counts same-tag objects of the *highest* level used
+ // (e.g. level tag3 for composite tag tag1>tag2>tag3 ).
+ // GetData ( pstr& ... ) only copies a pointer to data.
+ pstr GetData ( cpstr Tag=NULL, int objNo=1 );
+ XML_RC GetData ( pstr & Data, cpstr Tag=NULL, int objNo=1 );
+ XML_RC GetData ( realtype & V, cpstr Tag=NULL, int objNo=1 );
+ XML_RC GetData ( int & iV, cpstr Tag=NULL, int objNo=1 );
+ XML_RC GetData ( bool & bV, cpstr Tag=NULL, int objNo=1 );
+
+ PXMLObject GetObject ( cpstr Tag, int objNo=1 );
+ PXMLObject GetFirstObject();
+ PXMLObject GetLastObject ();
+ inline int GetNumberOfObjects() { return nObjects; }
+ PXMLObject GetObject ( int objectNo ); // 0,1,...
+
+ inline PXMLObject GetParent() { return parent; }
+
+ void AddObject ( PXMLObject XMLObject, int lenInc=10 );
+ void InsertObject ( PXMLObject XMLObject, int pos,
+ int lenInc=10 );
+
+ XML_RC WriteObject ( cpstr FName, int pos=0, int ident=2 );
+ void WriteObject ( io::RFile f, int pos=0, int ident=2 );
+ XML_RC ReadObject ( cpstr FName );
+ XML_RC ReadObject ( io::RFile f, pstr S, int & pos, int slen );
+
+ virtual void Copy ( PXMLObject xmlObject );
+
+ void write ( io::RFile f );
+ void read ( io::RFile f );
+
+ protected:
+ PXMLObject parent;
+ pstr objTag;
+ pstr objData;
+ int nObjects,nAlloc;
+ PPXMLObject object;
+ int nAttributes,nAttrAlloc;
+ psvector attr_name,attr_value;
+
+ void InitXMLObject();
+ virtual void FreeMemory ();
+
+ inline void SetParent ( PXMLObject p ) { parent = p; }
+
+ };
+
+
+ extern PXMLObject mmCIF2XML ( mmcif::PData mmCIFData,
+ int * rc=NULL );
+ extern PXMLObject mmCIF2XML ( cpstr XMLName, mmcif::PFile mmCIFFile,
+ int * rc=NULL );
+
+ } // namespace xml
+
+} // namespace mmdb
+
+#endif
+
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/mmdb.git
More information about the debian-science-commits
mailing list