mirror of
https://github.com/PDB-REDO/libcifpp.git
synced 2026-06-04 22:14:24 +08:00
Compare commits
295 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf9b12043f | ||
|
|
1d79a9e915 | ||
|
|
28b4deaf32 | ||
|
|
694d93f50b | ||
|
|
8fed9a1302 | ||
|
|
4fa2d84374 | ||
|
|
0e43b81c34 | ||
|
|
eaf38e6353 | ||
|
|
4012a71f6c | ||
|
|
5a71dbecdc | ||
|
|
6675768ab4 | ||
|
|
63256f09ad | ||
|
|
be54866ca4 | ||
|
|
7329009fff | ||
|
|
bb5d72a40e | ||
|
|
85d68b93eb | ||
|
|
360d970033 | ||
|
|
87d87fe5b0 | ||
|
|
bdfde18728 | ||
|
|
1d0b2b8c6e | ||
|
|
7e91ae334f | ||
|
|
515d16fe79 | ||
|
|
896a8ebbdc | ||
|
|
ae23938aa4 | ||
|
|
4db05c20ae | ||
|
|
8bb0663313 | ||
|
|
83b2c651f1 | ||
|
|
e65a782f45 | ||
|
|
43f418ae67 | ||
|
|
4b4757ee74 | ||
|
|
ac088dd0a4 | ||
|
|
31c86d9c8a | ||
|
|
85b08f9d77 | ||
|
|
d50529c6b9 | ||
|
|
bb9d81616b | ||
|
|
024607002e | ||
|
|
31ce161543 | ||
|
|
359538e170 | ||
|
|
d45ce5060d | ||
|
|
6aebf8408f | ||
|
|
5ce8d87b19 | ||
|
|
f815b8588a | ||
|
|
e812e2e092 | ||
|
|
43eda65dd8 | ||
|
|
3a94384775 | ||
|
|
7c5bf01090 | ||
|
|
3f421f34a2 | ||
|
|
c7f67525ec | ||
|
|
71a78813e1 | ||
|
|
62face74ee | ||
|
|
1cbfbd8f4f | ||
|
|
3928be4939 | ||
|
|
a967154625 | ||
|
|
78dd9a3c02 | ||
|
|
52d6b2eace | ||
|
|
2ef9e6b843 | ||
|
|
48d9d22d70 | ||
|
|
a3d9bc01a0 | ||
|
|
52ea0bc7fc | ||
|
|
ba804abb34 | ||
|
|
6835a9808b | ||
|
|
77fc4080c5 | ||
|
|
599d0cb537 | ||
|
|
59a7ff68e0 | ||
|
|
80bb24f347 | ||
|
|
34c7fd3f54 | ||
|
|
fac1eb915a | ||
|
|
3a84a8e6e8 | ||
|
|
dd02b3633d | ||
|
|
54728d49be | ||
|
|
2afddc23ff | ||
|
|
700c1d408d | ||
|
|
e3297d0de6 | ||
|
|
e4ced4caef | ||
|
|
14e32bed28 | ||
|
|
a3cf3343c9 | ||
|
|
188fa4e59c | ||
|
|
d053492a7c | ||
|
|
8d9f4f007b | ||
|
|
5084e7185a | ||
|
|
11b4c1d399 | ||
|
|
a56b6b136d | ||
|
|
b6e8f79c1a | ||
|
|
eda40b8eb6 | ||
|
|
c0c4be78f2 | ||
|
|
513dbb6bfd | ||
|
|
77e0b3f776 | ||
|
|
a7249eb2ca | ||
|
|
51aebf844a | ||
|
|
38121e20f5 | ||
|
|
dbd826867f | ||
|
|
fe519e71a5 | ||
|
|
072882e005 | ||
|
|
3ab625cb2b | ||
|
|
2583975afd | ||
|
|
9ec0eae41f | ||
|
|
f2449abb79 | ||
|
|
4a5312a648 | ||
|
|
9c636544b3 | ||
|
|
19714ecb0b | ||
|
|
9fbd41aef9 | ||
|
|
c432ac4d7c | ||
|
|
267302429c | ||
|
|
db164a2045 | ||
|
|
9b1e935628 | ||
|
|
f1dfe12c24 | ||
|
|
0bdda4610a | ||
|
|
530d1110d9 | ||
|
|
d170c8da78 | ||
|
|
fe6d7a11ca | ||
|
|
6082b11959 | ||
|
|
01dbe675c8 | ||
|
|
a825cfc687 | ||
|
|
9f81a4ef89 | ||
|
|
c9f37c74b4 | ||
|
|
ffd82dfee0 | ||
|
|
6ef927cfa1 | ||
|
|
13a38fd011 | ||
|
|
f90990507a | ||
|
|
55b1c56647 | ||
|
|
1c009d481d | ||
|
|
42c72958a8 | ||
|
|
13109f767a | ||
|
|
72e6708076 | ||
|
|
aaf25de2d0 | ||
|
|
0cbb927b0f | ||
|
|
59f2387b68 | ||
|
|
6d07611e49 | ||
|
|
f7b12dedc0 | ||
|
|
2cce9e5379 | ||
|
|
5e1fe8211a | ||
|
|
29ebdcf7d2 | ||
|
|
4206f26699 | ||
|
|
dd7a4f1189 | ||
|
|
d1b3f08d5b | ||
|
|
9a7aeed632 | ||
|
|
963d51bbcb | ||
|
|
ef7a6f8f9d | ||
|
|
85aed9fb40 | ||
|
|
603a0eca6b | ||
|
|
cccbfe025d | ||
|
|
778fa86410 | ||
|
|
b4da5aeda3 | ||
|
|
4ddfe65734 | ||
|
|
95d0d55715 | ||
|
|
ec09e7ba57 | ||
|
|
74750a7940 | ||
|
|
0de2ae3673 | ||
|
|
a236547a54 | ||
|
|
8f12d15439 | ||
|
|
535ea566de | ||
|
|
e095d3bf67 | ||
|
|
bb0562ebc1 | ||
|
|
ec4ea697dd | ||
|
|
4918f572b4 | ||
|
|
0119c93aa0 | ||
|
|
03c95609dd | ||
|
|
3650bc9269 | ||
|
|
25e2c38076 | ||
|
|
a265b97058 | ||
|
|
fa7a0de6db | ||
|
|
996710728a | ||
|
|
b5f159c345 | ||
|
|
958d1fb32c | ||
|
|
28620841e0 | ||
|
|
e0d2c1328c | ||
|
|
9a54b6b990 | ||
|
|
e27908b9ee | ||
|
|
63fa06d656 | ||
|
|
9856d0de35 | ||
|
|
a2a1e63e06 | ||
|
|
a83fb55961 | ||
|
|
83965b9a7f | ||
|
|
e5bd42b4c7 | ||
|
|
602c770a45 | ||
|
|
64e2793c51 | ||
|
|
51b6c7eb3f | ||
|
|
1cf8e7b72a | ||
|
|
bc50f86836 | ||
|
|
909a33c01a | ||
|
|
f66bd7fdaa | ||
|
|
7f23427272 | ||
|
|
4f2427e95c | ||
|
|
1546cedb63 | ||
|
|
d3bc435a2e | ||
|
|
4436ad4358 | ||
|
|
5af0296028 | ||
|
|
b450cdf16d | ||
|
|
f96499cdd8 | ||
|
|
274120c9fc | ||
|
|
0d50305679 | ||
|
|
6999b7a12a | ||
|
|
8118c073c4 | ||
|
|
27bda1c6a0 | ||
|
|
7927a7c0dd | ||
|
|
39ead681b0 | ||
|
|
9c05120753 | ||
|
|
91abdc568b | ||
|
|
b1a6180a67 | ||
|
|
a789367ee8 | ||
|
|
61dbb7c137 | ||
|
|
834a3a50f9 | ||
|
|
7a423aecf7 | ||
|
|
91f7f9c238 | ||
|
|
af930b23a1 | ||
|
|
8047cda02d | ||
|
|
773137e852 | ||
|
|
efd96f18b4 | ||
|
|
deeac050f9 | ||
|
|
0ab408e1b3 | ||
|
|
521fafdd32 | ||
|
|
66fa88ec88 | ||
|
|
4738d97948 | ||
|
|
cc2f705a21 | ||
|
|
3d9200f990 | ||
|
|
0af4eca14f | ||
|
|
26dc7eaa08 | ||
|
|
9b5ef7548f | ||
|
|
41b2231ee5 | ||
|
|
4a81e814c1 | ||
|
|
ef6643122f | ||
|
|
00742f65af | ||
|
|
1da97e6ebb | ||
|
|
38a852ca20 | ||
|
|
a5b64ec805 | ||
|
|
6dc402263a | ||
|
|
54b8cb5c85 | ||
|
|
8bf1f01926 | ||
|
|
791d8bd98a | ||
|
|
5b963bf62f | ||
|
|
0dc6531395 | ||
|
|
07617dcdac | ||
|
|
2a2172a9eb | ||
|
|
065ba540b2 | ||
|
|
e19fc4f7b6 | ||
|
|
db5540cfc6 | ||
|
|
8aaf0d8813 | ||
|
|
e53c77cb7f | ||
|
|
1a8d585b9c | ||
|
|
d4de02a229 | ||
|
|
b60face9af | ||
|
|
91f8ac9edd | ||
|
|
6d12375691 | ||
|
|
924d37b603 | ||
|
|
6105c1f6fd | ||
|
|
93a96960f1 | ||
|
|
53091a321a | ||
|
|
eccf6c8855 | ||
|
|
2a2fefa80d | ||
|
|
65f17a7b26 | ||
|
|
d2716b4ea2 | ||
|
|
9af1dabbe6 | ||
|
|
1e4e0638b7 | ||
|
|
724c834656 | ||
|
|
ef4120fd72 | ||
|
|
3a9688089c | ||
|
|
eb4f2f778f | ||
|
|
a793eb4c51 | ||
|
|
6f1a592cc9 | ||
|
|
1242ce1d29 | ||
|
|
7dedb46d08 | ||
|
|
0d18d47775 | ||
|
|
4664c0bbe0 | ||
|
|
4543e34c00 | ||
|
|
b85f340cc7 | ||
|
|
c73e18fc26 | ||
|
|
17034d3bff | ||
|
|
4632a41763 | ||
|
|
16492f6f5b | ||
|
|
4362fd9d6e | ||
|
|
3b44209b15 | ||
|
|
679a15b637 | ||
|
|
b4a52806e6 | ||
|
|
311961e80b | ||
|
|
0e31a9b17f | ||
|
|
d3194f8cc0 | ||
|
|
2a9bb5752a | ||
|
|
821c1ef94f | ||
|
|
ba0e39c0da | ||
|
|
371c2aa876 | ||
|
|
05ec536059 | ||
|
|
b0272a1cd5 | ||
|
|
caf80a0efe | ||
|
|
032138c4d3 | ||
|
|
e0dc9f1c95 | ||
|
|
c5d277fb43 | ||
|
|
d0b7e21c77 | ||
|
|
b1de54f8b1 | ||
|
|
141764edf5 | ||
|
|
00fe32b76f | ||
|
|
bfd74e6f01 | ||
|
|
edf132c4bd | ||
|
|
f3878b3760 | ||
|
|
6c93599687 | ||
|
|
ca881b82b5 |
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
obj.dbg/
|
||||
obj/
|
||||
.libs/
|
||||
.vscode/
|
||||
autom4te.cache/
|
||||
GNUmakefile
|
||||
include/cif++/Config.hpp
|
||||
tools/symop-map-generator
|
||||
test/unit-test
|
||||
libcif++.pc
|
||||
libcif++.la
|
||||
config.status
|
||||
config.log
|
||||
libtool
|
||||
34
.travis.yml
Normal file
34
.travis.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
language: cpp
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
dist: focal
|
||||
|
||||
osx_image:
|
||||
- xcode12
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
# - clang
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libboost-all-dev
|
||||
|
||||
before_install:
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update ; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install boost make; fi
|
||||
|
||||
script:
|
||||
- ./configure
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then gmake ; else make ; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then gmake test ; else make test ; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then sudo gmake install; else sudo make install; fi
|
||||
|
||||
jobs:
|
||||
allow_failures:
|
||||
- os: osx
|
||||
|
||||
229
GNUmakefile.in
Normal file
229
GNUmakefile.in
Normal file
@@ -0,0 +1,229 @@
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
# Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# makefile for libcif++
|
||||
|
||||
.PHONY: firstTarget
|
||||
firstTarget: all
|
||||
|
||||
CXX = @CXX@
|
||||
CXXFLAGS = @CXXFLAGS@ @BOOST_CPPFLAGS@ @LIBBZ2_CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@ @LIBS@ @BOOST_LDFLAGS@ @LIBBZ2_LDFLAGS@
|
||||
LIBS = @LIBS@ \
|
||||
@BOOST_IOSTREAMS_LIB@
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
libdir = @libdir@
|
||||
includedir = @includedir@
|
||||
datarootdir = @datarootdir@
|
||||
datadir = @datadir@
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
|
||||
LIB_NAME = @PACKAGE_NAME@
|
||||
LIB_TARGET = $(LIB_NAME).la
|
||||
|
||||
CCP4DIR = @CCP4@
|
||||
CLIBD ?= $(CCP4DIR)/lib/data
|
||||
|
||||
DATADIR = $(datadir)/libcifpp
|
||||
|
||||
ifeq "$(CHECK_CONFIG)" "1"
|
||||
|
||||
GNUmakefile: config.status GNUmakefile.in
|
||||
$(SHELL) ./config.status
|
||||
|
||||
config.status: configure
|
||||
$(SHELL) ./config.status --recheck
|
||||
|
||||
configure: configure.ac
|
||||
autoconf
|
||||
|
||||
LIBTOOL_DEPS = @LIBTOOL_DEPS@
|
||||
libtool: $(LIBTOOL_DEPS)
|
||||
$(SHELL) ./config.status --recheck
|
||||
|
||||
endif
|
||||
|
||||
# libtool stuff
|
||||
|
||||
LIBTOOL = $(SHELL) ./libtool
|
||||
CXXCOMPILE = $(LIBTOOL) --silent --tag=CXX --mode=compile $(CXX) $(CXXFLAGS)
|
||||
CXXLINK = $(LIBTOOL) --silent --tag=CXX --mode=link $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@
|
||||
|
||||
# main build variables
|
||||
CXXFLAGS += -I. -pthread -I include/
|
||||
CXXFLAGS += -Wall -Wno-multichar
|
||||
|
||||
# Use the DEBUG flag to build debug versions of the code
|
||||
DEBUG = @DEBUG@
|
||||
|
||||
ifeq "$(DEBUG)" "1"
|
||||
DEFINES += DEBUG
|
||||
CXXFLAGS += -g -O0
|
||||
LDFLAGS += -g
|
||||
else
|
||||
CXXFLAGS += -O2
|
||||
DEFINES += NDEBUG
|
||||
endif
|
||||
|
||||
# targets
|
||||
|
||||
VPATH += src:test
|
||||
|
||||
CXXFLAGS += $(DEFINES:%=-D%)
|
||||
|
||||
OBJDIR = obj
|
||||
ifeq "$(DEBUG)" "1"
|
||||
OBJDIR := $(OBJDIR).dbg
|
||||
endif
|
||||
|
||||
$(OBJDIR):
|
||||
mkdir -p $(OBJDIR)
|
||||
|
||||
LIBCIF_SRC = AtomType.cpp \
|
||||
Cif2PDB.cpp \
|
||||
Cif++.cpp \
|
||||
CifParser.cpp \
|
||||
CifUtils.cpp \
|
||||
CifValidator.cpp \
|
||||
Compound.cpp \
|
||||
PDB2Cif.cpp \
|
||||
PDB2CifRemark3.cpp \
|
||||
Point.cpp \
|
||||
Secondary.cpp \
|
||||
Structure.cpp \
|
||||
Symmetry.cpp \
|
||||
TlsParser.cpp
|
||||
|
||||
SOURCES = $(addprefix src/,$(LIBCIF_SRC))
|
||||
OBJECTS = $(addprefix $(OBJDIR)/, $(notdir $(SOURCES:%.cpp=%.lo)))
|
||||
|
||||
ifneq "$(CCP4DIR)" ""
|
||||
|
||||
# Special rules to generate symmetry operation number table
|
||||
tools/symop-map-generator: tools/symop-map-generator.cpp
|
||||
|
||||
src/SymOpTable_data.cpp: tools/symop-map-generator $(CLIBD)/symop.lib
|
||||
tools/symop-map-generator > $@
|
||||
|
||||
$(OBJDIR)/Symmetry.lo: src/SymOpTable_data.cpp
|
||||
|
||||
endif
|
||||
|
||||
$(LIB_TARGET): $(OBJECTS)
|
||||
$(CXXLINK) -rpath $(libdir) $(OBJECTS) $(LIBS)
|
||||
|
||||
lib: $(LIB_TARGET)
|
||||
.PHONY: libs
|
||||
|
||||
all: lib
|
||||
.PHONY: all
|
||||
|
||||
-include $(OBJECTS:%.lo=%.d)
|
||||
|
||||
$(OBJECTS:.lo=.d):
|
||||
|
||||
$(OBJDIR)/%.lo: %.cpp | $(OBJDIR)
|
||||
@ echo ">>" $<
|
||||
@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(OBJDIR)/$*.d -c -o $@ $<
|
||||
|
||||
$(OBJDIR)/%.o: %.cpp | $(OBJDIR)
|
||||
@ echo ">>" $<
|
||||
@ $(CXX) $(CXXFLAGS) -MT $@ -MD -MP -MF $(OBJDIR)/$*.d -c -o $@ $<
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf .libs $(OBJDIR)/* $(LIB_TARGET)
|
||||
|
||||
.PHONY: distclean
|
||||
distclean: clean
|
||||
rm -f libtool config.lt
|
||||
rm -f config.status config.cache config.log configure.lineno config.status.lineno
|
||||
rm -f GNUmakefile
|
||||
|
||||
# Test rules
|
||||
|
||||
define TEST_template =
|
||||
|
||||
-include $$(OBJDIR)/$(1)-test.d
|
||||
|
||||
$(1)_OBJECTS = $$(OBJDIR)/$(1)-test.o
|
||||
|
||||
test/$(1)-test: $(LIB_TARGET) $$($(1)_OBJECTS)
|
||||
@ echo ">>> building $(1)-test"
|
||||
$(LIBTOOL) --silent --tag=CXX --mode=link $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $$@ $$($(1)_OBJECTS) -L.libs -lcif++ $(LIBS)
|
||||
|
||||
.PHONY: $(1)-test
|
||||
$(1)-test: test/$(1)-test
|
||||
cd test; ./$(1)-test $$($(1)_PARAMS)
|
||||
|
||||
endef
|
||||
|
||||
TESTS = unit
|
||||
|
||||
$(foreach part,$(TESTS),$(eval $(call TEST_template,$(part))))
|
||||
|
||||
.PHONY: test
|
||||
test: $(TESTS:%=%-test)
|
||||
|
||||
HEADERS = \
|
||||
AtomType.hpp \
|
||||
CifParser.hpp \
|
||||
Compound.hpp \
|
||||
PDB2CifRemark3.hpp \
|
||||
Structure.hpp \
|
||||
Cif2PDB.hpp \
|
||||
CifUtils.hpp \
|
||||
Config.hpp \
|
||||
Point.hpp \
|
||||
Symmetry.hpp \
|
||||
Cif++.hpp \
|
||||
CifValidator.hpp \
|
||||
PDB2Cif.hpp \
|
||||
Secondary.hpp \
|
||||
TlsParser.hpp
|
||||
|
||||
.PHONY: install-lib
|
||||
install-lib: lib
|
||||
install -d $(libdir)
|
||||
$(LIBTOOL) --mode=install install $(LIB_TARGET) $(libdir)
|
||||
install -d $(DATADIR)/dictionaries
|
||||
for d in mmcif_ddl.dic mmcif_pdbx.dic; do \
|
||||
install -m644 rsrc/dictionaries/$$d $(DATADIR)/dictionaries/$$d; \
|
||||
done
|
||||
|
||||
.PHONY: install-dev
|
||||
install-dev:
|
||||
install -d $(includedir)/cif++
|
||||
for f in $(HEADERS); do install include/cif++/$$f $(includedir)/cif++/$$f; done
|
||||
install -d $(pkgconfigdir)
|
||||
install -m 644 $(LIB_NAME).pc $(pkgconfigdir)/$(LIB_NAME).pc
|
||||
|
||||
.PHONY: install
|
||||
install: install-lib install-dev
|
||||
|
||||
dist-clean: clean
|
||||
|
||||
FORCE:
|
||||
23
LICENSE
Normal file
23
LICENSE
Normal file
@@ -0,0 +1,23 @@
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
32
README.md
Normal file
32
README.md
Normal file
@@ -0,0 +1,32 @@
|
||||
[](https://travis-ci.org/PDB-REDO/libcifpp)
|
||||
|
||||
libcif++
|
||||
========
|
||||
|
||||
This library contains code to work with mmCIF and PDB files.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
The code for this library was written in C++17. You therefore need a
|
||||
recent compiler to build it. For the development gcc 9.3 and clang 9.0
|
||||
have been used.
|
||||
|
||||
Other requirements are:
|
||||
|
||||
- GNU make version 4.1 or higher.
|
||||
- Boost libraries, at least version 1.71
|
||||
- [mrc](https://github.com/mhekkel/mrc), a resource compiler that
|
||||
allows including data files into the executable making them easier to
|
||||
install. Strictly this is optional, but at the expense of a lot of
|
||||
functionality.
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
Simply configure, make and make install.
|
||||
|
||||
There's one configure flag that might be of interest: if you specify
|
||||
DEBUG=1 the make will create a debug version by default. Otherwise,
|
||||
you can run make with DEBUG=1 to create a debug version.
|
||||
1685
aclocal.m4
vendored
Normal file
1685
aclocal.m4
vendored
Normal file
File diff suppressed because it is too large
Load Diff
19
config-tests/cpp-17-test.cpp
Normal file
19
config-tests/cpp-17-test.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <algorithm>
|
||||
|
||||
template<typename COMP>
|
||||
class foo
|
||||
{
|
||||
public:
|
||||
foo(int a, COMP&& b)
|
||||
: m_a(a), m_b(std::move(b)) {}
|
||||
|
||||
int m_a;
|
||||
COMP m_b;
|
||||
};
|
||||
|
||||
void bar(const int& b)
|
||||
{
|
||||
int c = 1;
|
||||
auto f = new foo(c, [tag = c, b](const int& x)
|
||||
{ x < b; });
|
||||
}
|
||||
1480
config/config.guess
vendored
Executable file
1480
config/config.guess
vendored
Executable file
File diff suppressed because it is too large
Load Diff
1801
config/config.sub
vendored
Executable file
1801
config/config.sub
vendored
Executable file
File diff suppressed because it is too large
Load Diff
518
config/install-sh
Executable file
518
config/install-sh
Executable file
@@ -0,0 +1,518 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2018-03-11.20; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# 'make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
|
||||
tab=' '
|
||||
nl='
|
||||
'
|
||||
IFS=" $tab$nl"
|
||||
|
||||
# Set DOITPROG to "echo" to test this script.
|
||||
|
||||
doit=${DOITPROG-}
|
||||
doit_exec=${doit:-exec}
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
stripcmd=
|
||||
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
copy_on_change=false
|
||||
is_target_a_directory=possibly
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t)
|
||||
is_target_a_directory=always
|
||||
dst_arg=$2
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-T) is_target_a_directory=never;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# We allow the use of options -d and -T together, by making -d
|
||||
# take the precedence; this is for compatibility with GNU install.
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
if test -n "$dst_arg"; then
|
||||
echo "$0: target directory not allowed when installing a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call 'install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
if test $# -gt 1 || test "$is_target_a_directory" = always; then
|
||||
if test ! -d "$dst_arg"; then
|
||||
echo "$0: $dst_arg: Is not a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
do_exit='(exit $ret); exit $ret'
|
||||
trap "ret=129; $do_exit" 1
|
||||
trap "ret=130; $do_exit" 2
|
||||
trap "ret=141; $do_exit" 13
|
||||
trap "ret=143; $do_exit" 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $src in
|
||||
-* | [=\(\)!]) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
dst=$dst_arg
|
||||
|
||||
# If destination is a directory, append the input filename.
|
||||
if test -d "$dst"; then
|
||||
if test "$is_target_a_directory" = never; then
|
||||
echo "$0: $dst_arg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dstdir=$dst
|
||||
dstbase=`basename "$src"`
|
||||
case $dst in
|
||||
*/) dst=$dst$dstbase;;
|
||||
*) dst=$dst/$dstbase;;
|
||||
esac
|
||||
dstdir_status=0
|
||||
else
|
||||
dstdir=`dirname "$dst"`
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
case $dstdir in
|
||||
*/) dstdirslash=$dstdir;;
|
||||
*) dstdirslash=$dstdir/;;
|
||||
esac
|
||||
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
# Note that $RANDOM variable is not portable (e.g. dash); Use it
|
||||
# here however when possible just to lower collision chance.
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
|
||||
trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
|
||||
# Because "mkdir -p" follows existing symlinks and we likely work
|
||||
# directly in world-writeable /tmp, make sure that the '$tmpdir'
|
||||
# directory is successfully created first before we actually test
|
||||
# 'mkdir -p' feature.
|
||||
if (umask $mkdir_umask &&
|
||||
$mkdirprog $mkdir_mode "$tmpdir" &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
test_tmpdir="$tmpdir/a"
|
||||
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
[-=\(\)!]*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test X"$d" = X && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=${dstdirslash}_inst.$$_
|
||||
rmtmp=${dstdirslash}_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
set +f &&
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
{
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
11251
config/ltmain.sh
Normal file
11251
config/ltmain.sh
Normal file
File diff suppressed because it is too large
Load Diff
8394
config/m4/libtool.m4
vendored
Normal file
8394
config/m4/libtool.m4
vendored
Normal file
File diff suppressed because it is too large
Load Diff
437
config/m4/ltoptions.m4
vendored
Normal file
437
config/m4/ltoptions.m4
vendored
Normal file
@@ -0,0 +1,437 @@
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
#
|
||||
# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
|
||||
# Foundation, Inc.
|
||||
# Written by Gary V. Vaughan, 2004
|
||||
#
|
||||
# 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 ltoptions.m4
|
||||
|
||||
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
|
||||
|
||||
|
||||
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
|
||||
# ------------------------------------------
|
||||
m4_define([_LT_MANGLE_OPTION],
|
||||
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
|
||||
|
||||
|
||||
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
|
||||
# ---------------------------------------
|
||||
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
|
||||
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
|
||||
# saved as a flag.
|
||||
m4_define([_LT_SET_OPTION],
|
||||
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
|
||||
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
|
||||
_LT_MANGLE_DEFUN([$1], [$2]),
|
||||
[m4_warning([Unknown $1 option '$2'])])[]dnl
|
||||
])
|
||||
|
||||
|
||||
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
|
||||
# ------------------------------------------------------------
|
||||
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
|
||||
m4_define([_LT_IF_OPTION],
|
||||
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
|
||||
|
||||
|
||||
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
|
||||
# -------------------------------------------------------
|
||||
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
|
||||
# are set.
|
||||
m4_define([_LT_UNLESS_OPTIONS],
|
||||
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
|
||||
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
|
||||
[m4_define([$0_found])])])[]dnl
|
||||
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
|
||||
])[]dnl
|
||||
])
|
||||
|
||||
|
||||
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
|
||||
# ----------------------------------------
|
||||
# OPTION-LIST is a space-separated list of Libtool options associated
|
||||
# with MACRO-NAME. If any OPTION has a matching handler declared with
|
||||
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
|
||||
# the unknown option and exit.
|
||||
m4_defun([_LT_SET_OPTIONS],
|
||||
[# Set options
|
||||
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
|
||||
[_LT_SET_OPTION([$1], _LT_Option)])
|
||||
|
||||
m4_if([$1],[LT_INIT],[
|
||||
dnl
|
||||
dnl Simply set some default values (i.e off) if boolean options were not
|
||||
dnl specified:
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
|
||||
])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
|
||||
])
|
||||
dnl
|
||||
dnl If no reference was made to various pairs of opposing options, then
|
||||
dnl we run the default mode handler for the pair. For example, if neither
|
||||
dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
|
||||
dnl archives by default:
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
|
||||
[_LT_ENABLE_FAST_INSTALL])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
|
||||
[_LT_WITH_AIX_SONAME([aix])])
|
||||
])
|
||||
])# _LT_SET_OPTIONS
|
||||
|
||||
|
||||
## --------------------------------- ##
|
||||
## Macros to handle LT_INIT options. ##
|
||||
## --------------------------------- ##
|
||||
|
||||
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
|
||||
# -----------------------------------------
|
||||
m4_define([_LT_MANGLE_DEFUN],
|
||||
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
|
||||
|
||||
|
||||
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
|
||||
# -----------------------------------------------
|
||||
m4_define([LT_OPTION_DEFINE],
|
||||
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
|
||||
])# LT_OPTION_DEFINE
|
||||
|
||||
|
||||
# dlopen
|
||||
# ------
|
||||
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
|
||||
])
|
||||
|
||||
AU_DEFUN([AC_LIBTOOL_DLOPEN],
|
||||
[_LT_SET_OPTION([LT_INIT], [dlopen])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||
put the 'dlopen' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
|
||||
|
||||
|
||||
# win32-dll
|
||||
# ---------
|
||||
# Declare package support for building win32 dll's.
|
||||
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
|
||||
[enable_win32_dll=yes
|
||||
|
||||
case $host in
|
||||
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
|
||||
AC_CHECK_TOOL(AS, as, false)
|
||||
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
|
||||
AC_CHECK_TOOL(OBJDUMP, objdump, false)
|
||||
;;
|
||||
esac
|
||||
|
||||
test -z "$AS" && AS=as
|
||||
_LT_DECL([], [AS], [1], [Assembler program])dnl
|
||||
|
||||
test -z "$DLLTOOL" && DLLTOOL=dlltool
|
||||
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
|
||||
|
||||
test -z "$OBJDUMP" && OBJDUMP=objdump
|
||||
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
|
||||
])# win32-dll
|
||||
|
||||
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
|
||||
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
|
||||
_LT_SET_OPTION([LT_INIT], [win32-dll])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||
put the 'win32-dll' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
|
||||
|
||||
|
||||
# _LT_ENABLE_SHARED([DEFAULT])
|
||||
# ----------------------------
|
||||
# implement the --enable-shared flag, and supports the 'shared' and
|
||||
# 'disable-shared' LT_INIT options.
|
||||
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
|
||||
m4_define([_LT_ENABLE_SHARED],
|
||||
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||
AC_ARG_ENABLE([shared],
|
||||
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
|
||||
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
|
||||
[p=${PACKAGE-default}
|
||||
case $enableval in
|
||||
yes) enable_shared=yes ;;
|
||||
no) enable_shared=no ;;
|
||||
*)
|
||||
enable_shared=no
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
|
||||
for pkg in $enableval; do
|
||||
IFS=$lt_save_ifs
|
||||
if test "X$pkg" = "X$p"; then
|
||||
enable_shared=yes
|
||||
fi
|
||||
done
|
||||
IFS=$lt_save_ifs
|
||||
;;
|
||||
esac],
|
||||
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
|
||||
|
||||
_LT_DECL([build_libtool_libs], [enable_shared], [0],
|
||||
[Whether or not to build shared libraries])
|
||||
])# _LT_ENABLE_SHARED
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
|
||||
|
||||
# Old names:
|
||||
AC_DEFUN([AC_ENABLE_SHARED],
|
||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
|
||||
])
|
||||
|
||||
AC_DEFUN([AC_DISABLE_SHARED],
|
||||
[_LT_SET_OPTION([LT_INIT], [disable-shared])
|
||||
])
|
||||
|
||||
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
|
||||
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
|
||||
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
|
||||
|
||||
|
||||
|
||||
# _LT_ENABLE_STATIC([DEFAULT])
|
||||
# ----------------------------
|
||||
# implement the --enable-static flag, and support the 'static' and
|
||||
# 'disable-static' LT_INIT options.
|
||||
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
|
||||
m4_define([_LT_ENABLE_STATIC],
|
||||
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||
AC_ARG_ENABLE([static],
|
||||
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
|
||||
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
|
||||
[p=${PACKAGE-default}
|
||||
case $enableval in
|
||||
yes) enable_static=yes ;;
|
||||
no) enable_static=no ;;
|
||||
*)
|
||||
enable_static=no
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
|
||||
for pkg in $enableval; do
|
||||
IFS=$lt_save_ifs
|
||||
if test "X$pkg" = "X$p"; then
|
||||
enable_static=yes
|
||||
fi
|
||||
done
|
||||
IFS=$lt_save_ifs
|
||||
;;
|
||||
esac],
|
||||
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
|
||||
|
||||
_LT_DECL([build_old_libs], [enable_static], [0],
|
||||
[Whether or not to build static libraries])
|
||||
])# _LT_ENABLE_STATIC
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
|
||||
|
||||
# Old names:
|
||||
AC_DEFUN([AC_ENABLE_STATIC],
|
||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
|
||||
])
|
||||
|
||||
AC_DEFUN([AC_DISABLE_STATIC],
|
||||
[_LT_SET_OPTION([LT_INIT], [disable-static])
|
||||
])
|
||||
|
||||
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
|
||||
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
|
||||
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
|
||||
|
||||
|
||||
|
||||
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
|
||||
# ----------------------------------
|
||||
# implement the --enable-fast-install flag, and support the 'fast-install'
|
||||
# and 'disable-fast-install' LT_INIT options.
|
||||
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
|
||||
m4_define([_LT_ENABLE_FAST_INSTALL],
|
||||
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||
AC_ARG_ENABLE([fast-install],
|
||||
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
|
||||
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
|
||||
[p=${PACKAGE-default}
|
||||
case $enableval in
|
||||
yes) enable_fast_install=yes ;;
|
||||
no) enable_fast_install=no ;;
|
||||
*)
|
||||
enable_fast_install=no
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
|
||||
for pkg in $enableval; do
|
||||
IFS=$lt_save_ifs
|
||||
if test "X$pkg" = "X$p"; then
|
||||
enable_fast_install=yes
|
||||
fi
|
||||
done
|
||||
IFS=$lt_save_ifs
|
||||
;;
|
||||
esac],
|
||||
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
|
||||
|
||||
_LT_DECL([fast_install], [enable_fast_install], [0],
|
||||
[Whether or not to optimize for fast installation])dnl
|
||||
])# _LT_ENABLE_FAST_INSTALL
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
|
||||
|
||||
# Old names:
|
||||
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
|
||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
|
||||
the 'fast-install' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
|
||||
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
|
||||
the 'disable-fast-install' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
|
||||
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
|
||||
|
||||
|
||||
# _LT_WITH_AIX_SONAME([DEFAULT])
|
||||
# ----------------------------------
|
||||
# implement the --with-aix-soname flag, and support the `aix-soname=aix'
|
||||
# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
|
||||
# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'.
|
||||
m4_define([_LT_WITH_AIX_SONAME],
|
||||
[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
|
||||
shared_archive_member_spec=
|
||||
case $host,$enable_shared in
|
||||
power*-*-aix[[5-9]]*,yes)
|
||||
AC_MSG_CHECKING([which variant of shared library versioning to provide])
|
||||
AC_ARG_WITH([aix-soname],
|
||||
[AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
|
||||
[shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
|
||||
[case $withval in
|
||||
aix|svr4|both)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([Unknown argument to --with-aix-soname])
|
||||
;;
|
||||
esac
|
||||
lt_cv_with_aix_soname=$with_aix_soname],
|
||||
[AC_CACHE_VAL([lt_cv_with_aix_soname],
|
||||
[lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
|
||||
with_aix_soname=$lt_cv_with_aix_soname])
|
||||
AC_MSG_RESULT([$with_aix_soname])
|
||||
if test aix != "$with_aix_soname"; then
|
||||
# For the AIX way of multilib, we name the shared archive member
|
||||
# based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
|
||||
# and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
|
||||
# Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
|
||||
# the AIX toolchain works better with OBJECT_MODE set (default 32).
|
||||
if test 64 = "${OBJECT_MODE-32}"; then
|
||||
shared_archive_member_spec=shr_64
|
||||
else
|
||||
shared_archive_member_spec=shr
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
with_aix_soname=aix
|
||||
;;
|
||||
esac
|
||||
|
||||
_LT_DECL([], [shared_archive_member_spec], [0],
|
||||
[Shared archive member basename, for filename based shared library versioning on AIX])dnl
|
||||
])# _LT_WITH_AIX_SONAME
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
|
||||
|
||||
|
||||
# _LT_WITH_PIC([MODE])
|
||||
# --------------------
|
||||
# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
|
||||
# LT_INIT options.
|
||||
# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'.
|
||||
m4_define([_LT_WITH_PIC],
|
||||
[AC_ARG_WITH([pic],
|
||||
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
|
||||
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
|
||||
[lt_p=${PACKAGE-default}
|
||||
case $withval in
|
||||
yes|no) pic_mode=$withval ;;
|
||||
*)
|
||||
pic_mode=default
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
|
||||
for lt_pkg in $withval; do
|
||||
IFS=$lt_save_ifs
|
||||
if test "X$lt_pkg" = "X$lt_p"; then
|
||||
pic_mode=yes
|
||||
fi
|
||||
done
|
||||
IFS=$lt_save_ifs
|
||||
;;
|
||||
esac],
|
||||
[pic_mode=m4_default([$1], [default])])
|
||||
|
||||
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
|
||||
])# _LT_WITH_PIC
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
|
||||
|
||||
# Old name:
|
||||
AU_DEFUN([AC_LIBTOOL_PICMODE],
|
||||
[_LT_SET_OPTION([LT_INIT], [pic-only])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||
put the 'pic-only' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
|
||||
|
||||
## ----------------- ##
|
||||
## LTDL_INIT Options ##
|
||||
## ----------------- ##
|
||||
|
||||
m4_define([_LTDL_MODE], [])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
|
||||
[m4_define([_LTDL_MODE], [nonrecursive])])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
|
||||
[m4_define([_LTDL_MODE], [recursive])])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
|
||||
[m4_define([_LTDL_MODE], [subproject])])
|
||||
|
||||
m4_define([_LTDL_TYPE], [])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [installable],
|
||||
[m4_define([_LTDL_TYPE], [installable])])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
|
||||
[m4_define([_LTDL_TYPE], [convenience])])
|
||||
124
config/m4/ltsugar.m4
vendored
Normal file
124
config/m4/ltsugar.m4
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
|
||||
#
|
||||
# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
|
||||
# Foundation, Inc.
|
||||
# Written by Gary V. Vaughan, 2004
|
||||
#
|
||||
# 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 ltsugar.m4
|
||||
|
||||
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
|
||||
|
||||
|
||||
# lt_join(SEP, ARG1, [ARG2...])
|
||||
# -----------------------------
|
||||
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
|
||||
# associated separator.
|
||||
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
|
||||
# versions in m4sugar had bugs.
|
||||
m4_define([lt_join],
|
||||
[m4_if([$#], [1], [],
|
||||
[$#], [2], [[$2]],
|
||||
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
|
||||
m4_define([_lt_join],
|
||||
[m4_if([$#$2], [2], [],
|
||||
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
|
||||
|
||||
|
||||
# lt_car(LIST)
|
||||
# lt_cdr(LIST)
|
||||
# ------------
|
||||
# Manipulate m4 lists.
|
||||
# These macros are necessary as long as will still need to support
|
||||
# Autoconf-2.59, which quotes differently.
|
||||
m4_define([lt_car], [[$1]])
|
||||
m4_define([lt_cdr],
|
||||
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
|
||||
[$#], 1, [],
|
||||
[m4_dquote(m4_shift($@))])])
|
||||
m4_define([lt_unquote], $1)
|
||||
|
||||
|
||||
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
|
||||
# ------------------------------------------
|
||||
# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
|
||||
# Note that neither SEPARATOR nor STRING are expanded; they are appended
|
||||
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
|
||||
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
|
||||
# than defined and empty).
|
||||
#
|
||||
# This macro is needed until we can rely on Autoconf 2.62, since earlier
|
||||
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
|
||||
m4_define([lt_append],
|
||||
[m4_define([$1],
|
||||
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
|
||||
|
||||
|
||||
|
||||
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
|
||||
# ----------------------------------------------------------
|
||||
# Produce a SEP delimited list of all paired combinations of elements of
|
||||
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
|
||||
# has the form PREFIXmINFIXSUFFIXn.
|
||||
# Needed until we can rely on m4_combine added in Autoconf 2.62.
|
||||
m4_define([lt_combine],
|
||||
[m4_if(m4_eval([$# > 3]), [1],
|
||||
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
|
||||
[[m4_foreach([_Lt_prefix], [$2],
|
||||
[m4_foreach([_Lt_suffix],
|
||||
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
|
||||
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
|
||||
|
||||
|
||||
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
|
||||
# -----------------------------------------------------------------------
|
||||
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
|
||||
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
|
||||
m4_define([lt_if_append_uniq],
|
||||
[m4_ifdef([$1],
|
||||
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
|
||||
[lt_append([$1], [$2], [$3])$4],
|
||||
[$5])],
|
||||
[lt_append([$1], [$2], [$3])$4])])
|
||||
|
||||
|
||||
# lt_dict_add(DICT, KEY, VALUE)
|
||||
# -----------------------------
|
||||
m4_define([lt_dict_add],
|
||||
[m4_define([$1($2)], [$3])])
|
||||
|
||||
|
||||
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
|
||||
# --------------------------------------------
|
||||
m4_define([lt_dict_add_subkey],
|
||||
[m4_define([$1($2:$3)], [$4])])
|
||||
|
||||
|
||||
# lt_dict_fetch(DICT, KEY, [SUBKEY])
|
||||
# ----------------------------------
|
||||
m4_define([lt_dict_fetch],
|
||||
[m4_ifval([$3],
|
||||
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
|
||||
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
|
||||
|
||||
|
||||
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
|
||||
# -----------------------------------------------------------------
|
||||
m4_define([lt_if_dict_fetch],
|
||||
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
|
||||
[$5],
|
||||
[$6])])
|
||||
|
||||
|
||||
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
|
||||
# --------------------------------------------------------------
|
||||
m4_define([lt_dict_filter],
|
||||
[m4_if([$5], [], [],
|
||||
[lt_join(m4_quote(m4_default([$4], [[, ]])),
|
||||
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
|
||||
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
|
||||
])
|
||||
23
config/m4/ltversion.m4
vendored
Normal file
23
config/m4/ltversion.m4
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# ltversion.m4 -- version numbers -*- Autoconf -*-
|
||||
#
|
||||
# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
|
||||
# Written by Scott James Remnant, 2004
|
||||
#
|
||||
# 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.
|
||||
|
||||
# @configure_input@
|
||||
|
||||
# serial 4179 ltversion.m4
|
||||
# This file is part of GNU Libtool
|
||||
|
||||
m4_define([LT_PACKAGE_VERSION], [2.4.6])
|
||||
m4_define([LT_PACKAGE_REVISION], [2.4.6])
|
||||
|
||||
AC_DEFUN([LTVERSION_VERSION],
|
||||
[macro_version='2.4.6'
|
||||
macro_revision='2.4.6'
|
||||
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
|
||||
_LT_DECL(, macro_revision, 0)
|
||||
])
|
||||
99
config/m4/lt~obsolete.m4
vendored
Normal file
99
config/m4/lt~obsolete.m4
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
|
||||
#
|
||||
# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
|
||||
# Foundation, Inc.
|
||||
# Written by Scott James Remnant, 2004.
|
||||
#
|
||||
# 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 lt~obsolete.m4
|
||||
|
||||
# These exist entirely to fool aclocal when bootstrapping libtool.
|
||||
#
|
||||
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
|
||||
# which have later been changed to m4_define as they aren't part of the
|
||||
# exported API, or moved to Autoconf or Automake where they belong.
|
||||
#
|
||||
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
|
||||
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
|
||||
# using a macro with the same name in our local m4/libtool.m4 it'll
|
||||
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
|
||||
# and doesn't know about Autoconf macros at all.)
|
||||
#
|
||||
# So we provide this file, which has a silly filename so it's always
|
||||
# included after everything else. This provides aclocal with the
|
||||
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
|
||||
# because those macros already exist, or will be overwritten later.
|
||||
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
|
||||
#
|
||||
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
|
||||
# Yes, that means every name once taken will need to remain here until
|
||||
# we give up compatibility with versions before 1.7, at which point
|
||||
# we need to keep only those names which we still refer to.
|
||||
|
||||
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
|
||||
|
||||
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
|
||||
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
|
||||
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
|
||||
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
|
||||
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
|
||||
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
|
||||
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
|
||||
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
|
||||
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
|
||||
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
|
||||
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
|
||||
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
|
||||
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
|
||||
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
|
||||
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
|
||||
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
|
||||
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
|
||||
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
|
||||
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
|
||||
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
|
||||
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
|
||||
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
|
||||
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
|
||||
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
|
||||
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
|
||||
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
|
||||
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
|
||||
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
|
||||
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
|
||||
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
|
||||
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
|
||||
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
|
||||
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
|
||||
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
|
||||
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
|
||||
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
|
||||
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
|
||||
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
|
||||
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
|
||||
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
|
||||
57
configure.ac
Normal file
57
configure.ac
Normal file
@@ -0,0 +1,57 @@
|
||||
AC_PREREQ([2.69])
|
||||
|
||||
AC_INIT([libcif++], 1.0, [m.hekkelman@nki.nl])
|
||||
|
||||
dnl Switch to a C++ compiler, and check if it works.
|
||||
AC_LANG(C++)
|
||||
AX_CXX_COMPILE_STDCXX_17([noext])
|
||||
|
||||
AX_CHECK_COMPILE_FLAG([-fstandalone-debug], [ CXXFLAGS="$CXXFLAGS -fstandalone-debug" ], , [-Werror])
|
||||
|
||||
AC_CONFIG_SRCDIR([src/Cif++.cpp])
|
||||
AC_CONFIG_AUX_DIR(config)
|
||||
AC_CONFIG_MACRO_DIR([config/m4])
|
||||
AC_CONFIG_HEADERS([include/cif++/Config.hpp])
|
||||
|
||||
AC_PREFIX_DEFAULT(/usr/local)
|
||||
|
||||
dnl AC_DEFUN([read_test], [AC_LANG_SOURCE(
|
||||
dnl esyscmd(tools/m4esc.sh config-tests/$1))])
|
||||
dnl
|
||||
dnl AC_MSG_CHECKING([compiler standards compliance])
|
||||
dnl AC_COMPILE_IFELSE(
|
||||
dnl [read_test(cpp-17-test.cpp)], [],
|
||||
dnl [AC_MSG_ERROR([Your c++ compiler is not capable of compiling libcifpp, please upgrade])])
|
||||
dnl AC_MSG_RESULT(ok)
|
||||
|
||||
AC_PROG_INSTALL
|
||||
AC_ENABLE_STATIC
|
||||
AC_DISABLE_SHARED
|
||||
AC_PROG_LIBTOOL
|
||||
AC_SUBST(LIBTOOL_DEPS)
|
||||
|
||||
AC_ARG_VAR([DEBUG], [Build a debug version of the library])
|
||||
|
||||
AC_ARG_VAR([CCP4], [The location where CCP4 is installed])
|
||||
|
||||
AC_PATH_PROG([PKG_CONFIG], [pkg-config])
|
||||
|
||||
AC_CHECK_FUNCS([floor pow rint sqrt strchr strerror])
|
||||
AC_CHECK_HEADERS([sys/ioctl.h])
|
||||
AC_CHECK_HEADERS([termios.h])
|
||||
AC_CHECK_HEADER_STDBOOL
|
||||
AC_CHECK_TYPES([ptrdiff_t])
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
AX_BOOST_BASE([1.71], [], [
|
||||
AC_MSG_ERROR([Sorry, your boost is not found or not up-to-date.])
|
||||
])
|
||||
AX_BOOST_IOSTREAMS
|
||||
|
||||
AX_CHECK_LIBRARY([LIBZ], [zlib.h], [z], [],
|
||||
[AC_MSG_ERROR([libz not found - compressed files not supported])])
|
||||
AX_CHECK_LIBRARY([LIBBZ2], [bzlib.h], [bz2], [],
|
||||
[AC_MSG_ERROR([libbz2 not found - compressed files not supported])])
|
||||
|
||||
AC_OUTPUT([GNUmakefile
|
||||
libcif++.pc])
|
||||
5
debian/changelog
vendored
Normal file
5
debian/changelog
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
libcifpp (0.1.0-1) unstable; urgency=medium
|
||||
|
||||
* Initial release. (Closes: #XXXXXX)
|
||||
|
||||
-- Maarten L. Hekkelman <maarten@hekkelman.com> Mon, 28 Sep 2020 08:34:16 +0200
|
||||
44
debian/control
vendored
Normal file
44
debian/control
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
Source: libcifpp
|
||||
Maintainer: Debian Med Packaging Team <debian-med-packaging@lists.alioth.debian.org>
|
||||
Uploaders: Maarten L. Hekkelman <maarten@hekkelman.com>,
|
||||
Andreas Tille <tille@debian.org>
|
||||
Section: libs
|
||||
Priority: optional
|
||||
Build-Depends: debhelper-compat (= 12),
|
||||
autoconf-archive,
|
||||
libboost-dev,
|
||||
libboost-iostreams-dev,
|
||||
libboost-system-dev,
|
||||
zlib1g-dev,
|
||||
libbz2-dev
|
||||
Standards-Version: 4.5.0
|
||||
Vcs-Browser: https://salsa.debian.org/med-team/libcifpp
|
||||
Vcs-Git: https://salsa.debian.org/med-team/libcifpp.git
|
||||
Homepage: https://github.com/PDB-REDO/libcifpp
|
||||
Rules-Requires-Root: no
|
||||
|
||||
Package: libcifpp-dev
|
||||
Architecture: any
|
||||
Section: libdevel
|
||||
Depends: ${misc:Depends},
|
||||
libcifpp0.1 (= ${binary:Version}),
|
||||
libboost-dev,
|
||||
libboost-iostreams-dev,
|
||||
pkg-config
|
||||
Suggests: libcifpp-doc
|
||||
Description: Development files for libcifpp
|
||||
Libcifpp is a C++ library used to create and manipulate
|
||||
mmCIF and PDB files containing macro molecular structure information.
|
||||
.
|
||||
This specific package contains all files needed to develop new
|
||||
software using libcifpp.
|
||||
|
||||
Package: libcifpp0.1
|
||||
Architecture: any
|
||||
Depends: ${misc:Depends},
|
||||
${shlibs:Depends}
|
||||
Description: Library files for libcifpp
|
||||
Libcifpp is a C++ library used to create and manipulate
|
||||
mmCIF and PDB files containing macro molecular structure information.
|
||||
.
|
||||
This package contains the library file only.
|
||||
35
debian/copyright
vendored
Normal file
35
debian/copyright
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: libcifpp
|
||||
Upstream-Contact: Maarten L. Hekkelman <maarten@hekkelman.com>
|
||||
Source: http://github.com/PDB-REDO/libcifpp
|
||||
|
||||
Files: *
|
||||
Copyright: © 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
License: BSD-2-Clause
|
||||
|
||||
Files: debian/*
|
||||
Copyright: © 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
License: BSD-2-Clause
|
||||
|
||||
License: BSD-2-Clause
|
||||
Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
.
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
1
debian/libcifpp-dev.docs
vendored
Normal file
1
debian/libcifpp-dev.docs
vendored
Normal file
@@ -0,0 +1 @@
|
||||
README.md
|
||||
1
debian/libcifpp0.1.docs
vendored
Normal file
1
debian/libcifpp0.1.docs
vendored
Normal file
@@ -0,0 +1 @@
|
||||
README.md
|
||||
15
debian/patches/install-at-destdir
vendored
Normal file
15
debian/patches/install-at-destdir
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
Description: Fix makefiles to install at the correct location
|
||||
Author: Maarten L. Hekkelman <maarten@hekkelman.com>
|
||||
Last-Update: Mon, 28 Sep 2020 09:18:14 +0200
|
||||
|
||||
--- a/GNUmakefile.in
|
||||
+++ b/GNUmakefile.in
|
||||
@@ -33,7 +33,7 @@
|
||||
LIBS = @LIBS@ \
|
||||
@BOOST_IOSTREAMS_LIB@
|
||||
|
||||
-prefix = @prefix@
|
||||
+prefix = $(DESTDIR)/@prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
libdir = @libdir@
|
||||
includedir = @includedir@
|
||||
1
debian/patches/series
vendored
Normal file
1
debian/patches/series
vendored
Normal file
@@ -0,0 +1 @@
|
||||
install-at-destdir
|
||||
39
debian/rules
vendored
Normal file
39
debian/rules
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
DH_VERBOSE := 1
|
||||
|
||||
export DEB_BUILD_MAINT_OPTIONS=hardening=+all
|
||||
# Fixing reproducible builds
|
||||
LC_ALL := C.UTF-8
|
||||
export LC_ALL
|
||||
|
||||
export LIBRARY_VERSION=0.1
|
||||
|
||||
%:
|
||||
dh $@
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure -- --enable-documentation
|
||||
|
||||
override_dh_auto_install:
|
||||
$(MAKE) DESTDIR=$(CURDIR)/debian/libcifpp0.1 install-lib
|
||||
$(MAKE) DESTDIR=$(CURDIR)/debian/libcifpp-dev install-dev
|
||||
|
||||
override_dh_auto_configure-arch:
|
||||
dh_auto_configure -- --enable-shared
|
||||
|
||||
override_dh_auto_configure-indep:
|
||||
dh_auto_configure -- --enable-shared
|
||||
|
||||
override_dh_auto_test:
|
||||
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
|
||||
$(MAKE) test
|
||||
endif
|
||||
|
||||
override_dh_install:
|
||||
## cleaning up dependency_libs filed in *.la files
|
||||
sed -i "/dependency_libs/ s/'.*'/''/" `find . -name '*.la'`
|
||||
dh_install
|
||||
|
||||
override_dh_makeshlibs:
|
||||
dh_makeshlibs -- -v$(LIBRARY_VERSION)
|
||||
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@@ -0,0 +1 @@
|
||||
3.0 (quilt)
|
||||
0
debian/source/include-binaries
vendored
Normal file
0
debian/source/include-binaries
vendored
Normal file
2
debian/source/options
vendored
Normal file
2
debian/source/options
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
extend-diff-ignore = "(^|/)(\.gitignore|\.travis\.yml)$"
|
||||
|
||||
5
debian/upstream/metadata
vendored
Normal file
5
debian/upstream/metadata
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
Bug-Database: https://github.com/PDB-REDO/libcifpp/issues
|
||||
Bug-Submit: https://github.com/PDB-REDO/libcifpp/issues/new
|
||||
Repository: https://github.com/PDB-REDO/libcifpp.git
|
||||
Repository-Browse: https://github.com/PDB-REDO/libcifpp
|
||||
3
debian/watch
vendored
Normal file
3
debian/watch
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
version=4
|
||||
opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/libcifpp-$1\.tar\.gz/ \
|
||||
https://github.com/PDB-REDO/libcifpp/tags .*/v?(\d\S+)\.tar\.gz
|
||||
247
include/cif++/AtomType.hpp
Normal file
247
include/cif++/AtomType.hpp
Normal file
@@ -0,0 +1,247 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Lib for working with structures as contained in mmCIF and PDB files
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "cif++/Config.hpp"
|
||||
|
||||
namespace mmcif
|
||||
{
|
||||
|
||||
enum AtomType : uint8_t
|
||||
{
|
||||
Nn = 0, // Unknown
|
||||
|
||||
H = 1, // Hydrogen
|
||||
He = 2, // Helium
|
||||
|
||||
Li = 3, // Lithium
|
||||
Be = 4, // Beryllium
|
||||
B = 5, // Boron
|
||||
C = 6, // Carbon
|
||||
N = 7, // Nitrogen
|
||||
O = 8, // Oxygen
|
||||
F = 9, // Fluorine
|
||||
Ne = 10, // Neon
|
||||
|
||||
Na = 11, // Sodium
|
||||
Mg = 12, // Magnesium
|
||||
Al = 13, // Aluminium
|
||||
Si = 14, // Silicon
|
||||
P = 15, // Phosphorus
|
||||
S = 16, // Sulfur
|
||||
Cl = 17, // Chlorine
|
||||
Ar = 18, // Argon
|
||||
|
||||
K = 19, // Potassium
|
||||
Ca = 20, // Calcium
|
||||
Sc = 21, // Scandium
|
||||
Ti = 22, // Titanium
|
||||
V = 23, // Vanadium
|
||||
Cr = 24, // Chromium
|
||||
Mn = 25, // Manganese
|
||||
Fe = 26, // Iron
|
||||
Co = 27, // Cobalt
|
||||
Ni = 28, // Nickel
|
||||
Cu = 29, // Copper
|
||||
Zn = 30, // Zinc
|
||||
Ga = 31, // Gallium
|
||||
Ge = 32, // Germanium
|
||||
As = 33, // Arsenic
|
||||
Se = 34, // Selenium
|
||||
Br = 35, // Bromine
|
||||
Kr = 36, // Krypton
|
||||
|
||||
Rb = 37, // Rubidium
|
||||
Sr = 38, // Strontium
|
||||
Y = 39, // Yttrium
|
||||
Zr = 40, // Zirconium
|
||||
Nb = 41, // Niobium
|
||||
Mo = 42, // Molybdenum
|
||||
Tc = 43, // Technetium
|
||||
Ru = 44, // Ruthenium
|
||||
Rh = 45, // Rhodium
|
||||
Pd = 46, // Palladium
|
||||
Ag = 47, // Silver
|
||||
Cd = 48, // Cadmium
|
||||
In = 49, // Indium
|
||||
Sn = 50, // Tin
|
||||
Sb = 51, // Antimony
|
||||
Te = 52, // Tellurium
|
||||
I = 53, // Iodine
|
||||
Xe = 54, // Xenon
|
||||
Cs = 55, // Caesium
|
||||
Ba = 56, // Barium
|
||||
La = 57, // Lanthanum
|
||||
|
||||
Hf = 72, // Hafnium
|
||||
Ta = 73, // Tantalum
|
||||
W = 74, // Tungsten
|
||||
Re = 75, // Rhenium
|
||||
Os = 76, // Osmium
|
||||
Ir = 77, // Iridium
|
||||
Pt = 78, // Platinum
|
||||
Au = 79, // Gold
|
||||
Hg = 80, // Mercury
|
||||
Tl = 81, // Thallium
|
||||
Pb = 82, // Lead
|
||||
Bi = 83, // Bismuth
|
||||
Po = 84, // Polonium
|
||||
At = 85, // Astatine
|
||||
Rn = 86, // Radon
|
||||
Fr = 87, // Francium
|
||||
Ra = 88, // Radium
|
||||
Ac = 89, // Actinium
|
||||
|
||||
Rf = 104, // Rutherfordium
|
||||
Db = 105, // Dubnium
|
||||
Sg = 106, // Seaborgium
|
||||
Bh = 107, // Bohrium
|
||||
Hs = 108, // Hassium
|
||||
Mt = 109, // Meitnerium
|
||||
Ds = 110, // Darmstadtium
|
||||
Rg = 111, // Roentgenium
|
||||
Cn = 112, // Copernicium
|
||||
Nh = 113, // Nihonium
|
||||
Fl = 114, // Flerovium
|
||||
Mc = 115, // Moscovium
|
||||
Lv = 116, // Livermorium
|
||||
Ts = 117, // Tennessine
|
||||
Og = 118, // Oganesson
|
||||
|
||||
Ce = 58, // Cerium
|
||||
Pr = 59, // Praseodymium
|
||||
Nd = 60, // Neodymium
|
||||
Pm = 61, // Promethium
|
||||
Sm = 62, // Samarium
|
||||
Eu = 63, // Europium
|
||||
Gd = 64, // Gadolinium
|
||||
Tb = 65, // Terbium
|
||||
Dy = 66, // Dysprosium
|
||||
Ho = 67, // Holmium
|
||||
Er = 68, // Erbium
|
||||
Tm = 69, // Thulium
|
||||
Yb = 70, // Ytterbium
|
||||
Lu = 71, // Lutetium
|
||||
|
||||
Th = 90, // Thorium
|
||||
Pa = 91, // Protactinium
|
||||
U = 92, // Uranium
|
||||
Np = 93, // Neptunium
|
||||
Pu = 94, // Plutonium
|
||||
Am = 95, // Americium
|
||||
Cm = 96, // Curium
|
||||
Bk = 97, // Berkelium
|
||||
Cf = 98, // Californium
|
||||
Es = 99, // Einsteinium
|
||||
Fm = 100, // Fermium
|
||||
Md = 101, // Mendelevium
|
||||
No = 102, // Nobelium
|
||||
Lr = 103, // Lawrencium
|
||||
|
||||
D = 129, // Deuterium
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// AtomTypeInfo
|
||||
|
||||
enum RadiusType {
|
||||
eRadiusCalculated,
|
||||
eRadiusEmpirical,
|
||||
eRadiusCovalentEmpirical,
|
||||
|
||||
eRadiusSingleBond,
|
||||
eRadiusDoubleBond,
|
||||
eRadiusTripleBond,
|
||||
|
||||
eRadiusVanderWaals,
|
||||
|
||||
eRadiusTypeCount
|
||||
};
|
||||
|
||||
struct AtomTypeInfo
|
||||
{
|
||||
AtomType type;
|
||||
std::string name;
|
||||
std::string symbol;
|
||||
float weight;
|
||||
bool metal;
|
||||
float radii[eRadiusTypeCount];
|
||||
};
|
||||
|
||||
extern const AtomTypeInfo kKnownAtoms[];
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// AtomTypeTraits
|
||||
|
||||
class AtomTypeTraits
|
||||
{
|
||||
public:
|
||||
AtomTypeTraits(AtomType a);
|
||||
AtomTypeTraits(const std::string& symbol);
|
||||
|
||||
AtomType type() const { return mInfo->type; }
|
||||
std::string name() const { return mInfo->name; }
|
||||
std::string symbol() const { return mInfo->symbol; }
|
||||
float weight() const { return mInfo->weight; }
|
||||
|
||||
bool isMetal() const { return mInfo->metal; }
|
||||
|
||||
static bool isElement(const std::string& symbol);
|
||||
static bool isMetal(const std::string& symbol);
|
||||
|
||||
float radius(RadiusType type = eRadiusSingleBond) const
|
||||
{
|
||||
if (type >= eRadiusTypeCount)
|
||||
throw std::invalid_argument("invalid radius requested");
|
||||
return mInfo->radii[type] / 100.f;
|
||||
}
|
||||
|
||||
// data type encapsulating the Waasmaier & Kirfel scattering factors
|
||||
// in a simplified form (only a and b).
|
||||
// Added the electrion scattering factors as well
|
||||
struct SFData
|
||||
{
|
||||
double a[6], b[6];
|
||||
};
|
||||
|
||||
// to get the Cval and Siva values, use this constant as charge:
|
||||
enum { kWKSFVal = -99 };
|
||||
|
||||
const SFData& wksf(int charge = 0) const;
|
||||
const SFData& elsf() const;
|
||||
|
||||
private:
|
||||
const struct AtomTypeInfo* mInfo;
|
||||
};
|
||||
|
||||
}
|
||||
1870
include/cif++/Cif++.hpp
Normal file
1870
include/cif++/Cif++.hpp
Normal file
File diff suppressed because it is too large
Load Diff
39
include/cif++/Cif2PDB.hpp
Normal file
39
include/cif++/Cif2PDB.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cif++/Cif++.hpp"
|
||||
|
||||
void WritePDBFile(std::ostream& pdbFile, cif::File& cifFile);
|
||||
|
||||
/// \brief Just the HEADER, COMPND, SOURCE and AUTHOR lines
|
||||
void WritePDBHeaderLines(std::ostream& os, cif::File& cifFile);
|
||||
|
||||
std::string GetPDBHEADERLine(cif::File& cifFile, std::string::size_type truncate_at = 127);
|
||||
std::string GetPDBCOMPNDLine(cif::File& cifFile, std::string::size_type truncate_at = 127);
|
||||
std::string GetPDBSOURCELine(cif::File& cifFile, std::string::size_type truncate_at = 127);
|
||||
std::string GetPDBAUTHORLine(cif::File& cifFile, std::string::size_type truncate_at = 127);
|
||||
238
include/cif++/CifParser.hpp
Normal file
238
include/cif++/CifParser.hpp
Normal file
@@ -0,0 +1,238 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cif++/Cif++.hpp"
|
||||
|
||||
#include <stack>
|
||||
|
||||
namespace cif
|
||||
{
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
class CifParserError : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
CifParserError(uint32_t lineNr, const std::string& message);
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
extern const uint32_t kMaxLineLength;
|
||||
|
||||
extern const uint8_t kCharTraitsTable[128];
|
||||
|
||||
enum CharTraitsMask: uint8_t {
|
||||
kOrdinaryMask = 1 << 0,
|
||||
kNonBlankMask = 1 << 1,
|
||||
kTextLeadMask = 1 << 2,
|
||||
kAnyPrintMask = 1 << 3
|
||||
};
|
||||
|
||||
inline bool isWhite(int ch)
|
||||
{
|
||||
return std::isspace(ch) or ch == '#';
|
||||
}
|
||||
|
||||
inline bool isOrdinary(int ch)
|
||||
{
|
||||
return ch >= 0x20 and ch <= 0x7f and (kCharTraitsTable[ch - 0x20] & kOrdinaryMask) != 0;
|
||||
}
|
||||
|
||||
inline bool isNonBlank(int ch)
|
||||
{
|
||||
return ch > 0x20 and ch <= 0x7f and (kCharTraitsTable[ch - 0x20] & kNonBlankMask) != 0;
|
||||
}
|
||||
|
||||
inline bool isTextLead(int ch)
|
||||
{
|
||||
return ch >= 0x20 and ch <= 0x7f and (kCharTraitsTable[ch - 0x20] & kTextLeadMask) != 0;
|
||||
}
|
||||
|
||||
inline bool isAnyPrint(int ch)
|
||||
{
|
||||
return ch == '\t' or
|
||||
(ch >= 0x20 and ch <= 0x7f and (kCharTraitsTable[ch - 0x20] & kAnyPrintMask) != 0);
|
||||
}
|
||||
|
||||
inline bool isUnquotedString(const char* s)
|
||||
{
|
||||
bool result = isOrdinary(*s++);
|
||||
while (result and *s != 0)
|
||||
{
|
||||
result = isNonBlank(*s);
|
||||
++s;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
std::tuple<std::string,std::string> splitTagName(const std::string& tag);
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// sac Parser, analogous to SAX Parser (simple api for xml)
|
||||
|
||||
class SacParser
|
||||
{
|
||||
public:
|
||||
SacParser(std::istream& is);
|
||||
virtual ~SacParser() {}
|
||||
|
||||
enum CIFToken
|
||||
{
|
||||
eCIFTokenUnknown,
|
||||
|
||||
eCIFTokenEOF,
|
||||
|
||||
eCIFTokenDATA,
|
||||
eCIFTokenLOOP,
|
||||
eCIFTokenGLOBAL,
|
||||
eCIFTokenSAVE,
|
||||
eCIFTokenSTOP,
|
||||
eCIFTokenTag,
|
||||
eCIFTokenValue,
|
||||
};
|
||||
|
||||
static const char* kTokenName[];
|
||||
|
||||
enum CIFValueType
|
||||
{
|
||||
eCIFValueInt,
|
||||
eCIFValueFloat,
|
||||
eCIFValueNumeric,
|
||||
eCIFValueString,
|
||||
eCIFValueTextField,
|
||||
eCIFValueInapplicable,
|
||||
eCIFValueUnknown
|
||||
};
|
||||
|
||||
static const char* kValueName[];
|
||||
|
||||
int getNextChar();
|
||||
|
||||
void retract();
|
||||
void restart();
|
||||
|
||||
CIFToken getNextToken();
|
||||
void match(CIFToken token);
|
||||
|
||||
void parseFile();
|
||||
void parseGlobal();
|
||||
void parseDataBlock();
|
||||
|
||||
virtual void parseSaveFrame();
|
||||
|
||||
void parseDictionary();
|
||||
|
||||
void error(const std::string& msg);
|
||||
|
||||
// production methods, these are pure virtual here
|
||||
|
||||
virtual void produceDatablock(const std::string& name) = 0;
|
||||
virtual void produceCategory(const std::string& name) = 0;
|
||||
virtual void produceRow() = 0;
|
||||
virtual void produceItem(const std::string& category, const std::string& item, const std::string& value) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
enum State
|
||||
{
|
||||
eStateStart,
|
||||
eStateWhite,
|
||||
eStateComment,
|
||||
eStateQuestionMark,
|
||||
eStateDot,
|
||||
eStateQuotedString,
|
||||
eStateQuotedStringQuote,
|
||||
eStateUnquotedString,
|
||||
eStateTag,
|
||||
eStateTextField,
|
||||
eStateFloat = 100,
|
||||
eStateInt = 110,
|
||||
// eStateNumericSuffix = 200,
|
||||
eStateValue = 300
|
||||
};
|
||||
|
||||
std::istream& mData;
|
||||
|
||||
// Parser state
|
||||
bool mValidate;
|
||||
uint32_t mLineNr;
|
||||
bool mBol;
|
||||
int mState, mStart;
|
||||
CIFToken mLookahead;
|
||||
std::string mTokenValue;
|
||||
CIFValueType mTokenType;
|
||||
std::stack<int> mBuffer;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
class Parser : public SacParser
|
||||
{
|
||||
public:
|
||||
Parser(std::istream& is, File& f);
|
||||
|
||||
virtual void produceDatablock(const std::string& name);
|
||||
virtual void produceCategory(const std::string& name);
|
||||
virtual void produceRow();
|
||||
virtual void produceItem(const std::string& category, const std::string& item, const std::string& value);
|
||||
|
||||
protected:
|
||||
File& mFile;
|
||||
Datablock* mDataBlock;
|
||||
Datablock::iterator mCat;
|
||||
Row mRow;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
class DictParser : public Parser
|
||||
{
|
||||
public:
|
||||
|
||||
DictParser(Validator& validator, std::istream& is);
|
||||
~DictParser();
|
||||
|
||||
void loadDictionary();
|
||||
|
||||
private:
|
||||
|
||||
virtual void parseSaveFrame();
|
||||
|
||||
bool collectItemTypes();
|
||||
void linkItems();
|
||||
|
||||
Validator& mValidator;
|
||||
File mFile;
|
||||
struct DictParserDataImpl* mImpl;
|
||||
bool mCollectedItemTypes = false;
|
||||
};
|
||||
|
||||
}
|
||||
289
include/cif++/CifUtils.hpp
Normal file
289
include/cif++/CifUtils.hpp
Normal file
@@ -0,0 +1,289 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cif++/Config.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <list>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
struct rsrc_imp
|
||||
{
|
||||
unsigned int m_next;
|
||||
unsigned int m_child;
|
||||
unsigned int m_name;
|
||||
unsigned int m_size;
|
||||
unsigned int m_data;
|
||||
};
|
||||
|
||||
#if USE_RSRC
|
||||
extern const rsrc_imp gResourceIndex[];
|
||||
extern const char gResourceData[];
|
||||
extern const char gResourceName[];
|
||||
#endif
|
||||
|
||||
namespace cif
|
||||
{
|
||||
|
||||
// some basic utilities: Since we're using ASCII input only, we define for optimisation
|
||||
// our own case conversion routines.
|
||||
|
||||
bool iequals(const std::string& a, const std::string& b);
|
||||
int icompare(const std::string& a, const std::string& b);
|
||||
|
||||
bool iequals(const char* a, const char* b);
|
||||
int icompare(const char* a, const char* b);
|
||||
|
||||
void toLower(std::string& s);
|
||||
std::string toLowerCopy(const std::string& s);
|
||||
|
||||
// To make life easier, we also define iless and iset using iequals
|
||||
|
||||
struct iless
|
||||
{
|
||||
bool operator()(const std::string& a, const std::string& b) const
|
||||
{
|
||||
return icompare(a, b) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::set<std::string, iless> iset;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// This really makes a difference, having our own tolower routines
|
||||
|
||||
extern const uint8_t kCharToLowerMap[256];
|
||||
|
||||
inline char tolower(char ch)
|
||||
{
|
||||
return static_cast<char>(kCharToLowerMap[static_cast<uint8_t>(ch)]);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
std::tuple<std::string,std::string> splitTagName(const std::string& tag);
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// custom wordwrapping routine
|
||||
|
||||
std::vector<std::string> wordWrap(const std::string& text, unsigned int width);
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Code helping with terminal i/o
|
||||
|
||||
uint32_t get_terminal_width();
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Path of the current executable
|
||||
|
||||
std::string get_executable_path();
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// some manipulators to write coloured text to terminals
|
||||
|
||||
enum StringColour {
|
||||
scBLACK = 0, scRED, scGREEN, scYELLOW, scBLUE, scMAGENTA, scCYAN, scWHITE, scNONE = 9 };
|
||||
|
||||
template<typename String, typename CharT>
|
||||
struct ColouredString
|
||||
{
|
||||
static_assert(std::is_reference<String>::value or std::is_pointer<String>::value, "String type must be pointer or reference");
|
||||
|
||||
ColouredString(String s, StringColour fore, StringColour back, bool bold = true)
|
||||
: m_s(s), m_fore(fore), m_back(back), m_bold(bold) {}
|
||||
|
||||
ColouredString& operator=(const ColouredString&) = delete;
|
||||
|
||||
String m_s;
|
||||
StringColour m_fore, m_back;
|
||||
bool m_bold;
|
||||
};
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const ColouredString<const CharT*,CharT>& s)
|
||||
{
|
||||
if (isatty(STDOUT_FILENO))
|
||||
{
|
||||
std::basic_ostringstream<CharT, Traits> ostr;
|
||||
ostr << "\033[" << (30 + s.m_fore) << ';' << (s.m_bold ? "1" : "22") << ';' << (40 + s.m_back) << 'm'
|
||||
<< s.m_s
|
||||
<< "\033[0m";
|
||||
|
||||
return os << ostr.str();
|
||||
}
|
||||
else
|
||||
return os << s.m_s;
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits, typename String>
|
||||
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const ColouredString<String,CharT>& s)
|
||||
{
|
||||
if (isatty(STDOUT_FILENO))
|
||||
{
|
||||
std::basic_ostringstream<CharT, Traits> ostr;
|
||||
ostr << "\033[" << (30 + s.m_fore) << ';' << (s.m_bold ? "1" : "22") << ';' << (40 + s.m_back) << 'm'
|
||||
<< s.m_s
|
||||
<< "\033[0m";
|
||||
|
||||
return os << ostr.str();
|
||||
}
|
||||
else
|
||||
return os << s.m_s;
|
||||
}
|
||||
|
||||
template<typename CharT>
|
||||
inline auto coloured(const CharT* s, StringColour fore = scWHITE, StringColour back = scRED, bool bold = true)
|
||||
{
|
||||
return ColouredString<const CharT*, CharT>(s, fore, back, bold);
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits, typename Alloc>
|
||||
inline auto coloured(const std::basic_string<CharT, Traits, Alloc>& s, StringColour fore = scWHITE, StringColour back = scRED, bool bold = true)
|
||||
{
|
||||
return ColouredString<const std::basic_string<CharT, Traits, Alloc>, CharT>(s, fore, back, bold);
|
||||
}
|
||||
|
||||
template<typename CharT, typename Traits, typename Alloc>
|
||||
inline auto coloured(std::basic_string<CharT, Traits, Alloc>& s, StringColour fore = scWHITE, StringColour back = scRED, bool bold = true)
|
||||
{
|
||||
return ColouredString<std::basic_string<CharT, Traits, Alloc>, CharT>(s, fore, back, bold);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// A progress bar
|
||||
|
||||
class Progress
|
||||
{
|
||||
public:
|
||||
Progress(int64_t inMax, const std::string& inAction);
|
||||
virtual ~Progress();
|
||||
|
||||
void consumed(int64_t inConsumed); // consumed is relative
|
||||
void progress(int64_t inProgress); // progress is absolute
|
||||
|
||||
void message(const std::string& inMessage);
|
||||
|
||||
private:
|
||||
Progress(const Progress&);
|
||||
Progress& operator=(const Progress&);
|
||||
|
||||
struct ProgressImpl* mImpl;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// The new default is to load 'resource' files from the file system
|
||||
// since not everyone likes mrc. But if you do want to use mrc to load
|
||||
// resources, specify the compile time flag USE_RSRC.
|
||||
|
||||
/// \brief Simple class containing the data for a resource
|
||||
class rsrc
|
||||
{
|
||||
public:
|
||||
rsrc()
|
||||
: m_data(nullptr), m_size(0) {}
|
||||
rsrc(const char* data, size_t size)
|
||||
: m_data(data), m_size(size) {}
|
||||
rsrc(const rsrc& rhs)
|
||||
: m_data(rhs.m_data), m_size(rhs.m_size) {}
|
||||
|
||||
rsrc& operator=(const rsrc& rhs)
|
||||
{
|
||||
m_data = rhs.m_data;
|
||||
m_size = rhs.m_size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
explicit operator bool()
|
||||
{
|
||||
return m_data != nullptr and m_size > 0;
|
||||
}
|
||||
|
||||
const char* data() const { return m_data; }
|
||||
size_t size() const { return m_size; }
|
||||
|
||||
private:
|
||||
const char* m_data;
|
||||
size_t m_size;
|
||||
};
|
||||
|
||||
/// \brief loader types
|
||||
enum class rsrc_loader_type { mrsrc, file };
|
||||
|
||||
/// \brief loader info
|
||||
struct rsrc_loader_info
|
||||
{
|
||||
rsrc_loader_type type;
|
||||
std::string info;
|
||||
const void* ptrs[3];
|
||||
};
|
||||
|
||||
class rsrc_loader
|
||||
{
|
||||
public:
|
||||
|
||||
static void init(std::initializer_list<rsrc_loader_info> loaders =
|
||||
{
|
||||
{ rsrc_loader_type::file, "." },
|
||||
#if USE_RSRC
|
||||
{ rsrc_loader_type::mrsrc, "", { gResourceIndex, gResourceData, gResourceName } }
|
||||
#endif
|
||||
})
|
||||
{
|
||||
assert(not s_instance);
|
||||
s_instance.reset(new rsrc_loader(loaders));
|
||||
}
|
||||
|
||||
static rsrc load(const std::string& name)
|
||||
{
|
||||
assert(s_instance);
|
||||
if (not s_instance)
|
||||
init();
|
||||
|
||||
return s_instance->do_load(name);
|
||||
}
|
||||
|
||||
~rsrc_loader();
|
||||
|
||||
private:
|
||||
|
||||
rsrc_loader(const std::initializer_list<rsrc_loader_info>& loaders);
|
||||
|
||||
rsrc do_load(const std::string& name);
|
||||
|
||||
static std::unique_ptr<rsrc_loader> s_instance;
|
||||
|
||||
std::list<struct rsrc_loader_impl*> m_loaders;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
197
include/cif++/CifValidator.hpp
Normal file
197
include/cif++/CifValidator.hpp
Normal file
@@ -0,0 +1,197 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cif++/Cif++.hpp"
|
||||
|
||||
//// the std regex of gcc is crashing....
|
||||
// #include <boost/regex.hpp>
|
||||
|
||||
#include <regex>
|
||||
#include <set>
|
||||
|
||||
namespace cif
|
||||
{
|
||||
|
||||
struct ValidateCategory;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
class ValidationError : public std::exception
|
||||
{
|
||||
public:
|
||||
ValidationError(const std::string& msg);
|
||||
ValidationError(const std::string& cat, const std::string& item,
|
||||
const std::string& msg);
|
||||
const char* what() const noexcept { return mMsg.c_str(); }
|
||||
std::string mMsg;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
enum DDL_PrimitiveType
|
||||
{
|
||||
ptChar, ptUChar, ptNumb
|
||||
};
|
||||
|
||||
DDL_PrimitiveType mapToPrimitiveType(const std::string& s);
|
||||
|
||||
struct ValidateType
|
||||
{
|
||||
std::string mName;
|
||||
DDL_PrimitiveType mPrimitiveType;
|
||||
std::regex mRx;
|
||||
|
||||
bool operator<(const ValidateType& rhs) const
|
||||
{
|
||||
return icompare(mName, rhs.mName) < 0;
|
||||
}
|
||||
|
||||
// compare values based on type
|
||||
// int compare(const std::string& a, const std::string& b) const
|
||||
// {
|
||||
// return compare(a.c_str(), b.c_str());
|
||||
// }
|
||||
|
||||
int compare(const char* a, const char* b) const;
|
||||
};
|
||||
|
||||
struct ValidateItem
|
||||
{
|
||||
std::string mTag;
|
||||
bool mMandatory;
|
||||
const ValidateType* mType;
|
||||
cif::iset mEnums;
|
||||
std::string mDefault;
|
||||
bool mDefaultIsNull;
|
||||
ValidateCategory* mCategory = nullptr;
|
||||
|
||||
// ItemLinked is used for non-key links
|
||||
struct ItemLinked
|
||||
{
|
||||
ValidateItem* mParent;
|
||||
std::string mParentItem;
|
||||
std::string mChildItem;
|
||||
};
|
||||
|
||||
std::vector<ItemLinked> mLinked;
|
||||
|
||||
bool operator<(const ValidateItem& rhs) const
|
||||
{
|
||||
return icompare(mTag, rhs.mTag) < 0;
|
||||
}
|
||||
|
||||
bool operator==(const ValidateItem& rhs) const
|
||||
{
|
||||
return iequals(mTag, rhs.mTag);
|
||||
}
|
||||
|
||||
void operator()(std::string value) const;
|
||||
};
|
||||
|
||||
struct ValidateCategory
|
||||
{
|
||||
std::string mName;
|
||||
std::vector<std::string> mKeys;
|
||||
cif::iset mGroups;
|
||||
cif::iset mMandatoryFields;
|
||||
std::set<ValidateItem> mItemValidators;
|
||||
|
||||
bool operator<(const ValidateCategory& rhs) const
|
||||
{
|
||||
return icompare(mName, rhs.mName) < 0;
|
||||
}
|
||||
|
||||
void addItemValidator(ValidateItem&& v);
|
||||
|
||||
const ValidateItem* getValidatorForItem(std::string tag) const;
|
||||
|
||||
const std::set<ValidateItem>& itemValidators() const
|
||||
{
|
||||
return mItemValidators;
|
||||
}
|
||||
};
|
||||
|
||||
struct ValidateLink
|
||||
{
|
||||
int mLinkGroupID;
|
||||
std::string mParentCategory;
|
||||
std::vector<std::string> mParentKeys;
|
||||
std::string mChildCategory;
|
||||
std::vector<std::string> mChildKeys;
|
||||
std::string mLinkGroupLabel;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
class Validator
|
||||
{
|
||||
public:
|
||||
friend class DictParser;
|
||||
|
||||
Validator();
|
||||
~Validator();
|
||||
|
||||
Validator(const Validator& rhs) = delete;
|
||||
Validator& operator=(const Validator& rhs) = delete;
|
||||
|
||||
Validator(Validator&& rhs);
|
||||
Validator& operator=(Validator&& rhs);
|
||||
|
||||
void addTypeValidator(ValidateType&& v);
|
||||
const ValidateType* getValidatorForType(std::string typeCode) const;
|
||||
|
||||
void addCategoryValidator(ValidateCategory&& v);
|
||||
const ValidateCategory* getValidatorForCategory(std::string category) const;
|
||||
|
||||
void addLinkValidator(ValidateLink&& v);
|
||||
std::vector<const ValidateLink*> getLinksForParent(const std::string& category) const;
|
||||
std::vector<const ValidateLink*> getLinksForChild(const std::string& category) const;
|
||||
|
||||
void reportError(const std::string& msg, bool fatal);
|
||||
|
||||
std::string dictName() const { return mName; }
|
||||
void dictName(const std::string& name) { mName = name; }
|
||||
|
||||
std::string dictVersion() const { return mVersion; }
|
||||
void dictVersion(const std::string& version) { mVersion = version; }
|
||||
|
||||
private:
|
||||
|
||||
// name is fully qualified here:
|
||||
ValidateItem* getValidatorForItem(std::string name) const;
|
||||
|
||||
std::string mName;
|
||||
std::string mVersion;
|
||||
bool mStrict = false;
|
||||
// std::set<uint32_t> mSubCategories;
|
||||
std::set<ValidateType> mTypeValidators;
|
||||
std::set<ValidateCategory> mCategoryValidators;
|
||||
std::vector<ValidateLink> mLinkValidators;
|
||||
};
|
||||
|
||||
}
|
||||
342
include/cif++/Compound.hpp
Normal file
342
include/cif++/Compound.hpp
Normal file
@@ -0,0 +1,342 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "cif++/AtomType.hpp"
|
||||
#include "cif++/Cif++.hpp"
|
||||
|
||||
namespace mmcif
|
||||
{
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// The chemical composition of the structure in an mmCIF file is
|
||||
// defined in the class composition. A compositon consists of
|
||||
// entities. Each Entity can be either a polymer, a non-polymer
|
||||
// a macrolide or a water molecule.
|
||||
// Entities themselves are made up of compounds. And compounds
|
||||
// contain CompoundAtom records for each atom.
|
||||
|
||||
class Compound;
|
||||
class Link;
|
||||
struct CompoundAtom;
|
||||
|
||||
enum BondType { singleBond, doubleBond, tripleBond, delocalizedBond };
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// struct containing information about an atom in a chemical compound
|
||||
// This information comes from the CCP4 monomer library.
|
||||
|
||||
struct CompoundAtom
|
||||
{
|
||||
std::string id;
|
||||
AtomType typeSymbol;
|
||||
std::string typeEnergy;
|
||||
float partialCharge;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// struct containing information about the bonds
|
||||
// This information comes from the CCP4 monomer library.
|
||||
|
||||
struct CompoundBond
|
||||
{
|
||||
std::string atomID[2];
|
||||
BondType type;
|
||||
float distance;
|
||||
float esd;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// struct containing information about the bond-angles
|
||||
// This information comes from the CCP4 monomer library.
|
||||
|
||||
struct CompoundAngle
|
||||
{
|
||||
std::string atomID[3];
|
||||
float angle;
|
||||
float esd;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// struct containing information about the bond-angles
|
||||
// This information comes from the CCP4 monomer library.
|
||||
|
||||
struct CompoundTorsion
|
||||
{
|
||||
std::string atomID[4];
|
||||
float angle;
|
||||
float esd;
|
||||
int period;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// struct containing information about the bond-angles
|
||||
// This information comes from the CCP4 monomer library.
|
||||
|
||||
struct CompoundPlane
|
||||
{
|
||||
std::string id;
|
||||
std::vector<std::string> atomID;
|
||||
float esd;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// struct containing information about a chiral centre
|
||||
// This information comes from the CCP4 monomer library.
|
||||
|
||||
enum ChiralVolumeSign { negativ, positiv, both };
|
||||
|
||||
struct CompoundChiralCentre
|
||||
{
|
||||
std::string id;
|
||||
std::string atomIDCentre;
|
||||
std::string atomID[3];
|
||||
ChiralVolumeSign volumeSign;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a class that contains information about a chemical compound.
|
||||
// This information is derived from the ccp4 monomer library by default.
|
||||
// To create compounds, you'd best use the factory method.
|
||||
|
||||
class Compound
|
||||
{
|
||||
public:
|
||||
|
||||
Compound(const std::string& file, const std::string& id, const std::string& name,
|
||||
const std::string& group);
|
||||
|
||||
// factory method, create a Compound based on the three letter code
|
||||
// (for amino acids) or the one-letter code (for bases) or the
|
||||
// code as it is known in the CCP4 monomer library.
|
||||
|
||||
static const Compound* create(const std::string& id);
|
||||
|
||||
// this second factory method can create a Compound even if it is not
|
||||
// recorded in the library. It will take the values from the CCP4 lib
|
||||
// unless the value passed to this function is not empty.
|
||||
static const Compound* create(const std::string& id, const std::string& name,
|
||||
const std::string& type, const std::string& formula);
|
||||
|
||||
// add an additional path to the monomer library.
|
||||
static void addMonomerLibraryPath(const std::string& dir);
|
||||
|
||||
// accessors
|
||||
std::string id() const { return mID; }
|
||||
std::string name() const { return mName; }
|
||||
std::string type() const;
|
||||
std::string group() const { return mGroup; }
|
||||
std::vector<CompoundAtom> atoms() const { return mAtoms; }
|
||||
std::vector<CompoundBond> bonds() const { return mBonds; }
|
||||
std::vector<CompoundAngle> angles() const { return mAngles; }
|
||||
std::vector<CompoundChiralCentre> chiralCentres() const
|
||||
{ return mChiralCentres; }
|
||||
std::vector<CompoundPlane> planes() const { return mPlanes; }
|
||||
std::vector<CompoundTorsion> torsions() const { return mTorsions; }
|
||||
|
||||
CompoundAtom getAtomByID(const std::string& atomID) const;
|
||||
|
||||
bool atomsBonded(const std::string& atomId_1, const std::string& atomId_2) const;
|
||||
float atomBondValue(const std::string& atomId_1, const std::string& atomId_2) const;
|
||||
float bondAngle(const std::string& atomId_1, const std::string& atomId_2, const std::string& atomId_3) const;
|
||||
float chiralVolume(const std::string& centreID) const;
|
||||
|
||||
std::string formula() const;
|
||||
float formulaWeight() const;
|
||||
int charge() const;
|
||||
bool isWater() const;
|
||||
bool isSugar() const;
|
||||
|
||||
std::vector<std::string> isomers() const;
|
||||
bool isIsomerOf(const Compound& c) const;
|
||||
std::vector<std::tuple<std::string,std::string>> mapToIsomer(const Compound& c) const;
|
||||
|
||||
private:
|
||||
|
||||
~Compound();
|
||||
|
||||
cif::File mCF;
|
||||
|
||||
std::string mID;
|
||||
std::string mName;
|
||||
std::string mGroup;
|
||||
std::vector<CompoundAtom> mAtoms;
|
||||
std::vector<CompoundBond> mBonds;
|
||||
std::vector<CompoundAngle> mAngles;
|
||||
std::vector<CompoundTorsion>mTorsions;
|
||||
std::vector<CompoundChiralCentre>
|
||||
mChiralCentres;
|
||||
std::vector<CompoundPlane> mPlanes;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// struct containing information about the bonds
|
||||
// This information comes from the CCP4 monomer library.
|
||||
|
||||
struct LinkAtom
|
||||
{
|
||||
int compID;
|
||||
std::string atomID;
|
||||
|
||||
bool operator==(const LinkAtom& rhs) const { return compID == rhs.compID and atomID == rhs.atomID; }
|
||||
};
|
||||
|
||||
struct LinkBond
|
||||
{
|
||||
LinkAtom atom[2];
|
||||
BondType type;
|
||||
float distance;
|
||||
float esd;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// struct containing information about the bond-angles
|
||||
// This information comes from the CCP4 monomer library.
|
||||
|
||||
struct LinkAngle
|
||||
{
|
||||
LinkAtom atom[3];
|
||||
float angle;
|
||||
float esd;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// struct containing information about the bond-torsions
|
||||
// This information comes from the CCP4 monomer library.
|
||||
|
||||
struct LinkTorsion
|
||||
{
|
||||
LinkAtom atom[4];
|
||||
float angle;
|
||||
float esd;
|
||||
int period;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// struct containing information about the bond-angles
|
||||
// This information comes from the CCP4 monomer library.
|
||||
|
||||
struct LinkPlane
|
||||
{
|
||||
std::string id;
|
||||
std::vector<LinkAtom> atoms;
|
||||
float esd;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// struct containing information about a chiral centre
|
||||
// This information comes from the CCP4 monomer library.
|
||||
|
||||
struct LinkChiralCentre
|
||||
{
|
||||
std::string id;
|
||||
LinkAtom atomCentre;
|
||||
LinkAtom atom[3];
|
||||
ChiralVolumeSign volumeSign;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a class that contains information about a chemical link between compounds.
|
||||
// This information is derived from the ccp4 monomer library by default.
|
||||
|
||||
class Link
|
||||
{
|
||||
public:
|
||||
|
||||
Link(cif::Datablock& db);
|
||||
|
||||
// Factory method.
|
||||
static const Link& create(const std::string& id);
|
||||
|
||||
// accessors
|
||||
std::string id() const { return mID; }
|
||||
std::vector<LinkBond> bonds() const { return mBonds; }
|
||||
std::vector<LinkAngle> angles() const { return mAngles; }
|
||||
std::vector<LinkChiralCentre> chiralCentres() const { return mChiralCentres; }
|
||||
std::vector<LinkPlane> planes() const { return mPlanes; }
|
||||
std::vector<LinkTorsion> torsions() const { return mTorsions; }
|
||||
|
||||
float atomBondValue(const LinkAtom& atomId_1, const LinkAtom& atomId_2) const;
|
||||
float bondAngle(const LinkAtom& atomId_1, const LinkAtom& atomId_2, const LinkAtom& atomId_3) const;
|
||||
float chiralVolume(const std::string& id) const;
|
||||
|
||||
private:
|
||||
|
||||
~Link();
|
||||
|
||||
std::string mID;
|
||||
std::vector<LinkBond> mBonds;
|
||||
std::vector<LinkAngle> mAngles;
|
||||
std::vector<LinkTorsion> mTorsions;
|
||||
std::vector<LinkChiralCentre> mChiralCentres;
|
||||
std::vector<LinkPlane> mPlanes;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Factory class for Compound and Link objects
|
||||
|
||||
extern const std::map<std::string,char> kAAMap, kBaseMap;
|
||||
|
||||
class CompoundFactory
|
||||
{
|
||||
public:
|
||||
|
||||
static CompoundFactory& instance();
|
||||
|
||||
void pushDictionary(const std::string& inDictFile);
|
||||
void popDictionary();
|
||||
|
||||
bool isKnownPeptide(const std::string& res_name) const;
|
||||
bool isKnownBase(const std::string& res_name) const;
|
||||
|
||||
std::string unalias(const std::string& res_name) const;
|
||||
|
||||
const Compound* get(std::string id);
|
||||
const Compound* create(std::string id);
|
||||
|
||||
const Link* getLink(std::string id);
|
||||
const Link* createLink(std::string id);
|
||||
|
||||
private:
|
||||
|
||||
CompoundFactory();
|
||||
~CompoundFactory();
|
||||
|
||||
CompoundFactory(const CompoundFactory&) = delete;
|
||||
CompoundFactory& operator=(const CompoundFactory&) = delete;
|
||||
|
||||
static CompoundFactory* sInstance;
|
||||
|
||||
class CompoundFactoryImpl* mImpl;
|
||||
};
|
||||
|
||||
}
|
||||
82
include/cif++/Config.hpp.in
Normal file
82
include/cif++/Config.hpp.in
Normal file
@@ -0,0 +1,82 @@
|
||||
/* include/cif++/Config.hpp.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* define if the Boost library is available */
|
||||
#undef HAVE_BOOST
|
||||
|
||||
/* define if the Boost::Regex library is available */
|
||||
#undef HAVE_BOOST_REGEX
|
||||
|
||||
/* define if the compiler supports basic C++17 syntax */
|
||||
#undef HAVE_CXX17
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the `floor' function. */
|
||||
#undef HAVE_FLOOR
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if LIBBZ2 is found */
|
||||
#undef HAVE_LIBBZ2
|
||||
|
||||
/* Define to 1 if LIBZ is found */
|
||||
#undef HAVE_LIBZ
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `pow' function. */
|
||||
#undef HAVE_POW
|
||||
|
||||
/* Define to 1 if the system has the type `ptrdiff_t'. */
|
||||
#undef HAVE_PTRDIFF_T
|
||||
|
||||
/* Define to 1 if you have the `rint' function. */
|
||||
#undef HAVE_RINT
|
||||
|
||||
/* Define to 1 if you have the `sqrt' function. */
|
||||
#undef HAVE_SQRT
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#undef HAVE_STRCHR
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#undef HAVE_SYS_IOCTL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#undef HAVE_TERMIOS_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if the system has the type `_Bool'. */
|
||||
#undef HAVE__BOOL
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
59
include/cif++/PDB2Cif.hpp
Normal file
59
include/cif++/PDB2Cif.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cif++/Cif++.hpp"
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
struct PDBRecord
|
||||
{
|
||||
PDBRecord* mNext;
|
||||
uint32_t mLineNr;
|
||||
char mName[11];
|
||||
size_t mVlen;
|
||||
char mValue[0];
|
||||
|
||||
PDBRecord(uint32_t lineNr, const std::string& name, const std::string& value);
|
||||
~PDBRecord();
|
||||
|
||||
void* operator new(size_t);
|
||||
void* operator new(size_t size, size_t vLen);
|
||||
|
||||
void operator delete(void* p);
|
||||
|
||||
bool is(const char* name) const;
|
||||
|
||||
char vC(size_t column);
|
||||
std::string vS(size_t columnFirst, size_t columnLast = std::numeric_limits<size_t>::max());
|
||||
int vI(int columnFirst, int columnLast);
|
||||
std::string vF(size_t columnFirst, size_t columnLast);
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
void ReadPDBFile(std::istream& pdbFile, cif::File& cifFile);
|
||||
73
include/cif++/PDB2CifRemark3.hpp
Normal file
73
include/cif++/PDB2CifRemark3.hpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cif++/PDB2Cif.hpp"
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
struct TemplateLine;
|
||||
|
||||
class Remark3Parser
|
||||
{
|
||||
public:
|
||||
virtual ~Remark3Parser() {}
|
||||
|
||||
static bool parse(const std::string& expMethod, PDBRecord* r, cif::Datablock& db);
|
||||
|
||||
virtual std::string program();
|
||||
virtual std::string version();
|
||||
|
||||
protected:
|
||||
|
||||
Remark3Parser(const std::string& name, const std::string& expMethod, PDBRecord* r, cif::Datablock& db,
|
||||
const TemplateLine templatelines[], uint32_t templateLineCount, std::regex programVersion);
|
||||
|
||||
virtual float parse();
|
||||
std::string nextLine();
|
||||
|
||||
bool match(const char* expr, int nextState);
|
||||
void storeCapture(const char* category, std::initializer_list<const char*> items, bool createNew = false);
|
||||
void storeRefineLsRestr(const char* type, std::initializer_list<const char*> values);
|
||||
void updateRefineLsRestr(const char* type, std::initializer_list<const char*> values);
|
||||
|
||||
virtual void fixup() {}
|
||||
|
||||
std::string mName;
|
||||
std::string mExpMethod;
|
||||
PDBRecord* mRec;
|
||||
cif::Datablock mDb;
|
||||
std::string mLine;
|
||||
std::smatch mM;
|
||||
uint32_t mState;
|
||||
|
||||
const TemplateLine* mTemplate;
|
||||
uint32_t mTemplateCount;
|
||||
std::regex mProgramVersion;
|
||||
};
|
||||
|
||||
|
||||
412
include/cif++/Point.hpp
Normal file
412
include/cif++/Point.hpp
Normal file
@@ -0,0 +1,412 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "cif++/Config.hpp"
|
||||
|
||||
#include <boost/math/quaternion.hpp>
|
||||
|
||||
namespace mmcif
|
||||
{
|
||||
|
||||
typedef boost::math::quaternion<float> quaternion;
|
||||
|
||||
const long double
|
||||
kPI = 3.141592653589793238462643383279502884L;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// Point, a location with x, y and z coordinates as floating point.
|
||||
// This one is derived from a tuple<float,float,float> so
|
||||
// you can do things like:
|
||||
//
|
||||
// float x, y, z;
|
||||
// tie(x, y, z) = atom.loc();
|
||||
|
||||
template<typename F>
|
||||
struct PointF
|
||||
{
|
||||
typedef F FType;
|
||||
|
||||
FType mX, mY, mZ;
|
||||
|
||||
PointF() : mX(0), mY(0), mZ(0) {}
|
||||
PointF(FType x, FType y, FType z) : mX(x), mY(y), mZ(z) {}
|
||||
// PointF(const clipper::Coord_orth& pt): mX(pt[0]), mY(pt[1]), mZ(pt[2]) {}
|
||||
|
||||
template<typename PF>
|
||||
PointF(const PointF<PF>& pt)
|
||||
: mX(static_cast<F>(pt.mX))
|
||||
, mY(static_cast<F>(pt.mY))
|
||||
, mZ(static_cast<F>(pt.mZ)) {}
|
||||
|
||||
// PointF& operator=(const clipper::Coord_orth& rhs)
|
||||
// {
|
||||
// mX = rhs[0];
|
||||
// mY = rhs[1];
|
||||
// mZ = rhs[2];
|
||||
// return *this;
|
||||
// }
|
||||
|
||||
template<typename PF>
|
||||
PointF& operator=(const PointF<PF>& rhs)
|
||||
{
|
||||
mX = static_cast<F>(rhs.mX);
|
||||
mY = static_cast<F>(rhs.mY);
|
||||
mZ = static_cast<F>(rhs.mZ);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FType& getX() { return mX; }
|
||||
FType getX() const { return mX; }
|
||||
void setX(FType x) { mX = x; }
|
||||
|
||||
FType& getY() { return mY; }
|
||||
FType getY() const { return mY; }
|
||||
void setY(FType y) { mY = y; }
|
||||
|
||||
FType& getZ() { return mZ; }
|
||||
FType getZ() const { return mZ; }
|
||||
void setZ(FType z) { mZ = z; }
|
||||
|
||||
PointF& operator+=(const PointF& rhs)
|
||||
{
|
||||
mX += rhs.mX;
|
||||
mY += rhs.mY;
|
||||
mZ += rhs.mZ;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
PointF& operator+=(FType d)
|
||||
{
|
||||
mX += d;
|
||||
mY += d;
|
||||
mZ += d;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
PointF& operator-=(const PointF& rhs)
|
||||
{
|
||||
mX -= rhs.mX;
|
||||
mY -= rhs.mY;
|
||||
mZ -= rhs.mZ;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
PointF& operator-=(FType d)
|
||||
{
|
||||
mX -= d;
|
||||
mY -= d;
|
||||
mZ -= d;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
PointF& operator*=(FType rhs)
|
||||
{
|
||||
mX *= rhs;
|
||||
mY *= rhs;
|
||||
mZ *= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PointF& operator/=(FType rhs)
|
||||
{
|
||||
mX /= rhs;
|
||||
mY /= rhs;
|
||||
mZ /= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FType normalize()
|
||||
{
|
||||
auto length = mX * mX + mY * mY + mZ * mZ;
|
||||
if (length > 0)
|
||||
{
|
||||
length = std::sqrt(length);
|
||||
operator/=(length);
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
void rotate(const boost::math::quaternion<FType>& q)
|
||||
{
|
||||
boost::math::quaternion<FType> p(0, mX, mY, mZ);
|
||||
|
||||
p = q * p * boost::math::conj(q);
|
||||
|
||||
mX = p.R_component_2();
|
||||
mY = p.R_component_3();
|
||||
mZ = p.R_component_4();
|
||||
}
|
||||
|
||||
// operator clipper::Coord_orth() const
|
||||
// {
|
||||
// return clipper::Coord_orth(mX, mY, mZ);
|
||||
// }
|
||||
|
||||
operator std::tuple<const FType&, const FType&, const FType&>() const
|
||||
{
|
||||
return std::make_tuple(std::ref(mX), std::ref(mY), std::ref(mZ));
|
||||
}
|
||||
|
||||
operator std::tuple<FType&,FType&,FType&>()
|
||||
{
|
||||
return std::make_tuple(std::ref(mX), std::ref(mY), std::ref(mZ));
|
||||
}
|
||||
|
||||
bool operator==(const PointF& rhs) const
|
||||
{
|
||||
return mX == rhs.mX and mY == rhs.mY and mZ == rhs.mZ;
|
||||
}
|
||||
|
||||
// consider point as a vector... perhaps I should rename Point?
|
||||
FType lengthsq() const
|
||||
{
|
||||
return mX * mX + mY * mY + mZ * mZ;
|
||||
}
|
||||
|
||||
FType length() const
|
||||
{
|
||||
return sqrt(mX * mX + mY * mY + mZ * mZ);
|
||||
}
|
||||
};
|
||||
|
||||
typedef PointF<float> Point;
|
||||
typedef PointF<double> DPoint;
|
||||
|
||||
template<typename F>
|
||||
inline std::ostream& operator<<(std::ostream& os, const PointF<F>& pt)
|
||||
{
|
||||
os << '(' << pt.mX << ',' << pt.mY << ',' << pt.mZ << ')';
|
||||
return os;
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
inline PointF<F> operator+(const PointF<F>& lhs, const PointF<F>& rhs)
|
||||
{
|
||||
return PointF<F>(lhs.mX + rhs.mX, lhs.mY + rhs.mY, lhs.mZ + rhs.mZ);
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
inline PointF<F> operator-(const PointF<F>& lhs, const PointF<F>& rhs)
|
||||
{
|
||||
return PointF<F>(lhs.mX - rhs.mX, lhs.mY - rhs.mY, lhs.mZ - rhs.mZ);
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
inline PointF<F> operator-(const PointF<F>& pt)
|
||||
{
|
||||
return PointF<F>(-pt.mX, -pt.mY, -pt.mZ);
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
inline PointF<F> operator*(const PointF<F>& pt, F f)
|
||||
{
|
||||
return PointF<F>(pt.mX * f, pt.mY * f, pt.mZ * f);
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
inline PointF<F> operator*(F f, const PointF<F>& pt)
|
||||
{
|
||||
return PointF<F>(pt.mX * f, pt.mY * f, pt.mZ * f);
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
inline PointF<F> operator/(const PointF<F>& pt, F f)
|
||||
{
|
||||
return PointF<F>(pt.mX / f, pt.mY / f, pt.mZ / f);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// several standard 3d operations
|
||||
|
||||
template<typename F>
|
||||
inline double DistanceSquared(const PointF<F>& a, const PointF<F>& b)
|
||||
{
|
||||
return
|
||||
(a.mX - b.mX) * (a.mX - b.mX) +
|
||||
(a.mY - b.mY) * (a.mY - b.mY) +
|
||||
(a.mZ - b.mZ) * (a.mZ - b.mZ);
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
inline double Distance(const PointF<F>& a, const PointF<F>& b)
|
||||
{
|
||||
return sqrt(
|
||||
(a.mX - b.mX) * (a.mX - b.mX) +
|
||||
(a.mY - b.mY) * (a.mY - b.mY) +
|
||||
(a.mZ - b.mZ) * (a.mZ - b.mZ));
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
inline F DotProduct(const PointF<F>& a, const PointF<F>& b)
|
||||
{
|
||||
return a.mX * b.mX + a.mY * b.mY + a.mZ * b.mZ;
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
inline PointF<F> CrossProduct(const PointF<F>& a, const PointF<F>& b)
|
||||
{
|
||||
return PointF<F>(a.mY * b.mZ - b.mY * a.mZ,
|
||||
a.mZ * b.mX - b.mZ * a.mX,
|
||||
a.mX * b.mY - b.mX * a.mY);
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
double Angle(const PointF<F>& p1, const PointF<F>& p2, const PointF<F>& p3)
|
||||
{
|
||||
PointF<F> v1 = p1 - p2;
|
||||
PointF<F> v2 = p3 - p2;
|
||||
|
||||
return std::acos(DotProduct(v1, v2) / (v1.length() * v2.length())) * 180 / kPI;
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
double DihedralAngle(const PointF<F>& p1, const PointF<F>& p2, const PointF<F>& p3, const PointF<F>& p4)
|
||||
{
|
||||
PointF<F> v12 = p1 - p2; // vector from p2 to p1
|
||||
PointF<F> v43 = p4 - p3; // vector from p3 to p4
|
||||
|
||||
PointF<F> z = p2 - p3; // vector from p3 to p2
|
||||
|
||||
PointF<F> p = CrossProduct(z, v12);
|
||||
PointF<F> x = CrossProduct(z, v43);
|
||||
PointF<F> y = CrossProduct(z, x);
|
||||
|
||||
double u = DotProduct(x, x);
|
||||
double v = DotProduct(y, y);
|
||||
|
||||
double result = 360;
|
||||
if (u > 0 and v > 0)
|
||||
{
|
||||
u = DotProduct(p, x) / sqrt(u);
|
||||
v = DotProduct(p, y) / sqrt(v);
|
||||
if (u != 0 or v != 0)
|
||||
result = atan2(v, u) * 180 / kPI;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
double CosinusAngle(const PointF<F>& p1, const PointF<F>& p2, const PointF<F>& p3, const PointF<F>& p4)
|
||||
{
|
||||
PointF<F> v12 = p1 - p2;
|
||||
PointF<F> v34 = p3 - p4;
|
||||
|
||||
double result = 0;
|
||||
|
||||
double x = DotProduct(v12, v12) * DotProduct(v34, v34);
|
||||
if (x > 0)
|
||||
result = DotProduct(v12, v34) / sqrt(x);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// For e.g. simulated annealing, returns a new point that is moved in
|
||||
// a random direction with a distance randomly chosen from a normal
|
||||
// distribution with a stddev of offset.
|
||||
|
||||
template<typename F>
|
||||
PointF<F> Nudge(PointF<F> p, F offset);
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// We use quaternions to do rotations in 3d space
|
||||
|
||||
quaternion Normalize(quaternion q);
|
||||
|
||||
//std::tuple<double,Point> QuaternionToAngleAxis(quaternion q);
|
||||
Point Centroid(std::vector<Point>& Points);
|
||||
Point CenterPoints(std::vector<Point>& Points);
|
||||
quaternion AlignPoints(const std::vector<Point>& a, const std::vector<Point>& b);
|
||||
double RMSd(const std::vector<Point>& a, const std::vector<Point>& b);
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Helper class to generate evenly divided Points on a sphere
|
||||
// we use a fibonacci sphere to calculate even distribution of the dots
|
||||
|
||||
template<int N>
|
||||
class SphericalDots
|
||||
{
|
||||
public:
|
||||
enum { P = 2 * N + 1 };
|
||||
typedef typename std::array<Point,P> array_type;
|
||||
typedef typename array_type::const_iterator iterator;
|
||||
|
||||
static SphericalDots& instance()
|
||||
{
|
||||
static SphericalDots sInstance;
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
size_t size() const { return mPoints.size(); }
|
||||
const Point operator[](uint32_t inIx) const { return mPoints[inIx]; }
|
||||
iterator begin() const { return mPoints.begin(); }
|
||||
iterator end() const { return mPoints.end(); }
|
||||
|
||||
double weight() const { return mWeight; }
|
||||
|
||||
SphericalDots()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
const double
|
||||
kGoldenRatio = (1 + std::sqrt(5.0)) / 2;
|
||||
|
||||
mWeight = (4 * kPI) / P;
|
||||
|
||||
auto p = mPoints.begin();
|
||||
|
||||
for (int32_t i = -N; i <= N; ++i)
|
||||
{
|
||||
double lat = std::asin((2.0 * i) / P);
|
||||
double lon = std::fmod(i, kGoldenRatio) * 2 * kPI / kGoldenRatio;
|
||||
|
||||
p->mX = sin(lon) * cos(lat);
|
||||
p->mY = cos(lon) * cos(lat);
|
||||
p->mZ = sin(lat);
|
||||
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
array_type mPoints;
|
||||
double mWeight;
|
||||
};
|
||||
|
||||
typedef SphericalDots<50> SphericalDots_50;
|
||||
|
||||
}
|
||||
218
include/cif++/Secondary.hpp
Normal file
218
include/cif++/Secondary.hpp
Normal file
@@ -0,0 +1,218 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Calculate DSSP-like secondary structure information
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace mmcif
|
||||
{
|
||||
|
||||
class Structure;
|
||||
class Monomer;
|
||||
|
||||
struct Res;
|
||||
|
||||
extern const float
|
||||
kCouplingConstant, kMinHBondEnergy, kMaxHBondEnergy;
|
||||
|
||||
enum SecondaryStructureType : char
|
||||
{
|
||||
ssLoop = ' ',
|
||||
ssAlphahelix = 'H',
|
||||
ssBetabridge = 'B',
|
||||
ssStrand = 'E',
|
||||
ssHelix_3 = 'G',
|
||||
ssHelix_5 = 'I',
|
||||
ssHelix_PPII = 'P',
|
||||
ssTurn = 'T',
|
||||
ssBend = 'S'
|
||||
};
|
||||
|
||||
enum class HelixType
|
||||
{
|
||||
rh_3_10, rh_alpha, rh_pi, rh_pp
|
||||
};
|
||||
|
||||
enum class Helix
|
||||
{
|
||||
None, Start, End, StartAndEnd, Middle
|
||||
};
|
||||
|
||||
//struct HBond
|
||||
//{
|
||||
// std::string labelAsymID;
|
||||
// int labelSeqID;
|
||||
// double energy;
|
||||
//};
|
||||
//
|
||||
//struct BridgePartner
|
||||
//{
|
||||
// std::string labelAsymID;
|
||||
// int labelSeqID;
|
||||
// int ladder;
|
||||
// bool parallel;
|
||||
//};
|
||||
|
||||
struct SecondaryStructure
|
||||
{
|
||||
SecondaryStructureType type;
|
||||
// HBond donor[2], acceptor[2];
|
||||
// BridgePartner beta[2];
|
||||
// int sheet;
|
||||
// bool bend;
|
||||
};
|
||||
|
||||
//void CalculateSecondaryStructure(Structure& s);
|
||||
|
||||
const size_t
|
||||
kHistogramSize = 30;
|
||||
|
||||
struct DSSP_Statistics
|
||||
{
|
||||
uint32_t nrOfResidues, nrOfChains, nrOfSSBridges, nrOfIntraChainSSBridges, nrOfHBonds;
|
||||
uint32_t nrOfHBondsInAntiparallelBridges, nrOfHBondsInParallelBridges;
|
||||
uint32_t nrOfHBondsPerDistance[11] = {};
|
||||
double accessibleSurface = 0;
|
||||
|
||||
uint32_t residuesPerAlphaHelixHistogram[kHistogramSize] = {};
|
||||
uint32_t parallelBridgesPerLadderHistogram[kHistogramSize] = {};
|
||||
uint32_t antiparallelBridgesPerLadderHistogram[kHistogramSize] = {};
|
||||
uint32_t laddersPerSheetHistogram[kHistogramSize] = {};
|
||||
};
|
||||
|
||||
enum class ChainBreak
|
||||
{
|
||||
None, NewChain, Gap
|
||||
};
|
||||
|
||||
class DSSP
|
||||
{
|
||||
public:
|
||||
DSSP(const Structure& s, int min_poly_proline_stretch_length, bool calculateSurfaceAccessibility);
|
||||
~DSSP();
|
||||
|
||||
DSSP(const DSSP&) = delete;
|
||||
DSSP& operator=(const DSSP&) = delete;
|
||||
|
||||
SecondaryStructureType operator()(const std::string& inAsymID, int inSeqID) const;
|
||||
SecondaryStructureType operator()(const Monomer& m) const;
|
||||
|
||||
double accessibility(const std::string& inAsymID, int inSeqID) const;
|
||||
double accessibility(const Monomer& m) const;
|
||||
|
||||
bool isAlphaHelixEndBeforeStart(const Monomer& m) const;
|
||||
bool isAlphaHelixEndBeforeStart(const std::string& inAsymID, int inSeqID) const;
|
||||
|
||||
DSSP_Statistics GetStatistics() const;
|
||||
|
||||
class iterator;
|
||||
using res_iter = typename std::vector<Res>::iterator;
|
||||
|
||||
class ResidueInfo
|
||||
{
|
||||
public:
|
||||
friend class iterator;
|
||||
|
||||
explicit operator bool() const { return not empty(); }
|
||||
bool empty() const { return mImpl == nullptr; }
|
||||
|
||||
const Monomer& residue() const;
|
||||
std::string alt_id() const;
|
||||
|
||||
/// \brief return 0 if not a break, ' ' in case of a new chain and '*' in case of a broken chain
|
||||
ChainBreak chainBreak() const;
|
||||
|
||||
/// \brief the internal number in DSSP
|
||||
int nr() const;
|
||||
|
||||
SecondaryStructureType ss() const;
|
||||
|
||||
int ssBridgeNr() const;
|
||||
|
||||
Helix helix(HelixType helixType) const;
|
||||
|
||||
bool bend() const;
|
||||
|
||||
double accessibility() const;
|
||||
|
||||
/// \brief returns resinfo, ladder and parallel
|
||||
std::tuple<ResidueInfo,int,bool> bridgePartner(int i) const;
|
||||
|
||||
int sheet() const;
|
||||
|
||||
/// \brief return resinfo and the energy of the bond
|
||||
std::tuple<ResidueInfo,double> acceptor(int i) const;
|
||||
std::tuple<ResidueInfo,double> donor(int i) const;
|
||||
|
||||
private:
|
||||
ResidueInfo(Res* res);
|
||||
|
||||
Res* mImpl;
|
||||
};
|
||||
|
||||
class iterator
|
||||
{
|
||||
public:
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
using value_type = ResidueInfo;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
|
||||
iterator(const iterator& i);
|
||||
iterator(res_iter cur);
|
||||
iterator& operator=(const iterator& i);
|
||||
|
||||
reference operator*() { return mCurrent; }
|
||||
pointer operator->() { return &mCurrent; }
|
||||
|
||||
iterator& operator++();
|
||||
iterator operator++(int)
|
||||
{
|
||||
auto tmp(*this);
|
||||
this->operator++();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(const iterator& rhs) const { return mCurrent.mImpl == rhs.mCurrent.mImpl; }
|
||||
bool operator!=(const iterator& rhs) const { return mCurrent.mImpl != rhs.mCurrent.mImpl; }
|
||||
|
||||
private:
|
||||
ResidueInfo mCurrent;
|
||||
};
|
||||
|
||||
iterator begin() const;
|
||||
iterator end() const;
|
||||
|
||||
bool empty() const { return begin() == end(); }
|
||||
|
||||
private:
|
||||
struct DSSPImpl* mImpl;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
539
include/cif++/Structure.hpp
Normal file
539
include/cif++/Structure.hpp
Normal file
@@ -0,0 +1,539 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <numeric>
|
||||
|
||||
#include "cif++/AtomType.hpp"
|
||||
#include "cif++/Point.hpp"
|
||||
#include "cif++/Compound.hpp"
|
||||
#include "cif++/Cif++.hpp"
|
||||
|
||||
/*
|
||||
To modify a structure, you will have to use actions.
|
||||
|
||||
The currently supported actions are:
|
||||
|
||||
// - Move atom to new location
|
||||
- Remove atom
|
||||
// - Add new atom that was formerly missing
|
||||
// - Add alternate Residue
|
||||
-
|
||||
|
||||
*/
|
||||
|
||||
namespace mmcif
|
||||
{
|
||||
|
||||
class Atom;
|
||||
class Residue;
|
||||
class Monomer;
|
||||
class Polymer;
|
||||
class Structure;
|
||||
class File;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
class Atom
|
||||
{
|
||||
public:
|
||||
// Atom(const structure& s, const std::string& id);
|
||||
Atom();
|
||||
Atom(struct AtomImpl* impl);
|
||||
Atom(const Atom& rhs);
|
||||
|
||||
~Atom();
|
||||
|
||||
explicit operator bool() const { return mImpl_ != nullptr; }
|
||||
|
||||
// return a copy of this atom, with data copied instead of referenced
|
||||
Atom clone() const;
|
||||
|
||||
Atom& operator=(const Atom& rhs);
|
||||
|
||||
const std::string& id() const;
|
||||
AtomType type() const;
|
||||
|
||||
Point location() const;
|
||||
void location(Point p);
|
||||
|
||||
// Atom symmetryCopy(const Point& d, const clipper::RTop_orth& rt);
|
||||
// bool isSymmetryCopy() const;
|
||||
// std::string symmetry() const;
|
||||
// const clipper::RTop_orth& symop() const;
|
||||
|
||||
const Compound& comp() const;
|
||||
bool isWater() const;
|
||||
int charge() const;
|
||||
|
||||
float uIso() const;
|
||||
bool getAnisoU(float anisou[6]) const;
|
||||
float occupancy() const;
|
||||
|
||||
template<typename T>
|
||||
T property(const std::string& name) const;
|
||||
|
||||
template<typename T>
|
||||
void property(const std::string& name, const T& value);
|
||||
|
||||
// specifications
|
||||
std::string labelAtomID() const;
|
||||
std::string labelCompID() const;
|
||||
std::string labelAsymID() const;
|
||||
int labelSeqID() const;
|
||||
std::string labelAltID() const;
|
||||
bool isAlternate() const;
|
||||
|
||||
std::string authAtomID() const;
|
||||
std::string authCompID() const;
|
||||
std::string authAsymID() const;
|
||||
std::string authSeqID() const;
|
||||
std::string pdbxAuthInsCode() const;
|
||||
std::string pdbxAuthAltID() const;
|
||||
|
||||
std::string labelID() const;// label_comp_id + '_' + label_asym_id + '_' + label_seq_id
|
||||
std::string pdbID() const; // auth_comp_id + '_' + auth_asym_id + '_' + auth_seq_id + pdbx_PDB_ins_code
|
||||
|
||||
bool operator==(const Atom& rhs) const;
|
||||
|
||||
// // get clipper format Atom
|
||||
// clipper::Atom toClipper() const;
|
||||
|
||||
// Radius calculation based on integrating the density until perc of electrons is found
|
||||
void calculateRadius(float resHigh, float resLow, float perc);
|
||||
float radius() const;
|
||||
|
||||
// access data in compound for this atom
|
||||
|
||||
// the energy-type field
|
||||
std::string energyType() const;
|
||||
|
||||
// convenience routine
|
||||
bool isBackBone() const
|
||||
{
|
||||
auto atomID = labelAtomID();
|
||||
return atomID == "N" or atomID == "O" or atomID == "C" or atomID == "CA";
|
||||
}
|
||||
|
||||
void swap(Atom& b)
|
||||
{
|
||||
std::swap(mImpl_, b.mImpl_);
|
||||
}
|
||||
|
||||
int compare(const Atom& b) const;
|
||||
|
||||
bool operator<(const Atom& rhs) const
|
||||
{
|
||||
return compare(rhs) < 0;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const Atom& atom);
|
||||
|
||||
private:
|
||||
friend class Structure;
|
||||
void setID(int id);
|
||||
|
||||
AtomImpl* impl();
|
||||
const AtomImpl* impl() const;
|
||||
|
||||
struct AtomImpl* mImpl_;
|
||||
};
|
||||
|
||||
inline void swap(mmcif::Atom& a, mmcif::Atom& b)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
inline double Distance(const Atom& a, const Atom& b)
|
||||
{
|
||||
return Distance(a.location(), b.location());
|
||||
}
|
||||
|
||||
inline double DistanceSquared(const Atom& a, const Atom& b)
|
||||
{
|
||||
return DistanceSquared(a.location(), b.location());
|
||||
}
|
||||
|
||||
typedef std::vector<Atom> AtomView;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
class Residue
|
||||
{
|
||||
public:
|
||||
// constructors should be private, but that's not possible for now (needed in emplace)
|
||||
// constructor for waters
|
||||
Residue(const Structure& structure, const std::string& compoundID,
|
||||
const std::string& asymID, const std::string& authSeqID);
|
||||
|
||||
Residue(const Structure& structure, const std::string& compoundID,
|
||||
const std::string& asymID, int seqID = 0);
|
||||
|
||||
Residue(const Residue& rhs) = delete;
|
||||
Residue& operator=(const Residue& rhs) = delete;
|
||||
|
||||
Residue(Residue&& rhs);
|
||||
Residue& operator=(Residue&& rhs);
|
||||
|
||||
virtual ~Residue();
|
||||
|
||||
const Compound& compound() const;
|
||||
const AtomView& atoms() const;
|
||||
|
||||
/// \brief Unique atoms returns only the atoms without alternates and the first of each alternate atom id.
|
||||
AtomView unique_atoms() const;
|
||||
|
||||
/// \brief The alt ID used for the unique atoms
|
||||
std::string unique_alt_id() const;
|
||||
|
||||
Atom atomByID(const std::string& atomID) const;
|
||||
|
||||
const std::string& compoundID() const { return mCompoundID; }
|
||||
const std::string& asymID() const { return mAsymID; }
|
||||
int seqID() const { return mSeqID; }
|
||||
|
||||
std::string authAsymID() const;
|
||||
std::string authSeqID() const;
|
||||
std::string authInsCode() const;
|
||||
|
||||
// return a human readable PDB-like auth id (chain+seqnr+iCode)
|
||||
std::string authID() const;
|
||||
|
||||
// similar for mmCIF space
|
||||
std::string labelID() const;
|
||||
|
||||
// Is this residue a single entity?
|
||||
bool isEntity() const;
|
||||
|
||||
bool isWater() const { return mCompoundID == "HOH"; }
|
||||
|
||||
const Structure& structure() const { return *mStructure; }
|
||||
|
||||
bool empty() const { return mStructure == nullptr; }
|
||||
|
||||
bool hasAlternateAtoms() const;
|
||||
|
||||
// some routines for 3d work
|
||||
std::tuple<Point,float> centerAndRadius() const;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const Residue& res);
|
||||
|
||||
protected:
|
||||
|
||||
Residue() {}
|
||||
|
||||
friend class Polymer;
|
||||
|
||||
const Structure* mStructure = nullptr;
|
||||
std::string mCompoundID, mAsymID;
|
||||
int mSeqID = 0;
|
||||
std::string mAuthSeqID;
|
||||
AtomView mAtoms;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a monomer models a single Residue in a protein chain
|
||||
|
||||
class Monomer : public Residue
|
||||
{
|
||||
public:
|
||||
// Monomer();
|
||||
Monomer(const Monomer& rhs) = delete;
|
||||
Monomer& operator=(const Monomer& rhs) = delete;
|
||||
|
||||
Monomer(Monomer&& rhs);
|
||||
Monomer& operator=(Monomer&& rhs);
|
||||
|
||||
// Monomer(const Polymer& polymer, uint32_t index);
|
||||
Monomer(const Polymer& polymer, uint32_t index, int seqID,
|
||||
const std::string& compoundID);
|
||||
|
||||
bool is_first_in_chain() const;
|
||||
bool is_last_in_chain() const;
|
||||
|
||||
// convenience
|
||||
bool has_alpha() const;
|
||||
bool has_kappa() const;
|
||||
|
||||
// Assuming this is really an amino acid...
|
||||
|
||||
float phi() const;
|
||||
float psi() const;
|
||||
float alpha() const;
|
||||
float kappa() const;
|
||||
float tco() const;
|
||||
float omega() const;
|
||||
|
||||
// torsion angles
|
||||
size_t nrOfChis() const;
|
||||
float chi(size_t i) const;
|
||||
|
||||
bool isCis() const;
|
||||
|
||||
/// \brief Returns true if the four atoms C, CA, N and O are present
|
||||
bool isComplete() const;
|
||||
|
||||
/// \brief Returns true if any of the backbone atoms has an alternate
|
||||
bool hasAlternateBackboneAtoms() const;
|
||||
|
||||
Atom CAlpha() const { return atomByID("CA"); }
|
||||
Atom C() const { return atomByID("C"); }
|
||||
Atom N() const { return atomByID("N"); }
|
||||
Atom O() const { return atomByID("O"); }
|
||||
Atom H() const { return atomByID("H"); }
|
||||
|
||||
bool isBondedTo(const Monomer& rhs) const
|
||||
{
|
||||
return this != &rhs and areBonded(*this, rhs);
|
||||
}
|
||||
|
||||
static bool areBonded(const Monomer& a, const Monomer& b, float errorMargin = 0.5f);
|
||||
static bool isCis(const Monomer& a, const Monomer& b);
|
||||
static float omega(const Monomer& a, const Monomer& b);
|
||||
|
||||
// for LEU and VAL
|
||||
float chiralVolume() const;
|
||||
|
||||
private:
|
||||
const Polymer* mPolymer;
|
||||
uint32_t mIndex;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
class Polymer : public std::vector<Monomer>
|
||||
{
|
||||
public:
|
||||
Polymer(const Structure& s, const std::string& entityID, const std::string& asymID);
|
||||
|
||||
Polymer(const Polymer&) = delete;
|
||||
Polymer& operator=(const Polymer&) = delete;
|
||||
|
||||
// Polymer(Polymer&& rhs) = delete;
|
||||
// Polymer& operator=(Polymer&& rhs) = de;
|
||||
|
||||
Monomer& getBySeqID(int seqID);
|
||||
const Monomer& getBySeqID(int seqID) const;
|
||||
|
||||
Structure* structure() const { return mStructure; }
|
||||
|
||||
std::string asymID() const { return mAsymID; }
|
||||
std::string entityID() const { return mEntityID; }
|
||||
|
||||
std::string chainID() const;
|
||||
|
||||
int Distance(const Monomer& a, const Monomer& b) const;
|
||||
|
||||
private:
|
||||
|
||||
Structure* mStructure;
|
||||
std::string mEntityID;
|
||||
std::string mAsymID;
|
||||
cif::RowSet mPolySeq;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// file is a reference to the data stored in e.g. the cif file.
|
||||
// This object is not copyable.
|
||||
|
||||
class File : public std::enable_shared_from_this<File>
|
||||
{
|
||||
public:
|
||||
File();
|
||||
File(const std::string& path);
|
||||
~File();
|
||||
|
||||
File(const File&) = delete;
|
||||
File& operator=(const File&) = delete;
|
||||
|
||||
void load(const std::string& path);
|
||||
void save(const std::string& path);
|
||||
|
||||
Structure* model(size_t nr = 1);
|
||||
|
||||
struct FileImpl& impl() const { return *mImpl; }
|
||||
|
||||
cif::Datablock& data();
|
||||
cif::File& file();
|
||||
|
||||
private:
|
||||
|
||||
struct FileImpl* mImpl;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
enum class StructureOpenOptions
|
||||
{
|
||||
SkipHydrogen = 1 << 0
|
||||
};
|
||||
|
||||
inline bool operator&(StructureOpenOptions a, StructureOpenOptions b)
|
||||
{
|
||||
return static_cast<int>(a) bitand static_cast<int>(b);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
class Structure
|
||||
{
|
||||
public:
|
||||
Structure(File& p, uint32_t modelNr = 1, StructureOpenOptions options = {});
|
||||
Structure& operator=(const Structure&) = delete;
|
||||
~Structure();
|
||||
|
||||
// Create a read-only clone of the current structure (for multithreaded calculations that move atoms)
|
||||
Structure(const Structure&);
|
||||
|
||||
File& getFile() const;
|
||||
|
||||
const AtomView& atoms() const { return mAtoms; }
|
||||
AtomView waters() const;
|
||||
|
||||
const std::list<Polymer>& polymers() const { return mPolymers; }
|
||||
std::list<Polymer>& polymers() { return mPolymers; }
|
||||
|
||||
const std::vector<Residue>& nonPolymers() const { return mNonPolymers; }
|
||||
|
||||
Atom getAtomByID(std::string id) const;
|
||||
// Atom getAtomByLocation(Point pt, float maxDistance) const;
|
||||
|
||||
Atom getAtomByLabel(const std::string& atomID, const std::string& asymID,
|
||||
const std::string& compID, int seqID, const std::string& altID = "");
|
||||
|
||||
// Atom getAtomByAuth(const std::string& atomID, const std::string& asymID,
|
||||
// const std::string& compID, int seqID, const std::string& altID = "",
|
||||
// const std::string& pdbxAuthInsCode = "");
|
||||
|
||||
// map between auth and label locations
|
||||
|
||||
std::tuple<std::string,int,std::string> MapAuthToLabel(const std::string& asymID,
|
||||
const std::string& seqID, const std::string& compID, const std::string& insCode = "");
|
||||
|
||||
std::tuple<std::string,std::string,std::string,std::string> MapLabelToAuth(
|
||||
const std::string& asymID, int seqID, const std::string& compID);
|
||||
|
||||
// returns chain, seqnr, icode
|
||||
std::tuple<char,int,char> MapLabelToAuth(
|
||||
const std::string& asymID, int seqID) const;
|
||||
|
||||
// returns chain,seqnr,comp,iCode
|
||||
std::tuple<std::string,int,std::string,std::string> MapLabelToPDB(
|
||||
const std::string& asymID, int seqID, const std::string& compID,
|
||||
const std::string& authSeqID) const;
|
||||
|
||||
std::tuple<std::string,int,std::string> MapPDBToLabel(
|
||||
const std::string& asymID, int seqID, const std::string& compID, const std::string& iCode) const;
|
||||
|
||||
// Actions
|
||||
void removeAtom(Atom& a);
|
||||
void swapAtoms(Atom& a1, Atom& a2); // swap the labels for these atoms
|
||||
void moveAtom(Atom& a, Point p); // move atom to a new location
|
||||
void changeResidue(const Residue& res, const std::string& newCompound,
|
||||
const std::vector<std::tuple<std::string,std::string>>& remappedAtoms);
|
||||
|
||||
/// To sort the atoms in order of model > asym-id > res-id > atom-id
|
||||
/// Will asssign new atom_id's to all atoms. Be carefull
|
||||
void sortAtoms();
|
||||
|
||||
// iterator for all residues
|
||||
|
||||
class residue_iterator : public std::iterator<std::forward_iterator_tag, const Residue>
|
||||
{
|
||||
public:
|
||||
typedef std::iterator<std::forward_iterator_tag, const Residue> baseType;
|
||||
typedef typename baseType::pointer pointer;
|
||||
typedef typename baseType::reference reference;
|
||||
|
||||
typedef std::list<Polymer>::const_iterator poly_iterator;
|
||||
|
||||
residue_iterator(const Structure* s, poly_iterator polyIter, size_t polyResIndex, size_t nonPolyIndex);
|
||||
|
||||
reference operator*();
|
||||
pointer operator->();
|
||||
|
||||
residue_iterator& operator++();
|
||||
residue_iterator operator++(int);
|
||||
|
||||
bool operator==(const residue_iterator& rhs) const;
|
||||
bool operator!=(const residue_iterator& rhs) const;
|
||||
|
||||
private:
|
||||
const Structure& mStructure;
|
||||
poly_iterator mPolyIter;
|
||||
size_t mPolyResIndex;
|
||||
size_t mNonPolyIndex;
|
||||
};
|
||||
|
||||
class residue_view
|
||||
{
|
||||
public:
|
||||
residue_view(const Structure* s) : mStructure(s) {}
|
||||
residue_view(const residue_view& rhs) : mStructure(rhs.mStructure) {}
|
||||
residue_view& operator=(residue_view& rhs)
|
||||
{
|
||||
mStructure = rhs.mStructure;
|
||||
return *this;
|
||||
}
|
||||
|
||||
residue_iterator begin() const { return residue_iterator(mStructure, mStructure->mPolymers.begin(), 0, 0); }
|
||||
residue_iterator end() const { return residue_iterator(mStructure, mStructure->mPolymers.end(), 0, mStructure->mNonPolymers.size()); }
|
||||
size_t size() const
|
||||
{
|
||||
size_t ps = std::accumulate(mStructure->mPolymers.begin(), mStructure->mPolymers.end(), 0UL, [](size_t s, auto& p) { return s + p.size(); });
|
||||
return ps + mStructure->mNonPolymers.size();
|
||||
}
|
||||
|
||||
private:
|
||||
const Structure* mStructure;
|
||||
};
|
||||
|
||||
residue_view residues() const { return residue_view(this); }
|
||||
|
||||
private:
|
||||
friend Polymer;
|
||||
friend Residue;
|
||||
friend residue_view;
|
||||
friend residue_iterator;
|
||||
|
||||
cif::Category& category(const char* name) const;
|
||||
cif::Datablock& datablock() const;
|
||||
|
||||
void insertCompound(const std::string& compoundID, bool isEntity);
|
||||
|
||||
void loadData();
|
||||
void updateAtomIndex();
|
||||
|
||||
File& mFile;
|
||||
uint32_t mModelNr;
|
||||
AtomView mAtoms;
|
||||
std::vector<size_t> mAtomIndex;
|
||||
std::list<Polymer> mPolymers;
|
||||
std::vector<Residue> mNonPolymers;
|
||||
};
|
||||
|
||||
}
|
||||
34
include/cif++/Symmetry.hpp
Normal file
34
include/cif++/Symmetry.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace mmcif
|
||||
{
|
||||
|
||||
int GetSpacegroupNumber(std::string spacegroup); // alternative for clipper's parsing code
|
||||
|
||||
}
|
||||
57
include/cif++/TlsParser.hpp
Normal file
57
include/cif++/TlsParser.hpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "cif++/Cif++.hpp"
|
||||
|
||||
namespace cif
|
||||
{
|
||||
|
||||
extern const int
|
||||
kResidueNrWildcard,
|
||||
kNoSeqNum;
|
||||
|
||||
struct TLSSelection;
|
||||
typedef std::unique_ptr<TLSSelection> TLSSelectionPtr;
|
||||
|
||||
struct TLSResidue;
|
||||
|
||||
struct TLSSelection
|
||||
{
|
||||
virtual ~TLSSelection() {}
|
||||
virtual void CollectResidues(cif::Datablock& db, std::vector<TLSResidue>& residues, int indentLevel = 0) const = 0;
|
||||
std::vector<std::tuple<std::string,int,int>> GetRanges(cif::Datablock& db, bool pdbNamespace) const;
|
||||
};
|
||||
|
||||
// Low level: get the selections
|
||||
TLSSelectionPtr ParseSelectionDetails(const std::string& program, const std::string& selection);
|
||||
|
||||
}
|
||||
10
libcif++.pc.in
Normal file
10
libcif++.pc.in
Normal file
@@ -0,0 +1,10 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: libcif++
|
||||
Description: C++ library for the manipulation of mmCIF files.
|
||||
Version: @PACKAGE_VERSION@
|
||||
Libs: -L${libdir} -lcif++
|
||||
Cflags: -I${includedir}
|
||||
1871
rsrc/curves.xml
Normal file
1871
rsrc/curves.xml
Normal file
File diff suppressed because it is too large
Load Diff
3098
rsrc/dictionaries/mmcif_ddl.dic
Normal file
3098
rsrc/dictionaries/mmcif_ddl.dic
Normal file
File diff suppressed because it is too large
Load Diff
143782
rsrc/dictionaries/mmcif_pdbx.dic
Normal file
143782
rsrc/dictionaries/mmcif_pdbx.dic
Normal file
File diff suppressed because it is too large
Load Diff
36
rsrc/isomers.txt
Normal file
36
rsrc/isomers.txt
Normal file
@@ -0,0 +1,36 @@
|
||||
13R:13S
|
||||
1AB:IMR
|
||||
558:559
|
||||
6PG:LG6
|
||||
A:AMP
|
||||
ABA:DBB
|
||||
ALO:DTH
|
||||
BDR:BXX
|
||||
C:C5P
|
||||
CBI:MAL:MAB
|
||||
COA:COZ
|
||||
COM:COM
|
||||
CTL:TTL
|
||||
CTR:MLR
|
||||
DIL:IIL
|
||||
DNE:NLE
|
||||
DTL:MRY
|
||||
DX5:LXP:R5P
|
||||
G:G25
|
||||
GDC:GDD
|
||||
GDM:GMY
|
||||
GDU:GUD:UFM:UPG
|
||||
HY0:HYG
|
||||
I:IMP
|
||||
LLT:THM
|
||||
LPK:LTG
|
||||
M13:MDM
|
||||
PDE:PNE
|
||||
QDN:QI9
|
||||
R5A:R5B
|
||||
RUB:XBP
|
||||
RWF:SWF
|
||||
TBE:TBI
|
||||
U:U5P
|
||||
U2F:UP1:UPF
|
||||
UD1:UD2
|
||||
1318
src/AtomType.cpp
Normal file
1318
src/AtomType.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3114
src/Cif++.cpp
Normal file
3114
src/Cif++.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3978
src/Cif2PDB.cpp
Normal file
3978
src/Cif2PDB.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1097
src/CifParser.cpp
Normal file
1097
src/CifParser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
876
src/CifUtils.cpp
Normal file
876
src/CifUtils.cpp
Normal file
@@ -0,0 +1,876 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "cif++/Config.hpp"
|
||||
|
||||
#include <tuple>
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <chrono>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define TERM_WIDTH 80
|
||||
#else
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include "cif++/CifUtils.hpp"
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace cif
|
||||
{
|
||||
|
||||
extern int VERBOSE;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// This really makes a difference, having our own tolower routines
|
||||
|
||||
const uint8_t kCharToLowerMap[256] =
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
||||
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
||||
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
|
||||
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
bool iequals(const std::string& a, const std::string& b)
|
||||
{
|
||||
bool result = a.length() == b.length();
|
||||
for (auto ai = a.begin(), bi = b.begin(); result and ai != a.end() and bi != b.end(); ++ai, ++bi)
|
||||
result = tolower(*ai) == tolower(*bi);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool iequals(const char* a, const char* b)
|
||||
{
|
||||
bool result = true;
|
||||
for (; result and *a and *b; ++a, ++b)
|
||||
result = tolower(*a) == tolower(*b);
|
||||
|
||||
return result and *a == *b;
|
||||
}
|
||||
|
||||
int icompare(const std::string& a, const std::string& b)
|
||||
{
|
||||
int d = 0;
|
||||
auto ai = a.begin(), bi = b.begin();
|
||||
|
||||
for (; d == 0 and ai != a.end() and bi != b.end(); ++ai, ++bi)
|
||||
d = tolower(*ai) - tolower(*bi);
|
||||
|
||||
if (d == 0)
|
||||
{
|
||||
if (ai != a.end())
|
||||
d = 1;
|
||||
else if (bi != b.end())
|
||||
d = -1;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
int icompare(const char* a, const char* b)
|
||||
{
|
||||
int d = 0;
|
||||
|
||||
for (; d == 0 and *a != 0 and *b != 0; ++a, ++b)
|
||||
d = tolower(*a) - tolower(*b);
|
||||
|
||||
if (d == 0)
|
||||
{
|
||||
if (*a != 0)
|
||||
d = 1;
|
||||
else if (*b != 0)
|
||||
d = -1;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
void toLower(std::string& s)
|
||||
{
|
||||
for (auto& c: s)
|
||||
c = tolower(c);
|
||||
}
|
||||
|
||||
std::string toLowerCopy(const std::string& s)
|
||||
{
|
||||
std::string result(s);
|
||||
for (auto& c: result)
|
||||
c = tolower(c);
|
||||
return result;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
std::tuple<std::string,std::string> splitTagName(const std::string& tag)
|
||||
{
|
||||
if (tag.empty())
|
||||
throw std::runtime_error("empty tag");
|
||||
if (tag[0] != '_')
|
||||
throw std::runtime_error("tag does not start with underscore");
|
||||
|
||||
auto s = tag.find('.');
|
||||
if (s == std::string::npos)
|
||||
throw std::runtime_error("tag does not contain dot");
|
||||
return std::tuple<std::string,std::string>{
|
||||
tag.substr(1, s - 1), tag.substr(s + 1)
|
||||
};
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Simplified line breaking code taken from a decent text editor.
|
||||
// In this case, simplified means it only supports ASCII.
|
||||
|
||||
enum LineBreakClass
|
||||
{
|
||||
kLBC_OpenPunctuation,
|
||||
kLBC_ClosePunctuation,
|
||||
kLBC_CloseParenthesis,
|
||||
kLBC_Quotation,
|
||||
kLBC_NonBreaking,
|
||||
kLBC_Nonstarter,
|
||||
kLBC_Exlamation,
|
||||
kLBC_SymbolAllowingBreakAfter,
|
||||
kLBC_InfixNumericSeparator,
|
||||
kLBC_PrefixNumeric,
|
||||
kLBC_PostfixNumeric,
|
||||
kLBC_Numeric,
|
||||
kLBC_Alphabetic,
|
||||
kLBC_Ideographic,
|
||||
kLBC_Inseperable,
|
||||
kLBC_Hyphen,
|
||||
kLBC_BreakAfter,
|
||||
kLBC_BreakBefor,
|
||||
kLBC_BreakOpportunityBeforeAndAfter,
|
||||
kLBC_ZeroWidthSpace,
|
||||
kLBC_CombiningMark,
|
||||
kLBC_WordJoiner,
|
||||
kLBC_HangulLVSyllable,
|
||||
kLBC_HangulLVTSyllable,
|
||||
kLBC_HangulLJamo,
|
||||
kLBC_HangulVJamo,
|
||||
kLBC_HangulTJamo,
|
||||
|
||||
kLBC_MandatoryBreak,
|
||||
kLBC_CarriageReturn,
|
||||
kLBC_LineFeed,
|
||||
kLBC_NextLine,
|
||||
kLBC_Surrogate,
|
||||
kLBC_Space,
|
||||
kLBC_ContigentBreakOpportunity,
|
||||
kLBC_Ambiguous,
|
||||
kLBC_ComplexContext,
|
||||
kLBC_Unknown
|
||||
};
|
||||
|
||||
const LineBreakClass kASCII_LBTable[128] =
|
||||
{
|
||||
kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark,
|
||||
kLBC_CombiningMark, kLBC_BreakAfter, kLBC_LineFeed, kLBC_MandatoryBreak, kLBC_MandatoryBreak, kLBC_CarriageReturn, kLBC_CombiningMark, kLBC_CombiningMark,
|
||||
kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark,
|
||||
kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark,
|
||||
kLBC_Space, kLBC_Exlamation, kLBC_Quotation, kLBC_Alphabetic, kLBC_PrefixNumeric, kLBC_PostfixNumeric, kLBC_Alphabetic, kLBC_Quotation,
|
||||
kLBC_OpenPunctuation, kLBC_CloseParenthesis, kLBC_Alphabetic, kLBC_PrefixNumeric,
|
||||
|
||||
// comma treated differently here, it is not a numeric separator in PDB
|
||||
kLBC_SymbolAllowingBreakAfter/* kLBC_InfixNumericSeparator */,
|
||||
|
||||
kLBC_Hyphen, kLBC_InfixNumericSeparator, kLBC_SymbolAllowingBreakAfter,
|
||||
kLBC_Numeric, kLBC_Numeric, kLBC_Numeric, kLBC_Numeric, kLBC_Numeric, kLBC_Numeric, kLBC_Numeric, kLBC_Numeric,
|
||||
kLBC_Numeric, kLBC_Numeric, kLBC_InfixNumericSeparator, kLBC_InfixNumericSeparator, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Exlamation,
|
||||
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
|
||||
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
|
||||
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
|
||||
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_OpenPunctuation, kLBC_PrefixNumeric, kLBC_CloseParenthesis, kLBC_Alphabetic, kLBC_Alphabetic,
|
||||
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
|
||||
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
|
||||
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
|
||||
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_OpenPunctuation, kLBC_BreakAfter, kLBC_ClosePunctuation, kLBC_Alphabetic, kLBC_CombiningMark
|
||||
};
|
||||
|
||||
std::string::const_iterator nextLineBreak(std::string::const_iterator text, std::string::const_iterator end)
|
||||
{
|
||||
if (text == end)
|
||||
return text;
|
||||
|
||||
enum breakAction
|
||||
{
|
||||
DBK = 0, // direct break (blank in table)
|
||||
IBK, // indirect break (% in table)
|
||||
PBK, // prohibited break (^ in table)
|
||||
CIB, // combining indirect break
|
||||
CPB // combining prohibited break
|
||||
};
|
||||
|
||||
const breakAction brkTable[27][27] = {
|
||||
// OP CL CP QU GL NS EX SY IS PR PO NU AL ID IN HY BA BB B2 ZW CM WJ H2 H3 JL JV JT
|
||||
/* OP */ { PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, CPB, PBK, PBK, PBK, PBK, PBK, PBK },
|
||||
/* CL */ { DBK, PBK, PBK, IBK, IBK, PBK, PBK, PBK, PBK, IBK, IBK, DBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
|
||||
/* CP */ { DBK, PBK, PBK, IBK, IBK, PBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
|
||||
/* QU */ { PBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, IBK },
|
||||
/* GL */ { IBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, IBK },
|
||||
/* NS */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, DBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
|
||||
/* EX */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, DBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
|
||||
/* SY */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
|
||||
/* IS */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, IBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
|
||||
/* PR */ { IBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, IBK, IBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, IBK },
|
||||
/* PO */ { IBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, IBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
|
||||
/* NU */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
|
||||
/* AL */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, IBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
|
||||
/* ID */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
|
||||
/* IN */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
|
||||
/* HY */ { DBK, PBK, PBK, IBK, DBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
|
||||
/* BA */ { DBK, PBK, PBK, IBK, DBK, IBK, PBK, PBK, PBK, DBK, DBK, DBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
|
||||
/* BB */ { IBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, IBK },
|
||||
/* B2 */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, DBK, DBK, DBK, DBK, IBK, IBK, DBK, PBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
|
||||
/* ZW */ { DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, PBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK },
|
||||
/* CM */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, IBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
|
||||
/* WJ */ { IBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, IBK },
|
||||
/* H2 */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, IBK, IBK },
|
||||
/* H3 */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, IBK },
|
||||
/* JL */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, DBK },
|
||||
/* JV */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, IBK, IBK },
|
||||
/* JT */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, IBK },
|
||||
};
|
||||
|
||||
uint8_t ch = static_cast<uint8_t>(*text);
|
||||
|
||||
LineBreakClass cls;
|
||||
|
||||
if (ch == '\n')
|
||||
cls = kLBC_MandatoryBreak;
|
||||
else if (ch < 128)
|
||||
{
|
||||
cls = kASCII_LBTable[ch];
|
||||
if (cls > kLBC_MandatoryBreak and cls != kLBC_Space) // duh...
|
||||
cls = kLBC_Alphabetic;
|
||||
}
|
||||
else
|
||||
cls = kLBC_Unknown;
|
||||
|
||||
if (cls == kLBC_Space)
|
||||
cls = kLBC_WordJoiner;
|
||||
|
||||
LineBreakClass ncls = cls;
|
||||
|
||||
while (++text != end and cls != kLBC_MandatoryBreak)
|
||||
{
|
||||
ch = *text;
|
||||
|
||||
LineBreakClass lcls = ncls;
|
||||
|
||||
if (ch == '\n')
|
||||
{
|
||||
++text;
|
||||
break;
|
||||
}
|
||||
|
||||
ncls = kASCII_LBTable[ch];
|
||||
|
||||
if (ncls == kLBC_Space)
|
||||
continue;
|
||||
|
||||
breakAction brk = brkTable[cls][ncls];
|
||||
|
||||
if (brk == DBK or (brk == IBK and lcls == kLBC_Space))
|
||||
break;
|
||||
|
||||
cls = ncls;
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
std::vector<std::string> wrapLine(const std::string& text, unsigned int width)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
std::vector<size_t> offsets = { 0 };
|
||||
|
||||
auto b = text.begin();
|
||||
while (b != text.end())
|
||||
{
|
||||
auto e = nextLineBreak(b, text.end());
|
||||
|
||||
offsets.push_back(e - text.begin());
|
||||
|
||||
b = e;
|
||||
}
|
||||
|
||||
size_t count = offsets.size() - 1;
|
||||
|
||||
std::vector<size_t> minima(count + 1, 1000000);
|
||||
minima[0] = 0;
|
||||
std::vector<size_t> breaks(count + 1, 0);
|
||||
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
size_t j = i + 1;
|
||||
while (j <= count)
|
||||
{
|
||||
size_t w = offsets[j] - offsets[i];
|
||||
|
||||
if (w > width)
|
||||
break;
|
||||
|
||||
while (w > 0 and isspace(text[offsets[i] + w - 1]))
|
||||
--w;
|
||||
|
||||
size_t cost = minima[i];
|
||||
if (j < count) // last line may be shorter
|
||||
cost += (width - w) * (width - w);
|
||||
|
||||
if (cost < minima[j])
|
||||
{
|
||||
minima[j] = cost;
|
||||
breaks[j] = i;
|
||||
}
|
||||
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
||||
size_t j = count;
|
||||
while (j > 0)
|
||||
{
|
||||
size_t i = breaks[j];
|
||||
result.push_back(text.substr(offsets[i], offsets[j] - offsets[i]));
|
||||
j = i;
|
||||
}
|
||||
|
||||
reverse(result.begin(), result.end());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> wordWrap(const std::string& text, unsigned int width)
|
||||
{
|
||||
std::vector<std::string> paragraphs;
|
||||
ba::split(paragraphs, text, ba::is_any_of("\n"));
|
||||
|
||||
std::vector<std::string> result;
|
||||
for (auto& p: paragraphs)
|
||||
{
|
||||
if (p.empty())
|
||||
{
|
||||
result.push_back("");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto lines = wrapLine(p, width);
|
||||
result.insert(result.end(), lines.begin(), lines.end());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#ifdef _MSC_VER
|
||||
uint32_t get_terminal_width()
|
||||
{
|
||||
return TERM_WIDTH;
|
||||
}
|
||||
|
||||
// I don't have a windows machine to test the following code, please accept my apologies in case it fails...
|
||||
std::string GetExecutablePath()
|
||||
{
|
||||
WCHAR buffer[4096];
|
||||
|
||||
DWORD n = ::GetModuleFileNameW(nullptr, buffer, sizeof(buffer) / sizeof(WCHAR));
|
||||
if (n == 0)
|
||||
throw runtime_error("could not get exe path");
|
||||
|
||||
wstring ws(buffer);
|
||||
|
||||
return std::string(ws.begin(), ws.end());
|
||||
}
|
||||
|
||||
#else
|
||||
uint32_t get_terminal_width()
|
||||
{
|
||||
uint32_t result = 80;
|
||||
|
||||
if (isatty(STDOUT_FILENO))
|
||||
{
|
||||
struct winsize w;
|
||||
ioctl(0, TIOCGWINSZ, &w);
|
||||
result = w.ws_col;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string get_executable_path()
|
||||
{
|
||||
using namespace std::literals;
|
||||
|
||||
char path[PATH_MAX] = "";
|
||||
if (readlink("/proc/self/exe", path, sizeof(path)) == -1)
|
||||
throw std::runtime_error("could not get exe path "s + strerror(errno));
|
||||
return { path };
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
struct ProgressImpl
|
||||
{
|
||||
ProgressImpl(int64_t inMax, const std::string& inAction)
|
||||
: mMax(inMax), mConsumed(0), mAction(inAction), mMessage(inAction)
|
||||
, mThread(std::bind(&ProgressImpl::Run, this)) {}
|
||||
|
||||
void Run();
|
||||
void Stop()
|
||||
{
|
||||
mStop = true;
|
||||
if (mThread.joinable())
|
||||
mThread.join();
|
||||
}
|
||||
|
||||
void PrintProgress();
|
||||
void PrintDone();
|
||||
|
||||
int64_t mMax;
|
||||
std::atomic<int64_t>mConsumed;
|
||||
int64_t mLastConsumed = 0;
|
||||
int mSpinnerIndex = 0;
|
||||
std::string mAction, mMessage;
|
||||
std::mutex mMutex;
|
||||
std::thread mThread;
|
||||
std::chrono::time_point<std::chrono::system_clock>
|
||||
mStart = std::chrono::system_clock::now();
|
||||
bool mStop = false;
|
||||
};
|
||||
|
||||
void ProgressImpl::Run()
|
||||
{
|
||||
bool printedAny = false;
|
||||
|
||||
try
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
std::unique_lock lock(mMutex);
|
||||
|
||||
if (mStop or mConsumed == mMax)
|
||||
break;
|
||||
|
||||
auto elapsed = std::chrono::system_clock::now() - mStart;
|
||||
|
||||
if (elapsed < std::chrono::seconds(5))
|
||||
continue;
|
||||
|
||||
PrintProgress();
|
||||
printedAny = true;
|
||||
|
||||
}
|
||||
}
|
||||
catch (...) {}
|
||||
|
||||
if (printedAny)
|
||||
PrintDone();
|
||||
}
|
||||
|
||||
void ProgressImpl::PrintProgress()
|
||||
{
|
||||
// const char* kBlocks[] = {
|
||||
// " ", // 0
|
||||
// u8"\u258F", // 1
|
||||
// u8"\u258E", // 2
|
||||
// u8"\u258D", // 3
|
||||
// u8"\u258C", // 4
|
||||
// u8"\u258B", // 5
|
||||
// u8"\u258A", // 6
|
||||
// u8"\u2589", // 7
|
||||
// u8"\u2588", // 8
|
||||
// };
|
||||
|
||||
const char* kBlocks[] = {
|
||||
" ", // 0
|
||||
" ", // 1
|
||||
" ", // 2
|
||||
"-", // 3
|
||||
"-", // 4
|
||||
"-", // 5
|
||||
"=", // 6
|
||||
"=", // 7
|
||||
"=", // 8
|
||||
};
|
||||
|
||||
uint32_t width = get_terminal_width();
|
||||
|
||||
std::string msg;
|
||||
msg.reserve(width + 1);
|
||||
if (mMessage.length() <= 20)
|
||||
{
|
||||
msg = mMessage;
|
||||
if (msg.length() < 20)
|
||||
msg.append(20 - msg.length(), ' ');
|
||||
}
|
||||
else
|
||||
msg = mMessage.substr(0, 17) + "...";
|
||||
|
||||
msg += " |";
|
||||
|
||||
int64_t consumed = mConsumed;
|
||||
float progress = static_cast<float>(consumed) / mMax;
|
||||
int pi = static_cast<int>(std::ceil(progress * 33 * 8));
|
||||
// int tw = width - 28;
|
||||
// int twd = static_cast<int>(tw * progress + 0.5f);
|
||||
// msg.append(twd, '=');
|
||||
// msg.append(tw - twd, ' ');
|
||||
|
||||
for (int i = 0; i < 33; ++i)
|
||||
{
|
||||
if (pi <= 0)
|
||||
msg += kBlocks[0];
|
||||
else if (pi >= 8)
|
||||
msg += kBlocks[8];
|
||||
else
|
||||
msg += kBlocks[pi];
|
||||
pi -= 8;
|
||||
}
|
||||
|
||||
msg.append("| ");
|
||||
|
||||
// const char kSpinner[] = { '|', '/', '-', '\\' };
|
||||
const char kSpinner[] = { ' ', '.', 'o', 'O', '0', 'O', 'o', '.' };
|
||||
const size_t kSpinnerCount = sizeof(kSpinner);
|
||||
|
||||
if (mLastConsumed < consumed)
|
||||
{
|
||||
mLastConsumed = consumed;
|
||||
mSpinnerIndex = (mSpinnerIndex + 1) % kSpinnerCount;
|
||||
}
|
||||
|
||||
const char spinner[2] = { kSpinner[mSpinnerIndex], 0 };
|
||||
msg.append(spinner);
|
||||
|
||||
// int perc = static_cast<int>(100 * progress);
|
||||
// if (perc < 100)
|
||||
// msg += ' ';
|
||||
// if (perc < 10)
|
||||
// msg += ' ';
|
||||
// msg += to_string(perc);
|
||||
// msg += '%';
|
||||
|
||||
std::cout << '\r' << msg;
|
||||
std::cout.flush();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const std::chrono::duration<double>& t)
|
||||
{
|
||||
uint64_t s = static_cast<uint64_t>(std::trunc(t.count()));
|
||||
if (s > 24 * 60 * 60)
|
||||
{
|
||||
uint32_t days = s / (24 * 60 * 60);
|
||||
os << days << "d ";
|
||||
s %= 24 * 60 * 60;
|
||||
}
|
||||
|
||||
if (s > 60 * 60)
|
||||
{
|
||||
uint32_t hours = s / (60 * 60);
|
||||
os << hours << "h ";
|
||||
s %= 60 * 60;
|
||||
}
|
||||
|
||||
if (s > 60)
|
||||
{
|
||||
uint32_t minutes = s / 60;
|
||||
os << minutes << "m ";
|
||||
s %= 60;
|
||||
}
|
||||
|
||||
double ss = s + 1e-6 * (t.count() - s);
|
||||
|
||||
os << std::fixed << std::setprecision(1) << ss << 's';
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ProgressImpl::PrintDone()
|
||||
{
|
||||
std::chrono::duration<double> elapsed = std::chrono::system_clock::now() - mStart;
|
||||
|
||||
std::ostringstream msgstr;
|
||||
msgstr << mAction << " done in " << elapsed << " cpu / %ws wall";
|
||||
auto msg = msgstr.str();
|
||||
|
||||
uint32_t width = get_terminal_width();
|
||||
|
||||
if (msg.length() < width)
|
||||
msg += std::string(width - msg.length(), ' ');
|
||||
|
||||
std::cout << '\r' << msg << std::endl;
|
||||
}
|
||||
|
||||
Progress::Progress(int64_t inMax, const std::string& inAction)
|
||||
: mImpl(nullptr)
|
||||
{
|
||||
if (isatty(STDOUT_FILENO))
|
||||
mImpl = new ProgressImpl(inMax, inAction);
|
||||
}
|
||||
|
||||
Progress::~Progress()
|
||||
{
|
||||
if (mImpl != nullptr)
|
||||
mImpl->Stop();
|
||||
|
||||
delete mImpl;
|
||||
}
|
||||
|
||||
void Progress::consumed(int64_t inConsumed)
|
||||
{
|
||||
if (mImpl != nullptr and
|
||||
(mImpl->mConsumed += inConsumed) >= mImpl->mMax)
|
||||
{
|
||||
mImpl->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void Progress::progress(int64_t inProgress)
|
||||
{
|
||||
if (mImpl != nullptr and
|
||||
(mImpl->mConsumed = inProgress) >= mImpl->mMax)
|
||||
{
|
||||
mImpl->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void Progress::message(const std::string& inMessage)
|
||||
{
|
||||
if (mImpl != nullptr)
|
||||
{
|
||||
std::unique_lock lock(mImpl->mMutex);
|
||||
mImpl->mMessage = inMessage;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
std::unique_ptr<rsrc_loader> rsrc_loader::s_instance;
|
||||
|
||||
struct rsrc_loader_impl
|
||||
{
|
||||
virtual ~rsrc_loader_impl() {}
|
||||
virtual rsrc load(const std::string& path) const = 0;
|
||||
};
|
||||
|
||||
class rsrc_not_found_exception : public std::exception
|
||||
{
|
||||
public:
|
||||
virtual const char* what() const throw() { return "resource not found"; }
|
||||
};
|
||||
|
||||
struct mrsrc_rsrc_loader_impl : public rsrc_loader_impl
|
||||
{
|
||||
mrsrc_rsrc_loader_impl(const rsrc_loader_info& info);
|
||||
|
||||
virtual rsrc load(const std::string& path) const;
|
||||
|
||||
const rsrc_imp* m_index;
|
||||
const char* m_data;
|
||||
const char* m_name;
|
||||
};
|
||||
|
||||
mrsrc_rsrc_loader_impl::mrsrc_rsrc_loader_impl(const rsrc_loader_info& info)
|
||||
{
|
||||
m_index = static_cast<const rsrc_imp*>(info.ptrs[0]);
|
||||
m_data = reinterpret_cast<const char*>(info.ptrs[1]);
|
||||
m_name = reinterpret_cast<const char*>(info.ptrs[2]);
|
||||
}
|
||||
|
||||
rsrc mrsrc_rsrc_loader_impl::load(const std::string& path) const
|
||||
{
|
||||
auto node = m_index;
|
||||
|
||||
std::string p(path);
|
||||
|
||||
while (not p.empty())
|
||||
{
|
||||
if (node->m_child == 0) // no children, this is an error
|
||||
return {};
|
||||
|
||||
node = m_index + node->m_child;
|
||||
|
||||
std::string::size_type s = p.find('/');
|
||||
std::string name;
|
||||
|
||||
if (s != std::string::npos)
|
||||
{
|
||||
name = p.substr(0, s);
|
||||
p.erase(0, s + 1);
|
||||
}
|
||||
else
|
||||
std::swap(name, p);
|
||||
|
||||
while (name != m_name + node->m_name)
|
||||
{
|
||||
if (node->m_next == 0)
|
||||
return {};
|
||||
node = m_index + node->m_next;
|
||||
}
|
||||
}
|
||||
|
||||
return { m_data + node->m_data, node->m_size };
|
||||
}
|
||||
|
||||
struct mrsrc_file_loader_impl : public rsrc_loader_impl
|
||||
{
|
||||
mrsrc_file_loader_impl(const rsrc_loader_info& info);
|
||||
|
||||
virtual rsrc load(const std::string& path) const;
|
||||
|
||||
fs::path m_rsrc_dir;
|
||||
mutable std::mutex m_mutex;
|
||||
mutable std::map<fs::path,std::string> m_cache;
|
||||
};
|
||||
|
||||
mrsrc_file_loader_impl::mrsrc_file_loader_impl(const rsrc_loader_info& info)
|
||||
: m_rsrc_dir(info.info)
|
||||
{
|
||||
if (not fs::is_directory(m_rsrc_dir))
|
||||
{
|
||||
std::cerr << "The directory " << info.info << " does not exist" << std::endl
|
||||
<< "Loading dictionaries will most likely fail" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
rsrc mrsrc_file_loader_impl::load(const std::string& path) const
|
||||
{
|
||||
std::unique_lock lock(m_mutex);
|
||||
|
||||
fs::path p = m_rsrc_dir / path;
|
||||
|
||||
if (fs::exists(p))
|
||||
{
|
||||
auto i = m_cache.find(p);
|
||||
|
||||
if (i == m_cache.end())
|
||||
{
|
||||
std::ostringstream s;
|
||||
std::ifstream f(p);
|
||||
if (not f.is_open())
|
||||
throw std::runtime_error("Could not open " + p.string());
|
||||
|
||||
std::string line;
|
||||
while (std::getline(f, line))
|
||||
s << line << std::endl;
|
||||
|
||||
std::string data = s.str();
|
||||
std::tie(i, std::ignore) = m_cache.emplace(p, data);
|
||||
}
|
||||
|
||||
return { i->second.c_str(), i->second.length() };
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
rsrc_loader::rsrc_loader(const std::initializer_list<rsrc_loader_info>& loaders)
|
||||
{
|
||||
for (auto& l: loaders)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (l.type)
|
||||
{
|
||||
case rsrc_loader_type::file:
|
||||
m_loaders.push_back(new mrsrc_file_loader_impl(l));
|
||||
break;
|
||||
|
||||
case rsrc_loader_type::mrsrc:
|
||||
m_loaders.push_back(new mrsrc_rsrc_loader_impl(l));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
if (VERBOSE)
|
||||
std::cerr << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rsrc_loader::~rsrc_loader()
|
||||
{
|
||||
for (auto l: m_loaders)
|
||||
delete l;
|
||||
}
|
||||
|
||||
rsrc rsrc_loader::do_load(const std::string& name)
|
||||
{
|
||||
rsrc result;
|
||||
|
||||
for (auto loader: m_loaders)
|
||||
{
|
||||
result = loader->load(name);
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
355
src/CifValidator.cpp
Normal file
355
src/CifValidator.cpp
Normal file
@@ -0,0 +1,355 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
//// since gcc's regex is crashing....
|
||||
// #include <boost/regex.hpp>
|
||||
// #include <regex>
|
||||
|
||||
#include "cif++/Cif++.hpp"
|
||||
#include "cif++/CifParser.hpp"
|
||||
#include "cif++/CifValidator.hpp"
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
|
||||
extern int VERBOSE;
|
||||
|
||||
namespace cif
|
||||
{
|
||||
|
||||
ValidationError::ValidationError(const std::string& msg)
|
||||
: mMsg(msg)
|
||||
{
|
||||
}
|
||||
|
||||
ValidationError::ValidationError(const std::string& cat, const std::string& item, const std::string& msg)
|
||||
: mMsg("When validating _" + cat + '.' + item + ": " + msg)
|
||||
{
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
DDL_PrimitiveType mapToPrimitiveType(const std::string& s)
|
||||
{
|
||||
DDL_PrimitiveType result;
|
||||
if (iequals(s, "char"))
|
||||
result = ptChar;
|
||||
else if (iequals(s, "uchar"))
|
||||
result = ptUChar;
|
||||
else if (iequals(s, "numb"))
|
||||
result = ptNumb;
|
||||
else
|
||||
throw ValidationError("Not a known primitive type");
|
||||
return result;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
int ValidateType::compare(const char* a, const char* b) const
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (*a == 0)
|
||||
result = *b == 0 ? 0 : -1;
|
||||
else if (*b == 0)
|
||||
result = *a == 0 ? 0 : +1;
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (mPrimitiveType)
|
||||
{
|
||||
case ptNumb:
|
||||
{
|
||||
double da = strtod(a, nullptr);
|
||||
double db = strtod(b, nullptr);
|
||||
|
||||
auto d = da - db;
|
||||
if (std::abs(d) > std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
if (d > 0)
|
||||
result = 1;
|
||||
else if (d < 0)
|
||||
result = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ptUChar:
|
||||
case ptChar:
|
||||
{
|
||||
// CIF is guaranteed to have ascii only, therefore this primitive code will do
|
||||
// also, we're collapsing spaces
|
||||
|
||||
auto ai = a, bi = b;
|
||||
for (;;)
|
||||
{
|
||||
if (*ai == 0)
|
||||
{
|
||||
if (*bi != 0)
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
else if (*bi == 0)
|
||||
{
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
char ca = *ai;
|
||||
char cb = *bi;
|
||||
|
||||
if (mPrimitiveType == ptUChar)
|
||||
{
|
||||
ca = toupper(ca);
|
||||
cb = toupper(cb);
|
||||
}
|
||||
|
||||
result = ca - cb;
|
||||
|
||||
if (result != 0)
|
||||
break;
|
||||
|
||||
if (ca == ' ')
|
||||
{
|
||||
while (ai[1] == ' ')
|
||||
++ai;
|
||||
while (bi[1] == ' ')
|
||||
++bi;
|
||||
}
|
||||
|
||||
++ai;
|
||||
++bi;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::invalid_argument& ex)
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
//void ValidateItem::addLinked(ValidateItem* parent, const std::string& parentItem, const std::string& childItem)
|
||||
//{
|
||||
//// if (mParent != nullptr and VERBOSE)
|
||||
//// cerr << "replacing parent in " << mCategory->mName << " from " << mParent->mCategory->mName << " to " << parent->mCategory->mName << endl;
|
||||
//// mParent = parent;
|
||||
//
|
||||
// if (mType == nullptr and parent != nullptr)
|
||||
// mType = parent->mType;
|
||||
//
|
||||
// if (parent != nullptr)
|
||||
// {
|
||||
// mLinked.push_back({parent, parentItem, childItem});
|
||||
//
|
||||
// parent->mChildren.insert(this);
|
||||
////
|
||||
//// if (mCategory->mKeys == std::vector<std::string>{mTag})
|
||||
//// parent->mForeignKeys.insert(this);
|
||||
// }
|
||||
//}
|
||||
|
||||
void ValidateItem::operator()(std::string value) const
|
||||
{
|
||||
if (not value.empty() and value != "?" and value != ".")
|
||||
{
|
||||
if (mType != nullptr and not std::regex_match(value, mType->mRx))
|
||||
throw ValidationError(mCategory->mName, mTag, "Value '" + value + "' does not match type expression for type " + mType->mName);
|
||||
|
||||
if (not mEnums.empty())
|
||||
{
|
||||
if (mEnums.count(value) == 0)
|
||||
throw ValidationError(mCategory->mName, mTag, "Value '" + value + "' is not in the list of allowed values");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
void ValidateCategory::addItemValidator(ValidateItem&& v)
|
||||
{
|
||||
if (v.mMandatory)
|
||||
mMandatoryFields.insert(v.mTag);
|
||||
|
||||
v.mCategory = this;
|
||||
|
||||
auto r = mItemValidators.insert(std::move(v));
|
||||
if (not r.second and VERBOSE >= 4)
|
||||
std::cout << "Could not add validator for item " << v.mTag << " to category " << mName << std::endl;
|
||||
}
|
||||
|
||||
const ValidateItem* ValidateCategory::getValidatorForItem(std::string tag) const
|
||||
{
|
||||
const ValidateItem* result = nullptr;
|
||||
auto i = mItemValidators.find(ValidateItem{tag});
|
||||
if (i != mItemValidators.end())
|
||||
result = &*i;
|
||||
else if (VERBOSE > 4)
|
||||
std::cout << "No validator for tag " << tag << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
Validator::Validator()
|
||||
{
|
||||
}
|
||||
|
||||
Validator::~Validator()
|
||||
{
|
||||
}
|
||||
|
||||
void Validator::addTypeValidator(ValidateType&& v)
|
||||
{
|
||||
auto r = mTypeValidators.insert(std::move(v));
|
||||
if (not r.second and VERBOSE > 4)
|
||||
std::cout << "Could not add validator for type " << v.mName << std::endl;
|
||||
}
|
||||
|
||||
const ValidateType* Validator::getValidatorForType(std::string typeCode) const
|
||||
{
|
||||
const ValidateType* result = nullptr;
|
||||
|
||||
auto i = mTypeValidators.find(ValidateType{ typeCode, ptChar, std::regex() });
|
||||
if (i != mTypeValidators.end())
|
||||
result = &*i;
|
||||
else if (VERBOSE > 4)
|
||||
std::cout << "No validator for type " << typeCode << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Validator::addCategoryValidator(ValidateCategory&& v)
|
||||
{
|
||||
auto r = mCategoryValidators.insert(std::move(v));
|
||||
if (not r.second and VERBOSE > 4)
|
||||
std::cout << "Could not add validator for category " << v.mName << std::endl;
|
||||
}
|
||||
|
||||
const ValidateCategory* Validator::getValidatorForCategory(std::string category) const
|
||||
{
|
||||
const ValidateCategory* result = nullptr;
|
||||
auto i = mCategoryValidators.find(ValidateCategory{category});
|
||||
if (i != mCategoryValidators.end())
|
||||
result = &*i;
|
||||
else if (VERBOSE > 4)
|
||||
std::cout << "No validator for category " << category << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
ValidateItem* Validator::getValidatorForItem(std::string tag) const
|
||||
{
|
||||
ValidateItem* result = nullptr;
|
||||
|
||||
std::string cat, item;
|
||||
std::tie(cat, item) = splitTagName(tag);
|
||||
|
||||
auto* cv = getValidatorForCategory(cat);
|
||||
if (cv != nullptr)
|
||||
result = const_cast<ValidateItem*>(cv->getValidatorForItem(item));
|
||||
|
||||
if (result == nullptr and VERBOSE > 4)
|
||||
std::cout << "No validator for item " << tag << std::endl;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Validator::addLinkValidator(ValidateLink&& v)
|
||||
{
|
||||
assert(v.mParentKeys.size() == v.mChildKeys.size());
|
||||
if (v.mParentKeys.size() != v.mChildKeys.size())
|
||||
throw std::runtime_error("unequal number of keys for parent and child in link");
|
||||
|
||||
auto pcv = getValidatorForCategory(v.mParentCategory);
|
||||
auto ccv = getValidatorForCategory(v.mChildCategory);
|
||||
|
||||
if (pcv == nullptr)
|
||||
throw std::runtime_error("unknown parent category " + v.mParentCategory);
|
||||
|
||||
if (ccv == nullptr)
|
||||
throw std::runtime_error("unknown child category " + v.mChildCategory);
|
||||
|
||||
for (size_t i = 0; i < v.mParentKeys.size(); ++i)
|
||||
{
|
||||
auto piv = pcv->getValidatorForItem(v.mParentKeys[i]);
|
||||
|
||||
if (piv == nullptr)
|
||||
throw std::runtime_error("unknown parent tag _" + v.mParentCategory + '.' + v.mParentKeys[i]);
|
||||
|
||||
auto civ = ccv->getValidatorForItem(v.mChildKeys[i]);
|
||||
if (civ == nullptr)
|
||||
throw std::runtime_error("unknown child tag _" + v.mChildCategory + '.' + v.mChildKeys[i]);
|
||||
|
||||
if (civ->mType == nullptr and piv->mType != nullptr)
|
||||
const_cast<ValidateItem*>(civ)->mType = piv->mType;
|
||||
}
|
||||
|
||||
mLinkValidators.emplace_back(std::move(v));
|
||||
}
|
||||
|
||||
std::vector<const ValidateLink*> Validator::getLinksForParent(const std::string& category) const
|
||||
{
|
||||
std::vector<const ValidateLink*> result;
|
||||
|
||||
for (auto& l: mLinkValidators)
|
||||
{
|
||||
if (l.mParentCategory == category)
|
||||
result.push_back(&l);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<const ValidateLink*> Validator::getLinksForChild(const std::string& category) const
|
||||
{
|
||||
std::vector<const ValidateLink*> result;
|
||||
|
||||
for (auto& l: mLinkValidators)
|
||||
{
|
||||
if (l.mChildCategory == category)
|
||||
result.push_back(&l);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Validator::reportError(const std::string& msg, bool fatal)
|
||||
{
|
||||
if (mStrict or fatal)
|
||||
throw ValidationError(msg);
|
||||
else if (VERBOSE)
|
||||
std::cerr << msg << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
1419
src/Compound.cpp
Normal file
1419
src/Compound.cpp
Normal file
File diff suppressed because it is too large
Load Diff
5683
src/PDB2Cif.cpp
Normal file
5683
src/PDB2Cif.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1484
src/PDB2CifRemark3.cpp
Normal file
1484
src/PDB2CifRemark3.cpp
Normal file
File diff suppressed because it is too large
Load Diff
305
src/Point.cpp
Normal file
305
src/Point.cpp
Normal file
@@ -0,0 +1,305 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <random>
|
||||
#include <valarray>
|
||||
|
||||
#include "cif++/Point.hpp"
|
||||
|
||||
namespace mmcif
|
||||
{
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
quaternion Normalize(quaternion q)
|
||||
{
|
||||
std::valarray<double> t(4);
|
||||
|
||||
t[0] = q.R_component_1();
|
||||
t[1] = q.R_component_2();
|
||||
t[2] = q.R_component_3();
|
||||
t[3] = q.R_component_4();
|
||||
|
||||
t *= t;
|
||||
|
||||
double length = sqrt(t.sum());
|
||||
|
||||
if (length > 0.001)
|
||||
q /= length;
|
||||
else
|
||||
q = quaternion(1, 0, 0, 0);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
std::tuple<double,Point> QuaternionToAngleAxis(quaternion q)
|
||||
{
|
||||
if (q.R_component_1() > 1)
|
||||
q = Normalize(q);
|
||||
|
||||
// angle:
|
||||
double angle = 2 * acos(q.R_component_1());
|
||||
angle = angle * 180 / kPI;
|
||||
|
||||
// axis:
|
||||
double s = sqrt(1 - q.R_component_1() * q.R_component_1());
|
||||
if (s < 0.001)
|
||||
s = 1;
|
||||
|
||||
Point axis(q.R_component_2() / s, q.R_component_3() / s, q.R_component_4() / s);
|
||||
|
||||
return std::make_tuple(angle, axis);
|
||||
}
|
||||
|
||||
Point CenterPoints(std::vector<Point>& Points)
|
||||
{
|
||||
Point t;
|
||||
|
||||
for (Point& pt : Points)
|
||||
{
|
||||
t.mX += pt.mX;
|
||||
t.mY += pt.mY;
|
||||
t.mZ += pt.mZ;
|
||||
}
|
||||
|
||||
t.mX /= Points.size();
|
||||
t.mY /= Points.size();
|
||||
t.mZ /= Points.size();
|
||||
|
||||
for (Point& pt : Points)
|
||||
{
|
||||
pt.mX -= t.mX;
|
||||
pt.mY -= t.mY;
|
||||
pt.mZ -= t.mZ;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
Point Centroid(std::vector<Point>& Points)
|
||||
{
|
||||
Point result;
|
||||
|
||||
for (Point& pt : Points)
|
||||
result += pt;
|
||||
|
||||
result /= Points.size();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
double RMSd(const std::vector<Point>& a, const std::vector<Point>& b)
|
||||
{
|
||||
double sum = 0;
|
||||
for (uint32_t i = 0; i < a.size(); ++i)
|
||||
{
|
||||
std::valarray<double> d(3);
|
||||
|
||||
d[0] = b[i].mX - a[i].mX;
|
||||
d[1] = b[i].mY - a[i].mY;
|
||||
d[2] = b[i].mZ - a[i].mZ;
|
||||
|
||||
d *= d;
|
||||
|
||||
sum += d.sum();
|
||||
}
|
||||
|
||||
return std::sqrt(sum / a.size());
|
||||
}
|
||||
|
||||
// The next function returns the largest solution for a quartic equation
|
||||
// based on Ferrari's algorithm.
|
||||
// A depressed quartic is of the form:
|
||||
//
|
||||
// x^4 + ax^2 + bx + c = 0
|
||||
//
|
||||
// (since I'm too lazy to find out a better way, I've implemented the
|
||||
// routine using complex values to avoid nan's as a result of taking
|
||||
// sqrt of a negative number)
|
||||
double LargestDepressedQuarticSolution(double a, double b, double c)
|
||||
{
|
||||
std::complex<double> P = - (a * a) / 12 - c;
|
||||
std::complex<double> Q = - (a * a * a) / 108 + (a * c) / 3 - (b * b) / 8;
|
||||
std::complex<double> R = - Q / 2.0 + std::sqrt((Q * Q) / 4.0 + (P * P * P) / 27.0);
|
||||
|
||||
std::complex<double> U = std::pow(R, 1 / 3.0);
|
||||
|
||||
std::complex<double> y;
|
||||
if (U == 0.0)
|
||||
y = -5.0 * a / 6.0 + U - std::pow(Q, 1.0 / 3.0);
|
||||
else
|
||||
y = -5.0 * a / 6.0 + U - P / (3.0 * U);
|
||||
|
||||
std::complex<double> W = std::sqrt(a + 2.0 * y);
|
||||
|
||||
// And to get the final result:
|
||||
// result = (±W + sqrt(-(3 * alpha + 2 * y ± 2 * beta / W))) / 2;
|
||||
// We want the largest result, so:
|
||||
|
||||
std::valarray<double> t(4);
|
||||
|
||||
t[0] = (( W + std::sqrt(-(3.0 * a + 2.0 * y + 2.0 * b / W))) / 2.0).real();
|
||||
t[1] = (( W + std::sqrt(-(3.0 * a + 2.0 * y - 2.0 * b / W))) / 2.0).real();
|
||||
t[2] = ((-W + std::sqrt(-(3.0 * a + 2.0 * y + 2.0 * b / W))) / 2.0).real();
|
||||
t[3] = ((-W + std::sqrt(-(3.0 * a + 2.0 * y - 2.0 * b / W))) / 2.0).real();
|
||||
|
||||
return t.max();
|
||||
}
|
||||
|
||||
//quaternion AlignPoints(const vector<Point>& pa, const vector<Point>& pb)
|
||||
//{
|
||||
// // First calculate M, a 3x3 matrix containing the sums of products of the coordinates of A and B
|
||||
// matrix<double> M(3, 3, 0);
|
||||
//
|
||||
// for (uint32_t i = 0; i < pa.size(); ++i)
|
||||
// {
|
||||
// const Point& a = pa[i];
|
||||
// const Point& b = pb[i];
|
||||
//
|
||||
// M(0, 0) += a.mX * b.mX; M(0, 1) += a.mX * b.mY; M(0, 2) += a.mX * b.mZ;
|
||||
// M(1, 0) += a.mY * b.mX; M(1, 1) += a.mY * b.mY; M(1, 2) += a.mY * b.mZ;
|
||||
// M(2, 0) += a.mZ * b.mX; M(2, 1) += a.mZ * b.mY; M(2, 2) += a.mZ * b.mZ;
|
||||
// }
|
||||
//
|
||||
// // Now calculate N, a symmetric 4x4 matrix
|
||||
// symmetric_matrix<double> N(4);
|
||||
//
|
||||
// N(0, 0) = M(0, 0) + M(1, 1) + M(2, 2);
|
||||
// N(0, 1) = M(1, 2) - M(2, 1);
|
||||
// N(0, 2) = M(2, 0) - M(0, 2);
|
||||
// N(0, 3) = M(0, 1) - M(1, 0);
|
||||
//
|
||||
// N(1, 1) = M(0, 0) - M(1, 1) - M(2, 2);
|
||||
// N(1, 2) = M(0, 1) + M(1, 0);
|
||||
// N(1, 3) = M(0, 2) + M(2, 0);
|
||||
//
|
||||
// N(2, 2) = -M(0, 0) + M(1, 1) - M(2, 2);
|
||||
// N(2, 3) = M(1, 2) + M(2, 1);
|
||||
//
|
||||
// N(3, 3) = -M(0, 0) - M(1, 1) + M(2, 2);
|
||||
//
|
||||
// // det(N - λI) = 0
|
||||
// // find the largest λ (λm)
|
||||
// //
|
||||
// // Aλ4 + Bλ3 + Cλ2 + Dλ + E = 0
|
||||
// // A = 1
|
||||
// // B = 0
|
||||
// // and so this is a so-called depressed quartic
|
||||
// // solve it using Ferrari's algorithm
|
||||
//
|
||||
// double C = -2 * (
|
||||
// M(0, 0) * M(0, 0) + M(0, 1) * M(0, 1) + M(0, 2) * M(0, 2) +
|
||||
// M(1, 0) * M(1, 0) + M(1, 1) * M(1, 1) + M(1, 2) * M(1, 2) +
|
||||
// M(2, 0) * M(2, 0) + M(2, 1) * M(2, 1) + M(2, 2) * M(2, 2));
|
||||
//
|
||||
// double D = 8 * (M(0, 0) * M(1, 2) * M(2, 1) +
|
||||
// M(1, 1) * M(2, 0) * M(0, 2) +
|
||||
// M(2, 2) * M(0, 1) * M(1, 0)) -
|
||||
// 8 * (M(0, 0) * M(1, 1) * M(2, 2) +
|
||||
// M(1, 2) * M(2, 0) * M(0, 1) +
|
||||
// M(2, 1) * M(1, 0) * M(0, 2));
|
||||
//
|
||||
// double E =
|
||||
// (N(0,0) * N(1,1) - N(0,1) * N(0,1)) * (N(2,2) * N(3,3) - N(2,3) * N(2,3)) +
|
||||
// (N(0,1) * N(0,2) - N(0,0) * N(2,1)) * (N(2,1) * N(3,3) - N(2,3) * N(1,3)) +
|
||||
// (N(0,0) * N(1,3) - N(0,1) * N(0,3)) * (N(2,1) * N(2,3) - N(2,2) * N(1,3)) +
|
||||
// (N(0,1) * N(2,1) - N(1,1) * N(0,2)) * (N(0,2) * N(3,3) - N(2,3) * N(0,3)) +
|
||||
// (N(1,1) * N(0,3) - N(0,1) * N(1,3)) * (N(0,2) * N(2,3) - N(2,2) * N(0,3)) +
|
||||
// (N(0,2) * N(1,3) - N(2,1) * N(0,3)) * (N(0,2) * N(1,3) - N(2,1) * N(0,3));
|
||||
//
|
||||
// // solve quartic
|
||||
// double lm = LargestDepressedQuarticSolution(C, D, E);
|
||||
//
|
||||
// // calculate t = (N - λI)
|
||||
// matrix<double> li = identity_matrix<double>(4) * lm;
|
||||
// matrix<double> t = N - li;
|
||||
//
|
||||
// // calculate a matrix of cofactors for t
|
||||
// matrix<double> cf(4, 4);
|
||||
//
|
||||
// const uint32_t ixs[4][3] =
|
||||
// {
|
||||
// { 1, 2, 3 },
|
||||
// { 0, 2, 3 },
|
||||
// { 0, 1, 3 },
|
||||
// { 0, 1, 2 }
|
||||
// };
|
||||
//
|
||||
// uint32_t maxR = 0;
|
||||
// for (uint32_t r = 0; r < 4; ++r)
|
||||
// {
|
||||
// const uint32_t* ir = ixs[r];
|
||||
//
|
||||
// for (uint32_t c = 0; c < 4; ++c)
|
||||
// {
|
||||
// const uint32_t* ic = ixs[c];
|
||||
//
|
||||
// cf(r, c) =
|
||||
// t(ir[0], ic[0]) * t(ir[1], ic[1]) * t(ir[2], ic[2]) +
|
||||
// t(ir[0], ic[1]) * t(ir[1], ic[2]) * t(ir[2], ic[0]) +
|
||||
// t(ir[0], ic[2]) * t(ir[1], ic[0]) * t(ir[2], ic[1]) -
|
||||
// t(ir[0], ic[2]) * t(ir[1], ic[1]) * t(ir[2], ic[0]) -
|
||||
// t(ir[0], ic[1]) * t(ir[1], ic[0]) * t(ir[2], ic[2]) -
|
||||
// t(ir[0], ic[0]) * t(ir[1], ic[2]) * t(ir[2], ic[1]);
|
||||
// }
|
||||
//
|
||||
// if (r > maxR and cf(r, 0) > cf(maxR, 0))
|
||||
// maxR = r;
|
||||
// }
|
||||
//
|
||||
// // NOTE the negation of the y here, why? Maybe I swapped r/c above?
|
||||
// quaternion q(cf(maxR, 0), cf(maxR, 1), -cf(maxR, 2), cf(maxR, 3));
|
||||
// q = Normalize(q);
|
||||
//
|
||||
// return q;
|
||||
//}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
Point Nudge(Point p, float offset)
|
||||
{
|
||||
static std::random_device rd;
|
||||
static std::mt19937_64 rng(rd());
|
||||
|
||||
std::uniform_real_distribution<> randomAngle(0, 2 * kPI);
|
||||
std::normal_distribution<> randomOffset(0, offset);
|
||||
|
||||
float theta = randomAngle(rng);
|
||||
float phi1 = randomAngle(rng) - kPI;
|
||||
float phi2 = randomAngle(rng) - kPI;
|
||||
|
||||
quaternion q = boost::math::spherical(1.0f, theta, phi1, phi2);
|
||||
|
||||
Point r{ 0, 0, 1 };
|
||||
r.rotate(q);
|
||||
r *= randomOffset(rng);
|
||||
|
||||
return p + r;
|
||||
}
|
||||
|
||||
}
|
||||
1543
src/Secondary.cpp
Normal file
1543
src/Secondary.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2193
src/Structure.cpp
Normal file
2193
src/Structure.cpp
Normal file
File diff suppressed because it is too large
Load Diff
5714
src/SymOpTable_data.cpp
Normal file
5714
src/SymOpTable_data.cpp
Normal file
File diff suppressed because it is too large
Load Diff
94
src/Symmetry.cpp
Normal file
94
src/Symmetry.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "cif++/Config.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
#include "cif++/Symmetry.hpp"
|
||||
#include "cif++/CifUtils.hpp"
|
||||
|
||||
namespace mmcif
|
||||
{
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Unfortunately, clipper has a different numbering scheme than PDB
|
||||
// for rotation numbers. So we created a table to map those.
|
||||
// Perhaps a bit over the top, but hey....
|
||||
|
||||
#include "SymOpTable_data.cpp"
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
int GetSpacegroupNumber(std::string spacegroup)
|
||||
{
|
||||
if (spacegroup == "P 21 21 2 A")
|
||||
spacegroup = "P 21 21 2 (a)";
|
||||
else if (spacegroup.empty())
|
||||
throw std::runtime_error("No spacegroup, cannot continue");
|
||||
|
||||
int result = 0;
|
||||
|
||||
const size_t N = sizeof(kSpaceGroups) / sizeof(Spacegroup);
|
||||
int32_t L = 0, R = static_cast<int32_t>(N - 1);
|
||||
while (L <= R)
|
||||
{
|
||||
int32_t i = (L + R) / 2;
|
||||
|
||||
int d = spacegroup.compare(kSpaceGroups[i].name);
|
||||
|
||||
if (d > 0)
|
||||
L = i + 1;
|
||||
else if (d < 0)
|
||||
R = i - 1;
|
||||
else
|
||||
{
|
||||
result = kSpaceGroups[i].nr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// not found, see if we can find a match based on xHM name
|
||||
if (result == 0)
|
||||
{
|
||||
for (auto& sp: kSpaceGroups)
|
||||
{
|
||||
if (sp.xHM == spacegroup)
|
||||
{
|
||||
result = sp.nr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result == 0)
|
||||
throw std::runtime_error("Spacegroup name " + spacegroup + " was not found in table");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
1894
src/TlsParser.cpp
Normal file
1894
src/TlsParser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
128
test/unit-test.cpp
Normal file
128
test/unit-test.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE LibCifPP_Test
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
|
||||
// #include "cif++/DistanceMap.hpp"
|
||||
#include "cif++/Cif++.hpp"
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
cif::File operator""_cf(const char* text, size_t length)
|
||||
{
|
||||
struct membuf : public std::streambuf
|
||||
{
|
||||
membuf(char* text, size_t length)
|
||||
{
|
||||
this->setg(text, text, text + length);
|
||||
}
|
||||
} buffer(const_cast<char*>(text), length);
|
||||
|
||||
std::istream is(&buffer);
|
||||
return cif::File(is);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ut1)
|
||||
{
|
||||
// using namespace mmcif;
|
||||
|
||||
auto f = R"(data_TEST
|
||||
#
|
||||
loop_
|
||||
_test.id
|
||||
_test.name
|
||||
1 aap
|
||||
2 noot
|
||||
3 mies
|
||||
)"_cf;
|
||||
|
||||
auto& db = f.firstDatablock();
|
||||
|
||||
BOOST_CHECK(db.getName() == "TEST");
|
||||
|
||||
auto& test = db["test"];
|
||||
BOOST_CHECK(test.size() == 3);
|
||||
|
||||
// wrong! the next lines will crash. And that's OK, don't do that
|
||||
// for (auto r: test)
|
||||
// test.erase(r);
|
||||
|
||||
// BOOST_CHECK(test.empty());
|
||||
|
||||
// test.purge();
|
||||
|
||||
auto n = test.erase(cif::Key("id") == 1, [](const cif::Row& r) {
|
||||
BOOST_CHECK_EQUAL(r["id"].as<int>(), 1);
|
||||
BOOST_CHECK_EQUAL(r["name"].as<std::string>(), "aap");
|
||||
});
|
||||
|
||||
BOOST_CHECK_EQUAL(n, 1);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ut2)
|
||||
{
|
||||
// using namespace mmcif;
|
||||
|
||||
auto f = R"(data_TEST
|
||||
#
|
||||
loop_
|
||||
_test.id
|
||||
_test.name
|
||||
_test.value
|
||||
1 aap 1.0
|
||||
2 noot 1.1
|
||||
3 mies 1.2
|
||||
)"_cf;
|
||||
|
||||
auto& db = f.firstDatablock();
|
||||
|
||||
BOOST_CHECK(db.getName() == "TEST");
|
||||
|
||||
auto& test = db["test"];
|
||||
BOOST_CHECK(test.size() == 3);
|
||||
|
||||
int n = 0;
|
||||
for (auto r: test.find(cif::Key("name") == "aap"))
|
||||
{
|
||||
BOOST_CHECK(++n == 1);
|
||||
BOOST_CHECK(r["id"].as<int>() == 1);
|
||||
BOOST_CHECK(r["name"].as<std::string>() == "aap");
|
||||
BOOST_CHECK(r["value"].as<float>() == 1.0);
|
||||
}
|
||||
|
||||
auto t = test.find(cif::Key("id") == 1);
|
||||
BOOST_CHECK(not t.empty());
|
||||
BOOST_CHECK(t.front()["name"].as<std::string>() == "aap");
|
||||
|
||||
auto t2 = test.find(cif::Key("value") == 1.2);
|
||||
BOOST_CHECK(not t2.empty());
|
||||
BOOST_CHECK(t2.front()["name"].as<std::string>() == "mies");
|
||||
}
|
||||
13
tools/m4esc.sh
Executable file
13
tools/m4esc.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
file="$1"
|
||||
|
||||
echo -n "[["
|
||||
while IFS= read -r line; do
|
||||
echo $line | sed -e 's/\[/@<:@/g' -e 's/\]/@:>@/g' -e 's/#/@%:@/g' -e 's/\$/@S|@/g'
|
||||
echo
|
||||
done < "$file"
|
||||
|
||||
echo -n "]]"
|
||||
451
tools/symop-map-generator.cpp
Normal file
451
tools/symop-map-generator.cpp
Normal file
@@ -0,0 +1,451 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
cd ~/projects/pdb-redo/libcif++/tools/
|
||||
clang++ -I ~/my-clipper/include -L ~/my-clipper/lib -o symop-map-generator symop-map-generator.cpp -lclipper-core
|
||||
./symop-map-generator
|
||||
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
#include <map>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
std::regex kNameRx(R"(^(\d+) +(\d+) +(\d+) +(\S+) +(\S+) +(\S+) +'([^']+)'( +'([^']+)')?(?: +!.+)?$)");
|
||||
|
||||
class SymopParser
|
||||
{
|
||||
public:
|
||||
SymopParser() {}
|
||||
|
||||
array<int,15> parse(const string& s)
|
||||
{
|
||||
m_p = s.begin();
|
||||
m_e = s.end();
|
||||
m_lookahead = next_token();
|
||||
|
||||
parsepart(0);
|
||||
match((Token)',');
|
||||
parsepart(1);
|
||||
match((Token)',');
|
||||
parsepart(2);
|
||||
|
||||
if (m_lookahead != 0 or m_p != m_e)
|
||||
throw runtime_error("symmetry expression contains more data than expected");
|
||||
|
||||
return {
|
||||
m_rot[0][0], m_rot[0][1], m_rot[0][2],
|
||||
m_rot[1][0], m_rot[1][1], m_rot[1][2],
|
||||
m_rot[2][0], m_rot[2][1], m_rot[2][2],
|
||||
m_trn[0][0], m_trn[0][1],
|
||||
m_trn[1][0], m_trn[1][1],
|
||||
m_trn[2][0], m_trn[2][1]
|
||||
};
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
enum Token : int { Eof = 0, Number = 256, XYZ };
|
||||
|
||||
string to_string(Token t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case Eof: return "end of expression";
|
||||
case Number: return "number";
|
||||
case XYZ: return "'x', 'y' or 'z'";
|
||||
default:
|
||||
if (isprint(t))
|
||||
return string({'\'', static_cast<char>(t), '\''});
|
||||
return "invalid character " + std::to_string(static_cast<int>(t));
|
||||
}
|
||||
}
|
||||
|
||||
Token next_token()
|
||||
{
|
||||
Token result = Eof;
|
||||
while (m_p != m_e)
|
||||
{
|
||||
char ch = *m_p++;
|
||||
if (ch == ' ')
|
||||
continue;
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case 'x':
|
||||
case 'X':
|
||||
result = XYZ;
|
||||
m_nr = 0;
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
case 'Y':
|
||||
result = XYZ;
|
||||
m_nr = 1;
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
case 'Z':
|
||||
result = XYZ;
|
||||
m_nr = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isdigit(ch))
|
||||
{
|
||||
m_nr = ch - '0';
|
||||
result = Number;
|
||||
}
|
||||
else
|
||||
result = (Token)ch;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void match(Token token)
|
||||
{
|
||||
if (m_lookahead != token)
|
||||
throw runtime_error("Unexpected character " + to_string(m_lookahead) + " expected " + to_string(token));
|
||||
|
||||
m_lookahead = next_token();
|
||||
}
|
||||
|
||||
void parsepart(int row)
|
||||
{
|
||||
do
|
||||
{
|
||||
int sign = m_lookahead == '-' ? -1 : 1;
|
||||
if (m_lookahead == '-' or m_lookahead == '+')
|
||||
match(m_lookahead);
|
||||
|
||||
if (m_lookahead == Number)
|
||||
{
|
||||
m_trn[row][0] = sign * m_nr;
|
||||
match(Number);
|
||||
|
||||
match((Token)'/');
|
||||
|
||||
m_trn[row][1] = m_nr;
|
||||
match(Number);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rot[row][m_nr] = sign;
|
||||
match(XYZ);
|
||||
}
|
||||
}
|
||||
while (m_lookahead == '+' or m_lookahead == '-');
|
||||
}
|
||||
|
||||
Token m_lookahead;
|
||||
int m_nr;
|
||||
|
||||
string m_s;
|
||||
string::const_iterator m_p, m_e;
|
||||
|
||||
int m_rot[3][3] = {};
|
||||
int m_trn[3][2] = {};
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
const char* CLIBD = getenv("CLIBD");
|
||||
|
||||
if (CLIBD == nullptr)
|
||||
throw runtime_error("CCP4 not sourced");
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// store symop data here
|
||||
vector<tuple<int,int,array<int,15>>> data;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
struct SymInfoBlock
|
||||
{
|
||||
int nr;
|
||||
string xHM;
|
||||
string Hall;
|
||||
string old[2];
|
||||
};
|
||||
|
||||
map<int,SymInfoBlock> symInfo;
|
||||
int symopnr, mysymnr = 10000;
|
||||
|
||||
ifstream file(CLIBD + "/syminfo.lib"s);
|
||||
if (not file.is_open())
|
||||
throw runtime_error("Could not open syminfo.lib file");
|
||||
|
||||
enum class State { skip, spacegroup } state = State::skip;
|
||||
|
||||
string line;
|
||||
string Hall;
|
||||
vector<string> old;
|
||||
|
||||
const regex rx(R"(^symbol +(Hall|xHM|old) +'(.+?)'(?: +'(.+?)')?$)"),
|
||||
rx2(R"(symbol ccp4 (\d+))");;
|
||||
|
||||
SymInfoBlock cur = {};
|
||||
|
||||
while (getline(file, line))
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case State::skip:
|
||||
if (line == "begin_spacegroup")
|
||||
{
|
||||
state = State::spacegroup;
|
||||
symopnr = 1;
|
||||
++mysymnr;
|
||||
cur = { mysymnr };
|
||||
}
|
||||
break;
|
||||
|
||||
case State::spacegroup:
|
||||
{
|
||||
smatch m;
|
||||
if (regex_match(line, m, rx))
|
||||
{
|
||||
if (m[1] == "old")
|
||||
{
|
||||
cur.old[0] = m[2];
|
||||
if (m[3].matched)
|
||||
cur.old[1] = m[3];
|
||||
}
|
||||
else if (m[1] == "xHM")
|
||||
cur.xHM = m[2];
|
||||
else if (m[1] == "Hall")
|
||||
cur.Hall = m[2];
|
||||
}
|
||||
else if (regex_match(line, m, rx2))
|
||||
{
|
||||
int nr = stoi(m[1]);
|
||||
if (nr != 0)
|
||||
cur.nr = nr;
|
||||
}
|
||||
else if (line.compare(0, 6, "symop ") == 0)
|
||||
{
|
||||
SymopParser p;
|
||||
data.emplace_back(cur.nr, symopnr, p.parse(line.substr(6)));
|
||||
++symopnr;
|
||||
}
|
||||
else if (line == "end_spacegroup")
|
||||
{
|
||||
symInfo.emplace(cur.nr, cur);
|
||||
state = State::skip;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// // --------------------------------------------------------------------
|
||||
|
||||
// string line;
|
||||
// string spacegroupName;
|
||||
// int spacegroupNr, symopnr;
|
||||
|
||||
// enum class State { Initial, InSpacegroup, Error } state = State::Initial;
|
||||
|
||||
// while (getline(file, line))
|
||||
// {
|
||||
// if (line.empty())
|
||||
// throw runtime_error("Invalid symop.lib file, contains empty line");
|
||||
|
||||
// switch (state)
|
||||
// {
|
||||
// case State::Error:
|
||||
// case State::InSpacegroup:
|
||||
// if (line[0] == ' ')
|
||||
// {
|
||||
// if (state == State::Error)
|
||||
// continue;
|
||||
|
||||
// try
|
||||
// {
|
||||
// SymopParser p;
|
||||
// data.emplace_back(spacegroupNr, symopnr, spacegroupName, p.parse(line));
|
||||
// ++symopnr;
|
||||
// }
|
||||
// catch (const exception& e)
|
||||
// {
|
||||
// cerr << line << endl
|
||||
// << e.what() << endl;
|
||||
// }
|
||||
|
||||
// continue;
|
||||
// }
|
||||
// // fall through
|
||||
|
||||
// case State::Initial:
|
||||
// {
|
||||
// smatch m;
|
||||
// if (not regex_match(line, m, kNameRx))
|
||||
// {
|
||||
// cerr << line << endl;
|
||||
// throw runtime_error("Name line does not match regular expression");
|
||||
// }
|
||||
|
||||
// spacegroupNr = stoi(m[1]);
|
||||
// spacegroupName = m[7];
|
||||
// symopnr = 1;
|
||||
|
||||
// if (not symInfo.count(spacegroupNr))
|
||||
// throw runtime_error("Symmetry nr not found in syminfo.lib");
|
||||
|
||||
// if (symInfo[spacegroupNr].xHM != spacegroupName)
|
||||
// cerr << "Inconsistent data between symop.lib and syminfo.lib for spacegroup nr " << to_string(spacegroupNr) << endl;
|
||||
|
||||
// state = State::InSpacegroup;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
sort(data.begin(), data.end());
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
cout << R"(// This file was generated from $CLIBD/symop.lib
|
||||
// and $CLIBD/syminfo.lib using symop-map-generator,
|
||||
// part of the PDB-REDO suite of programs.
|
||||
|
||||
struct Spacegroup
|
||||
{
|
||||
const char* name;
|
||||
const char* xHM;
|
||||
const char* Hall;
|
||||
int nr;
|
||||
} kSpaceGroups[] =
|
||||
{
|
||||
)";
|
||||
|
||||
vector<tuple<string,int,string,string>> spacegroups;
|
||||
|
||||
for (auto& [nr, info]: symInfo)
|
||||
{
|
||||
spacegroups.emplace_back(info.old[0], nr, info.xHM, info.Hall);
|
||||
if (info.old[1].empty() == false)
|
||||
spacegroups.emplace_back(info.old[1], nr, info.xHM, info.Hall);
|
||||
}
|
||||
|
||||
sort(spacegroups.begin(), spacegroups.end());
|
||||
|
||||
for (auto [old, nr, xHM, Hall]: spacegroups)
|
||||
{
|
||||
old = '"' + old + '"' + string(20 - old.length(), ' ');
|
||||
xHM = '"' + xHM + '"' + string(30 - xHM.length(), ' ');
|
||||
|
||||
for (string::size_type p = Hall.length(); p > 0; --p)
|
||||
{
|
||||
if (Hall[p - 1] == '"')
|
||||
Hall.insert(p - 1, "\\", 1);
|
||||
}
|
||||
|
||||
Hall = '"' + Hall + '"' + string(40 - Hall.length(), ' ');
|
||||
|
||||
cout << "\t{ " << old << ", " << xHM << ", " << Hall << ", " << nr << " }," << endl;
|
||||
}
|
||||
|
||||
cout << R"(
|
||||
};
|
||||
|
||||
union SymopData
|
||||
{
|
||||
struct
|
||||
{
|
||||
int rot_0_0:2;
|
||||
int rot_0_1:2;
|
||||
int rot_0_2:2;
|
||||
int rot_1_0:2;
|
||||
int rot_1_1:2;
|
||||
int rot_1_2:2;
|
||||
int rot_2_0:2;
|
||||
int rot_2_1:2;
|
||||
int rot_2_2:2;
|
||||
unsigned int trn_0_0:3;
|
||||
unsigned int trn_0_1:3;
|
||||
unsigned int trn_1_0:3;
|
||||
unsigned int trn_1_1:3;
|
||||
unsigned int trn_2_0:3;
|
||||
unsigned int trn_2_1:3;
|
||||
};
|
||||
uint64_t iv:36;
|
||||
};
|
||||
|
||||
struct SymopDataBlock
|
||||
{
|
||||
uint16_t spacegroupNr;
|
||||
uint8_t rotationalNr;
|
||||
SymopData rt;
|
||||
} kSymopNrTable[] = {
|
||||
)" << endl;
|
||||
|
||||
int spacegroupNr = 0;
|
||||
for (auto& sd: data)
|
||||
{
|
||||
int sp, o;
|
||||
tie(sp, o, ignore) = sd;
|
||||
|
||||
if (sp > spacegroupNr)
|
||||
cout << " // " << symInfo[sp].xHM << endl;
|
||||
spacegroupNr = sp;
|
||||
|
||||
cout << " { " << setw(3) << sp
|
||||
<< ", " << setw(3) << o << ", { { ";
|
||||
for (auto i: get<2>(sd))
|
||||
cout << setw(2) << i << ',';
|
||||
cout << " } } }," << endl;
|
||||
}
|
||||
|
||||
cout << "};" << endl;
|
||||
}
|
||||
catch (const exception& ex)
|
||||
{
|
||||
cerr << endl
|
||||
<< "Program terminated due to error:" << endl
|
||||
<< ex.what() << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user